< prev index next >

src/share/vm/opto/divnode.cpp

Print this page




 101 
 102   // Result
 103   Node *q = NULL;
 104 
 105   if (d == 1) {
 106     // division by +/- 1
 107     if (!d_pos) {
 108       // Just negate the value
 109       q = new SubINode(phase->intcon(0), dividend);
 110     }
 111   } else if ( is_power_of_2(d) ) {
 112     // division by +/- a power of 2
 113 
 114     // See if we can simply do a shift without rounding
 115     bool needs_rounding = true;
 116     const Type *dt = phase->type(dividend);
 117     const TypeInt *dti = dt->isa_int();
 118     if (dti && dti->_lo >= 0) {
 119       // we don't need to round a positive dividend
 120       needs_rounding = false;
 121     } else if( dividend->Opcode() == Op_AndI ) {
 122       // An AND mask of sufficient size clears the low bits and
 123       // I can avoid rounding.
 124       const TypeInt *andconi_t = phase->type( dividend->in(2) )->isa_int();
 125       if( andconi_t && andconi_t->is_con() ) {
 126         jint andconi = andconi_t->get_con();
 127         if( andconi < 0 && is_power_of_2(-andconi) && (-andconi) >= d ) {
 128           if( (-andconi) == d ) // Remove AND if it clears bits which will be shifted
 129             dividend = dividend->in(1);
 130           needs_rounding = false;
 131         }
 132       }
 133     }
 134 
 135     // Add rounding to the shift to handle the sign bit
 136     int l = log2_intptr(d-1)+1;
 137     if (needs_rounding) {
 138       // Divide-by-power-of-2 can be made into a shift, but you have to do
 139       // more math for the rounding.  You need to add 0 for positive
 140       // numbers, and "i-1" for negative numbers.  Example: i=4, so the
 141       // shift is by 2.  You need to add 3 to negative dividends and 0 to


 242     r2 = 2*r2;            // Update r2 = rem(2**p, |d|).
 243     if (r2 >= ad) {       // (Must be an unsigned
 244       q2 = q2 + 1;        // comparison here).
 245       r2 = r2 - ad;
 246     }
 247     delta = ad - r2;
 248   } while (q1 < delta || (q1 == delta && r1 == 0));
 249 
 250   M = q2 + 1;
 251   if (d < 0) M = -M;      // Magic number and
 252   s = p - 64;             // shift amount to return.
 253 
 254   return true;
 255 }
 256 
 257 //---------------------long_by_long_mulhi--------------------------------------
 258 // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication
 259 static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) {
 260   // If the architecture supports a 64x64 mulhi, there is
 261   // no need to synthesize it in ideal nodes.
 262   if (Matcher::has_match_rule(Op_MulHiL)) {
 263     Node* v = phase->longcon(magic_const);
 264     return new MulHiLNode(dividend, v);
 265   }
 266 
 267   // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed.
 268   // (http://www.hackersdelight.org/HDcode/mulhs.c)
 269   //
 270   // int mulhs(int u, int v) {
 271   //    unsigned u0, v0, w0;
 272   //    int u1, v1, w1, w2, t;
 273   //
 274   //    u0 = u & 0xFFFF;  u1 = u >> 16;
 275   //    v0 = v & 0xFFFF;  v1 = v >> 16;
 276   //    w0 = u0*v0;
 277   //    t  = u1*v0 + (w0 >> 16);
 278   //    w1 = t & 0xFFFF;
 279   //    w2 = t >> 16;
 280   //    w1 = u0*v1 + w1;
 281   //    return u1*v1 + w2 + (w1 >> 16);
 282   // }


 354   Node *q = NULL;
 355 
 356   if (d == 1) {
 357     // division by +/- 1
 358     if (!d_pos) {
 359       // Just negate the value
 360       q = new SubLNode(phase->longcon(0), dividend);
 361     }
 362   } else if ( is_power_of_2_long(d) ) {
 363 
 364     // division by +/- a power of 2
 365 
 366     // See if we can simply do a shift without rounding
 367     bool needs_rounding = true;
 368     const Type *dt = phase->type(dividend);
 369     const TypeLong *dtl = dt->isa_long();
 370 
 371     if (dtl && dtl->_lo > 0) {
 372       // we don't need to round a positive dividend
 373       needs_rounding = false;
 374     } else if( dividend->Opcode() == Op_AndL ) {
 375       // An AND mask of sufficient size clears the low bits and
 376       // I can avoid rounding.
 377       const TypeLong *andconl_t = phase->type( dividend->in(2) )->isa_long();
 378       if( andconl_t && andconl_t->is_con() ) {
 379         jlong andconl = andconl_t->get_con();
 380         if( andconl < 0 && is_power_of_2_long(-andconl) && (-andconl) >= d ) {
 381           if( (-andconl) == d ) // Remove AND if it clears bits which will be shifted
 382             dividend = dividend->in(1);
 383           needs_rounding = false;
 384         }
 385       }
 386     }
 387 
 388     // Add rounding to the shift to handle the sign bit
 389     int l = log2_long(d-1)+1;
 390     if (needs_rounding) {
 391       // Divide-by-power-of-2 can be made into a shift, but you have to do
 392       // more math for the rounding.  You need to add 0 for positive
 393       // numbers, and "i-1" for negative numbers.  Example: i=4, so the
 394       // shift is by 2.  You need to add 3 to negative dividends and 0 to


1265   // Make sure that the sign of the fmod is equal to the sign of the dividend
1266   jlong xr = jlong_cast(fmod(f1, f2));
1267   if ((x1 ^ xr) < 0) {
1268     xr ^= min_jlong;
1269   }
1270 
1271   return TypeD::make(jdouble_cast(xr));
1272 }
1273 
1274 //=============================================================================
1275 
1276 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) {
1277   init_req(0, c);
1278   init_req(1, dividend);
1279   init_req(2, divisor);
1280 }
1281 
1282 //------------------------------make------------------------------------------
1283 DivModINode* DivModINode::make(Node* div_or_mod) {
1284   Node* n = div_or_mod;
1285   assert(n->Opcode() == Op_DivI || n->Opcode() == Op_ModI,
1286          "only div or mod input pattern accepted");
1287 
1288   DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2));
1289   Node*        dproj  = new ProjNode(divmod, DivModNode::div_proj_num);
1290   Node*        mproj  = new ProjNode(divmod, DivModNode::mod_proj_num);
1291   return divmod;
1292 }
1293 
1294 //------------------------------make------------------------------------------
1295 DivModLNode* DivModLNode::make(Node* div_or_mod) {
1296   Node* n = div_or_mod;
1297   assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL,
1298          "only div or mod input pattern accepted");
1299 
1300   DivModLNode* divmod = new DivModLNode(n->in(0), n->in(1), n->in(2));
1301   Node*        dproj  = new ProjNode(divmod, DivModNode::div_proj_num);
1302   Node*        mproj  = new ProjNode(divmod, DivModNode::mod_proj_num);
1303   return divmod;
1304 }
1305 
1306 //------------------------------match------------------------------------------
1307 // return result(s) along with their RegMask info
1308 Node *DivModINode::match( const ProjNode *proj, const Matcher *match ) {
1309   uint ideal_reg = proj->ideal_reg();
1310   RegMask rm;
1311   if (proj->_con == div_proj_num) {
1312     rm = match->divI_proj_mask();
1313   } else {
1314     assert(proj->_con == mod_proj_num, "must be div or mod projection");
1315     rm = match->modI_proj_mask();
1316   }
1317   return new MachProjNode(this, proj->_con, rm, ideal_reg);
1318 }
1319 
1320 
1321 //------------------------------match------------------------------------------
1322 // return result(s) along with their RegMask info
1323 Node *DivModLNode::match( const ProjNode *proj, const Matcher *match ) {
1324   uint ideal_reg = proj->ideal_reg();
1325   RegMask rm;
1326   if (proj->_con == div_proj_num) {
1327     rm = match->divL_proj_mask();
1328   } else {
1329     assert(proj->_con == mod_proj_num, "must be div or mod projection");
1330     rm = match->modL_proj_mask();
1331   }
1332   return new MachProjNode(this, proj->_con, rm, ideal_reg);
1333 }


 101 
 102   // Result
 103   Node *q = NULL;
 104 
 105   if (d == 1) {
 106     // division by +/- 1
 107     if (!d_pos) {
 108       // Just negate the value
 109       q = new SubINode(phase->intcon(0), dividend);
 110     }
 111   } else if ( is_power_of_2(d) ) {
 112     // division by +/- a power of 2
 113 
 114     // See if we can simply do a shift without rounding
 115     bool needs_rounding = true;
 116     const Type *dt = phase->type(dividend);
 117     const TypeInt *dti = dt->isa_int();
 118     if (dti && dti->_lo >= 0) {
 119       // we don't need to round a positive dividend
 120       needs_rounding = false;
 121     } else if( dividend->Opcode() == Opcodes::Op_AndI ) {
 122       // An AND mask of sufficient size clears the low bits and
 123       // I can avoid rounding.
 124       const TypeInt *andconi_t = phase->type( dividend->in(2) )->isa_int();
 125       if( andconi_t && andconi_t->is_con() ) {
 126         jint andconi = andconi_t->get_con();
 127         if( andconi < 0 && is_power_of_2(-andconi) && (-andconi) >= d ) {
 128           if( (-andconi) == d ) // Remove AND if it clears bits which will be shifted
 129             dividend = dividend->in(1);
 130           needs_rounding = false;
 131         }
 132       }
 133     }
 134 
 135     // Add rounding to the shift to handle the sign bit
 136     int l = log2_intptr(d-1)+1;
 137     if (needs_rounding) {
 138       // Divide-by-power-of-2 can be made into a shift, but you have to do
 139       // more math for the rounding.  You need to add 0 for positive
 140       // numbers, and "i-1" for negative numbers.  Example: i=4, so the
 141       // shift is by 2.  You need to add 3 to negative dividends and 0 to


 242     r2 = 2*r2;            // Update r2 = rem(2**p, |d|).
 243     if (r2 >= ad) {       // (Must be an unsigned
 244       q2 = q2 + 1;        // comparison here).
 245       r2 = r2 - ad;
 246     }
 247     delta = ad - r2;
 248   } while (q1 < delta || (q1 == delta && r1 == 0));
 249 
 250   M = q2 + 1;
 251   if (d < 0) M = -M;      // Magic number and
 252   s = p - 64;             // shift amount to return.
 253 
 254   return true;
 255 }
 256 
 257 //---------------------long_by_long_mulhi--------------------------------------
 258 // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication
 259 static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) {
 260   // If the architecture supports a 64x64 mulhi, there is
 261   // no need to synthesize it in ideal nodes.
 262   if (Matcher::has_match_rule(Opcodes::Op_MulHiL)) {
 263     Node* v = phase->longcon(magic_const);
 264     return new MulHiLNode(dividend, v);
 265   }
 266 
 267   // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed.
 268   // (http://www.hackersdelight.org/HDcode/mulhs.c)
 269   //
 270   // int mulhs(int u, int v) {
 271   //    unsigned u0, v0, w0;
 272   //    int u1, v1, w1, w2, t;
 273   //
 274   //    u0 = u & 0xFFFF;  u1 = u >> 16;
 275   //    v0 = v & 0xFFFF;  v1 = v >> 16;
 276   //    w0 = u0*v0;
 277   //    t  = u1*v0 + (w0 >> 16);
 278   //    w1 = t & 0xFFFF;
 279   //    w2 = t >> 16;
 280   //    w1 = u0*v1 + w1;
 281   //    return u1*v1 + w2 + (w1 >> 16);
 282   // }


 354   Node *q = NULL;
 355 
 356   if (d == 1) {
 357     // division by +/- 1
 358     if (!d_pos) {
 359       // Just negate the value
 360       q = new SubLNode(phase->longcon(0), dividend);
 361     }
 362   } else if ( is_power_of_2_long(d) ) {
 363 
 364     // division by +/- a power of 2
 365 
 366     // See if we can simply do a shift without rounding
 367     bool needs_rounding = true;
 368     const Type *dt = phase->type(dividend);
 369     const TypeLong *dtl = dt->isa_long();
 370 
 371     if (dtl && dtl->_lo > 0) {
 372       // we don't need to round a positive dividend
 373       needs_rounding = false;
 374     } else if( dividend->Opcode() == Opcodes::Op_AndL ) {
 375       // An AND mask of sufficient size clears the low bits and
 376       // I can avoid rounding.
 377       const TypeLong *andconl_t = phase->type( dividend->in(2) )->isa_long();
 378       if( andconl_t && andconl_t->is_con() ) {
 379         jlong andconl = andconl_t->get_con();
 380         if( andconl < 0 && is_power_of_2_long(-andconl) && (-andconl) >= d ) {
 381           if( (-andconl) == d ) // Remove AND if it clears bits which will be shifted
 382             dividend = dividend->in(1);
 383           needs_rounding = false;
 384         }
 385       }
 386     }
 387 
 388     // Add rounding to the shift to handle the sign bit
 389     int l = log2_long(d-1)+1;
 390     if (needs_rounding) {
 391       // Divide-by-power-of-2 can be made into a shift, but you have to do
 392       // more math for the rounding.  You need to add 0 for positive
 393       // numbers, and "i-1" for negative numbers.  Example: i=4, so the
 394       // shift is by 2.  You need to add 3 to negative dividends and 0 to


1265   // Make sure that the sign of the fmod is equal to the sign of the dividend
1266   jlong xr = jlong_cast(fmod(f1, f2));
1267   if ((x1 ^ xr) < 0) {
1268     xr ^= min_jlong;
1269   }
1270 
1271   return TypeD::make(jdouble_cast(xr));
1272 }
1273 
1274 //=============================================================================
1275 
1276 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) {
1277   init_req(0, c);
1278   init_req(1, dividend);
1279   init_req(2, divisor);
1280 }
1281 
1282 //------------------------------make------------------------------------------
1283 DivModINode* DivModINode::make(Node* div_or_mod) {
1284   Node* n = div_or_mod;
1285   assert(n->Opcode() == Opcodes::Op_DivI || n->Opcode() == Opcodes::Op_ModI,
1286          "only div or mod input pattern accepted");
1287 
1288   DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2));
1289   Node*        dproj  = new ProjNode(divmod, DivModNode::div_proj_num);
1290   Node*        mproj  = new ProjNode(divmod, DivModNode::mod_proj_num);
1291   return divmod;
1292 }
1293 
1294 //------------------------------make------------------------------------------
1295 DivModLNode* DivModLNode::make(Node* div_or_mod) {
1296   Node* n = div_or_mod;
1297   assert(n->Opcode() == Opcodes::Op_DivL || n->Opcode() == Opcodes::Op_ModL,
1298          "only div or mod input pattern accepted");
1299 
1300   DivModLNode* divmod = new DivModLNode(n->in(0), n->in(1), n->in(2));
1301   Node*        dproj  = new ProjNode(divmod, DivModNode::div_proj_num);
1302   Node*        mproj  = new ProjNode(divmod, DivModNode::mod_proj_num);
1303   return divmod;
1304 }
1305 
1306 //------------------------------match------------------------------------------
1307 // return result(s) along with their RegMask info
1308 Node *DivModINode::match( const ProjNode *proj, const Matcher *match ) {
1309   Opcodes ideal_reg = proj->ideal_reg();
1310   RegMask rm;
1311   if (proj->_con == div_proj_num) {
1312     rm = match->divI_proj_mask();
1313   } else {
1314     assert(proj->_con == mod_proj_num, "must be div or mod projection");
1315     rm = match->modI_proj_mask();
1316   }
1317   return new MachProjNode(this, proj->_con, rm, ideal_reg);
1318 }
1319 
1320 
1321 //------------------------------match------------------------------------------
1322 // return result(s) along with their RegMask info
1323 Node *DivModLNode::match( const ProjNode *proj, const Matcher *match ) {
1324   Opcodes ideal_reg = proj->ideal_reg();
1325   RegMask rm;
1326   if (proj->_con == div_proj_num) {
1327     rm = match->divL_proj_mask();
1328   } else {
1329     assert(proj->_con == mod_proj_num, "must be div or mod projection");
1330     rm = match->modL_proj_mask();
1331   }
1332   return new MachProjNode(this, proj->_con, rm, ideal_reg);
1333 }
< prev index next >