Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java @ 19505:16ad9711b44f
always inline intrinsics in the graph builder as well as any methods (recursively) called from an instrinsic
replace BytecodeParser.currentDepth with BytecodeParser.parent
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 19 Feb 2015 15:40:17 +0100 |
parents | 9525e4d5b385 |
children | 69b7ad0a3fda |
comparison
equal
deleted
inserted
replaced
19504:95aa11d4822d | 19505:16ad9711b44f |
---|---|
74 this.graphBuilderConfig = config; | 74 this.graphBuilderConfig = config; |
75 } | 75 } |
76 | 76 |
77 @Override | 77 @Override |
78 protected void run(StructuredGraph graph, HighTierContext context) { | 78 protected void run(StructuredGraph graph, HighTierContext context) { |
79 new Instance(context.getMetaAccess(), context.getStampProvider(), null, context.getConstantReflection(), graphBuilderConfig, context.getOptimisticOptimizations()).run(graph); | 79 new Instance(context.getMetaAccess(), context.getStampProvider(), null, context.getConstantReflection(), graphBuilderConfig, context.getOptimisticOptimizations(), false).run(graph); |
80 } | 80 } |
81 | 81 |
82 public GraphBuilderConfiguration getGraphBuilderConfig() { | 82 public GraphBuilderConfiguration getGraphBuilderConfig() { |
83 return graphBuilderConfig; | 83 return graphBuilderConfig; |
84 } | 84 } |
88 protected StructuredGraph currentGraph; | 88 protected StructuredGraph currentGraph; |
89 | 89 |
90 private final MetaAccessProvider metaAccess; | 90 private final MetaAccessProvider metaAccess; |
91 | 91 |
92 private ResolvedJavaMethod rootMethod; | 92 private ResolvedJavaMethod rootMethod; |
93 private final boolean rootMethodIsReplacement; | |
93 | 94 |
94 private final GraphBuilderConfiguration graphBuilderConfig; | 95 private final GraphBuilderConfiguration graphBuilderConfig; |
95 private final OptimisticOptimizations optimisticOpts; | 96 private final OptimisticOptimizations optimisticOpts; |
96 private final StampProvider stampProvider; | 97 private final StampProvider stampProvider; |
97 private final ConstantReflectionProvider constantReflection; | 98 private final ConstantReflectionProvider constantReflection; |
103 protected StructuredGraph getGraph() { | 104 protected StructuredGraph getGraph() { |
104 return currentGraph; | 105 return currentGraph; |
105 } | 106 } |
106 | 107 |
107 public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, SnippetReflectionProvider snippetReflectionProvider, ConstantReflectionProvider constantReflection, | 108 public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, SnippetReflectionProvider snippetReflectionProvider, ConstantReflectionProvider constantReflection, |
108 GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { | 109 GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, boolean rootMethodIsReplacement) { |
109 this.graphBuilderConfig = graphBuilderConfig; | 110 this.graphBuilderConfig = graphBuilderConfig; |
110 this.optimisticOpts = optimisticOpts; | 111 this.optimisticOpts = optimisticOpts; |
111 this.metaAccess = metaAccess; | 112 this.metaAccess = metaAccess; |
112 this.stampProvider = stampProvider; | 113 this.stampProvider = stampProvider; |
113 this.constantReflection = constantReflection; | 114 this.constantReflection = constantReflection; |
114 this.snippetReflectionProvider = snippetReflectionProvider; | 115 this.snippetReflectionProvider = snippetReflectionProvider; |
116 this.rootMethodIsReplacement = rootMethodIsReplacement; | |
115 assert metaAccess != null; | 117 assert metaAccess != null; |
116 } | 118 } |
117 | 119 |
118 public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig, | 120 public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig, |
119 OptimisticOptimizations optimisticOpts) { | 121 OptimisticOptimizations optimisticOpts, boolean rootMethodIsReplacement) { |
120 this(metaAccess, stampProvider, null, constantReflection, graphBuilderConfig, optimisticOpts); | 122 this(metaAccess, stampProvider, null, constantReflection, graphBuilderConfig, optimisticOpts, rootMethodIsReplacement); |
121 } | 123 } |
122 | 124 |
123 @Override | 125 @Override |
124 protected void run(StructuredGraph graph) { | 126 protected void run(StructuredGraph graph) { |
125 ResolvedJavaMethod method = graph.method(); | 127 ResolvedJavaMethod method = graph.method(); |
129 this.currentGraph = graph; | 131 this.currentGraph = graph; |
130 HIRFrameStateBuilder frameState = new HIRFrameStateBuilder(method, graph, true, null); | 132 HIRFrameStateBuilder frameState = new HIRFrameStateBuilder(method, graph, true, null); |
131 frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving(), this.graphBuilderConfig.getParameterPlugin()); | 133 frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving(), this.graphBuilderConfig.getParameterPlugin()); |
132 TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); | 134 TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); |
133 try { | 135 try { |
134 BytecodeParser parser = new BytecodeParser(metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI, false); | 136 BytecodeParser parser = new BytecodeParser(null, metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI, rootMethodIsReplacement); |
135 parser.build(0, graph.start(), frameState); | 137 parser.build(graph.start(), frameState); |
136 | 138 |
137 parser.connectLoopEndToBegin(); | 139 parser.connectLoopEndToBegin(); |
138 | 140 |
139 // remove dead parameters | 141 // remove dead parameters |
140 for (ParameterNode param : currentGraph.getNodes(ParameterNode.TYPE)) { | 142 for (ParameterNode param : currentGraph.getNodes(ParameterNode.TYPE)) { |
175 public class BytecodeParser extends AbstractBytecodeParser<ValueNode, HIRFrameStateBuilder> implements GraphBuilderContext { | 177 public class BytecodeParser extends AbstractBytecodeParser<ValueNode, HIRFrameStateBuilder> implements GraphBuilderContext { |
176 | 178 |
177 private BciBlockMapping blockMap; | 179 private BciBlockMapping blockMap; |
178 private LocalLiveness liveness; | 180 private LocalLiveness liveness; |
179 protected final int entryBCI; | 181 protected final int entryBCI; |
180 private int currentDepth; | 182 private final BytecodeParser parent; |
181 | 183 |
182 private LineNumberTable lnt; | 184 private LineNumberTable lnt; |
183 private int previousLineNumber; | 185 private int previousLineNumber; |
184 private int currentLineNumber; | 186 private int currentLineNumber; |
185 | 187 |
204 /** | 206 /** |
205 * @param isReplacement specifies if this object is being used to parse a method that | 207 * @param isReplacement specifies if this object is being used to parse a method that |
206 * implements the semantics of another method (i.e., an intrinsic) or | 208 * implements the semantics of another method (i.e., an intrinsic) or |
207 * bytecode instruction (i.e., a snippet) | 209 * bytecode instruction (i.e., a snippet) |
208 */ | 210 */ |
209 public BytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, int entryBCI, | 211 public BytecodeParser(BytecodeParser parent, MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, |
210 boolean isReplacement) { | 212 OptimisticOptimizations optimisticOpts, int entryBCI, boolean isReplacement) { |
211 super(metaAccess, method, graphBuilderConfig, optimisticOpts, isReplacement); | 213 super(metaAccess, method, graphBuilderConfig, optimisticOpts, isReplacement); |
212 this.entryBCI = entryBCI; | 214 this.entryBCI = entryBCI; |
215 this.parent = parent; | |
213 | 216 |
214 if (graphBuilderConfig.insertNonSafepointDebugInfo()) { | 217 if (graphBuilderConfig.insertNonSafepointDebugInfo()) { |
215 lnt = method.getLineNumberTable(); | 218 lnt = method.getLineNumberTable(); |
216 previousLineNumber = -1; | 219 previousLineNumber = -1; |
217 } | 220 } |
238 | 241 |
239 public FixedWithNextNode getBeforeUnwindNode() { | 242 public FixedWithNextNode getBeforeUnwindNode() { |
240 return this.beforeUnwindNode; | 243 return this.beforeUnwindNode; |
241 } | 244 } |
242 | 245 |
243 protected void build(int depth, FixedWithNextNode startInstruction, HIRFrameStateBuilder startFrameState) { | 246 protected void build(FixedWithNextNode startInstruction, HIRFrameStateBuilder startFrameState) { |
244 this.currentDepth = depth; | |
245 if (PrintProfilingInformation.getValue() && profilingInfo != null) { | 247 if (PrintProfilingInformation.getValue() && profilingInfo != null) { |
246 TTY.println("Profiling info for " + method.format("%H.%n(%p)")); | 248 TTY.println("Profiling info for " + method.format("%H.%n(%p)")); |
247 TTY.println(MetaUtil.indent(profilingInfo.toString(method, CodeUtil.NEW_LINE), " ")); | 249 TTY.println(MetaUtil.indent(profilingInfo.toString(method, CodeUtil.NEW_LINE), " ")); |
248 } | 250 } |
249 | 251 |
849 } | 851 } |
850 } | 852 } |
851 | 853 |
852 if (tryInvocationPlugin(args, targetMethod, resultType)) { | 854 if (tryInvocationPlugin(args, targetMethod, resultType)) { |
853 if (GraalOptions.TraceInlineDuringParsing.getValue()) { | 855 if (GraalOptions.TraceInlineDuringParsing.getValue()) { |
854 TTY.println(format("%sUsed invocation plugin for %s", nSpaces(currentDepth), targetMethod)); | 856 TTY.println(format("%sUsed invocation plugin for %s", nSpaces(getDepth()), targetMethod)); |
855 } | 857 } |
856 return; | 858 return; |
857 } | 859 } |
858 | 860 |
859 if (tryAnnotatedInvocationPlugin(args, targetMethod)) { | 861 if (tryAnnotatedInvocationPlugin(args, targetMethod)) { |
860 if (GraalOptions.TraceInlineDuringParsing.getValue()) { | 862 if (GraalOptions.TraceInlineDuringParsing.getValue()) { |
861 TTY.println(format("%sUsed annotated invocation plugin for %s", nSpaces(currentDepth), targetMethod)); | 863 TTY.println(format("%sUsed annotated invocation plugin for %s", nSpaces(getDepth()), targetMethod)); |
862 } | 864 } |
863 return; | 865 return; |
864 } | 866 } |
865 | 867 |
866 if (tryInline(args, targetMethod, invokeKind, returnType)) { | 868 if (tryInline(args, targetMethod, invokeKind, returnType)) { |
920 private boolean tryInline(ValueNode[] args, ResolvedJavaMethod targetMethod, InvokeKind invokeKind, JavaType returnType) { | 922 private boolean tryInline(ValueNode[] args, ResolvedJavaMethod targetMethod, InvokeKind invokeKind, JavaType returnType) { |
921 InlineInvokePlugin plugin = graphBuilderConfig.getInlineInvokePlugin(); | 923 InlineInvokePlugin plugin = graphBuilderConfig.getInlineInvokePlugin(); |
922 if (plugin == null || !invokeKind.isDirect() || !targetMethod.canBeInlined()) { | 924 if (plugin == null || !invokeKind.isDirect() || !targetMethod.canBeInlined()) { |
923 return false; | 925 return false; |
924 } | 926 } |
925 ResolvedJavaMethod inlinedMethod = plugin.getInlinedMethod(this, targetMethod, args, returnType, currentDepth); | 927 ResolvedJavaMethod inlinedMethod = plugin.getInlinedMethod(this, targetMethod, args, returnType); |
926 if (inlinedMethod != null && inlinedMethod.hasBytecodes()) { | 928 if (inlinedMethod != null) { |
927 if (TraceInlineDuringParsing.getValue()) { | 929 if (TraceInlineDuringParsing.getValue()) { |
928 int bci = this.bci(); | 930 int bci = this.bci(); |
929 StackTraceElement ste = this.method.asStackTraceElement(bci); | 931 StackTraceElement ste = this.method.asStackTraceElement(bci); |
930 TTY.println(format("%s%s (%s:%d) inlining call to %s", nSpaces(currentDepth), method.getName(), ste.getFileName(), ste.getLineNumber(), inlinedMethod.format("%h.%n(%p)"))); | 932 TTY.println(format("%s%s (%s:%d) inlining call to %s", nSpaces(getDepth()), method.getName(), ste.getFileName(), ste.getLineNumber(), inlinedMethod.format("%h.%n(%p)"))); |
931 } | 933 } |
932 parseAndInlineCallee(inlinedMethod, args, parsingReplacement || !inlinedMethod.equals(targetMethod)); | 934 parseAndInlineCallee(inlinedMethod, args, parsingReplacement || inlinedMethod != targetMethod); |
933 plugin.postInline(inlinedMethod); | 935 plugin.postInline(inlinedMethod); |
934 return true; | 936 return true; |
935 } | 937 } |
936 | 938 |
937 return false; | 939 return false; |
938 } | 940 } |
939 | 941 |
940 private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, boolean isReplacement) { | 942 private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, boolean isReplacement) { |
941 BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, INVOCATION_ENTRY_BCI, isReplacement); | 943 BytecodeParser parser = new BytecodeParser(this, metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, INVOCATION_ENTRY_BCI, isReplacement); |
942 final FrameState[] lazyFrameState = new FrameState[1]; | 944 final FrameState[] lazyFrameState = new FrameState[1]; |
943 | 945 |
944 // Replacements often produce nodes with an illegal kind (e.g., pointer stamps) | 946 // Replacements often produce nodes with an illegal kind (e.g., pointer stamps) |
945 // so the frame state builder should not check the types flowing through the frame | 947 // so the frame state builder should not check the types flowing through the frame |
946 // since all such assertions are in terms of Java kinds. | 948 // since all such assertions are in terms of Java kinds. |
951 lazyFrameState[0] = frameState.create(bci()); | 953 lazyFrameState[0] = frameState.create(bci()); |
952 } | 954 } |
953 return lazyFrameState[0]; | 955 return lazyFrameState[0]; |
954 }); | 956 }); |
955 startFrameState.initializeFromArgumentsArray(args); | 957 startFrameState.initializeFromArgumentsArray(args); |
956 parser.build(currentDepth + 1, this.lastInstr, startFrameState); | 958 parser.build(this.lastInstr, startFrameState); |
957 | 959 |
958 FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode(); | 960 FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode(); |
959 this.lastInstr = calleeBeforeReturnNode; | 961 this.lastInstr = calleeBeforeReturnNode; |
960 if (calleeBeforeReturnNode != null) { | 962 if (calleeBeforeReturnNode != null) { |
961 ValueNode calleeReturnValue = parser.getReturnValue(); | 963 ValueNode calleeReturnValue = parser.getReturnValue(); |
1005 } | 1007 } |
1006 | 1008 |
1007 @Override | 1009 @Override |
1008 protected void genReturn(ValueNode x) { | 1010 protected void genReturn(ValueNode x) { |
1009 | 1011 |
1010 if (this.currentDepth == 0) { | 1012 if (parent == null) { |
1011 frameState.setRethrowException(false); | 1013 frameState.setRethrowException(false); |
1012 frameState.clearStack(); | 1014 frameState.clearStack(); |
1013 beforeReturn(x); | 1015 beforeReturn(x); |
1014 append(new ReturnNode(x)); | 1016 append(new ReturnNode(x)); |
1015 } else { | 1017 } else { |
1513 assert frameState.stackSize() == 0; | 1515 assert frameState.stackSize() == 0; |
1514 beforeReturn(x); | 1516 beforeReturn(x); |
1515 this.returnValue = x; | 1517 this.returnValue = x; |
1516 this.beforeReturnNode = this.lastInstr; | 1518 this.beforeReturnNode = this.lastInstr; |
1517 } else if (block == blockMap.getUnwindBlock()) { | 1519 } else if (block == blockMap.getUnwindBlock()) { |
1518 if (currentDepth == 0) { | 1520 if (parent == null) { |
1519 frameState.setRethrowException(false); | 1521 frameState.setRethrowException(false); |
1520 createUnwind(); | 1522 createUnwind(); |
1521 } else { | 1523 } else { |
1522 ValueNode exception = frameState.apop(); | 1524 ValueNode exception = frameState.apop(); |
1523 this.unwindValue = exception; | 1525 this.unwindValue = exception; |
1682 | 1684 |
1683 // read the opcode | 1685 // read the opcode |
1684 int opcode = stream.currentBC(); | 1686 int opcode = stream.currentBC(); |
1685 assert traceState(); | 1687 assert traceState(); |
1686 assert traceInstruction(bci, opcode, bci == block.startBci); | 1688 assert traceInstruction(bci, opcode, bci == block.startBci); |
1687 if (currentDepth == 0 && bci == entryBCI) { | 1689 if (parent == null && bci == entryBCI) { |
1688 if (block.getJsrScope() != JsrScope.EMPTY_SCOPE) { | 1690 if (block.getJsrScope() != JsrScope.EMPTY_SCOPE) { |
1689 throw new BailoutException("OSR into a JSR scope is not supported"); | 1691 throw new BailoutException("OSR into a JSR scope is not supported"); |
1690 } | 1692 } |
1691 EntryMarkerNode x = append(new EntryMarkerNode()); | 1693 EntryMarkerNode x = append(new EntryMarkerNode()); |
1692 frameState.insertProxies(x); | 1694 frameState.insertProxies(x); |
1829 | 1831 |
1830 boolean genReturn = false; | 1832 boolean genReturn = false; |
1831 boolean genConditional = false; | 1833 boolean genConditional = false; |
1832 if (gotoOrFallThroughAfterConstant(trueBlock) && gotoOrFallThroughAfterConstant(falseBlock) && trueBlock.getSuccessor(0) == falseBlock.getSuccessor(0)) { | 1834 if (gotoOrFallThroughAfterConstant(trueBlock) && gotoOrFallThroughAfterConstant(falseBlock) && trueBlock.getSuccessor(0) == falseBlock.getSuccessor(0)) { |
1833 genConditional = true; | 1835 genConditional = true; |
1834 } else if (this.currentDepth != 0 && returnAfterConstant(trueBlock) && returnAfterConstant(falseBlock)) { | 1836 } else if (parent != null && returnAfterConstant(trueBlock) && returnAfterConstant(falseBlock)) { |
1835 genReturn = true; | 1837 genReturn = true; |
1836 genConditional = true; | 1838 genConditional = true; |
1837 } | 1839 } |
1838 | 1840 |
1839 if (genConditional) { | 1841 if (genConditional) { |
1932 public boolean parsingReplacement() { | 1934 public boolean parsingReplacement() { |
1933 return parsingReplacement; | 1935 return parsingReplacement; |
1934 } | 1936 } |
1935 | 1937 |
1936 public StructuredGraph getGraph() { | 1938 public StructuredGraph getGraph() { |
1939 | |
1937 return currentGraph; | 1940 return currentGraph; |
1938 } | 1941 } |
1939 | 1942 |
1940 public GuardingNode getCurrentBlockGuard() { | 1943 public GuardingNode getCurrentBlockGuard() { |
1941 return (GuardingNode) getFirstInstruction(currentBlock, getCurrentDimension()); | 1944 return (GuardingNode) getFirstInstruction(currentBlock, getCurrentDimension()); |
1942 } | 1945 } |
1943 | 1946 |
1947 public GraphBuilderContext getParent() { | |
1948 return parent; | |
1949 } | |
1950 | |
1951 public int getDepth() { | |
1952 return parent == null ? 0 : 1 + parent.getDepth(); | |
1953 } | |
1954 | |
1944 @Override | 1955 @Override |
1945 public String toString() { | 1956 public String toString() { |
1946 return method.format("%H.%n(%p)@") + bci(); | 1957 Formatter fmt = new Formatter(); |
1958 BytecodeParser bp = this; | |
1959 String indent = ""; | |
1960 while (bp != null) { | |
1961 if (bp != this) { | |
1962 fmt.format("%n%s", indent); | |
1963 } | |
1964 fmt.format("%s replacement=%s", bp.method.asStackTraceElement(bp.bci()), parsingReplacement); | |
1965 bp = bp.parent; | |
1966 indent += " "; | |
1967 } | |
1968 return fmt.toString(); | |
1947 } | 1969 } |
1948 } | 1970 } |
1949 } | 1971 } |
1950 | 1972 |
1951 static String nSpaces(int n) { | 1973 static String nSpaces(int n) { |