27 #include "opto/cfgnode.hpp" 28 #include "opto/matcher.hpp" 29 #include "opto/mathexactnode.hpp" 30 #include "opto/multnode.hpp" 31 #include "opto/opcodes.hpp" 32 #include "opto/phaseX.hpp" 33 #include "opto/regmask.hpp" 34 #include "opto/type.hpp" 35 36 //============================================================================= 37 //------------------------------MultiNode-------------------------------------- 38 const RegMask &MultiNode::out_RegMask() const { 39 return RegMask::Empty; 40 } 41 42 Node *MultiNode::match( const ProjNode *proj, const Matcher *m ) { return proj->clone(); } 43 44 //------------------------------proj_out--------------------------------------- 45 // Get a named projection 46 ProjNode* MultiNode::proj_out(uint which_proj) const { 47 assert((Opcode() != Op_If && Opcode() != Op_RangeCheck) || which_proj == (uint)true || which_proj == (uint)false, "must be 1 or 0"); 48 assert((Opcode() != Op_If && Opcode() != Op_RangeCheck) || outcnt() == 2, "bad if #1"); 49 for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) { 50 Node *p = fast_out(i); 51 if (p->is_Proj()) { 52 ProjNode *proj = p->as_Proj(); 53 if (proj->_con == which_proj) { 54 assert((Opcode() != Op_If && Opcode() != Op_RangeCheck) || proj->Opcode() == (which_proj ? Op_IfTrue : Op_IfFalse), "bad if #2"); 55 return proj; 56 } 57 } else { 58 assert(p == this && this->is_Start(), "else must be proj"); 59 continue; 60 } 61 } 62 return NULL; 63 } 64 65 //============================================================================= 66 //------------------------------ProjNode--------------------------------------- 67 uint ProjNode::hash() const { 68 // only one input 69 return (uintptr_t)in(TypeFunc::Control) + (_con << 1) + (_is_io_use ? 1 : 0); 70 } 71 uint ProjNode::cmp( const Node &n ) const { return _con == ((ProjNode&)n)._con && ((ProjNode&)n)._is_io_use == _is_io_use; } 72 uint ProjNode::size_of() const { return sizeof(ProjNode); } 73 74 // Test if we propagate interesting control along this projection 142 if (n->is_Start()) return; // alas, starts can have mach. projs. also 143 if (_con == SCMemProjNode::SCMEMPROJCON ) return; 144 const Type* t = n->bottom_type(); 145 if (t == Type::TOP) return; // multi is dead 146 assert(_con < t->is_tuple()->cnt(), "ProjNode::_con must be in range"); 147 } 148 149 //------------------------------Value------------------------------------------ 150 const Type* ProjNode::Value(PhaseGVN* phase) const { 151 if (in(0) == NULL) return Type::TOP; 152 return proj_type(phase->type(in(0))); 153 } 154 155 //------------------------------out_RegMask------------------------------------ 156 // Pass the buck uphill 157 const RegMask &ProjNode::out_RegMask() const { 158 return RegMask::Empty; 159 } 160 161 //------------------------------ideal_reg-------------------------------------- 162 uint ProjNode::ideal_reg() const { 163 return bottom_type()->ideal_reg(); 164 } 165 166 //-------------------------------is_uncommon_trap_proj---------------------------- 167 // Return uncommon trap call node if proj is for "proj->[region->..]call_uct" 168 // NULL otherwise 169 CallStaticJavaNode* ProjNode::is_uncommon_trap_proj(Deoptimization::DeoptReason reason) { 170 int path_limit = 10; 171 Node* out = this; 172 for (int ct = 0; ct < path_limit; ct++) { 173 out = out->unique_ctrl_out(); 174 if (out == NULL) 175 return NULL; 176 if (out->is_CallStaticJava()) { 177 CallStaticJavaNode* call = out->as_CallStaticJava(); 178 int req = call->uncommon_trap_request(); 179 if (req != 0) { 180 Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); 181 if (trap_reason == reason || reason == Deoptimization::Reason_none) { 182 return call; 183 } 184 } 185 return NULL; // don't do further after call 186 } 187 if (out->Opcode() != Op_Region) 188 return NULL; 189 } 190 return NULL; 191 } 192 193 //-------------------------------is_uncommon_trap_if_pattern------------------------- 194 // Return uncommon trap call node for "if(test)-> proj -> ... 195 // | 196 // V 197 // other_proj->[region->..]call_uct" 198 // NULL otherwise 199 // "must_reason_predicate" means the uct reason must be Reason_predicate 200 CallStaticJavaNode* ProjNode::is_uncommon_trap_if_pattern(Deoptimization::DeoptReason reason) { 201 Node *in0 = in(0); 202 if (!in0->is_If()) return NULL; 203 // Variation of a dead If node. 204 if (in0->outcnt() < 2) return NULL; 205 IfNode* iff = in0->as_If(); 206 207 // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate 208 if (reason != Deoptimization::Reason_none) { 209 if (iff->in(1)->Opcode() != Op_Conv2B || 210 iff->in(1)->in(1)->Opcode() != Op_Opaque1) { 211 return NULL; 212 } 213 } 214 215 ProjNode* other_proj = iff->proj_out(1-_con); 216 if (other_proj == NULL) // Should never happen, but make Parfait happy. 217 return NULL; 218 CallStaticJavaNode* call = other_proj->is_uncommon_trap_proj(reason); 219 if (call != NULL) { 220 assert(reason == Deoptimization::Reason_none || 221 Compile::current()->is_predicate_opaq(iff->in(1)->in(1)), "should be on the list"); 222 return call; 223 } 224 return NULL; 225 } 226 227 ProjNode* ProjNode::other_if_proj() const { 228 assert(_con == 0 || _con == 1, "not an if?"); 229 return in(0)->as_If()->proj_out(1-_con); 230 } | 27 #include "opto/cfgnode.hpp" 28 #include "opto/matcher.hpp" 29 #include "opto/mathexactnode.hpp" 30 #include "opto/multnode.hpp" 31 #include "opto/opcodes.hpp" 32 #include "opto/phaseX.hpp" 33 #include "opto/regmask.hpp" 34 #include "opto/type.hpp" 35 36 //============================================================================= 37 //------------------------------MultiNode-------------------------------------- 38 const RegMask &MultiNode::out_RegMask() const { 39 return RegMask::Empty; 40 } 41 42 Node *MultiNode::match( const ProjNode *proj, const Matcher *m ) { return proj->clone(); } 43 44 //------------------------------proj_out--------------------------------------- 45 // Get a named projection 46 ProjNode* MultiNode::proj_out(uint which_proj) const { 47 assert((Opcode() != Opcodes::Op_If && Opcode() != Opcodes::Op_RangeCheck) || which_proj == (uint)true || which_proj == (uint)false, "must be 1 or 0"); 48 assert((Opcode() != Opcodes::Op_If && Opcode() != Opcodes::Op_RangeCheck) || outcnt() == 2, "bad if #1"); 49 for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) { 50 Node *p = fast_out(i); 51 if (p->is_Proj()) { 52 ProjNode *proj = p->as_Proj(); 53 if (proj->_con == which_proj) { 54 assert((Opcode() != Opcodes::Op_If && Opcode() != Opcodes::Op_RangeCheck) || proj->Opcode() == (which_proj ? Opcodes::Op_IfTrue : Opcodes::Op_IfFalse), "bad if #2"); 55 return proj; 56 } 57 } else { 58 assert(p == this && this->is_Start(), "else must be proj"); 59 continue; 60 } 61 } 62 return NULL; 63 } 64 65 //============================================================================= 66 //------------------------------ProjNode--------------------------------------- 67 uint ProjNode::hash() const { 68 // only one input 69 return (uintptr_t)in(TypeFunc::Control) + (_con << 1) + (_is_io_use ? 1 : 0); 70 } 71 uint ProjNode::cmp( const Node &n ) const { return _con == ((ProjNode&)n)._con && ((ProjNode&)n)._is_io_use == _is_io_use; } 72 uint ProjNode::size_of() const { return sizeof(ProjNode); } 73 74 // Test if we propagate interesting control along this projection 142 if (n->is_Start()) return; // alas, starts can have mach. projs. also 143 if (_con == SCMemProjNode::SCMEMPROJCON ) return; 144 const Type* t = n->bottom_type(); 145 if (t == Type::TOP) return; // multi is dead 146 assert(_con < t->is_tuple()->cnt(), "ProjNode::_con must be in range"); 147 } 148 149 //------------------------------Value------------------------------------------ 150 const Type* ProjNode::Value(PhaseGVN* phase) const { 151 if (in(0) == NULL) return Type::TOP; 152 return proj_type(phase->type(in(0))); 153 } 154 155 //------------------------------out_RegMask------------------------------------ 156 // Pass the buck uphill 157 const RegMask &ProjNode::out_RegMask() const { 158 return RegMask::Empty; 159 } 160 161 //------------------------------ideal_reg-------------------------------------- 162 Opcodes ProjNode::ideal_reg() const { 163 return bottom_type()->ideal_reg(); 164 } 165 166 //-------------------------------is_uncommon_trap_proj---------------------------- 167 // Return uncommon trap call node if proj is for "proj->[region->..]call_uct" 168 // NULL otherwise 169 CallStaticJavaNode* ProjNode::is_uncommon_trap_proj(Deoptimization::DeoptReason reason) { 170 int path_limit = 10; 171 Node* out = this; 172 for (int ct = 0; ct < path_limit; ct++) { 173 out = out->unique_ctrl_out(); 174 if (out == NULL) 175 return NULL; 176 if (out->is_CallStaticJava()) { 177 CallStaticJavaNode* call = out->as_CallStaticJava(); 178 int req = call->uncommon_trap_request(); 179 if (req != 0) { 180 Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); 181 if (trap_reason == reason || reason == Deoptimization::Reason_none) { 182 return call; 183 } 184 } 185 return NULL; // don't do further after call 186 } 187 if (out->Opcode() != Opcodes::Op_Region) 188 return NULL; 189 } 190 return NULL; 191 } 192 193 //-------------------------------is_uncommon_trap_if_pattern------------------------- 194 // Return uncommon trap call node for "if(test)-> proj -> ... 195 // | 196 // V 197 // other_proj->[region->..]call_uct" 198 // NULL otherwise 199 // "must_reason_predicate" means the uct reason must be Reason_predicate 200 CallStaticJavaNode* ProjNode::is_uncommon_trap_if_pattern(Deoptimization::DeoptReason reason) { 201 Node *in0 = in(0); 202 if (!in0->is_If()) return NULL; 203 // Variation of a dead If node. 204 if (in0->outcnt() < 2) return NULL; 205 IfNode* iff = in0->as_If(); 206 207 // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate 208 if (reason != Deoptimization::Reason_none) { 209 if (iff->in(1)->Opcode() != Opcodes::Op_Conv2B || 210 iff->in(1)->in(1)->Opcode() != Opcodes::Op_Opaque1) { 211 return NULL; 212 } 213 } 214 215 ProjNode* other_proj = iff->proj_out(1-_con); 216 if (other_proj == NULL) // Should never happen, but make Parfait happy. 217 return NULL; 218 CallStaticJavaNode* call = other_proj->is_uncommon_trap_proj(reason); 219 if (call != NULL) { 220 assert(reason == Deoptimization::Reason_none || 221 Compile::current()->is_predicate_opaq(iff->in(1)->in(1)), "should be on the list"); 222 return call; 223 } 224 return NULL; 225 } 226 227 ProjNode* ProjNode::other_if_proj() const { 228 assert(_con == 0 || _con == 1, "not an if?"); 229 return in(0)->as_If()->proj_out(1-_con); 230 } |