--- a/hotspot/src/share/vm/opto/compile.cpp Fri Feb 18 10:07:34 2011 -0800
+++ b/hotspot/src/share/vm/opto/compile.cpp Tue Apr 05 19:14:03 2011 -0700
@@ -2050,6 +2050,52 @@
// Note that OffsetBot and OffsetTop are very negative.
}
+// Eliminate trivially redundant StoreCMs and accumulate their
+// precedence edges.
+static void eliminate_redundant_card_marks(Node* n) {
+ assert(n->Opcode() == Op_StoreCM, "expected StoreCM");
+ if (n->in(MemNode::Address)->outcnt() > 1) {
+ // There are multiple users of the same address so it might be
+ // possible to eliminate some of the StoreCMs
+ Node* mem = n->in(MemNode::Memory);
+ Node* adr = n->in(MemNode::Address);
+ Node* val = n->in(MemNode::ValueIn);
+ Node* prev = n;
+ bool done = false;
+ // Walk the chain of StoreCMs eliminating ones that match. As
+ // long as it's a chain of single users then the optimization is
+ // safe. Eliminating partially redundant StoreCMs would require
+ // cloning copies down the other paths.
+ while (mem->Opcode() == Op_StoreCM && mem->outcnt() == 1 && !done) {
+ if (adr == mem->in(MemNode::Address) &&
+ val == mem->in(MemNode::ValueIn)) {
+ // redundant StoreCM
+ if (mem->req() > MemNode::OopStore) {
+ // Hasn't been processed by this code yet.
+ n->add_prec(mem->in(MemNode::OopStore));
+ } else {
+ // Already converted to precedence edge
+ for (uint i = mem->req(); i < mem->len(); i++) {
+ // Accumulate any precedence edges
+ if (mem->in(i) != NULL) {
+ n->add_prec(mem->in(i));
+ }
+ }
+ // Everything above this point has been processed.
+ done = true;
+ }
+ // Eliminate the previous StoreCM
+ prev->set_req(MemNode::Memory, mem->in(MemNode::Memory));
+ assert(mem->outcnt() == 0, "should be dead");
+ mem->disconnect_inputs(NULL);
+ } else {
+ prev = mem;
+ }
+ mem = prev->in(MemNode::Memory);
+ }
+ }
+}
+
//------------------------------final_graph_reshaping_impl----------------------
// Implement items 1-5 from final_graph_reshaping below.
static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) {
@@ -2176,9 +2222,19 @@
frc.inc_float_count();
goto handle_mem;
+ case Op_StoreCM:
+ {
+ // Convert OopStore dependence into precedence edge
+ Node* prec = n->in(MemNode::OopStore);
+ n->del_req(MemNode::OopStore);
+ n->add_prec(prec);
+ eliminate_redundant_card_marks(n);
+ }
+
+ // fall through
+
case Op_StoreB:
case Op_StoreC:
- case Op_StoreCM:
case Op_StorePConditional:
case Op_StoreI:
case Op_StoreL: