src/share/vm/opto/memnode.cpp

Print this page

        

*** 239,278 **** // let the subclass continue analyzing... return NULL; } // Helper function for proving some simple control dominations. ! // Attempt to prove that control input 'dom' dominates (or equals) 'sub'. // Already assumes that 'dom' is available at 'sub', and that 'sub' // is not a constant (dominated by the method's StartNode). // Used by MemNode::find_previous_store to prove that the // control input of a memory operation predates (dominates) // an allocation it wants to look past. ! bool MemNode::detect_dominating_control(Node* dom, Node* sub) { ! if (dom == NULL) return false; ! if (dom->is_Proj()) dom = dom->in(0); ! if (dom->is_Start()) return true; // anything inside the method ! if (dom->is_Root()) return true; // dom 'controls' a constant ! int cnt = 20; // detect cycle or too much effort ! while (sub != NULL) { // walk 'sub' up the chain to 'dom' ! if (--cnt < 0) return false; // in a cycle or too complex ! if (sub == dom) return true; ! if (sub->is_Start()) return false; ! if (sub->is_Root()) return false; ! Node* up = sub->in(0); ! if (sub == up && sub->is_Region()) { ! for (uint i = 1; i < sub->req(); i++) { ! Node* in = sub->in(i); ! if (in != NULL && !in->is_top() && in != sub) { ! up = in; break; // take any path on the way up to 'dom' } } } - if (sub == up) return false; // some kind of tight cycle - sub = up; } ! return false; } //---------------------detect_ptr_independence--------------------------------- // Used by MemNode::find_previous_store to prove that two base // pointers are never equal. --- 239,333 ---- // let the subclass continue analyzing... return NULL; } // Helper function for proving some simple control dominations. ! // Attempt to prove that all control inputs of 'dom' dominate 'sub'. // Already assumes that 'dom' is available at 'sub', and that 'sub' // is not a constant (dominated by the method's StartNode). // Used by MemNode::find_previous_store to prove that the // control input of a memory operation predates (dominates) // an allocation it wants to look past. ! bool MemNode::all_controls_dominate(Node* dom, Node* sub) { ! if (dom == NULL || dom->is_top() || sub == NULL || sub->is_top()) ! return false; // Conservative answer for dead code ! ! // Check 'dom'. ! dom = dom->find_exact_control(dom); ! if (dom == NULL || dom->is_top()) ! return false; // Conservative answer for dead code ! ! if (dom->is_Start() || dom->is_Root() || dom == sub) ! return true; ! ! // 'dom' dominates 'sub' if its control edge and control edges ! // of all its inputs dominate or equal to sub's control edge. ! ! // Currently 'sub' is either Allocate, Initialize or Start nodes. ! assert(sub->is_Allocate() || sub->is_Initialize() || sub->is_Start(), "expecting only these nodes"); ! ! // Get control edge of 'sub'. ! sub = sub->find_exact_control(sub->in(0)); ! if (sub == NULL || sub->is_top()) ! return false; // Conservative answer for dead code ! ! assert(sub->is_CFG(), "expecting control"); ! ! if (sub == dom) ! return true; ! ! if (sub->is_Start() || sub->is_Root()) ! return false; ! ! { ! // Check all control edges of 'dom'. ! ! ResourceMark rm; ! Arena* arena = Thread::current()->resource_area(); ! Node_List nlist(arena); ! Unique_Node_List dom_list(arena); ! ! dom_list.push(dom); ! bool only_dominating_controls = false; ! ! for (uint next = 0; next < dom_list.size(); next++) { ! Node* n = dom_list.at(next); ! if (!n->is_CFG() && n->pinned()) { ! // Check only own control edge for pinned non-control nodes. ! n = n->find_exact_control(n->in(0)); ! if (n == NULL || n->is_top()) ! return false; // Conservative answer for dead code ! assert(n->is_CFG(), "expecting control"); } + if (n->is_Start() || n->is_Root()) { + only_dominating_controls = true; + } else if (n->is_CFG()) { + if (n->dominates(sub, nlist)) + only_dominating_controls = true; + else + return false; + } else { + // First, own control edge. + Node* m = n->find_exact_control(n->in(0)); + if (m == NULL) + continue; + if (m->is_top()) + return false; // Conservative answer for dead code + dom_list.push(m); + + // Now, the rest of edges. + uint cnt = n->req(); + for (uint i = 1; i < cnt; i++) { + m = n->find_exact_control(n->in(i)); + if (m == NULL || m->is_top()) + continue; + dom_list.push(m); } } } ! return only_dominating_controls; ! } } //---------------------detect_ptr_independence--------------------------------- // Used by MemNode::find_previous_store to prove that two base // pointers are never equal.
*** 289,301 **** return (p1 != p2) && p1->is_Con() && p2->is_Con(); } else if (a1 != NULL && a2 != NULL) { // both allocations return (a1 != a2); } else if (a1 != NULL) { // one allocation a1 // (Note: p2->is_Con implies p2->in(0)->is_Root, which dominates.) ! return detect_dominating_control(p2->in(0), a1->in(0)); } else { //(a2 != NULL) // one allocation a2 ! return detect_dominating_control(p1->in(0), a2->in(0)); } return false; } --- 344,356 ---- return (p1 != p2) && p1->is_Con() && p2->is_Con(); } else if (a1 != NULL && a2 != NULL) { // both allocations return (a1 != a2); } else if (a1 != NULL) { // one allocation a1 // (Note: p2->is_Con implies p2->in(0)->is_Root, which dominates.) ! return all_controls_dominate(p2, a1); } else { //(a2 != NULL) // one allocation a2 ! return all_controls_dominate(p1, a2); } return false; }
*** 377,388 **** bool known_independent = false; if (alloc == st_alloc) known_identical = true; else if (alloc != NULL) known_independent = true; ! else if (ctrl != NULL && ! detect_dominating_control(ctrl, st_alloc->in(0))) known_independent = true; if (known_independent) { // The bases are provably independent: Either they are // manifestly distinct allocations, or else the control --- 432,442 ---- bool known_independent = false; if (alloc == st_alloc) known_identical = true; else if (alloc != NULL) known_independent = true; ! else if (all_controls_dominate(this, st_alloc)) known_independent = true; if (known_independent) { // The bases are provably independent: Either they are // manifestly distinct allocations, or else the control
*** 1066,1076 **** if (in(MemNode::Control) != NULL) { intptr_t ignore = 0; Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore); if (base != NULL && phase->type(base)->higher_equal(TypePtr::NOTNULL) ! && detect_dominating_control(base->in(0), phase->C->start())) { // A method-invariant, non-null address (constant or 'this' argument). set_req(MemNode::Control, NULL); } } --- 1120,1130 ---- if (in(MemNode::Control) != NULL) { intptr_t ignore = 0; Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore); if (base != NULL && phase->type(base)->higher_equal(TypePtr::NOTNULL) ! && all_controls_dominate(base, phase->C->start())) { // A method-invariant, non-null address (constant or 'this' argument). set_req(MemNode::Control, NULL); } }
*** 2487,2497 **** // If we already know that the enclosing memory op is pinned right after // the init, then any control flow that the store has picked up // must have preceded the init, or else be equal to the init. // Even after loop optimizations (which might change control edges) // a store is never pinned *before* the availability of its inputs. ! if (!MemNode::detect_dominating_control(ctl, this->in(0))) return false; // failed to prove a good control } // Check data edges for possible dependencies on 'this'. --- 2541,2551 ---- // If we already know that the enclosing memory op is pinned right after // the init, then any control flow that the store has picked up // must have preceded the init, or else be equal to the init. // Even after loop optimizations (which might change control edges) // a store is never pinned *before* the availability of its inputs. ! if (!MemNode::all_controls_dominate(n, this)) return false; // failed to prove a good control } // Check data edges for possible dependencies on 'this'.