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 }