Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: src/arm/lithium-arm.cc

Issue 9638018: [v8-dev] Optimise Math.floor(x/y) to use integer division for specific divisor.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 LOperand* dividend = UseFixed(instr->left(), r0); 1312 LOperand* dividend = UseFixed(instr->left(), r0);
1313 LOperand* divisor = UseFixed(instr->right(), r1); 1313 LOperand* divisor = UseFixed(instr->right(), r1);
1314 return AssignEnvironment(AssignPointerMap( 1314 return AssignEnvironment(AssignPointerMap(
1315 DefineFixed(new(zone()) LDivI(dividend, divisor), r0))); 1315 DefineFixed(new(zone()) LDivI(dividend, divisor), r0)));
1316 } else { 1316 } else {
1317 return DoArithmeticT(Token::DIV, instr); 1317 return DoArithmeticT(Token::DIV, instr);
1318 } 1318 }
1319 } 1319 }
1320 1320
1321 1321
1322 bool LChunkBuilder::HasMagicNumberForDivisor(int32_t divisor) {
1323 uint32_t divisor_abs = abs(divisor);
1324 // Dividing by 0, 1, and powers of 2 is easy.
1325 // Note that IsPowerOf2(0) returns true;
1326 ASSERT(IsPowerOf2(0) == true);
1327 if (IsPowerOf2(divisor_abs)) return true;
1328
1329 // We have magic numbers for a few specific divisors.
1330 // Details and proofs can be found in:
1331 // - Hacker's Delight, Henry S. Warren, Jr.
1332 // - The PowerPC Compiler Writer’s Guide
1333 // and probably many others.
1334 //
1335 // We handle
1336 // <divisor with magic numbers> * <power of 2>
1337 // but not
1338 // <divisor with magic numbers> * <other divisor with magic numbers>
1339 int32_t power_of_2_factor =
1340 CompilerIntrinsics::CountTrailingZeros(divisor_abs);
1341 DivMagicNumbers magic_numbers =
1342 DivMagicNumberFor(divisor_abs >> power_of_2_factor);
1343 if (magic_numbers.M != InvalidDivMagicNumber.M) return true;
1344
1345 return false;
1346 }
1347
1348
1349 HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) {
1350 // A change from an integer32 can be replaced by the integer32 value.
1351 if (dividend->IsChange() &&
1352 HChange::cast(dividend)->from().IsInteger32()) {
1353 return HChange::cast(dividend)->value();
1354 }
1355 // Change representation to integer32 if the constant can be represented as an
1356 // integer32 value.
1357 if (dividend->IsConstant() &&
1358 HConstant::cast(dividend)->HasInteger32Value()) {
fschneider 2012/04/17 07:41:10 This would only occur is in Math.floor(a/b) both a
Alexandre 2012/04/17 10:01:50 In short: yes we should remove it. Long: Division
1359 return HConstant::cast(dividend)->CopyToRepresentation(
1360 Representation::Integer32());
1361 }
1362 return NULL;
1363 }
1364
1365
1366 HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
1367 // Only optimize when we have magic numbers for the divisor.
1368 // The standard integer division routine is usually slower than transitionning
1369 // to VFP.
1370 if (divisor->IsConstant() &&
1371 HConstant::cast(divisor)->HasInteger32Value()) {
1372 HConstant* constant_val = HConstant::cast(divisor);
1373 int32_t int32_val = constant_val->Integer32Value();
1374 if (LChunkBuilder::HasMagicNumberForDivisor(int32_val)) {
1375 return constant_val->CopyToRepresentation(Representation::Integer32());
1376 }
1377 }
1378 return NULL;
1379 }
1380
1381
1382 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1383 HValue* right = instr->right();
1384 LOperand* dividend = UseRegister(instr->left());
1385 LOperand* divisor = UseRegisterOrConstant(right);
1386 LOperand* remainder = TempRegister();
1387 ASSERT(right->IsConstant() &&
1388 HConstant::cast(right)->HasInteger32Value() &&
1389 HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value()));
1390 return AssignEnvironment(DefineAsRegister(
1391 new LMathFloorOfDiv(dividend, divisor, remainder)));
1392 }
1393
1394
1322 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1395 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1323 if (instr->representation().IsInteger32()) { 1396 if (instr->representation().IsInteger32()) {
1324 ASSERT(instr->left()->representation().IsInteger32()); 1397 ASSERT(instr->left()->representation().IsInteger32());
1325 ASSERT(instr->right()->representation().IsInteger32()); 1398 ASSERT(instr->right()->representation().IsInteger32());
1326 1399
1327 LModI* mod; 1400 LModI* mod;
1328 if (instr->HasPowerOf2Divisor()) { 1401 if (instr->HasPowerOf2Divisor()) {
1329 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); 1402 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
1330 LOperand* value = UseRegisterAtStart(instr->left()); 1403 LOperand* value = UseRegisterAtStart(instr->left());
1331 mod = new(zone()) LModI(value, UseOrConstant(instr->right())); 1404 mod = new(zone()) LModI(value, UseOrConstant(instr->right()));
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
2315 2388
2316 2389
2317 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2390 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2318 LOperand* object = UseRegister(instr->object()); 2391 LOperand* object = UseRegister(instr->object());
2319 LOperand* index = UseRegister(instr->index()); 2392 LOperand* index = UseRegister(instr->index());
2320 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); 2393 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index));
2321 } 2394 }
2322 2395
2323 2396
2324 } } // namespace v8::internal 2397 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('j') | src/utils.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698