< prev index next >
src/share/vm/ci/ciTypeFlow.cpp
Print this page
@@ -1586,10 +1586,11 @@
ciTypeFlow::JsrSet* jsrs) {
_ciblock = ciblk;
_exceptions = NULL;
_exc_klasses = NULL;
_successors = NULL;
+ _predecessors = new (outer->arena()) GrowableArray<Block*>(outer->arena(), 1, 0, NULL);
_state = new (outer->arena()) StateVector(outer);
JsrSet* new_jsrs =
new (outer->arena()) JsrSet(outer->arena(), jsrs->size());
jsrs->copy_into(new_jsrs);
_jsrs = new_jsrs;
@@ -1769,10 +1770,16 @@
default:
ShouldNotReachHere();
break;
}
}
+
+ // Set predecessor information
+ for (int i = 0; i < _successors->length(); i++) {
+ Block* block = _successors->at(i);
+ block->predecessors()->append(this);
+ }
}
return _successors;
}
// ------------------------------------------------------------------
@@ -1907,10 +1914,22 @@
st->print(" ");
successor->print_value_on(st);
st->cr();
}
}
+ if (_predecessors == NULL) {
+ st->print_cr(" No predecessor information");
+ } else {
+ int num_predecessors = _predecessors->length();
+ st->print_cr(" Predecessors : %d", num_predecessors);
+ for (int i = 0; i < num_predecessors; i++) {
+ Block* predecessor = _predecessors->at(i);
+ st->print(" ");
+ predecessor->print_value_on(st);
+ st->cr();
+ }
+ }
if (_exceptions == NULL) {
st->print_cr(" No exception information");
} else {
int num_exceptions = _exceptions->length();
st->print_cr(" Exceptions : %d", num_exceptions);
@@ -2882,10 +2901,71 @@
rpo_print_on(tty);
}
}
// ------------------------------------------------------------------
+// ciTypeFlow::is_dominated_by
+//
+// Determine if the instruction at bci is dominated by the instruction at dom_bci.
+bool ciTypeFlow::is_dominated_by(int bci, int dom_bci) {
+ ResourceMark rm;
+ JsrSet* jsr_null = new ciTypeFlow::JsrSet(NULL);
+ int index = _methodBlocks->block_containing(bci)->index();
+ int dom_index = _methodBlocks->block_containing(dom_bci)->index();
+ Block* block = get_block_for(index, jsr_null, ciTypeFlow::no_create);
+ Block* dom_block = get_block_for(dom_index, jsr_null, ciTypeFlow::no_create);
+
+ // Start block dominates all other blocks
+ if (start_block()->rpo() == dom_block->rpo()) {
+ return true;
+ }
+
+ // Dominated[i] is true if block i is dominated by dom_block
+ int num_blocks = _methodBlocks->num_blocks();
+ bool* dominated = NEW_RESOURCE_ARRAY(bool, num_blocks);
+ for (int i = 0; i < num_blocks; ++i) {
+ dominated[i] = true;
+ }
+ dominated[start_block()->rpo()] = false;
+
+ // Iterative dominator algorithm
+ bool changed = true;
+ while (changed) {
+ changed = false;
+ // Use reverse postorder iteration
+ for (Block* blk = _rpo_list; blk != NULL; blk = blk->rpo_next()) {
+ if (blk->is_start()) {
+ // Ignore start block
+ continue;
+ }
+ // The block is dominated if it is the dominating block
+ // itself or if all predecessors are dominated.
+ int index = blk->rpo();
+ bool dom = (index == dom_block->rpo());
+ if (!dom) {
+ // Check if all predecessors are dominated
+ dom = true;
+ for (int i = 0; i < blk->predecessors()->length(); ++i) {
+ Block* pred = blk->predecessors()->at(i);
+ if (!dominated[pred->rpo()]) {
+ dom = false;
+ break;
+ }
+ }
+ }
+ // Update dominator information
+ if (dominated[index] != dom) {
+ changed = true;
+ dominated[index] = dom;
+ }
+ }
+ }
+ // block dominated by dom_block?
+ return dominated[block->rpo()];
+}
+
+// ------------------------------------------------------------------
// ciTypeFlow::record_failure()
// The ciTypeFlow object keeps track of failure reasons separately from the ciEnv.
// This is required because there is not a 1-1 relation between the ciEnv and
// the TypeFlow passes within a compilation task. For example, if the compiler
// is considering inlining a method, it will request a TypeFlow. If that fails,
< prev index next >