OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1042 RawAbstractType* SmiToDoubleComp::CompileType() const { | 1042 RawAbstractType* SmiToDoubleComp::CompileType() const { |
1043 return Type::DoubleInterface(); | 1043 return Type::DoubleInterface(); |
1044 } | 1044 } |
1045 | 1045 |
1046 | 1046 |
1047 RawAbstractType* CheckClassComp::CompileType() const { | 1047 RawAbstractType* CheckClassComp::CompileType() const { |
1048 return AbstractType::null(); | 1048 return AbstractType::null(); |
1049 } | 1049 } |
1050 | 1050 |
1051 | 1051 |
1052 RawAbstractType* CheckSmiComp::CompileType() const { | |
1053 return AbstractType::null(); | |
1054 } | |
1055 | |
1056 | |
1057 // Optimizations that eliminate or simplify individual computations. | |
1058 Definition* Computation::TryReplace(BindInstr* instr) const { | |
1059 return instr; | |
1060 } | |
1061 | |
1062 | |
1063 Definition* StrictCompareComp::TryReplace(BindInstr* instr) const { | |
1064 UseVal* left_use = left()->AsUse(); | |
1065 UseVal* right_use = right()->AsUse(); | |
1066 if ((right_use == NULL) || (left_use == NULL)) return instr; | |
1067 if (!right_use->BindsToConstant()) return instr; | |
1068 const Object& right_constant = right_use->BoundConstant(); | |
1069 Definition* left = left_use->definition(); | |
1070 // TODO(fschneider): Handle other cases: e === false and e !== true/false. | |
1071 // Handles e === true. | |
1072 if ((kind() == Token::kEQ_STRICT) && | |
1073 (right_constant.raw() == Bool::True()) && | |
1074 (left_use->ResultCid() == kBoolCid)) { | |
1075 // Remove the constant from the graph. | |
1076 BindInstr* right = right_use->definition()->AsBind(); | |
1077 if (right != NULL) { | |
1078 right->set_use_list(NULL); | |
1079 right->RemoveFromGraph(); | |
1080 } | |
1081 // Return left subexpression as the replacement for this instruction. | |
1082 return left; | |
1083 } | |
1084 return instr; | |
1085 } | |
1086 | |
1087 | |
1088 Definition* CheckSmiComp::TryReplace(BindInstr* instr) const { | |
1089 return (value()->ResultCid() == kSmiCid) ? NULL : instr; | |
srdjan
2012/08/22 15:56:51
This is too early to eliminate all checks as FlowG
Florian Schneider
2012/08/23 07:53:15
Already done. TryReplace is called by the pass Opt
| |
1090 } | |
1091 | |
1092 | |
1052 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and | 1093 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and |
1053 // PrepareEntry). Only assembly code that can be shared across all architectures | 1094 // PrepareEntry). Only assembly code that can be shared across all architectures |
1054 // can be used. Machine specific register allocation and code generation | 1095 // can be used. Machine specific register allocation and code generation |
1055 // is located in intermediate_language_<arch>.cc | 1096 // is located in intermediate_language_<arch>.cc |
1056 | 1097 |
1057 | |
1058 // True iff. the arguments to a call will be properly pushed and can | |
1059 // be popped after the call. | |
1060 template <typename T> static bool VerifyCallComputation(T* comp) { | |
1061 // Argument values should be consecutive temps. | |
1062 // | |
1063 // TODO(kmillikin): implement stack height tracking so we can also assert | |
1064 // they are on top of the stack. | |
1065 intptr_t previous = -1; | |
1066 for (int i = 0; i < comp->ArgumentCount(); ++i) { | |
1067 Value* val = comp->ArgumentAt(i); | |
1068 if (!val->IsUse()) return false; | |
1069 intptr_t current = val->AsUse()->definition()->temp_index(); | |
1070 if (i != 0) { | |
1071 if (current != (previous + 1)) return false; | |
1072 } | |
1073 previous = current; | |
1074 } | |
1075 return true; | |
1076 } | |
1077 | |
1078 | |
1079 #define __ compiler->assembler()-> | 1098 #define __ compiler->assembler()-> |
1080 | 1099 |
1081 void GraphEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { | 1100 void GraphEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
1082 // Nothing to do. | 1101 // Nothing to do. |
1083 } | 1102 } |
1084 | 1103 |
1085 | 1104 |
1086 void JoinEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { | 1105 void JoinEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
1087 __ Bind(compiler->GetBlockLabel(this)); | 1106 __ Bind(compiler->GetBlockLabel(this)); |
1088 if (HasParallelMove()) { | 1107 if (HasParallelMove()) { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1243 return summary; | 1262 return summary; |
1244 } | 1263 } |
1245 | 1264 |
1246 | 1265 |
1247 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1266 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1248 // Nothing to do. Context register were loaded by register allocator. | 1267 // Nothing to do. Context register were loaded by register allocator. |
1249 ASSERT(locs()->in(0).reg() == CTX); | 1268 ASSERT(locs()->in(0).reg() == CTX); |
1250 } | 1269 } |
1251 | 1270 |
1252 | 1271 |
1253 Definition* StrictCompareComp::TryReplace(BindInstr* instr) { | |
1254 UseVal* left_use = left()->AsUse(); | |
1255 UseVal* right_use = right()->AsUse(); | |
1256 if ((right_use == NULL) || (left_use == NULL)) return NULL; | |
1257 if (!right_use->BindsToConstant()) return NULL; | |
1258 const Object& right_constant = right_use->BoundConstant(); | |
1259 Definition* left = left_use->definition(); | |
1260 // TODO(fschneider): Handle other cases: e === false and e !== true/false. | |
1261 // Handles e === true. | |
1262 if ((kind() == Token::kEQ_STRICT) && | |
1263 (right_constant.raw() == Bool::True()) && | |
1264 (left_use->ResultCid() == kBoolCid)) { | |
1265 // Remove the constant from the graph. | |
1266 BindInstr* right = right_use->definition()->AsBind(); | |
1267 if (right != NULL) { | |
1268 right->set_use_list(NULL); | |
1269 right->RemoveFromGraph(); | |
1270 } | |
1271 // Return left subexpression as the replacement for this instruction. | |
1272 return left; | |
1273 } | |
1274 return NULL; | |
1275 } | |
1276 | |
1277 | |
1278 LocationSummary* StrictCompareComp::MakeLocationSummary() const { | 1272 LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
1279 return LocationSummary::Make(2, | 1273 return LocationSummary::Make(2, |
1280 Location::SameAsFirstInput(), | 1274 Location::SameAsFirstInput(), |
1281 LocationSummary::kNoCall); | 1275 LocationSummary::kNoCall); |
1282 } | 1276 } |
1283 | 1277 |
1284 | 1278 |
1285 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1279 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1286 Register left = locs()->in(0).reg(); | 1280 Register left = locs()->in(0).reg(); |
1287 Register right = locs()->in(1).reg(); | 1281 Register right = locs()->in(1).reg(); |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1523 intptr_t fixed_parameter_count) | 1517 intptr_t fixed_parameter_count) |
1524 : values_(definitions.length()), | 1518 : values_(definitions.length()), |
1525 locations_(NULL), | 1519 locations_(NULL), |
1526 fixed_parameter_count_(fixed_parameter_count) { | 1520 fixed_parameter_count_(fixed_parameter_count) { |
1527 for (intptr_t i = 0; i < definitions.length(); ++i) { | 1521 for (intptr_t i = 0; i < definitions.length(); ++i) { |
1528 values_.Add(UseDefinition(definitions[i])); | 1522 values_.Add(UseDefinition(definitions[i])); |
1529 } | 1523 } |
1530 } | 1524 } |
1531 | 1525 |
1532 | 1526 |
1527 Environment* Environment::Copy() const { | |
1528 Environment* copy = new Environment(values().length(), | |
1529 fixed_parameter_count()); | |
1530 GrowableArray<Value*>* values_copy = copy->values_ptr(); | |
1531 for (intptr_t i = 0; i < values().length(); ++i) { | |
1532 Value* val = values()[i]; | |
1533 values_copy->Add(val->IsUse() | |
1534 ? UseDefinition(values()[i]->AsUse()->definition()) | |
1535 : val); | |
1536 } | |
1537 return copy; | |
1538 } | |
1539 | |
1540 | |
1533 #undef __ | 1541 #undef __ |
1534 | 1542 |
1535 } // namespace dart | 1543 } // namespace dart |
OLD | NEW |