Mercurial > hg > graal-compiler
comparison src/share/vm/c1/c1_IR.cpp @ 1584:b812ff5abc73
6958292: C1: Enable parallel compilation
Summary: Enable parallel compilation in C1
Reviewed-by: never, kvn
author | iveresov |
---|---|
date | Fri, 04 Jun 2010 11:18:04 -0700 |
parents | e9ff18c4ace7 |
children | d5d065957597 |
comparison
equal
deleted
inserted
replaced
1583:02e771df338e | 1584:b812ff5abc73 |
---|---|
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 { |
1336 } | 1334 } |
1337 n = last->next(); | 1335 n = last->next(); |
1338 } | 1336 } |
1339 | 1337 |
1340 #ifdef ASSERT | 1338 #ifdef ASSERT |
1341 if (block->state()) block->state()->values_do(check_substitute); | 1339 SubstitutionChecker check_substitute; |
1342 block->block_values_do(check_substitute); | 1340 if (block->state()) block->state()->values_do(&check_substitute); |
1343 if (block->end() && block->end()->state()) block->end()->state()->values_do(check_substitute); | 1341 block->block_values_do(&check_substitute); |
1342 if (block->end() && block->end()->state()) block->end()->state()->values_do(&check_substitute); | |
1344 #endif | 1343 #endif |
1345 } | 1344 } |