< prev index next >

src/share/vm/opto/gcm.cpp

Print this page

        

*** 519,539 **** tty->print_cr("*** Possible Anti-Dependence Bug: Load consumes all of memory."); load->dump(2); if (VerifyAliases) assert(load_alias_idx != Compile::AliasIdxBot, ""); } #endif ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrComp), "String compare is only known 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrEquals), "String equals is a 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrIndexOf), "String indexOf is a 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrIndexOfChar), "String indexOfChar is a 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_AryEq), "Arrays equals is a 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_HasNegatives), "HasNegatives is a 'load' that does not conflict with any stores"); if (!C->alias_type(load_alias_idx)->is_rewritable()) { // It is impossible to spoil this load by putting stores before it, // because we know that the stores will never update the value --- 519,539 ---- tty->print_cr("*** Possible Anti-Dependence Bug: Load consumes all of memory."); load->dump(2); if (VerifyAliases) assert(load_alias_idx != Compile::AliasIdxBot, ""); } #endif ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Opcodes::Op_StrComp), "String compare is only known 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Opcodes::Op_StrEquals), "String equals is a 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Opcodes::Op_StrIndexOf), "String indexOf is a 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Opcodes::Op_StrIndexOfChar), "String indexOfChar is a 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Opcodes::Op_AryEq), "Arrays equals is a 'load' that does not conflict with any stores"); ! assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Opcodes::Op_HasNegatives), "HasNegatives is a 'load' that does not conflict with any stores"); if (!C->alias_type(load_alias_idx)->is_rewritable()) { // It is impossible to spoil this load by putting stores before it, // because we know that the stores will never update the value
*** 596,612 **** worklist_mem.push(NULL); while (worklist_store.size() > 0) { // Examine a nearby store to see if it might interfere with our load. Node* mem = worklist_mem.pop(); Node* store = worklist_store.pop(); ! uint op = store->Opcode(); // MergeMems do not directly have anti-deps. // Treat them as internal nodes in a forward tree of memory states, // the leaves of which are each a 'possible-def'. if (store == initial_mem // root (exclusive) of tree we are searching ! || op == Op_MergeMem // internal node of tree we are searching ) { mem = store; // It's not a possibly interfering store. if (store == initial_mem) initial_mem = NULL; // only process initial memory once --- 596,612 ---- worklist_mem.push(NULL); while (worklist_store.size() > 0) { // Examine a nearby store to see if it might interfere with our load. Node* mem = worklist_mem.pop(); Node* store = worklist_store.pop(); ! Opcodes op = store->Opcode(); // MergeMems do not directly have anti-deps. // Treat them as internal nodes in a forward tree of memory states, // the leaves of which are each a 'possible-def'. if (store == initial_mem // root (exclusive) of tree we are searching ! || op == Opcodes::Op_MergeMem // internal node of tree we are searching ) { mem = store; // It's not a possibly interfering store. if (store == initial_mem) initial_mem = NULL; // only process initial memory once
*** 626,636 **** worklist_store.push(store); } continue; } ! if (op == Op_MachProj || op == Op_Catch) continue; if (store->needs_anti_dependence_check()) continue; // not really a store // Compute the alias index. Loads and stores with different alias // indices do not need anti-dependence edges. Wide MemBar's are // anti-dependent on everything (except immutable memories). --- 626,636 ---- worklist_store.push(store); } continue; } ! if (op == Opcodes::Op_MachProj || op == Opcodes::Op_Catch) continue; if (store->needs_anti_dependence_check()) continue; // not really a store // Compute the alias index. Loads and stores with different alias // indices do not need anti-dependence edges. Wide MemBar's are // anti-dependent on everything (except immutable memories).
*** 644,654 **** if (load_alias_idx != Compile::AliasIdxRaw) { // Check for call into the runtime using the Java calling // convention (and from there into a wrapper); it has no // _method. Can't do this optimization for Native calls because // they CAN write to Java memory. ! if (mstore->ideal_Opcode() == Op_CallStaticJava) { assert(mstore->is_MachSafePoint(), ""); MachSafePointNode* ms = (MachSafePointNode*) mstore; assert(ms->is_MachCallJava(), ""); MachCallJavaNode* mcj = (MachCallJavaNode*) ms; if (mcj->_method == NULL) { --- 644,654 ---- if (load_alias_idx != Compile::AliasIdxRaw) { // Check for call into the runtime using the Java calling // convention (and from there into a wrapper); it has no // _method. Can't do this optimization for Native calls because // they CAN write to Java memory. ! if (mstore->ideal_Opcode() == Opcodes::Op_CallStaticJava) { assert(mstore->is_MachSafePoint(), ""); MachSafePointNode* ms = (MachSafePointNode*) mstore; assert(ms->is_MachCallJava(), ""); MachCallJavaNode* mcj = (MachCallJavaNode*) ms; if (mcj->_method == NULL) {
*** 658,678 **** } } // Same for SafePoints: they read/write Raw but only read otherwise. // This is basically a workaround for SafePoints only defining control // instead of control + memory. ! if (mstore->ideal_Opcode() == Op_SafePoint) continue; } else { // Some raw memory, such as the load of "top" at an allocation, // can be control dependent on the previous safepoint. See // comments in GraphKit::allocate_heap() about control input. // Inserting an anti-dep between such a safepoint and a use // creates a cycle, and will cause a subsequent failure in // local scheduling. (BugId 4919904) // (%%% How can a control input be a safepoint and not a projection??) ! if (mstore->ideal_Opcode() == Op_SafePoint && load->in(0) == mstore) continue; } } // Identify a block that the current load must be above, --- 658,678 ---- } } // Same for SafePoints: they read/write Raw but only read otherwise. // This is basically a workaround for SafePoints only defining control // instead of control + memory. ! if (mstore->ideal_Opcode() == Opcodes::Op_SafePoint) continue; } else { // Some raw memory, such as the load of "top" at an allocation, // can be control dependent on the previous safepoint. See // comments in GraphKit::allocate_heap() about control input. // Inserting an anti-dep between such a safepoint and a use // creates a cycle, and will cause a subsequent failure in // local scheduling. (BugId 4919904) // (%%% How can a control input be a safepoint and not a projection??) ! if (mstore->ideal_Opcode() == Opcodes::Op_SafePoint && load->in(0) == mstore) continue; } } // Identify a block that the current load must be above,
*** 1225,1240 **** continue; MachNode* mach = self->is_Mach() ? self->as_Mach() : NULL; if (mach) { switch (mach->ideal_Opcode()) { ! case Op_CreateEx: // Don't move exception creation early->add_inst(self); continue; break; ! case Op_CheckCastPP: // Don't move CheckCastPP nodes away from their input, if the input // is a rawptr (5071820). Node *def = self->in(1); if (def != NULL && def->bottom_type()->base() == Type::RawPtr) { early->add_inst(self); --- 1225,1240 ---- continue; MachNode* mach = self->is_Mach() ? self->as_Mach() : NULL; if (mach) { switch (mach->ideal_Opcode()) { ! case Opcodes::Op_CreateEx: // Don't move exception creation early->add_inst(self); continue; break; ! case Opcodes::Op_CheckCastPP: // Don't move CheckCastPP nodes away from their input, if the input // is a rawptr (5071820). Node *def = self->in(1); if (def != NULL && def->bottom_type()->base() == Type::RawPtr) { early->add_inst(self);
*** 1295,1305 **** // Must clone guys stay next to use; no hoisting allowed. // Also cannot hoist guys that alter memory or are otherwise not // allocatable (hoisting can make a value live longer, leading to // anti and output dependency problems which are normally resolved // by the register allocator giving everyone a different register). ! if (mach != NULL && must_clone[mach->ideal_Opcode()]) try_to_hoist = false; Block* late = NULL; if (try_to_hoist) { // Now find the block with the least execution frequency. --- 1295,1305 ---- // Must clone guys stay next to use; no hoisting allowed. // Also cannot hoist guys that alter memory or are otherwise not // allocatable (hoisting can make a value live longer, leading to // anti and output dependency problems which are normally resolved // by the register allocator giving everyone a different register). ! if (mach != NULL && must_clone[static_cast<uint>(mach->ideal_Opcode())]) try_to_hoist = false; Block* late = NULL; if (try_to_hoist) { // Now find the block with the least execution frequency.
*** 1818,1828 **** // Determine the probability of reaching successor 'i' from the receiver block. float Block::succ_prob(uint i) { int eidx = end_idx(); Node *n = get_node(eidx); // Get ending Node ! int op = n->Opcode(); if (n->is_Mach()) { if (n->is_MachNullCheck()) { // Can only reach here if called after lcm. The original Op_If is gone, // so we attempt to infer the probability from one or both of the // successor blocks. --- 1818,1828 ---- // Determine the probability of reaching successor 'i' from the receiver block. float Block::succ_prob(uint i) { int eidx = end_idx(); Node *n = get_node(eidx); // Get ending Node ! Opcodes op = n->Opcode(); if (n->is_Mach()) { if (n->is_MachNullCheck()) { // Can only reach here if called after lcm. The original Op_If is gone, // so we attempt to infer the probability from one or both of the // successor blocks.
*** 1844,1895 **** } // Switch on branch type switch( op ) { ! case Op_CountedLoopEnd: ! case Op_If: { assert (i < 2, "just checking"); // Conditionals pass on only part of their frequency float prob = n->as_MachIf()->_prob; assert(prob >= 0.0 && prob <= 1.0, "out of range probability"); // If succ[i] is the FALSE branch, invert path info ! if( get_node(i + eidx + 1)->Opcode() == Op_IfFalse ) { return 1.0f - prob; // not taken } else { return prob; // taken } } ! case Op_Jump: // Divide the frequency between all successors evenly return 1.0f/_num_succs; ! case Op_Catch: { const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj(); if (ci->_con == CatchProjNode::fall_through_index) { // Fall-thru path gets the lion's share. return 1.0f - PROB_UNLIKELY_MAG(5)*_num_succs; } else { // Presume exceptional paths are equally unlikely return PROB_UNLIKELY_MAG(5); } } ! case Op_Root: ! case Op_Goto: // Pass frequency straight thru to target return 1.0f; ! case Op_NeverBranch: return 0.0f; ! case Op_TailCall: ! case Op_TailJump: ! case Op_Return: ! case Op_Halt: ! case Op_Rethrow: // Do not push out freq to root block return 0.0f; default: ShouldNotReachHere(); --- 1844,1895 ---- } // Switch on branch type switch( op ) { ! case Opcodes::Op_CountedLoopEnd: ! case Opcodes::Op_If: { assert (i < 2, "just checking"); // Conditionals pass on only part of their frequency float prob = n->as_MachIf()->_prob; assert(prob >= 0.0 && prob <= 1.0, "out of range probability"); // If succ[i] is the FALSE branch, invert path info ! if( get_node(i + eidx + 1)->Opcode() == Opcodes::Op_IfFalse ) { return 1.0f - prob; // not taken } else { return prob; // taken } } ! case Opcodes::Op_Jump: // Divide the frequency between all successors evenly return 1.0f/_num_succs; ! case Opcodes::Op_Catch: { const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj(); if (ci->_con == CatchProjNode::fall_through_index) { // Fall-thru path gets the lion's share. return 1.0f - PROB_UNLIKELY_MAG(5)*_num_succs; } else { // Presume exceptional paths are equally unlikely return PROB_UNLIKELY_MAG(5); } } ! case Opcodes::Op_Root: ! case Opcodes::Op_Goto: // Pass frequency straight thru to target return 1.0f; ! case Opcodes::Op_NeverBranch: return 0.0f; ! case Opcodes::Op_TailCall: ! case Opcodes::Op_TailJump: ! case Opcodes::Op_Return: ! case Opcodes::Op_Halt: ! case Opcodes::Op_Rethrow: // Do not push out freq to root block return 0.0f; default: ShouldNotReachHere();
*** 1902,1912 **** // Return the number of fall-through candidates for a block int Block::num_fall_throughs() { int eidx = end_idx(); Node *n = get_node(eidx); // Get ending Node ! int op = n->Opcode(); if (n->is_Mach()) { if (n->is_MachNullCheck()) { // In theory, either side can fall-thru, for simplicity sake, // let's say only the false branch can now. return 1; --- 1902,1912 ---- // Return the number of fall-through candidates for a block int Block::num_fall_throughs() { int eidx = end_idx(); Node *n = get_node(eidx); // Get ending Node ! Opcodes op = n->Opcode(); if (n->is_Mach()) { if (n->is_MachNullCheck()) { // In theory, either side can fall-thru, for simplicity sake, // let's say only the false branch can now. return 1;
*** 1914,1948 **** op = n->as_Mach()->ideal_Opcode(); } // Switch on branch type switch( op ) { ! case Op_CountedLoopEnd: ! case Op_If: return 2; ! case Op_Root: ! case Op_Goto: return 1; ! case Op_Catch: { for (uint i = 0; i < _num_succs; i++) { const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj(); if (ci->_con == CatchProjNode::fall_through_index) { return 1; } } return 0; } ! case Op_Jump: ! case Op_NeverBranch: ! case Op_TailCall: ! case Op_TailJump: ! case Op_Return: ! case Op_Halt: ! case Op_Rethrow: return 0; default: ShouldNotReachHere(); } --- 1914,1948 ---- op = n->as_Mach()->ideal_Opcode(); } // Switch on branch type switch( op ) { ! case Opcodes::Op_CountedLoopEnd: ! case Opcodes::Op_If: return 2; ! case Opcodes::Op_Root: ! case Opcodes::Op_Goto: return 1; ! case Opcodes::Op_Catch: { for (uint i = 0; i < _num_succs; i++) { const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj(); if (ci->_con == CatchProjNode::fall_through_index) { return 1; } } return 0; } ! case Opcodes::Op_Jump: ! case Opcodes::Op_NeverBranch: ! case Opcodes::Op_TailCall: ! case Opcodes::Op_TailJump: ! case Opcodes::Op_Return: ! case Opcodes::Op_Halt: ! case Opcodes::Op_Rethrow: return 0; default: ShouldNotReachHere(); }
*** 1954,1993 **** // Return true if a specific successor could be fall-through target. bool Block::succ_fall_through(uint i) { int eidx = end_idx(); Node *n = get_node(eidx); // Get ending Node ! int op = n->Opcode(); if (n->is_Mach()) { if (n->is_MachNullCheck()) { // In theory, either side can fall-thru, for simplicity sake, // let's say only the false branch can now. ! return get_node(i + eidx + 1)->Opcode() == Op_IfFalse; } op = n->as_Mach()->ideal_Opcode(); } // Switch on branch type switch( op ) { ! case Op_CountedLoopEnd: ! case Op_If: ! case Op_Root: ! case Op_Goto: return true; ! case Op_Catch: { const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj(); return ci->_con == CatchProjNode::fall_through_index; } ! case Op_Jump: ! case Op_NeverBranch: ! case Op_TailCall: ! case Op_TailJump: ! case Op_Return: ! case Op_Halt: ! case Op_Rethrow: return false; default: ShouldNotReachHere(); } --- 1954,1993 ---- // Return true if a specific successor could be fall-through target. bool Block::succ_fall_through(uint i) { int eidx = end_idx(); Node *n = get_node(eidx); // Get ending Node ! Opcodes op = n->Opcode(); if (n->is_Mach()) { if (n->is_MachNullCheck()) { // In theory, either side can fall-thru, for simplicity sake, // let's say only the false branch can now. ! return get_node(i + eidx + 1)->Opcode() == Opcodes::Op_IfFalse; } op = n->as_Mach()->ideal_Opcode(); } // Switch on branch type switch( op ) { ! case Opcodes::Op_CountedLoopEnd: ! case Opcodes::Op_If: ! case Opcodes::Op_Root: ! case Opcodes::Op_Goto: return true; ! case Opcodes::Op_Catch: { const CatchProjNode *ci = get_node(i + eidx + 1)->as_CatchProj(); return ci->_con == CatchProjNode::fall_through_index; } ! case Opcodes::Op_Jump: ! case Opcodes::Op_NeverBranch: ! case Opcodes::Op_TailCall: ! case Opcodes::Op_TailJump: ! case Opcodes::Op_Return: ! case Opcodes::Op_Halt: ! case Opcodes::Op_Rethrow: return false; default: ShouldNotReachHere(); }
*** 1999,2011 **** // Update the probability of a two-branch to be uncommon void Block::update_uncommon_branch(Block* ub) { int eidx = end_idx(); Node *n = get_node(eidx); // Get ending Node ! int op = n->as_Mach()->ideal_Opcode(); ! assert(op == Op_CountedLoopEnd || op == Op_If, "must be a If"); assert(num_fall_throughs() == 2, "must be a two way branch block"); // Which successor is ub? uint s; for (s = 0; s <_num_succs; s++) { --- 1999,2011 ---- // Update the probability of a two-branch to be uncommon void Block::update_uncommon_branch(Block* ub) { int eidx = end_idx(); Node *n = get_node(eidx); // Get ending Node ! Opcodes op = n->as_Mach()->ideal_Opcode(); ! assert(op == Opcodes::Op_CountedLoopEnd || op == Opcodes::Op_If, "must be a If"); assert(num_fall_throughs() == 2, "must be a two way branch block"); // Which successor is ub? uint s; for (s = 0; s <_num_succs; s++) {
*** 2013,2023 **** } assert(s < 2, "uncommon successor must be found"); // If ub is the true path, make the proability small, else // ub is the false path, and make the probability large ! bool invert = (get_node(s + eidx + 1)->Opcode() == Op_IfFalse); // Get existing probability float p = n->as_MachIf()->_prob; if (invert) p = 1.0 - p; --- 2013,2023 ---- } assert(s < 2, "uncommon successor must be found"); // If ub is the true path, make the proability small, else // ub is the false path, and make the probability large ! bool invert = (get_node(s + eidx + 1)->Opcode() == Opcodes::Op_IfFalse); // Get existing probability float p = n->as_MachIf()->_prob; if (invert) p = 1.0 - p;
< prev index next >