102 Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { 103 if( in(0) && remove_dead_region(phase, can_reshape) ) return this; 104 // Don't bother trying to transform a dead node 105 if( in(0) && in(0)->is_top() ) return NULL; 106 assert( !phase->eqv(in(Condition), this) && 107 !phase->eqv(in(IfFalse), this) && 108 !phase->eqv(in(IfTrue), this), "dead loop in CMoveNode::Ideal" ); 109 if( phase->type(in(Condition)) == Type::TOP ) 110 return NULL; // return NULL when Condition is dead 111 112 if( in(IfFalse)->is_Con() && !in(IfTrue)->is_Con() ) { 113 if( in(Condition)->is_Bool() ) { 114 BoolNode* b = in(Condition)->as_Bool(); 115 BoolNode* b2 = b->negate(phase); 116 return make( phase->C, in(Control), phase->transform(b2), in(IfTrue), in(IfFalse), _type ); 117 } 118 } 119 return NULL; 120 } 121 122 //------------------------------is_cmove_id------------------------------------ 123 // Helper function to check for CMOVE identity. Shared with PhiNode::Identity 124 Node *CMoveNode::is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f, BoolNode *b ) { 125 // Check for Cmp'ing and CMove'ing same values 126 if( (phase->eqv(cmp->in(1),f) && 127 phase->eqv(cmp->in(2),t)) || 128 // Swapped Cmp is OK 129 (phase->eqv(cmp->in(2),f) && 130 phase->eqv(cmp->in(1),t)) ) { 131 // Check for "(t==f)?t:f;" and replace with "f" 132 if( b->_test._test == BoolTest::eq ) 133 return f; 134 // Allow the inverted case as well 135 // Check for "(t!=f)?t:f;" and replace with "t" 136 if( b->_test._test == BoolTest::ne ) 137 return t; 138 } 139 return NULL; 140 } 141 142 //------------------------------Identity--------------------------------------- 143 // Conditional-move is an identity if both inputs are the same, or the test 144 // true or false. | 102 Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { 103 if( in(0) && remove_dead_region(phase, can_reshape) ) return this; 104 // Don't bother trying to transform a dead node 105 if( in(0) && in(0)->is_top() ) return NULL; 106 assert( !phase->eqv(in(Condition), this) && 107 !phase->eqv(in(IfFalse), this) && 108 !phase->eqv(in(IfTrue), this), "dead loop in CMoveNode::Ideal" ); 109 if( phase->type(in(Condition)) == Type::TOP ) 110 return NULL; // return NULL when Condition is dead 111 112 if( in(IfFalse)->is_Con() && !in(IfTrue)->is_Con() ) { 113 if( in(Condition)->is_Bool() ) { 114 BoolNode* b = in(Condition)->as_Bool(); 115 BoolNode* b2 = b->negate(phase); 116 return make( phase->C, in(Control), phase->transform(b2), in(IfTrue), in(IfFalse), _type ); 117 } 118 } 119 return NULL; 120 } 121 122 //-----------------------------is_float_or_double_zero----------------------- 123 // Helper function for is_cmove_id to find float or double constant 0.0 124 bool CMoveNode::is_float_or_double_zero(PhaseTransform* phase, Node *val) { 125 const Type* t = phase->type(val); 126 if (t == Type::TOP) return false; 127 const TypeF *tf = t->isa_float_constant(); 128 if( tf != NULL && tf->_f==0.0) 129 return true; 130 const TypeD *td = t->isa_double_constant(); 131 if( td != NULL && td->_d==0.0) 132 return true; 133 134 return false; 135 } 136 137 //------------------------------is_cmove_id------------------------------------ 138 // Helper function to check for CMOVE identity. Shared with PhiNode::Identity 139 Node *CMoveNode::is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f, BoolNode *b ) { 140 // Give up this identity check if either "t" or "f" is 0.0 (or -0.0) 141 // For example, for (f==0.0)?0.0:f, and if f = -0.0, the result should be 0.0 instead of -0.0(f) 142 // NOTE: non-constant double or float may still turn out to be 0.0 (-0.0). However, it may be 143 // too expensive to disable this optimization for general cases. 144 if( is_float_or_double_zero(phase, t) || 145 is_float_or_double_zero(phase, f) ) 146 return NULL; 147 148 // Check for Cmp'ing and CMove'ing same values 149 if( (phase->eqv(cmp->in(1),f) && 150 phase->eqv(cmp->in(2),t)) || 151 // Swapped Cmp is OK 152 (phase->eqv(cmp->in(2),f) && 153 phase->eqv(cmp->in(1),t)) ) { 154 // Check for "(t==f)?t:f;" and replace with "f" 155 if( b->_test._test == BoolTest::eq ) 156 return f; 157 // Allow the inverted case as well 158 // Check for "(t!=f)?t:f;" and replace with "t" 159 if( b->_test._test == BoolTest::ne ) 160 return t; 161 } 162 return NULL; 163 } 164 165 //------------------------------Identity--------------------------------------- 166 // Conditional-move is an identity if both inputs are the same, or the test 167 // true or false. |