@@ -606,19 +606,17 @@ const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node* val, Node* if_proj
606
606
if (iff->in (1 ) && iff->in (1 )->is_Bool ()) {
607
607
BoolNode* bol = iff->in (1 )->as_Bool ();
608
608
if (bol->in (1 ) && bol->in (1 )->is_Cmp ()) {
609
- const CmpNode* cmp = bol->in (1 )->as_Cmp ();
609
+ const CmpNode* cmp = bol->in (1 )->as_Cmp ();
610
610
if (cmp->in (1 ) == val) {
611
611
const TypeInt* cmp2_t = gvn->type (cmp->in (2 ))->isa_int ();
612
612
if (cmp2_t != NULL ) {
613
613
jint lo = cmp2_t ->_lo ;
614
614
jint hi = cmp2_t ->_hi ;
615
- const TypeInt* val_t = gvn->type (val)->isa_int ();
616
- bool is_unsigned = (cmp->Opcode () == Op_CmpU);
617
615
BoolTest::mask msk = if_proj->Opcode () == Op_IfTrue ? bol->_test ._test : bol->_test .negate ();
618
616
switch (msk) {
619
617
case BoolTest::ne: {
620
- assert (!is_unsigned, " unsigned comparison is not supported" );
621
618
// If val is compared to its lower or upper bound, we can narrow the type
619
+ const TypeInt* val_t = gvn->type (val)->isa_int ();
622
620
if (val_t != NULL && !val_t ->singleton () && cmp2_t ->is_con ()) {
623
621
if (val_t ->_lo == lo) {
624
622
return TypeInt::make (val_t ->_lo + 1 , val_t ->_hi , val_t ->_widen );
@@ -630,51 +628,31 @@ const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node* val, Node* if_proj
630
628
return NULL ;
631
629
}
632
630
case BoolTest::eq:
633
- assert (!is_unsigned, " unsigned comparison is not supported" );
634
631
return cmp2_t ;
635
632
case BoolTest::lt:
636
- if (is_unsigned && lo >= 0 ) {
637
- // cmp2 >= 0: val u<= cmp2 can only pass if val >= 0. Set val->_lo to 0.
638
- lo = 0 ;
639
- } else {
640
- // The lower bound of val cannot be improved.
641
- lo = TypeInt::INT->_lo ;
642
- }
633
+ lo = TypeInt::INT->_lo ;
643
634
if (hi != min_jint) {
644
635
hi = hi - 1 ;
645
636
}
646
637
break ;
647
638
case BoolTest::le:
648
- if (is_unsigned && lo >= 0 ) {
649
- // cmp2 >= 0: val u<= cmp2 can only pass if val >= 0. Set val->_lo to 0.
650
- lo = 0 ;
651
- } else {
652
- // The lower bound of val cannot be improved.
653
- lo = TypeInt::INT->_lo ;
654
- }
639
+ lo = TypeInt::INT->_lo ;
655
640
break ;
656
641
case BoolTest::gt:
657
- if (is_unsigned && (val_t == NULL || val_t ->_lo < 0 )) {
658
- // val u> cmp2 passes for val < 0
659
- lo = TypeInt::INT->_lo ;
660
- } else if (lo != max_jint) {
642
+ if (lo != max_jint) {
661
643
lo = lo + 1 ;
662
644
}
663
645
hi = TypeInt::INT->_hi ;
664
646
break ;
665
647
case BoolTest::ge:
666
- if (is_unsigned && (val_t == NULL || val_t ->_lo < 0 )) {
667
- // val u>= cmp2 passes for val < 0
668
- lo = TypeInt::INT->_lo ;
669
- }
670
- // else lo unchanged
648
+ // lo unchanged
671
649
hi = TypeInt::INT->_hi ;
672
650
break ;
673
651
default :
674
- ShouldNotReachHere ();
675
652
break ;
676
653
}
677
- return TypeInt::make (lo, hi, cmp2_t ->_widen );
654
+ const TypeInt* rtn_t = TypeInt::make (lo, hi, cmp2_t ->_widen );
655
+ return rtn_t ;
678
656
}
679
657
}
680
658
}
@@ -722,17 +700,16 @@ const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node* val, Node* if_proj
722
700
//
723
701
724
702
// Is the comparison for this If suitable for folding?
725
- bool IfNode::cmp_folds (PhaseIterGVN* igvn) {
703
+ bool IfNode::cmpi_folds (PhaseIterGVN* igvn, bool fold_ne ) {
726
704
return in (1 ) != NULL &&
727
705
in (1 )->is_Bool () &&
728
706
in (1 )->in (1 ) != NULL &&
729
- (in (1 )->in (1 )->Opcode () == Op_CmpI ||
730
- in (1 )->in (1 )->Opcode () == Op_CmpU) &&
707
+ in (1 )->in (1 )->Opcode () == Op_CmpI &&
731
708
in (1 )->in (1 )->in (2 ) != NULL &&
732
709
in (1 )->in (1 )->in (2 ) != igvn->C ->top () &&
733
710
(in (1 )->as_Bool ()->_test .is_less () ||
734
711
in (1 )->as_Bool ()->_test .is_greater () ||
735
- in (1 )->as_Bool ()->_test ._test == BoolTest::ne);
712
+ (fold_ne && in (1 )->as_Bool ()->_test ._test == BoolTest::ne) );
736
713
}
737
714
738
715
// Is a dominating control suitable for folding with this if?
@@ -742,9 +719,10 @@ bool IfNode::is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn) {
742
719
ctrl->in (0 ) != NULL &&
743
720
ctrl->in (0 )->Opcode () == Op_If &&
744
721
ctrl->in (0 )->outcnt () == 2 &&
745
- ctrl->in (0 )->as_If ()->cmp_folds (igvn) &&
722
+ ctrl->in (0 )->as_If ()->cmpi_folds (igvn, true ) &&
723
+ // Must compare same value
746
724
ctrl->in (0 )->in (1 )->in (1 )->in (1 ) != NULL &&
747
- in (1 )->in (1 )->in (1 ) != NULL ;
725
+ ctrl-> in (0 )-> in ( 1 )->in (1 )->in (1 ) == in ( 1 )-> in ( 1 )-> in ( 1 ) ;
748
726
}
749
727
750
728
// Do this If and the dominating If share a region?
@@ -859,94 +837,8 @@ bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNod
859
837
return false ;
860
838
}
861
839
862
- // There might be an AddINode (marked with *) with a constant increment
863
- // in-between the CmpNodes and the common value we compare.
864
- // Check for the following cases and return true if a common value is
865
- // compared. Also save the constant value that is added to infer
866
- // the type of the common value we compare.
867
- //
868
- // Variant 1 Variant 2 Variant 3 Variant 4
869
- //
870
- // res_val res_val res_val res_val
871
- // / \ / \ / \ / \
872
- // dom_cmp \ / this_val* dom_val* \ dom_val* this_val*
873
- // this_cmp / \ / \ | \
874
- // dom_cmp \ dom_cmp \ dom_cmp \
875
- // this_cmp this_cmp this_cmp
876
- bool IfNode::get_base_comparing_value (Node* dom_if, PhaseIterGVN* igvn, jint& this_adj_val, jint& dom_adj_val) {
877
- assert (dom_if->in (1 )->in (1 )->is_Cmp () && in (1 )->in (1 )->is_Cmp (), " compare expected" );
878
- Node* dom_val = dom_if->in (1 )->in (1 )->in (1 );
879
- Node* this_val = in (1 )->in (1 )->in (1 );
880
- assert (dom_val != NULL && this_val != NULL , " sanity" );
881
- if (this_val == dom_val) {
882
- // Variant 1
883
- return true ;
884
- } else if (this_val->is_Add () && this_val->in (1 ) == dom_val) {
885
- const TypeInt* val_t = igvn->type (this_val->in (2 ))->isa_int ();
886
- if (val_t != NULL && val_t ->is_con ()) {
887
- // Variant 2
888
- this_adj_val = val_t ->get_con ();
889
- return true ;
890
- }
891
- } else if (dom_val->is_Add () && this_val == dom_val->in (1 )) {
892
- const TypeInt* val_t = igvn->type (dom_val->in (2 ))->isa_int ();
893
- if (val_t != NULL && val_t ->is_con ()) {
894
- // Variant 3
895
- dom_adj_val = val_t ->get_con ();
896
- return true ;
897
- }
898
- } else if (this_val->is_Add () && dom_val->is_Add () && this_val->in (1 ) != NULL && this_val->in (1 ) == dom_val->in (1 )) {
899
- const TypeInt* domval_t = igvn->type (dom_val->in (2 ))->isa_int ();
900
- const TypeInt* thisval_t = igvn->type (this_val->in (2 ))->isa_int ();
901
- if (thisval_t != NULL && domval_t != NULL && thisval_t ->is_con () && domval_t ->is_con ()) {
902
- // Variant 4
903
- this_adj_val = thisval_t ->get_con ();
904
- dom_adj_val = domval_t ->get_con ();
905
- return true ;
906
- }
907
- }
908
- return false ;
909
- }
910
-
911
- // Check if dominating if determines the result of this if
912
- bool IfNode::fold_dominated_if (ProjNode* proj, PhaseIterGVN* igvn) {
913
- Node* this_val = in (1 )->in (1 )->in (1 );
914
- Node* dom_if = proj->in (0 )->as_If ();
915
- Node* dom_val = dom_if->in (1 )->in (1 )->in (1 );
916
- jint this_adj_val = 0 ;
917
- jint dom_adj_val = 0 ;
918
-
919
- // Must compare same value
920
- if (get_base_comparing_value (dom_if, igvn, this_adj_val, dom_adj_val)) {
921
- const TypeInt* failtype = filtered_int_type (igvn, dom_val, proj);
922
- if (failtype != NULL ) {
923
- if (dom_adj_val != 0 ) {
924
- // To account for the AddINode, subtract the constant increment from the type
925
- failtype = dom_val->as_Add ()->add_ring (failtype, TypeInt::make (-dom_adj_val))->is_int ();
926
- }
927
- for (int i = 0 ; i < 2 ; ++i) {
928
- const TypeInt* type = filtered_int_type (igvn, this_val, proj_out (i));
929
- if (type != NULL ) {
930
- if (this_adj_val != 0 ) {
931
- // To account for the AddINode, subtract the constant increment from the type
932
- type = this_val->as_Add ()->add_ring (type, TypeInt::make (-this_adj_val))->is_int ();
933
- }
934
- type = failtype->join (type)->is_int ();
935
- if (type->empty ()) {
936
- // Replace Bool with constant
937
- igvn->_worklist .push (in (1 ));
938
- igvn->replace_input_of (this , 1 , igvn->intcon (proj_out (1 -i)->_con ));
939
- return true ;
940
- }
941
- }
942
- }
943
- }
944
- }
945
- return false ;
946
- }
947
-
948
840
// Check that the 2 CmpI can be folded into as single CmpU and proceed with the folding
949
- bool IfNode::fold_to_unsigned (ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn) {
841
+ bool IfNode::fold_compares_helper (ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn) {
950
842
Node* this_cmp = in (1 )->in (1 );
951
843
BoolNode* this_bool = in (1 )->as_Bool ();
952
844
IfNode* dom_iff = proj->in (0 )->as_If ();
@@ -955,17 +847,13 @@ bool IfNode::fold_to_unsigned(ProjNode* proj, ProjNode* success, ProjNode* fail,
955
847
Node* hi = this_cmp->in (2 );
956
848
Node* n = this_cmp->in (1 );
957
849
ProjNode* otherproj = proj->other_if_proj ();
958
- assert (this_cmp->Opcode () == Op_CmpI && dom_iff->in (1 )->in (1 )->Opcode () == Op_CmpI, " Unexpected CmpNode" );
850
+
851
+ const TypeInt* lo_type = IfNode::filtered_int_type (igvn, n, otherproj);
852
+ const TypeInt* hi_type = IfNode::filtered_int_type (igvn, n, success);
959
853
960
854
BoolTest::mask lo_test = dom_bool->_test ._test ;
961
855
BoolTest::mask hi_test = this_bool->_test ._test ;
962
856
BoolTest::mask cond = hi_test;
963
- if (lo_test == BoolTest::ne || hi_test == BoolTest::ne) {
964
- return false ;
965
- }
966
-
967
- const TypeInt* lo_type = IfNode::filtered_int_type (igvn, n, otherproj);
968
- const TypeInt* hi_type = IfNode::filtered_int_type (igvn, n, success);
969
857
970
858
// convert:
971
859
//
@@ -993,7 +881,7 @@ bool IfNode::fold_to_unsigned(ProjNode* proj, ProjNode* success, ProjNode* fail,
993
881
// sets the lower bound if any.
994
882
Node* adjusted_lim = NULL ;
995
883
if (lo_type != NULL && hi_type != NULL && hi_type->_lo > lo_type->_hi &&
996
- hi_type->_hi == max_jint && lo_type->_lo == min_jint) {
884
+ hi_type->_hi == max_jint && lo_type->_lo == min_jint && lo_test != BoolTest::ne ) {
997
885
assert ((dom_bool->_test .is_less () && !proj->_con ) ||
998
886
(dom_bool->_test .is_greater () && proj->_con ), " incorrect test" );
999
887
// this test was canonicalized
@@ -1038,7 +926,7 @@ bool IfNode::fold_to_unsigned(ProjNode* proj, ProjNode* success, ProjNode* fail,
1038
926
return false ;
1039
927
}
1040
928
} else if (lo_type != NULL && hi_type != NULL && lo_type->_lo > hi_type->_hi &&
1041
- lo_type->_hi == max_jint && hi_type->_lo == min_jint) {
929
+ lo_type->_hi == max_jint && hi_type->_lo == min_jint && lo_test != BoolTest::ne ) {
1042
930
1043
931
// this_bool = <
1044
932
// dom_bool = < (proj = True) or dom_bool = >= (proj = False)
@@ -1096,6 +984,20 @@ bool IfNode::fold_to_unsigned(ProjNode* proj, ProjNode* success, ProjNode* fail,
1096
984
return false ;
1097
985
}
1098
986
} else {
987
+ const TypeInt* failtype = filtered_int_type (igvn, n, proj);
988
+ if (failtype != NULL ) {
989
+ const TypeInt* type2 = filtered_int_type (igvn, n, fail);
990
+ if (type2 != NULL ) {
991
+ failtype = failtype->join (type2)->is_int ();
992
+ if (failtype->_lo > failtype->_hi ) {
993
+ // previous if determines the result of this if so
994
+ // replace Bool with constant
995
+ igvn->_worklist .push (in (1 ));
996
+ igvn->replace_input_of (this , 1 , igvn->intcon (success->_con ));
997
+ return true ;
998
+ }
999
+ }
1000
+ }
1099
1001
lo = NULL ;
1100
1002
hi = NULL ;
1101
1003
}
@@ -1359,57 +1261,42 @@ void IfNode::reroute_side_effect_free_unc(ProjNode* proj, ProjNode* dom_proj, Ph
1359
1261
Node* IfNode::fold_compares (PhaseIterGVN* igvn) {
1360
1262
if (Opcode () != Op_If) return NULL ;
1361
1263
1362
- if (cmp_folds (igvn)) {
1264
+ if (cmpi_folds (igvn)) {
1363
1265
Node* ctrl = in (0 );
1364
- Node* cmp = in (1 )->in (1 );
1365
- Node* val = cmp->in (1 );
1366
- // An integer comparison immediately dominated by another integer comparison
1367
- if (is_ctrl_folds (ctrl, igvn)) {
1368
- ProjNode* proj = ctrl->as_Proj ();
1369
- if (fold_dominated_if (proj, igvn)) {
1266
+ if (is_ctrl_folds (ctrl, igvn) && ctrl->outcnt () == 1 ) {
1267
+ // A integer comparison immediately dominated by another integer
1268
+ // comparison
1269
+ ProjNode* success = NULL ;
1270
+ ProjNode* fail = NULL ;
1271
+ ProjNode* dom_cmp = ctrl->as_Proj ();
1272
+ if (has_shared_region (dom_cmp, success, fail) &&
1273
+ // Next call modifies graph so must be last
1274
+ fold_compares_helper (dom_cmp, success, fail, igvn)) {
1370
1275
return this ;
1371
1276
}
1372
- Node* dom_cmp = ctrl->in (0 )->in (1 )->in (1 );
1373
- Node* dom_val = dom_cmp->in (1 );
1374
- if (cmp->Opcode () == Op_CmpI && dom_cmp->Opcode () == Op_CmpI && val == dom_val && ctrl->outcnt () == 1 ) {
1375
- ProjNode* success = NULL ;
1376
- ProjNode* fail = NULL ;
1377
- if (has_shared_region (proj, success, fail) &&
1378
- // Next call modifies graph so must be last
1379
- fold_to_unsigned (proj, success, fail, igvn)) {
1380
- return this ;
1381
- }
1382
- if (has_only_uncommon_traps (proj, success, fail, igvn) &&
1383
- // Next call modifies graph so must be last
1384
- fold_to_unsigned (proj, success, fail, igvn)) {
1385
- return merge_uncommon_traps (proj, success, fail, igvn);
1386
- }
1277
+ if (has_only_uncommon_traps (dom_cmp, success, fail, igvn) &&
1278
+ // Next call modifies graph so must be last
1279
+ fold_compares_helper (dom_cmp, success, fail, igvn)) {
1280
+ return merge_uncommon_traps (dom_cmp, success, fail, igvn);
1387
1281
}
1388
- }
1389
- if (ctrl->in (0 ) != NULL &&
1390
- ctrl->in (0 )->in (0 ) != NULL ) {
1282
+ return NULL ;
1283
+ } else if (ctrl->in (0 ) != NULL &&
1284
+ ctrl->in (0 )->in (0 ) != NULL ) {
1391
1285
ProjNode* success = NULL ;
1392
1286
ProjNode* fail = NULL ;
1393
1287
Node* dom = ctrl->in (0 )->in (0 );
1394
- ProjNode* dom_proj = dom->isa_Proj ();
1395
- ProjNode* other_proj = ctrl->isa_Proj ();
1288
+ ProjNode* dom_cmp = dom->isa_Proj ();
1289
+ ProjNode* other_cmp = ctrl->isa_Proj ();
1396
1290
1397
1291
// Check if it's an integer comparison dominated by another
1398
1292
// integer comparison with another test in between
1399
- if (is_ctrl_folds (dom, igvn)) {
1400
- if (fold_dominated_if (dom_proj, igvn)) {
1401
- return this ;
1402
- }
1403
- Node* dom_cmp = dom->in (0 )->in (1 )->in (1 );
1404
- Node* dom_val = dom_cmp->in (1 );
1405
- if (cmp->Opcode () == Op_CmpI && dom_cmp->Opcode () == Op_CmpI && val == dom_val &&
1406
- has_only_uncommon_traps (dom_proj, success, fail, igvn) &&
1407
- is_side_effect_free_test (other_proj, igvn) &&
1408
- // Next call modifies graph so must be last
1409
- fold_to_unsigned (dom_proj, success, fail, igvn)) {
1410
- reroute_side_effect_free_unc (other_proj, dom_proj, igvn);
1411
- return merge_uncommon_traps (dom_proj, success, fail, igvn);
1412
- }
1293
+ if (is_ctrl_folds (dom, igvn) &&
1294
+ has_only_uncommon_traps (dom_cmp, success, fail, igvn) &&
1295
+ is_side_effect_free_test (other_cmp, igvn) &&
1296
+ // Next call modifies graph so must be last
1297
+ fold_compares_helper (dom_cmp, success, fail, igvn)) {
1298
+ reroute_side_effect_free_unc (other_cmp, dom_cmp, igvn);
1299
+ return merge_uncommon_traps (dom_cmp, success, fail, igvn);
1413
1300
}
1414
1301
}
1415
1302
}
0 commit comments