@@ -447,6 +447,47 @@ static Node *transform_long_divide( PhaseGVN *phase, Node *dividend, jlong divis
447447 return q;
448448}
449449
450+ template <typename TypeClass, typename Unsigned>
451+ Node* unsigned_div_ideal (PhaseGVN* phase, bool can_reshape, Node* div) {
452+ // Check for dead control input
453+ if (div->in (0 ) != nullptr && div->remove_dead_region (phase, can_reshape)) {
454+ return div;
455+ }
456+ // Don't bother trying to transform a dead node
457+ if (div->in (0 ) != nullptr && div->in (0 )->is_top ()) {
458+ return nullptr ;
459+ }
460+
461+ const Type* t = phase->type (div->in (2 ));
462+ if (t == Type::TOP) {
463+ return nullptr ;
464+ }
465+ const TypeClass* type_divisor = t->cast <TypeClass>();
466+
467+ // Check for useless control input
468+ // Check for excluding div-zero case
469+ if (div->in (0 ) != nullptr && (type_divisor->_hi < 0 || type_divisor->_lo > 0 )) {
470+ div->set_req (0 , nullptr ); // Yank control input
471+ return div;
472+ }
473+
474+ if (!type_divisor->is_con ()) {
475+ return nullptr ;
476+ }
477+ Unsigned divisor = static_cast <Unsigned>(type_divisor->get_con ()); // Get divisor
478+
479+ if (divisor == 0 || divisor == 1 ) {
480+ return nullptr ; // Dividing by zero constant does not idealize
481+ }
482+
483+ if (is_power_of_2 (divisor)) {
484+ return make_urshift<TypeClass>(div->in (1 ), phase->intcon (log2i_graceful (divisor)));
485+ }
486+
487+ return nullptr ;
488+ }
489+
490+
450491// =============================================================================
451492// ------------------------------Identity---------------------------------------
452493// If the divisor is 1, we are an identity on the dividend.
@@ -873,12 +914,9 @@ const Type* UDivINode::Value(PhaseGVN* phase) const {
873914
874915// ------------------------------Idealize---------------------------------------
875916Node *UDivINode::Ideal (PhaseGVN *phase, bool can_reshape) {
876- // Check for dead control input
877- if (in (0 ) && remove_dead_region (phase, can_reshape)) return this ;
878- return nullptr ;
917+ return unsigned_div_ideal<TypeInt, juint>(phase, can_reshape, this );
879918}
880919
881-
882920// =============================================================================
883921// ------------------------------Identity---------------------------------------
884922// If the divisor is 1, we are an identity on the dividend.
@@ -912,12 +950,9 @@ const Type* UDivLNode::Value(PhaseGVN* phase) const {
912950
913951// ------------------------------Idealize---------------------------------------
914952Node *UDivLNode::Ideal (PhaseGVN *phase, bool can_reshape) {
915- // Check for dead control input
916- if (in (0 ) && remove_dead_region (phase, can_reshape)) return this ;
917- return nullptr ;
953+ return unsigned_div_ideal<TypeLong, julong>(phase, can_reshape, this );
918954}
919955
920-
921956// =============================================================================
922957// ------------------------------Idealize---------------------------------------
923958Node *ModINode::Ideal (PhaseGVN *phase, bool can_reshape) {
@@ -1084,12 +1119,98 @@ const Type* ModINode::Value(PhaseGVN* phase) const {
10841119
10851120// =============================================================================
10861121// ------------------------------Idealize---------------------------------------
1087- Node *UModINode::Ideal (PhaseGVN *phase, bool can_reshape) {
1122+
1123+ template <typename TypeClass, typename Unsigned>
1124+ static Node* unsigned_mod_ideal (PhaseGVN* phase, bool can_reshape, Node* mod) {
10881125 // Check for dead control input
1089- if ( in (0 ) && remove_dead_region (phase, can_reshape) ) return this ;
1126+ if (mod->in (0 ) != nullptr && mod->remove_dead_region (phase, can_reshape)) {
1127+ return mod;
1128+ }
1129+ // Don't bother trying to transform a dead node
1130+ if (mod->in (0 ) != nullptr && mod->in (0 )->is_top ()) {
1131+ return nullptr ;
1132+ }
1133+
1134+ // Get the modulus
1135+ const Type* t = phase->type (mod->in (2 ));
1136+ if (t == Type::TOP) {
1137+ return nullptr ;
1138+ }
1139+ const TypeClass* type_divisor = t->cast <TypeClass>();
1140+
1141+ // Check for useless control input
1142+ // Check for excluding mod-zero case
1143+ if (mod->in (0 ) != nullptr && (type_divisor->_hi < 0 || type_divisor->_lo > 0 )) {
1144+ mod->set_req (0 , nullptr ); // Yank control input
1145+ return mod;
1146+ }
1147+
1148+ if (!type_divisor->is_con ()) {
1149+ return nullptr ;
1150+ }
1151+ Unsigned divisor = static_cast <Unsigned>(type_divisor->get_con ());
1152+
1153+ if (divisor == 0 ) {
1154+ return nullptr ;
1155+ }
1156+
1157+ if (is_power_of_2 (divisor)) {
1158+ return make_and<TypeClass>(mod->in (1 ), phase->makecon (TypeClass::make (divisor - 1 )));
1159+ }
1160+
10901161 return nullptr ;
10911162}
10921163
1164+ template <typename TypeClass, typename Unsigned, typename Signed>
1165+ static const Type* unsigned_mod_value (PhaseGVN* phase, const Node* mod) {
1166+ const Type* t1 = phase->type (mod->in (1 ));
1167+ const Type* t2 = phase->type (mod->in (2 ));
1168+ if (t1 == Type::TOP) {
1169+ return Type::TOP;
1170+ }
1171+ if (t2 == Type::TOP) {
1172+ return Type::TOP;
1173+ }
1174+
1175+ // 0 MOD X is 0
1176+ if (t1 == TypeClass::ZERO) {
1177+ return TypeClass::ZERO;
1178+ }
1179+ // X MOD X is 0
1180+ if (mod->in (1 ) == mod->in (2 )) {
1181+ return TypeClass::ZERO;
1182+ }
1183+
1184+ // Either input is BOTTOM ==> the result is the local BOTTOM
1185+ const Type* bot = mod->bottom_type ();
1186+ if ((t1 == bot) || (t2 == bot) ||
1187+ (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM)) {
1188+ return bot;
1189+ }
1190+
1191+ const TypeClass* type_divisor = t2->cast <TypeClass>();
1192+ if (type_divisor->is_con () && type_divisor->get_con () == 1 ) {
1193+ return TypeClass::ZERO;
1194+ }
1195+
1196+ const TypeClass* type_dividend = t1->cast <TypeClass>();
1197+ if (type_dividend->is_con () && type_divisor->is_con ()) {
1198+ Unsigned dividend = static_cast <Unsigned>(type_dividend->get_con ());
1199+ Unsigned divisor = static_cast <Unsigned>(type_divisor->get_con ());
1200+ return TypeClass::make (static_cast <Signed>(dividend % divisor));
1201+ }
1202+
1203+ return bot;
1204+ }
1205+
1206+ Node* UModINode::Ideal (PhaseGVN* phase, bool can_reshape) {
1207+ return unsigned_mod_ideal<TypeInt, juint>(phase, can_reshape, this );
1208+ }
1209+
1210+ const Type* UModINode::Value (PhaseGVN* phase) const {
1211+ return unsigned_mod_value<TypeInt, juint, jint>(phase, this );
1212+ }
1213+
10931214// =============================================================================
10941215// ------------------------------Idealize---------------------------------------
10951216Node *ModLNode::Ideal (PhaseGVN *phase, bool can_reshape) {
@@ -1303,11 +1424,12 @@ const Type* ModFNode::Value(PhaseGVN* phase) const {
13031424// =============================================================================
13041425// ------------------------------Idealize---------------------------------------
13051426Node *UModLNode::Ideal (PhaseGVN *phase, bool can_reshape) {
1306- // Check for dead control input
1307- if ( in (0 ) && remove_dead_region (phase, can_reshape) ) return this ;
1308- return nullptr ;
1427+ return unsigned_mod_ideal<TypeLong, julong>(phase, can_reshape, this );
13091428}
13101429
1430+ const Type* UModLNode::Value (PhaseGVN* phase) const {
1431+ return unsigned_mod_value<TypeLong, julong, jlong>(phase, this );
1432+ }
13111433
13121434// =============================================================================
13131435// ------------------------------Value------------------------------------------
0 commit comments