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

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 345563007: Add Uint32 representation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 377
378 378
379 UnboxedConstantInstr::UnboxedConstantInstr(const Object& value) 379 UnboxedConstantInstr::UnboxedConstantInstr(const Object& value)
380 : ConstantInstr(value), constant_address_(0) { 380 : ConstantInstr(value), constant_address_(0) {
381 // Only doubles supported for now. 381 // Only doubles supported for now.
382 ASSERT(value.IsDouble()); 382 ASSERT(value.IsDouble());
383 constant_address_ = 383 constant_address_ =
384 FlowGraphBuilder::FindDoubleConstant(Double::Cast(value).value()); 384 FlowGraphBuilder::FindDoubleConstant(Double::Cast(value).value());
385 } 385 }
386 386
387
388 bool Value::BindsTo32BitMaskConstant() const {
389 if (!definition()->IsUnboxInteger() || !definition()->IsUnboxUint32()) {
390 return false;
391 }
392 // Two cases to consider: UnboxInteger and UnboxUint32.
393 if (definition()->IsUnboxInteger()) {
394 UnboxIntegerInstr* instr = definition()->AsUnboxInteger();
395 if (!instr->value()->BindsToConstant()) {
396 return false;
397 }
398 const Object& obj = instr->value()->BoundConstant();
399 if (!obj.IsMint()) {
400 return false;
401 }
402 Mint& mint = Mint::Handle();
403 mint ^= obj.raw();
404 return mint.value() == kMaxUint32;
405 } else if (definition()->IsUnboxUint32()) {
406 UnboxUint32Instr* instr = definition()->AsUnboxUint32();
407 if (!instr->value()->BindsToConstant()) {
408 return false;
409 }
410 const Object& obj = instr->value()->BoundConstant();
411 if (!obj.IsMint()) {
412 return false;
413 }
414 Mint& mint = Mint::Handle();
415 mint ^= obj.raw();
416 return mint.value() == kMaxUint32;
417 }
418 return false;
419 }
420
421
387 // Returns true if the value represents a constant. 422 // Returns true if the value represents a constant.
388 bool Value::BindsToConstant() const { 423 bool Value::BindsToConstant() const {
389 return definition()->IsConstant(); 424 return definition()->IsConstant();
390 } 425 }
391 426
392 427
393 // Returns true if the value represents constant null. 428 // Returns true if the value represents constant null.
394 bool Value::BindsToConstantNull() const { 429 bool Value::BindsToConstantNull() const {
395 ConstantInstr* constant = definition()->AsConstant(); 430 ConstantInstr* constant = definition()->AsConstant();
396 return (constant != NULL) && constant->value().IsNull(); 431 return (constant != NULL) && constant->value().IsNull();
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 1341
1307 bool BinarySmiOpInstr::RightIsPowerOfTwoConstant() const { 1342 bool BinarySmiOpInstr::RightIsPowerOfTwoConstant() const {
1308 if (!right()->definition()->IsConstant()) return false; 1343 if (!right()->definition()->IsConstant()) return false;
1309 const Object& constant = right()->definition()->AsConstant()->value(); 1344 const Object& constant = right()->definition()->AsConstant()->value();
1310 if (!constant.IsSmi()) return false; 1345 if (!constant.IsSmi()) return false;
1311 const intptr_t int_value = Smi::Cast(constant).Value(); 1346 const intptr_t int_value = Smi::Cast(constant).Value();
1312 return Utils::IsPowerOfTwo(Utils::Abs(int_value)); 1347 return Utils::IsPowerOfTwo(Utils::Abs(int_value));
1313 } 1348 }
1314 1349
1315 1350
1316 static bool ToIntegerConstant(Value* value, intptr_t* result) { 1351 static bool ToIntegerConstant(Value* value, int64_t* result) {
1317 if (!value->BindsToConstant()) { 1352 if (!value->BindsToConstant()) {
1318 if (value->definition()->IsUnboxDouble()) { 1353 if (value->definition()->IsUnboxDouble()) {
1319 return ToIntegerConstant(value->definition()->AsUnboxDouble()->value(), 1354 return ToIntegerConstant(value->definition()->AsUnboxDouble()->value(),
1320 result); 1355 result);
1321 } 1356 }
1322 return false; 1357 return false;
1323 } 1358 }
1324 1359
1325 const Object& constant = value->BoundConstant(); 1360 const Object& constant = value->BoundConstant();
1326 if (constant.IsDouble()) { 1361 if (constant.IsDouble()) {
1327 const Double& double_constant = Double::Cast(constant); 1362 const Double& double_constant = Double::Cast(constant);
1328 *result = static_cast<intptr_t>(double_constant.value()); 1363 *result = static_cast<int64_t>(double_constant.value());
1329 return (static_cast<double>(*result) == double_constant.value()); 1364 return (static_cast<double>(*result) == double_constant.value());
1330 } else if (constant.IsSmi()) { 1365 } else if (constant.IsSmi()) {
1331 *result = Smi::Cast(constant).Value(); 1366 *result = Smi::Cast(constant).Value();
1332 return true; 1367 return true;
1368 } else if (constant.IsMint()) {
1369 *result = Mint::Cast(constant).value();
1370 return true;
1333 } 1371 }
1334 1372
1335 return false; 1373 return false;
1336 } 1374 }
1337 1375
1338 1376
1339 static Definition* CanonicalizeCommutativeArithmetic(Token::Kind op, 1377 static Definition* CanonicalizeCommutativeArithmetic(
1340 intptr_t cid, 1378 Token::Kind op,
1341 Value* left, 1379 intptr_t cid,
1342 Value* right) { 1380 Value* left,
1381 Value* right,
1382 int64_t mask = static_cast<int64_t>(0xFFFFFFFFFFFFFFFF)) {
1343 ASSERT((cid == kSmiCid) || (cid == kDoubleCid) || (cid == kMintCid)); 1383 ASSERT((cid == kSmiCid) || (cid == kDoubleCid) || (cid == kMintCid));
1344 1384
1345 intptr_t left_value; 1385 int64_t left_value;
1346 if (!ToIntegerConstant(left, &left_value)) { 1386 if (!ToIntegerConstant(left, &left_value)) {
1347 return NULL; 1387 return NULL;
1348 } 1388 }
1349 1389
1390 // Apply truncation mask to left_value.
1391 left_value &= mask;
1392
1350 switch (op) { 1393 switch (op) {
1351 case Token::kMUL: 1394 case Token::kMUL:
1352 if (left_value == 1) { 1395 if (left_value == 1) {
1353 if ((cid == kDoubleCid) && 1396 if ((cid == kDoubleCid) &&
1354 (right->definition()->representation() != kUnboxedDouble)) { 1397 (right->definition()->representation() != kUnboxedDouble)) {
1355 // Can't yet apply the equivalence because representation selection 1398 // Can't yet apply the equivalence because representation selection
1356 // did not run yet. We need it to guarantee that right value is 1399 // did not run yet. We need it to guarantee that right value is
1357 // correctly coerced to double. The second canonicalization pass 1400 // correctly coerced to double. The second canonicalization pass
1358 // will apply this equivalence. 1401 // will apply this equivalence.
1359 return NULL; 1402 return NULL;
(...skipping 10 matching lines...) Expand all
1370 if ((left_value == 0) && (cid != kDoubleCid)) { 1413 if ((left_value == 0) && (cid != kDoubleCid)) {
1371 // Can't apply this equivalence to double operations because 1414 // Can't apply this equivalence to double operations because
1372 // 0.0 + (-0.0) is 0.0 not -0.0. 1415 // 0.0 + (-0.0) is 0.0 not -0.0.
1373 return right->definition(); 1416 return right->definition();
1374 } 1417 }
1375 break; 1418 break;
1376 case Token::kBIT_AND: 1419 case Token::kBIT_AND:
1377 ASSERT(cid != kDoubleCid); 1420 ASSERT(cid != kDoubleCid);
1378 if (left_value == 0) { 1421 if (left_value == 0) {
1379 return left->definition(); 1422 return left->definition();
1380 } else if (left_value == -1) { 1423 } else if (left_value == mask) {
1381 return right->definition(); 1424 return right->definition();
1382 } 1425 }
1383 break; 1426 break;
1384 case Token::kBIT_OR: 1427 case Token::kBIT_OR:
1385 ASSERT(cid != kDoubleCid); 1428 ASSERT(cid != kDoubleCid);
1386 if (left_value == 0) { 1429 if (left_value == 0) {
1387 return right->definition(); 1430 return right->definition();
1388 } else if (left_value == -1) { 1431 } else if (left_value == mask) {
1389 return left->definition(); 1432 return left->definition();
1390 } 1433 }
1391 break; 1434 break;
1392 case Token::kBIT_XOR: 1435 case Token::kBIT_XOR:
1393 ASSERT(cid != kDoubleCid); 1436 ASSERT(cid != kDoubleCid);
1394 if (left_value == 0) { 1437 if (left_value == 0) {
1395 return right->definition(); 1438 return right->definition();
1396 } 1439 }
1397 break; 1440 break;
1398 default: 1441 default:
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 right(), 1547 right(),
1505 left()); 1548 left());
1506 if (result != NULL) { 1549 if (result != NULL) {
1507 return result; 1550 return result;
1508 } 1551 }
1509 1552
1510 return this; 1553 return this;
1511 } 1554 }
1512 1555
1513 1556
1557 Definition* BinaryUint32OpInstr::Canonicalize(FlowGraph* flow_graph) {
1558 Definition* result = NULL;
1559
1560 const int64_t truncation_mask = static_cast<int64_t>(0xFFFFFFFF);
1561
1562 result = CanonicalizeCommutativeArithmetic(op_kind(),
1563 kMintCid,
1564 left(),
1565 right(),
1566 truncation_mask);
1567 if (result != NULL) {
1568 return result;
1569 }
1570
1571 result = CanonicalizeCommutativeArithmetic(op_kind(),
1572 kMintCid,
1573 right(),
1574 left(),
1575 truncation_mask);
1576 if (result != NULL) {
1577 return result;
1578 }
1579
1580 return this;
1581 }
1582
1583
1514 // Optimizations that eliminate or simplify individual instructions. 1584 // Optimizations that eliminate or simplify individual instructions.
1515 Instruction* Instruction::Canonicalize(FlowGraph* flow_graph) { 1585 Instruction* Instruction::Canonicalize(FlowGraph* flow_graph) {
1516 return this; 1586 return this;
1517 } 1587 }
1518 1588
1519 1589
1520 Definition* Definition::Canonicalize(FlowGraph* flow_graph) { 1590 Definition* Definition::Canonicalize(FlowGraph* flow_graph) {
1521 return this; 1591 return this;
1522 } 1592 }
1523 1593
(...skipping 2511 matching lines...) Expand 10 before | Expand all | Expand 10 after
4035 case Token::kTRUNCDIV: return 0; 4105 case Token::kTRUNCDIV: return 0;
4036 case Token::kMOD: return 1; 4106 case Token::kMOD: return 1;
4037 default: UNIMPLEMENTED(); return -1; 4107 default: UNIMPLEMENTED(); return -1;
4038 } 4108 }
4039 } 4109 }
4040 4110
4041 4111
4042 #undef __ 4112 #undef __
4043 4113
4044 } // namespace dart 4114 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698