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

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

Issue 13867006: Inline binary Float32x4 ops. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 (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/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 && ic_data.HasReceiverClassId(kSmiCid) 524 && ic_data.HasReceiverClassId(kSmiCid)
525 && ic_data.HasReceiverClassId(kMintCid); 525 && ic_data.HasReceiverClassId(kMintCid);
526 } 526 }
527 527
528 528
529 static bool HasOnlyTwoSmis(const ICData& ic_data) { 529 static bool HasOnlyTwoSmis(const ICData& ic_data) {
530 return (ic_data.NumberOfChecks() == 1) && 530 return (ic_data.NumberOfChecks() == 1) &&
531 ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid); 531 ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid);
532 } 532 }
533 533
534 static bool HasOnlyTwoFloat32x4s(const ICData& ic_data) {
535 return (ic_data.NumberOfChecks() == 1) &&
536 ICDataHasReceiverArgumentClassIds(ic_data, kFloat32x4Cid, kFloat32x4Cid);
537 }
538
534 539
535 // Returns false if the ICData contains anything other than the 4 combinations 540 // Returns false if the ICData contains anything other than the 4 combinations
536 // of Mint and Smi for the receiver and argument classes. 541 // of Mint and Smi for the receiver and argument classes.
537 static bool HasTwoMintOrSmi(const ICData& ic_data) { 542 static bool HasTwoMintOrSmi(const ICData& ic_data) {
538 GrowableArray<intptr_t> class_ids(2); 543 GrowableArray<intptr_t> class_ids(2);
539 class_ids.Add(kSmiCid); 544 class_ids.Add(kSmiCid);
540 class_ids.Add(kMintCid); 545 class_ids.Add(kMintCid);
541 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids); 546 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids);
542 } 547 }
543 548
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 ? kMintCid 963 ? kMintCid
959 : kSmiCid; 964 : kSmiCid;
960 } else if (HasTwoMintOrSmi(ic_data) && 965 } else if (HasTwoMintOrSmi(ic_data) &&
961 FlowGraphCompiler::SupportsUnboxedMints()) { 966 FlowGraphCompiler::SupportsUnboxedMints()) {
962 // Don't generate mint code if the IC data is marked because of an 967 // Don't generate mint code if the IC data is marked because of an
963 // overflow. 968 // overflow.
964 if (ic_data.deopt_reason() == kDeoptBinaryMintOp) return false; 969 if (ic_data.deopt_reason() == kDeoptBinaryMintOp) return false;
965 operands_type = kMintCid; 970 operands_type = kMintCid;
966 } else if (ShouldSpecializeForDouble(ic_data)) { 971 } else if (ShouldSpecializeForDouble(ic_data)) {
967 operands_type = kDoubleCid; 972 operands_type = kDoubleCid;
973 } else if (HasOnlyTwoFloat32x4s(ic_data)) {
974 operands_type = kFloat32x4Cid;
968 } else { 975 } else {
969 return false; 976 return false;
970 } 977 }
971 break; 978 break;
972 case Token::kMUL: 979 case Token::kMUL:
973 if (HasOnlyTwoSmis(ic_data)) { 980 if (HasOnlyTwoSmis(ic_data)) {
974 // Don't generate smi code if the IC data is marked because of an 981 // Don't generate smi code if the IC data is marked because of an
975 // overflow. 982 // overflow.
976 // TODO(fschneider): Add unboxed mint multiplication. 983 // TODO(fschneider): Add unboxed mint multiplication.
977 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false; 984 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false;
978 operands_type = kSmiCid; 985 operands_type = kSmiCid;
979 } else if (ShouldSpecializeForDouble(ic_data)) { 986 } else if (ShouldSpecializeForDouble(ic_data)) {
980 operands_type = kDoubleCid; 987 operands_type = kDoubleCid;
988 } else if (HasOnlyTwoFloat32x4s(ic_data)) {
989 operands_type = kFloat32x4Cid;
981 } else { 990 } else {
982 return false; 991 return false;
983 } 992 }
984 break; 993 break;
985 case Token::kDIV: 994 case Token::kDIV:
986 if (ShouldSpecializeForDouble(ic_data)) { 995 if (ShouldSpecializeForDouble(ic_data)) {
987 operands_type = kDoubleCid; 996 operands_type = kDoubleCid;
997 } else if (HasOnlyTwoFloat32x4s(ic_data)) {
998 operands_type = kFloat32x4Cid;
988 } else { 999 } else {
989 return false; 1000 return false;
990 } 1001 }
991 break; 1002 break;
992 case Token::kMOD: 1003 case Token::kMOD:
993 if (HasOnlyTwoSmis(ic_data)) { 1004 if (HasOnlyTwoSmis(ic_data)) {
994 operands_type = kSmiCid; 1005 operands_type = kSmiCid;
995 } else { 1006 } else {
996 return false; 1007 return false;
997 } 1008 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 ShiftMintOpInstr* shift_op = 1075 ShiftMintOpInstr* shift_op =
1065 new ShiftMintOpInstr(op_kind, new Value(left), new Value(right), 1076 new ShiftMintOpInstr(op_kind, new Value(left), new Value(right),
1066 call); 1077 call);
1067 ReplaceCall(call, shift_op); 1078 ReplaceCall(call, shift_op);
1068 } else { 1079 } else {
1069 BinaryMintOpInstr* bin_op = 1080 BinaryMintOpInstr* bin_op =
1070 new BinaryMintOpInstr(op_kind, new Value(left), new Value(right), 1081 new BinaryMintOpInstr(op_kind, new Value(left), new Value(right),
1071 call); 1082 call);
1072 ReplaceCall(call, bin_op); 1083 ReplaceCall(call, bin_op);
1073 } 1084 }
1085 } else if (operands_type == kFloat32x4Cid) {
1086 CheckClassInstr* check_class;
1087 // Type check left.
1088 ICData& lvalue_check = ICData::ZoneHandle();
1089 lvalue_check = call->ic_data()->AsUnaryClassChecksForArgNr(0);
1090 check_class = new CheckClassInstr(new Value(left), call->deopt_id(),
1091 lvalue_check);
1092 InsertBefore(call, check_class, call->env(), Definition::kEffect);
Vyacheslav Egorov (Google) 2013/04/15 13:49:21 AddCheckClass(left->definition(), ca
Cutch 2013/04/15 14:07:06 Done.
1093 // Type check right.
1094 ICData& rvalue_check = ICData::ZoneHandle();
1095 rvalue_check = call->ic_data()->AsUnaryClassChecksForArgNr(1);
1096 check_class = new CheckClassInstr(new Value(right), call->deopt_id(),
1097 rvalue_check);
1098 InsertBefore(call, check_class, call->env(), Definition::kEffect);
Vyacheslav Egorov (Google) 2013/04/15 13:49:21 AddCheckClass(right->definition(), c
Cutch 2013/04/15 14:07:06 Done.
1099 // Replace call.
1100 BinaryFloat32x4OpInstr* float32x4_bin_op =
1101 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right),
1102 call);
1103 ReplaceCall(call, float32x4_bin_op);
1074 } else if (op_kind == Token::kMOD) { 1104 } else if (op_kind == Token::kMOD) {
1075 // TODO(vegorov): implement fast path code for modulo. 1105 // TODO(vegorov): implement fast path code for modulo.
1076 ASSERT(operands_type == kSmiCid); 1106 ASSERT(operands_type == kSmiCid);
1077 if (!right->IsConstant()) return false; 1107 if (!right->IsConstant()) return false;
1078 const Object& obj = right->AsConstant()->value(); 1108 const Object& obj = right->AsConstant()->value();
1079 if (!obj.IsSmi()) return false; 1109 if (!obj.IsSmi()) return false;
1080 const intptr_t value = Smi::Cast(obj).Value(); 1110 const intptr_t value = Smi::Cast(obj).Value();
1081 if ((value <= 0) || !Utils::IsPowerOfTwo(value)) return false; 1111 if ((value <= 0) || !Utils::IsPowerOfTwo(value)) return false;
1082 1112
1083 // Insert smi check and attach a copy of the original environment 1113 // Insert smi check and attach a copy of the original environment
(...skipping 3308 matching lines...) Expand 10 before | Expand all | Expand 10 after
4392 const Object& right = instr->right()->definition()->constant_value(); 4422 const Object& right = instr->right()->definition()->constant_value();
4393 if (IsNonConstant(left) || IsNonConstant(right)) { 4423 if (IsNonConstant(left) || IsNonConstant(right)) {
4394 SetValue(instr, non_constant_); 4424 SetValue(instr, non_constant_);
4395 } else if (IsConstant(left) && IsConstant(right)) { 4425 } else if (IsConstant(left) && IsConstant(right)) {
4396 // TODO(kmillikin): Handle binary operation. 4426 // TODO(kmillikin): Handle binary operation.
4397 SetValue(instr, non_constant_); 4427 SetValue(instr, non_constant_);
4398 } 4428 }
4399 } 4429 }
4400 4430
4401 4431
4432 void ConstantPropagator::VisitBinaryFloat32x4Op(
4433 BinaryFloat32x4OpInstr* instr) {
4434 const Object& left = instr->left()->definition()->constant_value();
4435 const Object& right = instr->right()->definition()->constant_value();
4436 if (IsNonConstant(left) || IsNonConstant(right)) {
4437 SetValue(instr, non_constant_);
4438 } else if (IsConstant(left) && IsConstant(right)) {
4439 // TODO(kmillikin): Handle binary operation.
4440 SetValue(instr, non_constant_);
4441 }
4442 }
4443
4444
4402 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) { 4445 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) {
4403 const Object& value = instr->value()->definition()->constant_value(); 4446 const Object& value = instr->value()->definition()->constant_value();
4404 if (IsNonConstant(value)) { 4447 if (IsNonConstant(value)) {
4405 SetValue(instr, non_constant_); 4448 SetValue(instr, non_constant_);
4406 } else if (IsConstant(value)) { 4449 } else if (IsConstant(value)) {
4407 // TODO(kmillikin): Handle sqrt. 4450 // TODO(kmillikin): Handle sqrt.
4408 SetValue(instr, non_constant_); 4451 SetValue(instr, non_constant_);
4409 } 4452 }
4410 } 4453 }
4411 4454
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
5016 if (changed) { 5059 if (changed) {
5017 // We may have changed the block order and the dominator tree. 5060 // We may have changed the block order and the dominator tree.
5018 flow_graph->DiscoverBlocks(); 5061 flow_graph->DiscoverBlocks();
5019 GrowableArray<BitVector*> dominance_frontier; 5062 GrowableArray<BitVector*> dominance_frontier;
5020 flow_graph->ComputeDominators(&dominance_frontier); 5063 flow_graph->ComputeDominators(&dominance_frontier);
5021 } 5064 }
5022 } 5065 }
5023 5066
5024 5067
5025 } // namespace dart 5068 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698