285 // Implementation of IR |
285 // Implementation of IR |
286 |
286 |
287 IR::IR(Compilation* compilation, ciMethod* method, int osr_bci) : |
287 IR::IR(Compilation* compilation, ciMethod* method, int osr_bci) : |
288 _locals_size(in_WordSize(-1)) |
288 _locals_size(in_WordSize(-1)) |
289 , _num_loops(0) { |
289 , _num_loops(0) { |
290 // initialize data structures |
|
291 ValueType::initialize(); |
|
292 Instruction::initialize(); |
|
293 BlockBegin::initialize(); |
|
294 GraphBuilder::initialize(); |
|
295 // setup IR fields |
290 // setup IR fields |
296 _compilation = compilation; |
291 _compilation = compilation; |
297 _top_scope = new IRScope(compilation, NULL, -1, method, osr_bci, true); |
292 _top_scope = new IRScope(compilation, NULL, -1, method, osr_bci, true); |
298 _code = NULL; |
293 _code = NULL; |
299 } |
294 } |
379 iterate_preorder(&cef); |
374 iterate_preorder(&cef); |
380 cef.split_edges(); |
375 cef.split_edges(); |
381 } |
376 } |
382 |
377 |
383 |
378 |
384 class UseCountComputer: public AllStatic { |
379 class UseCountComputer: public ValueVisitor, BlockClosure { |
385 private: |
380 private: |
386 static void update_use_count(Value* n) { |
381 void visit(Value* n) { |
387 // Local instructions and Phis for expression stack values at the |
382 // Local instructions and Phis for expression stack values at the |
388 // start of basic blocks are not added to the instruction list |
383 // start of basic blocks are not added to the instruction list |
389 if ((*n)->bci() == -99 && (*n)->as_Local() == NULL && |
384 if ((*n)->bci() == -99 && (*n)->as_Local() == NULL && |
390 (*n)->as_Phi() == NULL) { |
385 (*n)->as_Phi() == NULL) { |
391 assert(false, "a node was not appended to the graph"); |
386 assert(false, "a node was not appended to the graph"); |
392 Compilation::current_compilation()->bailout("a node was not appended to the graph"); |
387 Compilation::current()->bailout("a node was not appended to the graph"); |
393 } |
388 } |
394 // use n's input if not visited before |
389 // use n's input if not visited before |
395 if (!(*n)->is_pinned() && !(*n)->has_uses()) { |
390 if (!(*n)->is_pinned() && !(*n)->has_uses()) { |
396 // note: a) if the instruction is pinned, it will be handled by compute_use_count |
391 // note: a) if the instruction is pinned, it will be handled by compute_use_count |
397 // b) if the instruction has uses, it was touched before |
392 // b) if the instruction has uses, it was touched before |
400 } |
395 } |
401 // use n |
396 // use n |
402 (*n)->_use_count++; |
397 (*n)->_use_count++; |
403 } |
398 } |
404 |
399 |
405 static Values* worklist; |
400 Values* worklist; |
406 static int depth; |
401 int depth; |
407 enum { |
402 enum { |
408 max_recurse_depth = 20 |
403 max_recurse_depth = 20 |
409 }; |
404 }; |
410 |
405 |
411 static void uses_do(Value* n) { |
406 void uses_do(Value* n) { |
412 depth++; |
407 depth++; |
413 if (depth > max_recurse_depth) { |
408 if (depth > max_recurse_depth) { |
414 // don't allow the traversal to recurse too deeply |
409 // don't allow the traversal to recurse too deeply |
415 worklist->push(*n); |
410 worklist->push(*n); |
416 } else { |
411 } else { |
417 (*n)->input_values_do(update_use_count); |
412 (*n)->input_values_do(this); |
418 // special handling for some instructions |
413 // special handling for some instructions |
419 if ((*n)->as_BlockEnd() != NULL) { |
414 if ((*n)->as_BlockEnd() != NULL) { |
420 // note on BlockEnd: |
415 // note on BlockEnd: |
421 // must 'use' the stack only if the method doesn't |
416 // must 'use' the stack only if the method doesn't |
422 // terminate, however, in those cases stack is empty |
417 // terminate, however, in those cases stack is empty |
423 (*n)->state_values_do(update_use_count); |
418 (*n)->state_values_do(this); |
424 } |
419 } |
425 } |
420 } |
426 depth--; |
421 depth--; |
427 } |
422 } |
428 |
423 |
429 static void basic_compute_use_count(BlockBegin* b) { |
424 void block_do(BlockBegin* b) { |
430 depth = 0; |
425 depth = 0; |
431 // process all pinned nodes as the roots of expression trees |
426 // process all pinned nodes as the roots of expression trees |
432 for (Instruction* n = b; n != NULL; n = n->next()) { |
427 for (Instruction* n = b; n != NULL; n = n->next()) { |
433 if (n->is_pinned()) uses_do(&n); |
428 if (n->is_pinned()) uses_do(&n); |
434 } |
429 } |
447 } |
442 } |
448 } |
443 } |
449 assert(depth == 0, "should have counted back down"); |
444 assert(depth == 0, "should have counted back down"); |
450 } |
445 } |
451 |
446 |
|
447 UseCountComputer() { |
|
448 worklist = new Values(); |
|
449 depth = 0; |
|
450 } |
|
451 |
452 public: |
452 public: |
453 static void compute(BlockList* blocks) { |
453 static void compute(BlockList* blocks) { |
454 worklist = new Values(); |
454 UseCountComputer ucc; |
455 blocks->blocks_do(basic_compute_use_count); |
455 blocks->iterate_backward(&ucc); |
456 worklist = NULL; |
|
457 } |
456 } |
458 }; |
457 }; |
459 |
458 |
460 |
|
461 Values* UseCountComputer::worklist = NULL; |
|
462 int UseCountComputer::depth = 0; |
|
463 |
459 |
464 // helper macro for short definition of trace-output inside code |
460 // helper macro for short definition of trace-output inside code |
465 #ifndef PRODUCT |
461 #ifndef PRODUCT |
466 #define TRACE_LINEAR_SCAN(level, code) \ |
462 #define TRACE_LINEAR_SCAN(level, code) \ |
467 if (TraceLinearScanLevel >= level) { \ |
463 if (TraceLinearScanLevel >= level) { \ |
1300 #endif |
1296 #endif |
1301 } |
1297 } |
1302 |
1298 |
1303 #endif // PRODUCT |
1299 #endif // PRODUCT |
1304 |
1300 |
1305 void SubstitutionResolver::substitute(Value* v) { |
1301 void SubstitutionResolver::visit(Value* v) { |
1306 Value v0 = *v; |
1302 Value v0 = *v; |
1307 if (v0) { |
1303 if (v0) { |
1308 Value vs = v0->subst(); |
1304 Value vs = v0->subst(); |
1309 if (vs != v0) { |
1305 if (vs != v0) { |
1310 *v = v0->subst(); |
1306 *v = v0->subst(); |
1311 } |
1307 } |
1312 } |
1308 } |
1313 } |
1309 } |
1314 |
1310 |
1315 #ifdef ASSERT |
1311 #ifdef ASSERT |
1316 void check_substitute(Value* v) { |
1312 class SubstitutionChecker: public ValueVisitor { |
1317 Value v0 = *v; |
1313 void visit(Value* v) { |
1318 if (v0) { |
1314 Value v0 = *v; |
1319 Value vs = v0->subst(); |
1315 if (v0) { |
1320 assert(vs == v0, "missed substitution"); |
1316 Value vs = v0->subst(); |
1321 } |
1317 assert(vs == v0, "missed substitution"); |
1322 } |
1318 } |
|
1319 } |
|
1320 }; |
1323 #endif |
1321 #endif |
1324 |
1322 |
1325 |
1323 |
1326 void SubstitutionResolver::block_do(BlockBegin* block) { |
1324 void SubstitutionResolver::block_do(BlockBegin* block) { |
1327 Instruction* last = NULL; |
1325 Instruction* last = NULL; |
1328 for (Instruction* n = block; n != NULL;) { |
1326 for (Instruction* n = block; n != NULL;) { |
1329 n->values_do(substitute); |
1327 n->values_do(this); |
1330 // need to remove this instruction from the instruction stream |
1328 // need to remove this instruction from the instruction stream |
1331 if (n->subst() != n) { |
1329 if (n->subst() != n) { |
1332 assert(last != NULL, "must have last"); |
1330 assert(last != NULL, "must have last"); |
1333 last->set_next(n->next(), n->next()->bci()); |
1331 last->set_next(n->next(), n->next()->bci()); |
1334 } else { |
1332 } else { |