comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java @ 17260:222b60e248ba

Truffle-DSL: fixed regression with @SlowPath on specialize0.
author Christian Humer <christian.humer@gmail.com>
date Tue, 30 Sep 2014 00:48:47 +0200
parents 6ee7afea175a
children b4e38f4ca414
comparison
equal deleted inserted replaced
17259:eff18e262a13 17260:222b60e248ba
127 127
128 private static String castValueName(Parameter parameter) { 128 private static String castValueName(Parameter parameter) {
129 return valueName(parameter) + "Cast"; 129 return valueName(parameter) + "Cast";
130 } 130 }
131 131
132 private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean evaluated) { 132 private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean disableFrame, boolean evaluated) {
133 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { 133 if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
134 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); 134 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue"));
135 } 135 }
136 for (Parameter parameter : specialization.getParameters()) { 136 for (Parameter parameter : specialization.getParameters()) {
137 ParameterSpec spec = parameter.getSpecification(); 137 ParameterSpec spec = parameter.getSpecification();
138 if (forceFrame && spec.getName().equals("frame")) { 138 if ((disableFrame || forceFrame) && spec.getName().equals("frame")) {
139 continue; 139 continue;
140 } 140 }
141 if (spec.isLocal()) { 141 if (spec.isLocal()) {
142 continue; 142 continue;
143 } 143 }
150 method.addParameter(new CodeVariableElement(parameter.getType(), name)); 150 method.addParameter(new CodeVariableElement(parameter.getType(), name));
151 } 151 }
152 } 152 }
153 153
154 private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, 154 private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame,
155 Map<String, String> customNames) { 155 boolean disableFrame, Map<String, String> customNames) {
156 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { 156 if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
157 builder.string("frameValue"); 157 builder.string("frameValue");
158 } 158 }
159 for (Parameter parameter : specialization.getParameters()) { 159 for (Parameter parameter : specialization.getParameters()) {
160 ParameterSpec spec = parameter.getSpecification(); 160 ParameterSpec spec = parameter.getSpecification();
161 if (forceFrame && spec.getName().equals("frame")) { 161 if ((disableFrame || forceFrame) && spec.getName().equals("frame")) {
162 continue; 162 continue;
163 } 163 }
164 164
165 if (parameter.getSpecification().isLocal()) { 165 if (parameter.getSpecification().isLocal()) {
166 continue; 166 continue;
320 } 320 }
321 321
322 /** 322 /**
323 * <pre> 323 * <pre>
324 * variant1 $condition != null 324 * variant1 $condition != null
325 * 325 *
326 * $type $name = defaultValue($type); 326 * $type $name = defaultValue($type);
327 * if ($condition) { 327 * if ($condition) {
328 * $name = $value; 328 * $name = $value;
329 * } 329 * }
330 * 330 *
331 * variant2 $condition != null 331 * variant2 $condition != null
332 * $type $name = $value; 332 * $type $name = $value;
333 * </pre> 333 * </pre>
334 * 334 *
335 * . 335 * .
1032 } 1032 }
1033 1033
1034 private Element createInfoMessage(NodeData node) { 1034 private Element createInfoMessage(NodeData node) {
1035 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), CREATE_INFO); 1035 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), CREATE_INFO);
1036 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message")); 1036 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message"));
1037 addInternalValueParameters(method, node.getGenericSpecialization(), false, false); 1037 addInternalValueParameters(method, node.getGenericSpecialization(), false, false, false);
1038 1038
1039 CodeTreeBuilder builder = method.createBuilder(); 1039 CodeTreeBuilder builder = method.createBuilder();
1040 1040
1041 builder.startIf().tree(truffleBooleanOption(builder, TruffleTypes.OPTION_DETAILED_REWRITE_REASONS)).end(); 1041 builder.startIf().tree(truffleBooleanOption(builder, TruffleTypes.OPTION_DETAILED_REWRITE_REASONS)).end();
1042 builder.startBlock(); 1042 builder.startBlock();
1087 return method; 1087 return method;
1088 } 1088 }
1089 1089
1090 private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph) { 1090 private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph) {
1091 CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_CHAINED); 1091 CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_CHAINED);
1092 addInternalValueParameters(cachedExecute, polymorph, true, false); 1092 addInternalValueParameters(cachedExecute, polymorph, true, false, false);
1093 1093
1094 ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0); 1094 ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0);
1095 boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(getContext()); 1095 boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(getContext());
1096 if (sourceThrowsUnexpected && sourceExecutableType.getType().equals(node.getGenericSpecialization().getReturnType().getTypeSystemType())) { 1096 if (sourceThrowsUnexpected && sourceExecutableType.getType().equals(node.getGenericSpecialization().getReturnType().getTypeSystemType())) {
1097 sourceThrowsUnexpected = false; 1097 sourceThrowsUnexpected = false;
1242 1242
1243 protected final CodeExecutableElement createExecuteUninitialized() { 1243 protected final CodeExecutableElement createExecuteUninitialized() {
1244 NodeData node = getModel().getNode(); 1244 NodeData node = getModel().getNode();
1245 SpecializationData generic = node.getGenericSpecialization(); 1245 SpecializationData generic = node.getGenericSpecialization();
1246 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), generic.getReturnType().getType(), EXECUTE_UNINITIALIZED); 1246 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), generic.getReturnType().getType(), EXECUTE_UNINITIALIZED);
1247 addInternalValueParameters(method, generic, true, false); 1247 addInternalValueParameters(method, generic, true, false, false);
1248 CodeTreeBuilder builder = method.createBuilder(); 1248 CodeTreeBuilder builder = method.createBuilder();
1249 1249
1250 boolean needsFrame = node.isFrameUsedByAnyGuard(getContext());
1250 CodeTreeBuilder createSpecializationCall = builder.create(); 1251 CodeTreeBuilder createSpecializationCall = builder.create();
1251 createSpecializationCall.startCall(SPECIALIZE); 1252 createSpecializationCall.startCall(SPECIALIZE);
1252 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, node.isFrameUsedByAnyGuard(getContext()), null); 1253 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null);
1253 createSpecializationCall.end(); 1254 createSpecializationCall.end();
1254 builder.declaration(baseClassName(node), "newNode", createSpecializationCall); 1255 builder.declaration(baseClassName(node), "newNode", createSpecializationCall);
1255 1256
1256 if (generic.isReachable()) { 1257 if (generic.isReachable()) {
1257 builder.startIf().string("newNode == null").end().startBlock(); 1258 builder.startIf().string("newNode == null").end().startBlock();
1267 } 1268 }
1268 1269
1269 builder.startReturn(); 1270 builder.startReturn();
1270 builder.startStaticCall(context.getTruffleTypes().getDslShare(), "rewriteUninitialized").string("this").string("newNode").end(); 1271 builder.startStaticCall(context.getTruffleTypes().getDslShare(), "rewriteUninitialized").string("this").string("newNode").end();
1271 builder.string(".").startCall(EXECUTE_CHAINED); 1272 builder.string(".").startCall(EXECUTE_CHAINED);
1272 addInternalValueParameterNames(builder, generic, generic, null, true, null); 1273 addInternalValueParameterNames(builder, generic, generic, null, true, false, null);
1273 builder.end(); 1274 builder.end();
1274 builder.end(); 1275 builder.end();
1275 1276
1276 if (generic.isReachable()) { 1277 if (generic.isReachable()) {
1277 builder.end(); 1278 builder.end();
1281 } 1282 }
1282 1283
1283 private CodeTree createInfoCall(CodeTreeBuilder parent, SpecializationData specialization, String reason) { 1284 private CodeTree createInfoCall(CodeTreeBuilder parent, SpecializationData specialization, String reason) {
1284 CodeTreeBuilder builder = parent.create(); 1285 CodeTreeBuilder builder = parent.create();
1285 builder.startCall(CREATE_INFO).string(reason); 1286 builder.startCall(CREATE_INFO).string(reason);
1286 addInternalValueParameterNames(builder, specialization, specialization, null, false, null); 1287 addInternalValueParameterNames(builder, specialization, specialization, null, false, false, null);
1287 builder.end(); 1288 builder.end();
1288 return builder.getRoot(); 1289 return builder.getRoot();
1289 } 1290 }
1290 1291
1291 private CodeExecutableElement createMonomorphicRewrite() { 1292 private CodeExecutableElement createMonomorphicRewrite() {
1292 NodeData node = getModel().getNode(); 1293 NodeData node = getModel().getNode();
1293 1294
1294 SpecializationData generic = node.getGenericSpecialization(); 1295 SpecializationData generic = node.getGenericSpecialization();
1295 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), generic.getReturnType().getType(), REWRITE); 1296 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), generic.getReturnType().getType(), REWRITE);
1296 addInternalValueParameters(method, generic, true, false); 1297 addInternalValueParameters(method, generic, true, false, false);
1297 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); 1298 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason"));
1298 1299
1300 boolean needsFrame = node.isFrameUsedByAnyGuard(getContext());
1299 CodeTreeBuilder builder = method.createBuilder(); 1301 CodeTreeBuilder builder = method.createBuilder();
1300 1302
1301 builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end().end(); 1303 builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end().end();
1302 String baseClassName = baseClassName(getModel().getNode()); 1304 String baseClassName = baseClassName(getModel().getNode());
1303 CodeTreeBuilder createSpecializationCall = builder.create(); 1305 CodeTreeBuilder createSpecializationCall = builder.create();
1304 createSpecializationCall.startCall(SPECIALIZE); 1306 createSpecializationCall.startCall(SPECIALIZE);
1305 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, node.isFrameUsedByAnyGuard(getContext()), null); 1307 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null);
1306 createSpecializationCall.end(); 1308 createSpecializationCall.end();
1307 builder.declaration(baseClassName, "newNode", createSpecializationCall); 1309 builder.declaration(baseClassName, "newNode", createSpecializationCall);
1308 1310
1309 builder.startIf().string("newNode == null").end().startBlock(); 1311 builder.startIf().string("newNode == null").end().startBlock();
1310 builder.startStatement(); 1312 builder.startStatement();
1326 builder.tree(createRewritePolymorphic(builder, node, "this")); 1328 builder.tree(createRewritePolymorphic(builder, node, "this"));
1327 builder.end(); 1329 builder.end();
1328 1330
1329 builder.startReturn(); 1331 builder.startReturn();
1330 builder.startCall("returnNode", EXECUTE_CHAINED); 1332 builder.startCall("returnNode", EXECUTE_CHAINED);
1331 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, null); 1333 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, false, null);
1332 builder.end(); 1334 builder.end();
1333 builder.end(); 1335 builder.end();
1334 1336
1335 return method; 1337 return method;
1336 } 1338 }
1361 1363
1362 if (!needsFrame) { 1364 if (!needsFrame) {
1363 method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath())); 1365 method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath()));
1364 } 1366 }
1365 1367
1366 addInternalValueParameters(method, node.getGenericSpecialization(), needsFrame, false); 1368 addInternalValueParameters(method, node.getGenericSpecialization(), needsFrame, !needsFrame, false);
1367 final CodeTreeBuilder builder = method.createBuilder(); 1369 final CodeTreeBuilder builder = method.createBuilder();
1368 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, new CodeBlock<SpecializationData>() { 1370 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, new CodeBlock<SpecializationData>() {
1369 1371
1370 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { 1372 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
1371 return createCreateSpecializationMethodBody0(builder, current, needsFrame); 1373 return createCreateSpecializationMethodBody0(builder, current, needsFrame);
2227 2229
2228 builder.startReturn(); 2230 builder.startReturn();
2229 2231
2230 CodeTreeBuilder execute = new CodeTreeBuilder(builder); 2232 CodeTreeBuilder execute = new CodeTreeBuilder(builder);
2231 execute.startCall("next0", EXECUTE_CHAINED); 2233 execute.startCall("next0", EXECUTE_CHAINED);
2232 addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, null); 2234 addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, false, null);
2233 execute.end(); 2235 execute.end();
2234 2236
2235 TypeData sourceType = polymorphic.getReturnType().getTypeSystemType(); 2237 TypeData sourceType = polymorphic.getReturnType().getTypeSystemType();
2236 2238
2237 builder.tree(createExpectExecutableType(node, sourceType, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), execute.getRoot())); 2239 builder.tree(createExpectExecutableType(node, sourceType, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), execute.getRoot()));
2343 protected CodeTree createCallRewriteMonomorphic(CodeTreeBuilder parent, boolean hasUnexpected, TypeData returnType, SpecializationData current, Parameter exceptionParam, String reason) { 2345 protected CodeTree createCallRewriteMonomorphic(CodeTreeBuilder parent, boolean hasUnexpected, TypeData returnType, SpecializationData current, Parameter exceptionParam, String reason) {
2344 NodeData node = current.getNode(); 2346 NodeData node = current.getNode();
2345 SpecializationData generic = node.getGenericSpecialization(); 2347 SpecializationData generic = node.getGenericSpecialization();
2346 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); 2348 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent);
2347 specializeCall.startCall(REWRITE); 2349 specializeCall.startCall(REWRITE);
2348 addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, null); 2350 addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, false, null);
2349 specializeCall.doubleQuote(reason); 2351 specializeCall.doubleQuote(reason);
2350 specializeCall.end().end(); 2352 specializeCall.end().end();
2351 2353
2352 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 2354 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
2353 2355
2665 executeMethod.getModifiers().remove(Modifier.ABSTRACT); 2667 executeMethod.getModifiers().remove(Modifier.ABSTRACT);
2666 CodeTreeBuilder builder = executeMethod.createBuilder(); 2668 CodeTreeBuilder builder = executeMethod.createBuilder();
2667 2669
2668 if (specialization.isPolymorphic()) { 2670 if (specialization.isPolymorphic()) {
2669 builder.startReturn().startCall("this.next0", EXECUTE_CHAINED); 2671 builder.startReturn().startCall("this.next0", EXECUTE_CHAINED);
2670 addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, null); 2672 addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, false, null);
2671 builder.end().end(); 2673 builder.end().end();
2672 } else if (specialization.isUninitialized()) { 2674 } else if (specialization.isUninitialized()) {
2673 builder.tree(createDeoptimizeUninitialized(node, builder)); 2675 builder.tree(createDeoptimizeUninitialized(node, builder));
2674 builder.startReturn().startCall("this", EXECUTE_UNINITIALIZED); 2676 builder.startReturn().startCall("this", EXECUTE_UNINITIALIZED);
2675 addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, null); 2677 addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, false, null);
2676 builder.end().end(); 2678 builder.end().end();
2677 } else { 2679 } else {
2678 CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder); 2680 CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder);
2679 elseBuilder.startReturn().startCall("this.next0", EXECUTE_CHAINED); 2681 elseBuilder.startReturn().startCall("this.next0", EXECUTE_CHAINED);
2680 addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, null); 2682 addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, false, null);
2681 elseBuilder.end().end(); 2683 elseBuilder.end().end();
2682 2684
2683 builder.tree(createExecuteTree(builder, polymorphic, SpecializationGroup.create(specialization), new CodeBlock<SpecializationData>() { 2685 builder.tree(createExecuteTree(builder, polymorphic, SpecializationGroup.create(specialization), new CodeBlock<SpecializationData>() {
2684 2686
2685 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { 2687 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
2862 } 2864 }
2863 2865
2864 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent); 2866 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent);
2865 if (specialization.isPolymorphic()) { 2867 if (specialization.isPolymorphic()) {
2866 returnBuilder.startCall("next0", EXECUTE_CHAINED); 2868 returnBuilder.startCall("next0", EXECUTE_CHAINED);
2867 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, null); 2869 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null);
2868 returnBuilder.end(); 2870 returnBuilder.end();
2869 } else if (specialization.isUninitialized()) { 2871 } else if (specialization.isUninitialized()) {
2870 returnBuilder.startCall(EXECUTE_UNINITIALIZED); 2872 returnBuilder.startCall(EXECUTE_UNINITIALIZED);
2871 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, null); 2873 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null);
2872 returnBuilder.end(); 2874 returnBuilder.end();
2873 } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { 2875 } else if (specialization.getMethod() == null && !node.needsRewrites(context)) {
2874 emitEncounteredSynthetic(builder, specialization); 2876 emitEncounteredSynthetic(builder, specialization);
2875 } else { 2877 } else {
2876 returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null)); 2878 returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null));