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) {