Index: runtime/vm/intermediate_language.cc |
=================================================================== |
--- runtime/vm/intermediate_language.cc (revision 11146) |
+++ runtime/vm/intermediate_language.cc (working copy) |
@@ -1002,6 +1002,18 @@ |
} |
+bool BinarySmiOpComp::CanDeoptimize() const { |
+ switch (op_kind()) { |
+ case Token::kBIT_AND: |
+ case Token::kBIT_OR: |
+ case Token::kBIT_XOR: |
+ return false; |
+ default: |
+ return true; |
+ } |
+} |
+ |
+ |
RawAbstractType* BinaryMintOpComp::CompileType() const { |
ObjectStore* object_store = Isolate::Current()->object_store(); |
return object_store->mint_type(); |
@@ -1049,33 +1061,52 @@ |
} |
-// Shared code generation methods (EmitNativeCode, MakeLocationSummary, and |
-// PrepareEntry). Only assembly code that can be shared across all architectures |
-// can be used. Machine specific register allocation and code generation |
-// is located in intermediate_language_<arch>.cc |
+RawAbstractType* CheckSmiComp::CompileType() const { |
+ return AbstractType::null(); |
+} |
-// True iff. the arguments to a call will be properly pushed and can |
-// be popped after the call. |
-template <typename T> static bool VerifyCallComputation(T* comp) { |
- // Argument values should be consecutive temps. |
- // |
- // TODO(kmillikin): implement stack height tracking so we can also assert |
- // they are on top of the stack. |
- intptr_t previous = -1; |
- for (int i = 0; i < comp->ArgumentCount(); ++i) { |
- Value* val = comp->ArgumentAt(i); |
- if (!val->IsUse()) return false; |
- intptr_t current = val->AsUse()->definition()->temp_index(); |
- if (i != 0) { |
- if (current != (previous + 1)) return false; |
+// Optimizations that eliminate or simplify individual computations. |
+Definition* Computation::TryReplace(BindInstr* instr) const { |
+ return instr; |
+} |
+ |
+ |
+Definition* StrictCompareComp::TryReplace(BindInstr* instr) const { |
+ UseVal* left_use = left()->AsUse(); |
+ UseVal* right_use = right()->AsUse(); |
+ if ((right_use == NULL) || (left_use == NULL)) return instr; |
+ if (!right_use->BindsToConstant()) return instr; |
+ const Object& right_constant = right_use->BoundConstant(); |
+ Definition* left = left_use->definition(); |
+ // TODO(fschneider): Handle other cases: e === false and e !== true/false. |
+ // Handles e === true. |
+ if ((kind() == Token::kEQ_STRICT) && |
+ (right_constant.raw() == Bool::True()) && |
+ (left_use->ResultCid() == kBoolCid)) { |
+ // Remove the constant from the graph. |
+ BindInstr* right = right_use->definition()->AsBind(); |
+ if (right != NULL) { |
+ right->set_use_list(NULL); |
+ right->RemoveFromGraph(); |
} |
- previous = current; |
+ // Return left subexpression as the replacement for this instruction. |
+ return left; |
} |
- return true; |
+ return instr; |
} |
+Definition* CheckSmiComp::TryReplace(BindInstr* instr) const { |
+ return (value()->ResultCid() == kSmiCid) ? NULL : instr; |
+} |
+ |
+ |
+// Shared code generation methods (EmitNativeCode, MakeLocationSummary, and |
+// PrepareEntry). Only assembly code that can be shared across all architectures |
+// can be used. Machine specific register allocation and code generation |
+// is located in intermediate_language_<arch>.cc |
+ |
#define __ compiler->assembler()-> |
void GraphEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
@@ -1250,31 +1281,6 @@ |
} |
-Definition* StrictCompareComp::TryReplace(BindInstr* instr) { |
- UseVal* left_use = left()->AsUse(); |
- UseVal* right_use = right()->AsUse(); |
- if ((right_use == NULL) || (left_use == NULL)) return NULL; |
- if (!right_use->BindsToConstant()) return NULL; |
- const Object& right_constant = right_use->BoundConstant(); |
- Definition* left = left_use->definition(); |
- // TODO(fschneider): Handle other cases: e === false and e !== true/false. |
- // Handles e === true. |
- if ((kind() == Token::kEQ_STRICT) && |
- (right_constant.raw() == Bool::True()) && |
- (left_use->ResultCid() == kBoolCid)) { |
- // Remove the constant from the graph. |
- BindInstr* right = right_use->definition()->AsBind(); |
- if (right != NULL) { |
- right->set_use_list(NULL); |
- right->RemoveFromGraph(); |
- } |
- // Return left subexpression as the replacement for this instruction. |
- return left; |
- } |
- return NULL; |
-} |
- |
- |
LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
return LocationSummary::Make(2, |
Location::SameAsFirstInput(), |
@@ -1530,6 +1536,20 @@ |
} |
+Environment* Environment::Copy() const { |
+ Environment* copy = new Environment(values().length(), |
+ fixed_parameter_count()); |
+ GrowableArray<Value*>* values_copy = copy->values_ptr(); |
+ for (intptr_t i = 0; i < values().length(); ++i) { |
+ Value* val = values()[i]; |
+ values_copy->Add(val->IsUse() |
+ ? UseDefinition(values()[i]->AsUse()->definition()) |
+ : val); |
+ } |
+ return copy; |
+} |
+ |
+ |
#undef __ |
} // namespace dart |