2222 *
2323 */
2424
25- #include " castnode.hpp"
2625#include " opto/addnode.hpp"
2726#include " opto/callnode.hpp"
2827#include " opto/castnode.hpp"
3534#include " opto/type.hpp"
3635#include " utilities/checkedCast.hpp"
3736
37+ const ConstraintCastNode::DependencyType ConstraintCastNode::DependencyType::FloatingNarrowing (true , true , " floating narrowing dependency" ); // not pinned, narrows type
38+ const ConstraintCastNode::DependencyType ConstraintCastNode::DependencyType::FloatingNonNarrowing (true , false , " floating non-narrowing dependency" ); // not pinned, doesn't narrow type
39+ const ConstraintCastNode::DependencyType ConstraintCastNode::DependencyType::NonFloatingNarrowing (false , true , " non-floating narrowing dependency" ); // pinned, narrows type
40+ const ConstraintCastNode::DependencyType ConstraintCastNode::DependencyType::NonFloatingNonNarrowing (false , false , " non-floating non-narrowing dependency" ); // pinned, doesn't narrow type
41+
3842// =============================================================================
3943// If input is already higher or equal to cast type, then this is an identity.
4044Node* ConstraintCastNode::Identity (PhaseGVN* phase) {
41- if (_dependency == UnconditionalDependency) {
45+ if (!_dependency.narrows_type ()) {
46+ // If this cast doesn't carry a type dependency (i.e. not used for type narrowing), we cannot optimize it.
4247 return this ;
4348 }
49+
50+ // This cast node carries a type dependency. We can remove it if:
51+ // - Its input has a narrower type
52+ // - There's a dominating cast with same input but narrower type
4453 Node* dom = dominating_cast (phase, phase);
4554 if (dom != nullptr ) {
4655 return dom;
@@ -109,15 +118,15 @@ Node* ConstraintCastNode::Ideal(PhaseGVN* phase, bool can_reshape) {
109118}
110119
111120uint ConstraintCastNode::hash () const {
112- return TypeNode::hash () + ( int )_dependency + (_extra_types != nullptr ? _extra_types->hash () : 0 );
121+ return TypeNode::hash () + _dependency. hash () + (_extra_types != nullptr ? _extra_types->hash () : 0 );
113122}
114123
115124bool ConstraintCastNode::cmp (const Node &n) const {
116125 if (!TypeNode::cmp (n)) {
117126 return false ;
118127 }
119128 ConstraintCastNode& cast = (ConstraintCastNode&) n;
120- if (cast._dependency != _dependency) {
129+ if (! cast._dependency . cmp ( _dependency) ) {
121130 return false ;
122131 }
123132 if (_extra_types == nullptr || cast._extra_types == nullptr ) {
@@ -130,7 +139,7 @@ uint ConstraintCastNode::size_of() const {
130139 return sizeof (*this );
131140}
132141
133- Node* ConstraintCastNode::make_cast_for_basic_type (Node* c, Node* n, const Type* t, DependencyType dependency, BasicType bt) {
142+ Node* ConstraintCastNode::make_cast_for_basic_type (Node* c, Node* n, const Type* t, const DependencyType& dependency, BasicType bt) {
134143 switch (bt) {
135144 case T_INT:
136145 return new CastIINode (c, n, t, dependency);
@@ -143,9 +152,9 @@ Node* ConstraintCastNode::make_cast_for_basic_type(Node* c, Node* n, const Type*
143152}
144153
145154TypeNode* ConstraintCastNode::dominating_cast (PhaseGVN* gvn, PhaseTransform* pt) const {
146- if (_dependency == UnconditionalDependency) {
147- return nullptr ;
148- }
155+ // See discussion at definition of ConstraintCastNode::DependencyType: replacing this cast with a dominating one is
156+ // not safe if _dependency.narrows_type() is not true.
157+ assert (_dependency. narrows_type (), " cast can't be replaced by dominating one " );
149158 Node* val = in (1 );
150159 Node* ctl = in (0 );
151160 int opc = Opcode ();
@@ -205,30 +214,21 @@ void ConstraintCastNode::dump_spec(outputStream *st) const {
205214 st->print (" extra types: " );
206215 _extra_types->dump_on (st);
207216 }
208- if (_dependency != RegularDependency) {
209- st->print (" %s dependency" , _dependency == StrongDependency ? " strong" : " unconditional" );
210- }
217+ st->print (" " );
218+ _dependency.dump_on (st);
211219}
212220#endif
213221
214- const Type* CastIINode::Value (PhaseGVN* phase) const {
215- const Type *res = ConstraintCastNode::Value (phase);
216- if (res == Type::TOP) {
217- return Type::TOP;
218- }
219- assert (res->isa_int (), " res must be int" );
220-
221- // Similar to ConvI2LNode::Value() for the same reasons
222- // see if we can remove type assertion after loop opts
223- res = widen_type (phase, res, T_INT);
222+ CastIINode* CastIINode::make_with (Node* parent, const TypeInteger* type, const DependencyType& dependency) const {
223+ return new CastIINode (in (0 ), parent, type, dependency, _range_check_dependency, _extra_types);
224+ }
224225
225- return res;
226+ CastLLNode* CastLLNode::make_with (Node* parent, const TypeInteger* type, const DependencyType& dependency) const {
227+ return new CastLLNode (in (0 ), parent, type, dependency, _extra_types);
226228}
227229
228- Node* ConstraintCastNode::find_or_make_integer_cast (PhaseIterGVN* igvn, Node* parent, const TypeInteger* type) const {
229- Node* n = clone ();
230- n->set_req (1 , parent);
231- n->as_ConstraintCast ()->set_type (type);
230+ Node* ConstraintCastNode::find_or_make_integer_cast (PhaseIterGVN* igvn, Node* parent, const TypeInteger* type, const DependencyType& dependency) const {
231+ Node* n = make_with (parent, type, dependency);
232232 Node* existing = igvn->hash_find_insert (n);
233233 if (existing != nullptr ) {
234234 n->destruct (igvn);
@@ -242,14 +242,13 @@ Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) {
242242 if (progress != nullptr ) {
243243 return progress;
244244 }
245- if (can_reshape && !phase->C ->post_loop_opts_phase ()) {
246- // makes sure we run ::Value to potentially remove type assertion after loop opts
245+ if (!phase->C ->post_loop_opts_phase ()) {
246+ // makes sure we run widen_type() to potentially common type assertions after loop opts
247247 phase->C ->record_for_post_loop_opts_igvn (this );
248248 }
249249 if (!_range_check_dependency || phase->C ->post_loop_opts_phase ()) {
250250 return optimize_integer_cast (phase, T_INT);
251251 }
252- phase->C ->record_for_post_loop_opts_igvn (this );
253252 return nullptr ;
254253}
255254
@@ -279,9 +278,9 @@ void CastIINode::dump_spec(outputStream* st) const {
279278#endif
280279
281280CastIINode* CastIINode::pin_array_access_node () const {
282- assert (_dependency == RegularDependency , " already pinned" );
281+ assert (_dependency. is_floating () , " already pinned" );
283282 if (has_range_check ()) {
284- return new CastIINode (in (0 ), in (1 ), bottom_type (), StrongDependency , has_range_check ());
283+ return new CastIINode (in (0 ), in (1 ), bottom_type (), _dependency. with_pinned_dependency () , has_range_check ());
285284 }
286285 return nullptr ;
287286}
@@ -315,16 +314,6 @@ void CastIINode::remove_range_check_cast(Compile* C) {
315314}
316315
317316
318- const Type* CastLLNode::Value (PhaseGVN* phase) const {
319- const Type* res = ConstraintCastNode::Value (phase);
320- if (res == Type::TOP) {
321- return Type::TOP;
322- }
323- assert (res->isa_long (), " res must be long" );
324-
325- return widen_type (phase, res, T_LONG);
326- }
327-
328317bool CastLLNode::is_inner_loop_backedge (ProjNode* proj) {
329318 if (proj != nullptr ) {
330319 Node* ctrl_use = proj->unique_ctrl_out_or_null ();
@@ -392,7 +381,7 @@ Node* CastLLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
392381 return progress;
393382 }
394383 if (!phase->C ->post_loop_opts_phase ()) {
395- // makes sure we run ::Value to potentially remove type assertion after loop opts
384+ // makes sure we run widen_type() to potentially common type assertions after loop opts
396385 phase->C ->record_for_post_loop_opts_igvn (this );
397386 }
398387 // transform (CastLL (ConvI2L ..)) into (ConvI2L (CastII ..)) if the type of the CastLL is narrower than the type of
@@ -543,7 +532,7 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {
543532 return this ;
544533}
545534
546- Node* ConstraintCastNode::make_cast_for_type (Node* c, Node* in, const Type* type, DependencyType dependency,
535+ Node* ConstraintCastNode::make_cast_for_type (Node* c, Node* in, const Type* type, const DependencyType& dependency,
547536 const TypeTuple* types) {
548537 if (type->isa_int ()) {
549538 return new CastIINode (c, in, type, dependency, false , types);
@@ -564,7 +553,7 @@ Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type
564553 return nullptr ;
565554}
566555
567- Node* ConstraintCastNode::optimize_integer_cast (PhaseGVN* phase, BasicType bt) {
556+ Node* ConstraintCastNode::optimize_integer_cast_of_add (PhaseGVN* phase, BasicType bt) {
568557 PhaseIterGVN *igvn = phase->is_IterGVN ();
569558 const TypeInteger* this_type = this ->type ()->isa_integer (bt);
570559 if (this_type == nullptr ) {
@@ -586,8 +575,42 @@ Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
586575 Node* x = z->in (1 );
587576 Node* y = z->in (2 );
588577
589- Node* cx = find_or_make_integer_cast (igvn, x, rx);
590- Node* cy = find_or_make_integer_cast (igvn, y, ry);
578+ const TypeInteger* tx = phase->type (x)->is_integer (bt);
579+ const TypeInteger* ty = phase->type (y)->is_integer (bt);
580+
581+ // (Cast (Add x y) tz) is transformed into (Add (Cast x rx) (Cast y ry))
582+ //
583+ // tz = [tzlo, tzhi]
584+ // rx = [rxlo, rxhi]
585+ // ry = [rylo, ryhi]
586+ // with type of x, tx = [txlo, txhi]
587+ // with type of y, ty = [tylo, tyhi]
588+ //
589+ // From Compile::push_thru_add():
590+ // rxlo = max(tzlo - tyhi, txlo)
591+ // rxhi = min(tzhi - tylo, txhi)
592+ // rylo = max(tzlo - txhi, tylo)
593+ // ryhi = min(tzhi - txlo, tyhi)
594+ //
595+ // If x is a constant, then txlo = txhi
596+ // rxlo = txlo, rxhi = txhi
597+ // The bounds of the type of the Add after transformation then is:
598+ // rxlo + rylo >= txlo + tzlo - txhi >= tzlo
599+ // rxhi + ryhi <= txhi + tzhi - txlo <= tzhi
600+ // The resulting type is not wider than the type of the Cast
601+ // before transformation
602+ //
603+ // If neither x nor y are constant then the type of the resulting
604+ // Add can be wider than the type of the type of the Cast before
605+ // transformation.
606+ // For instance, tx = [0, 10], ty = [0, 10], tz = [0, 10]
607+ // then rx = [0, 10], ry = [0, 10]
608+ // and rx + ry = [0, 20] which is wider than tz
609+ //
610+ // Same reasoning applies to (Cast (Sub x y) tz)
611+ const DependencyType& dependency = (!tx->is_con () && !ty->is_con ()) ? _dependency.with_non_narrowing () : _dependency;
612+ Node* cx = find_or_make_integer_cast (igvn, x, rx, dependency);
613+ Node* cy = find_or_make_integer_cast (igvn, y, ry, dependency);
591614 if (op == Op_Add (bt)) {
592615 return AddNode::make (cx, cy, bt);
593616 } else {
@@ -599,11 +622,26 @@ Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
599622 return nullptr ;
600623}
601624
602- const Type* ConstraintCastNode::widen_type (const PhaseGVN* phase, const Type* res, BasicType bt) const {
603- if (!phase->C ->post_loop_opts_phase ()) {
625+ Node* ConstraintCastNode::optimize_integer_cast (PhaseGVN* phase, BasicType bt) {
626+ Node* res = optimize_integer_cast_of_add (phase, bt);
627+ if (res != nullptr ) {
604628 return res;
605629 }
630+ const Type* t = Value (phase);
631+ if (t != Type::TOP && phase->C ->post_loop_opts_phase ()) {
632+ const Type* bottom_t = bottom_type ();
633+ const TypeInteger* wide_t = widen_type (phase, bottom_t , bt);
634+ if (wide_t != bottom_t ) {
635+ // Widening the type of the Cast (to allow some commoning) causes the Cast to change how it can be optimized (if
636+ // type of its input is narrower than the Cast's type, we can't remove it to not loose the control dependency).
637+ return make_with (in (1 ), wide_t , _dependency.with_non_narrowing ());
638+ }
639+ }
640+ return nullptr ;
641+ }
606642
643+ const TypeInteger* ConstraintCastNode::widen_type (const PhaseGVN* phase, const Type* res, BasicType bt) const {
644+ const TypeInteger* this_type = res->is_integer (bt);
607645 // At VerifyConstraintCasts == 1, we verify the ConstraintCastNodes that are present during code
608646 // emission. This allows us detecting possible mis-scheduling due to these nodes being pinned at
609647 // the wrong control nodes.
@@ -612,10 +650,9 @@ const Type* ConstraintCastNode::widen_type(const PhaseGVN* phase, const Type* re
612650 // mis-transformations that may happen due to these nodes being pinned at the wrong control
613651 // nodes.
614652 if (VerifyConstraintCasts > 1 ) {
615- return res ;
653+ return this_type ;
616654 }
617655
618- const TypeInteger* this_type = res->is_integer (bt);
619656 const TypeInteger* in_type = phase->type (in (1 ))->isa_integer (bt);
620657 if (in_type != nullptr &&
621658 (in_type->lo_as_long () != this_type->lo_as_long () ||
@@ -636,5 +673,5 @@ const Type* ConstraintCastNode::widen_type(const PhaseGVN* phase, const Type* re
636673 MIN2 (in_type->hi_as_long (), hi1),
637674 MAX2 ((int )in_type->_widen , w1), bt);
638675 }
639- return res ;
676+ return this_type ;
640677}
0 commit comments