Index: runtime/vm/flow_graph_builder.cc |
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..198d6f68c5a2408a9d0c9a3cece17168309cdc57 |
--- /dev/null |
+++ b/runtime/vm/flow_graph_builder.cc |
@@ -0,0 +1,932 @@ |
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#include "vm/flow_graph_builder.h" |
+ |
+#include "vm/ast.h" |
+#include "vm/os.h" |
+#include "vm/parser.h" |
+ |
+namespace dart { |
+ |
+DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from graph builder."); |
+DECLARE_FLAG(bool, enable_type_checks); |
+ |
+class Computation : public ZoneAllocated { }; |
+ |
+ |
+class Value : public Computation { }; |
+ |
+ |
+class TempValue : public Value { |
+ public: |
+ explicit TempValue(intptr_t index) : index_(index) { } |
+ |
+ private: |
+ uintptr_t index_; |
srdjan
2012/02/16 14:14:34
->intptr_t (here and elsewhere).
We also add DISA
Kevin Millikin (Google)
2012/02/20 14:50:19
Thanks for reminding me.
It's strictly only neces
|
+}; |
+ |
+ |
+class InstanceValue: public Value { |
+ public: |
+ explicit InstanceValue(const Instance& instance) : instance_(instance) { } |
+ |
+ private: |
+ const Instance& instance_; |
+}; |
+ |
+ |
+class AssertAssignableComp : public Computation { |
+ public: |
+ explicit AssertAssignableComp(Value* value) : value_(value) { } |
+ |
+ private: |
+ Value* value_; |
+}; |
+ |
+ |
+class InstanceCallComp : public Computation { |
+ public: |
+ InstanceCallComp(Value* first, Value* second) : arguments_(2) { |
+ arguments_.Add(first); |
+ arguments_.Add(second); |
+ } |
+ |
+ private: |
+ GrowableArray<Value*> arguments_; |
+}; |
+ |
+ |
+class Instruction : public ZoneAllocated { |
+ public: |
+ virtual void set_successor(Instruction* instr) = 0; |
+}; |
+ |
+ |
+class DoInstr : public Instruction { |
+ public: |
+ explicit DoInstr(Computation* comp) : computation_(comp), successor_(NULL) { } |
+ |
+ virtual void set_successor(Instruction* instr) { successor_ = instr; } |
+ |
+ private: |
+ Computation* computation_; |
+ Instruction* successor_; |
+}; |
+ |
+ |
+class BindInstr : public Instruction { |
+ public: |
+ BindInstr(intptr_t index, Computation* comp) |
+ : index_(index), computation_(comp), successor_(NULL) { } |
+ |
+ virtual void set_successor(Instruction* instr) { successor_ = instr; } |
+ |
+ private: |
+ uintptr_t index_; |
+ Computation* computation_; |
+ Instruction* successor_; |
+}; |
+ |
+ |
+class ReturnInstr : public Instruction { |
+ public: |
+ explicit ReturnInstr(Value* value) : value_(value) { } |
+ |
+ virtual void set_successor(Instruction* instr) { UNREACHABLE(); } |
+ |
+ private: |
+ Value* value_; |
+}; |
+ |
+ |
+class BranchInstr : public Instruction { |
+ public: |
+ explicit BranchInstr(Value* value) |
+ : value_(value), first_successor_(NULL), second_successor_(NULL) { } |
+ |
+ virtual void set_successor(Instruction* instr) { UNREACHABLE(); } |
+ |
+ Instruction** first_successor_address() { return &first_successor_; } |
+ Instruction** second_successor_address() { return &second_successor_; } |
+ |
+ private: |
+ Value* value_; |
+ Instruction* first_successor_; |
+ Instruction* second_successor_; |
+}; |
+ |
+ |
+class EmptyInstr : public Instruction { |
+ public: |
+ EmptyInstr() : successor_(NULL) { } |
+ |
+ virtual void set_successor(Instruction* instr) { successor_ = instr; } |
+ |
+ private: |
+ Instruction* successor_; |
+}; |
+ |
+ |
+class JoinInstr : public Instruction { |
+ public: |
+ JoinInstr() : successor_(NULL) { } |
+ |
+ virtual void set_successor(Instruction* instr) { successor_ = instr; } |
+ |
+ private: |
+ Instruction* successor_; |
+}; |
+ |
+ |
+#define DEFINE_VISIT(type, name) virtual void Visit##type(type* node); |
+ |
+class TestBuilder; |
+ |
+class EffectBuilder : public AstNodeVisitor { |
+ public: |
+ EffectBuilder(const FlowGraphBuilder& owner, uintptr_t temp_index) |
+ : owner_(owner), |
+ temp_index_(temp_index), |
+ head_(NULL), |
+ tail_(NULL), |
+ bailing_out_(false) { } |
+ |
+ NODE_LIST(DEFINE_VISIT) |
+ |
+ Instruction* head() const { return head_; } |
+ Instruction* tail() const { return tail_; } |
+ uintptr_t temp_index() const { return temp_index_; } |
+ const FlowGraphBuilder& owner() const { return owner_; } |
+ |
+ bool is_empty() const { return head_ == NULL; } |
+ bool is_open() const { return is_empty() || tail_ != NULL; } |
+ |
+ void Bailout(const char* reason) { |
+ if (FLAG_trace_bailout) { |
+ OS::Print("Flow Graph Bailout: %s\n", reason); |
+ } |
+ bailing_out_ = true; |
+ } |
+ |
+ void Append(const EffectBuilder& other); |
+ void Append(Instruction* instruction); |
+ |
+ void Join(const TestBuilder& for_test, |
+ const EffectBuilder& for_true, |
+ const EffectBuilder& for_false); |
+ |
+ protected: |
+ bool bailing_out() const { return bailing_out_; } |
+ |
+ // Implement the core part of the translation of expression node types. |
+ AssertAssignableComp* TranslateAssignableNode(AssignableNode* node); |
+ InstanceCallComp* TranslateBinaryOpNode(BinaryOpNode* node); |
+ |
+ void Close() { tail_ = NULL; } |
+ uintptr_t AllocateTempIndex() { return temp_index_++; } |
+ |
+ private: |
+ // Input parameters. |
+ const FlowGraphBuilder& owner_; |
+ |
+ // In/out parameters. |
+ uintptr_t temp_index_; |
+ |
+ // Output parameters. |
+ Instruction* head_; |
+ Instruction* tail_; |
+ |
+ // State. |
+ bool bailing_out_; |
+}; |
+ |
+ |
+class ValueBuilder : public EffectBuilder { |
+ public: |
+ explicit ValueBuilder(const FlowGraphBuilder& owner, uintptr_t temp_index) |
+ : EffectBuilder(owner, temp_index), value_(NULL) { } |
+ |
+ NODE_LIST(DEFINE_VISIT) |
+ |
+ Value* value() const { return value_; } |
+ |
+ private: |
+ void ReturnTempValue() { value_ = new TempValue(AllocateTempIndex()); } |
+ |
+ // Output parameters. |
+ Value* value_; |
+}; |
+ |
+ |
+class TestBuilder : public EffectBuilder { |
+ public: |
+ explicit TestBuilder(const FlowGraphBuilder& owner, uintptr_t temp_index) |
+ : EffectBuilder(owner, temp_index), if_true_(NULL), if_false_(NULL) { } |
+ |
+ NODE_LIST(DEFINE_VISIT) |
+ |
+ bool can_be_true() const { return if_true_ != NULL; } |
+ bool can_be_false() const { return if_true_ != NULL; } |
srdjan
2012/02/16 14:14:34
In almost all of code 'can_be_true' and 'can_be_fa
Kevin Millikin (Google)
2012/02/20 14:50:19
There is some value in having them for things like
srdjan
2012/02/21 14:00:21
Since there will be no inlining at AST level this
|
+ |
+ Instruction** if_true() const { return if_true_; } |
+ Instruction** if_false() const { return if_false_; } |
+ |
+ private: |
+ void Branch(Value* value); |
+ |
+ // Output parameters. |
+ Instruction** if_true_; |
+ Instruction** if_false_; |
+}; |
+ |
+#undef DEFINE_VISIT |
+ |
+ |
+void EffectBuilder::Append(const EffectBuilder& other) { |
srdjan
2012/02/16 14:14:34
I'd rather use different names than function name
Kevin Millikin (Google)
2012/02/20 14:50:19
Done. Append works on graph fragments, AddInstruc
srdjan
2012/02/21 14:00:21
I assume that was all done in the other CL, will c
|
+ if (is_empty()) { |
+ head_ = other.head(); |
+ tail_ = other.tail(); |
+ } else if (is_open()) { |
+ tail()->set_successor(other.head()); |
+ tail_ = other.tail(); |
+ } |
srdjan
2012/02/16 14:14:34
Should an UNREACHABLE be added in an else clause
Kevin Millikin (Google)
2012/02/20 14:50:19
That's a good question. It's sometimes convenient
|
+} |
+ |
+ |
+void EffectBuilder::Append(Instruction* instruction) { |
srdjan
2012/02/16 14:14:34
ASSERT(instruction->successor() == NULL) ?
Kevin Millikin (Google)
2012/02/20 14:50:19
Asserted in set_successor functions, which makes t
|
+ if (is_empty()) { |
+ head_ = tail_ = instruction; |
+ } else if (is_open()) { |
+ tail()->set_successor(instruction); |
+ tail_ = instruction; |
+ } |
+} |
+ |
+ |
+void EffectBuilder::Join(const TestBuilder& for_test, |
+ const EffectBuilder& for_true, |
+ const EffectBuilder& for_false) { |
+ Instruction* last_true = NULL; |
+ Instruction* last_false = NULL; |
+ |
+ if (for_test.can_be_true()) { |
+ if (for_true.is_empty()) { |
+ last_true = new EmptyInstr; |
srdjan
2012/02/16 14:14:34
We are typically adding parenthesis to constructor
Kevin Millikin (Google)
2012/02/20 14:50:19
Done.
|
+ *for_test.if_true() = last_true; |
+ } else { |
+ *for_test.if_true() = for_true.head(); |
+ last_true = for_true.tail(); |
+ } |
+ } |
+ |
+ if (for_test.can_be_false()) { |
+ if (for_false.is_empty()) { |
+ *for_test.if_false() = last_false = new EmptyInstr; |
+ } else { |
+ *for_test.if_false() = for_false.head(); |
+ last_false = for_false.tail(); |
+ } |
+ } |
+ |
+ if (last_true == NULL) { |
+ tail_ = last_false; // May be NULL. |
+ } else if (last_false == NULL) { |
+ tail_ = last_true; |
+ } else { |
+ tail_ = new JoinInstr; |
+ last_true->set_successor(tail_); |
+ last_false->set_successor(tail_); |
+ } |
+} |
+ |
+ |
+void TestBuilder::Branch(Value* value) { |
+ BranchInstr* branch = new BranchInstr(value); |
+ Append(branch); |
+ Close(); |
+ if_true_ = branch->first_successor_address(); |
+ if_false_ = branch->second_successor_address(); |
+} |
+ |
+ |
+#define CHECK_ALIVE(bailout) \ |
+ do { \ |
+ if (bailing_out() || tail() == NULL) { \ |
+ bailout; \ |
+ } \ |
+ } while (false) |
+ |
+ |
+// <Statement> ::= Return { value: <Expression> |
+// inlined_finally_list: <InlinedFinally>* } |
+void EffectBuilder::VisitReturnNode(ReturnNode* node) { |
+ ValueBuilder for_value(owner(), temp_index()); |
+ node->value()->Visit(&for_value); |
+ Append(for_value); |
+ CHECK_ALIVE(return); |
+ |
+ for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
+ EffectBuilder for_effect(owner(), for_value.temp_index()); |
+ node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
+ Append(for_effect); |
+ CHECK_ALIVE(return); |
+ } |
+ |
+ Value* return_value = for_value.value(); |
+ if (FLAG_enable_type_checks) { |
+ const RawFunction::Kind kind = owner().parsed_function().function().kind(); |
+ // Implicit getters do not need a type check at return. |
+ if (kind != RawFunction::kImplicitGetter && |
+ kind != RawFunction::kConstImplicitGetter) { |
+ AssertAssignableComp* assert = new AssertAssignableComp(return_value); |
+ Append(new BindInstr(temp_index(), assert)); |
+ return_value = new TempValue(temp_index()); |
+ } |
+ } |
+ |
+ Append(new ReturnInstr(return_value)); |
+ Close(); |
+} |
+ |
+void ValueBuilder::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); } |
+void TestBuilder::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); } |
+ |
+ |
+// <Expression> ::= Literal { literal: Instance } |
+void EffectBuilder::VisitLiteralNode(LiteralNode* node) { |
+ return; |
+} |
+ |
+void ValueBuilder::VisitLiteralNode(LiteralNode* node) { |
+ value_ = new InstanceValue(node->literal()); |
+} |
+ |
+void TestBuilder::VisitLiteralNode(LiteralNode* node) { |
+ Branch(new InstanceValue(node->literal())); |
+} |
+ |
+ |
+// Type nodes only occur as the right-hand side of instanceof comparisons, |
+// and they are handled specially in that context. |
+void EffectBuilder::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
+void ValueBuilder::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
+void TestBuilder::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
+ |
+ |
+// <Expression> :: Assignable { expr: <Expression> |
+// type: AbstractType |
+// dst_name: String } |
+AssertAssignableComp* EffectBuilder::TranslateAssignableNode( |
+ AssignableNode* node) { |
+ ValueBuilder for_value(owner(), temp_index()); |
+ node->expr()->Visit(&for_value); |
+ Append(for_value); |
+ CHECK_ALIVE(return NULL); |
+ |
+ return new AssertAssignableComp(for_value.value()); |
+} |
+ |
+ |
+void EffectBuilder::VisitAssignableNode(AssignableNode* node) { |
+ AssertAssignableComp* assert = TranslateAssignableNode(node); |
+ Append(new DoInstr(assert)); |
+} |
+ |
+void ValueBuilder::VisitAssignableNode(AssignableNode* node) { |
+ AssertAssignableComp* assert = TranslateAssignableNode(node); |
+ Append(new BindInstr(temp_index(), assert)); |
+ ReturnTempValue(); |
+} |
+ |
+ |
+void TestBuilder::VisitAssignableNode(AssignableNode* node) { |
+ AssertAssignableComp* assert = TranslateAssignableNode(node); |
+ Append(new BindInstr(temp_index(), assert)); |
+ Branch(new TempValue(temp_index())); |
+} |
+ |
+ |
+// <Expression> :: BinaryOp { kind: Token::Kind |
+// left: <Expression> |
+// right: <Expression> } |
+InstanceCallComp* EffectBuilder::TranslateBinaryOpNode(BinaryOpNode* node) { |
+ if (node->kind() == Token::kAND || node->kind() == Token::kOR) { |
+ Bailout("EffectBuilder::VisitBinaryOpNode"); |
+ return NULL; |
+ } |
+ ValueBuilder for_left_value(owner(), temp_index()); |
+ node->left()->Visit(&for_left_value); |
+ ValueBuilder for_right_value(owner(), for_left_value.temp_index()); |
+ node->right()->Visit(&for_right_value); |
+ return new InstanceCallComp(for_left_value.value(), for_right_value.value()); |
+} |
+ |
+ |
+void EffectBuilder::VisitBinaryOpNode(BinaryOpNode* node) { |
+ InstanceCallComp* call = TranslateBinaryOpNode(node); |
+ CHECK_ALIVE(return); |
+ Append(new DoInstr(call)); |
+} |
+ |
+void ValueBuilder::VisitBinaryOpNode(BinaryOpNode* node) { |
+ InstanceCallComp* call = TranslateBinaryOpNode(node); |
+ CHECK_ALIVE(return); |
srdjan
2012/02/16 14:14:34
There seems to be some code duplication between Ef
Kevin Millikin (Google)
2012/02/20 14:50:19
Yeah. I created some helpers.
|
+ Append(new BindInstr(temp_index(), call)); |
+ ReturnTempValue(); |
+} |
+ |
+void TestBuilder::VisitBinaryOpNode(BinaryOpNode* node) { |
+ InstanceCallComp* call = TranslateBinaryOpNode(node); |
+ CHECK_ALIVE(return); |
+ Append(new BindInstr(temp_index(), call)); |
+ Branch(new TempValue(temp_index())); |
+} |
+ |
+ |
+void EffectBuilder::VisitStringConcatNode(StringConcatNode* node) { |
+ Bailout("EffectBuilder::VisitStringConcatNode"); |
+} |
+void ValueBuilder::VisitStringConcatNode(StringConcatNode* node) { |
+ Bailout("ValueBuilder::VisitStringConcatNode"); |
+} |
+void TestBuilder::VisitStringConcatNode(StringConcatNode* node) { |
+ Bailout("TestBuilder::VisitStringConcatNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitComparisonNode(ComparisonNode* node) { |
+ Bailout("EffectBuilder::VisitComparisonNode"); |
+} |
+void ValueBuilder::VisitComparisonNode(ComparisonNode* node) { |
+ Bailout("ValueBuilder::VisitComparisonNode"); |
+} |
+void TestBuilder::VisitComparisonNode(ComparisonNode* node) { |
+ Bailout("TestBuilder::VisitComparisonNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitUnaryOpNode(UnaryOpNode* node) { |
+ Bailout("EffectBuilder::VisitUnaryOpNode"); |
+} |
+void ValueBuilder::VisitUnaryOpNode(UnaryOpNode* node) { |
+ Bailout("ValueBuilder::VisitUnaryOpNode"); |
+} |
+void TestBuilder::VisitUnaryOpNode(UnaryOpNode* node) { |
+ Bailout("TestBuilder::VisitUnaryOpNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
+ Bailout("EffectBuilder::VisitIncrOpLocalNode"); |
+} |
+void ValueBuilder::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
+ Bailout("ValueBuilder::VisitIncrOpLocalNode"); |
+} |
+void TestBuilder::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
+ Bailout("TestBuilder::VisitIncrOpLocalNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitIncrOpInstanceFieldNode( |
+ IncrOpInstanceFieldNode* node) { |
+ Bailout("EffectBuilder::VisitIncrOpInstanceFieldNode"); |
+} |
+void ValueBuilder::VisitIncrOpInstanceFieldNode(IncrOpInstanceFieldNode* node) { |
+ Bailout("ValueBuilder::VisitIncrOpInstanceFieldNode"); |
+} |
+void TestBuilder::VisitIncrOpInstanceFieldNode(IncrOpInstanceFieldNode* node) { |
+ Bailout("TestBuilder::VisitIncrOpInstanceFieldNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitIncrOpStaticFieldNode(IncrOpStaticFieldNode* node) { |
+ Bailout("EffectBuilder::VisitIncrOpStaticFieldNode"); |
+} |
+void ValueBuilder::VisitIncrOpStaticFieldNode(IncrOpStaticFieldNode* node) { |
+ Bailout("ValueBuilder::VisitIncrOpStaticFieldNode"); |
+} |
+void TestBuilder::VisitIncrOpStaticFieldNode(IncrOpStaticFieldNode* node) { |
+ Bailout("TestBuilder::VisitIncrOpStaticFieldNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { |
+ Bailout("EffectBuilder::VisitIncrOpIndexedNode"); |
+} |
+void ValueBuilder::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { |
+ Bailout("ValueBuilder::VisitIncrOpIndexedNode"); |
+} |
+void TestBuilder::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { |
+ Bailout("TestBuilder::VisitIncrOpIndexedNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitConditionalExprNode(ConditionalExprNode* node) { |
+ Bailout("EffectBuilder::VisitConditionalExprNode"); |
+} |
+void ValueBuilder::VisitConditionalExprNode(ConditionalExprNode* node) { |
+ Bailout("ValueBuilder::VisitConditionalExprNode"); |
+} |
+void TestBuilder::VisitConditionalExprNode(ConditionalExprNode* node) { |
+ Bailout("TestBuilder::VisitConditionalExprNode"); |
+} |
+ |
+ |
+// <Statement> ::= If { condition: <Expression> |
+// true_branch: <Sequence> |
+// false_branch: <Sequence> } |
+void EffectBuilder::VisitIfNode(IfNode* node) { |
+ TestBuilder for_test(owner(), temp_index()); |
+ node->condition()->Visit(&for_test); |
+ Append(for_test); |
+ |
+ EffectBuilder for_true(owner(), temp_index()); |
+ EffectBuilder for_false(owner(), temp_index()); |
+ |
+ if (for_test.can_be_true()) node->true_branch()->Visit(&for_true); |
+ if (for_test.can_be_false()) node->false_branch()->Visit(&for_false); |
srdjan
2012/02/16 14:14:34
node->false_branch() can be NULL.
Kevin Millikin (Google)
2012/02/20 14:50:19
Thanks.
|
+ Join(for_test, for_true, for_false); |
+} |
+ |
+void ValueBuilder::VisitIfNode(IfNode* node) { UNREACHABLE(); } |
+void TestBuilder::VisitIfNode(IfNode* node) { UNREACHABLE(); } |
+ |
+ |
+void EffectBuilder::VisitSwitchNode(SwitchNode* node) { |
+ Bailout("EffectBuilder::VisitSwitchNode"); |
+} |
+void ValueBuilder::VisitSwitchNode(SwitchNode* node) { |
+ Bailout("ValueBuilder::VisitSwitchNode"); |
+} |
+void TestBuilder::VisitSwitchNode(SwitchNode* node) { |
+ Bailout("TestBuilder::VisitSwitchNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitCaseNode(CaseNode* node) { |
+ Bailout("EffectBuilder::VisitCaseNode"); |
+} |
+void ValueBuilder::VisitCaseNode(CaseNode* node) { |
+ Bailout("ValueBuilder::VisitCaseNode"); |
+} |
+void TestBuilder::VisitCaseNode(CaseNode* node) { |
+ Bailout("TestBuilder::VisitCaseNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitWhileNode(WhileNode* node) { |
+ Bailout("EffectBuilder::VisitWhileNode"); |
+} |
+void ValueBuilder::VisitWhileNode(WhileNode* node) { |
+ Bailout("ValueBuilder::VisitWhileNode"); |
+} |
+void TestBuilder::VisitWhileNode(WhileNode* node) { |
+ Bailout("TestBuilder::VisitWhileNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitDoWhileNode(DoWhileNode* node) { |
+ Bailout("EffectBuilder::VisitDoWhileNode"); |
+} |
+void ValueBuilder::VisitDoWhileNode(DoWhileNode* node) { |
+ Bailout("ValueBuilder::VisitDoWhileNode"); |
+} |
+void TestBuilder::VisitDoWhileNode(DoWhileNode* node) { |
+ Bailout("TestBuilder::VisitDoWhileNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitForNode(ForNode* node) { |
+ Bailout("EffectBuilder::VisitForNode"); |
+} |
+void ValueBuilder::VisitForNode(ForNode* node) { |
+ Bailout("ValueBuilder::VisitForNode"); |
+} |
+void TestBuilder::VisitForNode(ForNode* node) { |
+ Bailout("TestBuilder::VisitForNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitJumpNode(JumpNode* node) { |
+ Bailout("EffectBuilder::VisitJumpNode"); |
+} |
+void ValueBuilder::VisitJumpNode(JumpNode* node) { |
+ Bailout("ValueBuilder::VisitJumpNode"); |
+} |
+void TestBuilder::VisitJumpNode(JumpNode* node) { |
+ Bailout("TestBuilder::VisitJumpNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitArgumentListNode(ArgumentListNode* node) { |
+ Bailout("EffectBuilder::VisitArgumentListNode"); |
+} |
+void ValueBuilder::VisitArgumentListNode(ArgumentListNode* node) { |
+ Bailout("ValueBuilder::VisitArgumentListNode"); |
+} |
+void TestBuilder::VisitArgumentListNode(ArgumentListNode* node) { |
+ Bailout("TestBuilder::VisitArgumentListNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitArrayNode(ArrayNode* node) { |
+ Bailout("EffectBuilder::VisitArrayNode"); |
+} |
+void ValueBuilder::VisitArrayNode(ArrayNode* node) { |
+ Bailout("ValueBuilder::VisitArrayNode"); |
+} |
+void TestBuilder::VisitArrayNode(ArrayNode* node) { |
+ Bailout("TestBuilder::VisitArrayNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitClosureNode(ClosureNode* node) { |
+ Bailout("EffectBuilder::VisitClosureNode"); |
+} |
+void ValueBuilder::VisitClosureNode(ClosureNode* node) { |
+ Bailout("ValueBuilder::VisitClosureNode"); |
+} |
+void TestBuilder::VisitClosureNode(ClosureNode* node) { |
+ Bailout("TestBuilder::VisitClosureNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitInstanceCallNode(InstanceCallNode* node) { |
+ Bailout("EffectBuilder::VisitInstanceCallNode"); |
+} |
+void ValueBuilder::VisitInstanceCallNode(InstanceCallNode* node) { |
+ Bailout("ValueBuilder::VisitInstanceCallNode"); |
+} |
+void TestBuilder::VisitInstanceCallNode(InstanceCallNode* node) { |
+ Bailout("TestBuilder::VisitInstanceCallNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitStaticCallNode(StaticCallNode* node) { |
+ Bailout("EffectBuilder::VisitStaticCallNode"); |
+} |
+void ValueBuilder::VisitStaticCallNode(StaticCallNode* node) { |
+ Bailout("ValueBuilder::VisitStaticCallNode"); |
+} |
+void TestBuilder::VisitStaticCallNode(StaticCallNode* node) { |
+ Bailout("TestBuilder::VisitStaticCallNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitClosureCallNode(ClosureCallNode* node) { |
+ Bailout("EffectBuilder::VisitClosureCallNode"); |
+} |
+void ValueBuilder::VisitClosureCallNode(ClosureCallNode* node) { |
+ Bailout("ValueBuilder::VisitClosureCallNode"); |
+} |
+void TestBuilder::VisitClosureCallNode(ClosureCallNode* node) { |
+ Bailout("TestBuilder::VisitClosureCallNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitCloneContextNode(CloneContextNode* node) { |
+ Bailout("EffectBuilder::VisitCloneContextNode"); |
+} |
+void ValueBuilder::VisitCloneContextNode(CloneContextNode* node) { |
+ Bailout("ValueBuilder::VisitCloneContextNode"); |
+} |
+void TestBuilder::VisitCloneContextNode(CloneContextNode* node) { |
+ Bailout("TestBuilder::VisitCloneContextNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitConstructorCallNode(ConstructorCallNode* node) { |
+ Bailout("EffectBuilder::VisitConstructorCallNode"); |
+} |
+void ValueBuilder::VisitConstructorCallNode(ConstructorCallNode* node) { |
+ Bailout("ValueBuilder::VisitConstructorCallNode"); |
+} |
+void TestBuilder::VisitConstructorCallNode(ConstructorCallNode* node) { |
+ Bailout("TestBuilder::VisitConstructorCallNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitInstanceGetterNode(InstanceGetterNode* node) { |
+ Bailout("EffectBuilder::VisitInstanceGetterNode"); |
+} |
+void ValueBuilder::VisitInstanceGetterNode(InstanceGetterNode* node) { |
+ Bailout("ValueBuilder::VisitInstanceGetterNode"); |
+} |
+void TestBuilder::VisitInstanceGetterNode(InstanceGetterNode* node) { |
+ Bailout("TestBuilder::VisitInstanceGetterNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitInstanceSetterNode(InstanceSetterNode* node) { |
+ Bailout("EffectBuilder::VisitInstanceSetterNode"); |
+} |
+void ValueBuilder::VisitInstanceSetterNode(InstanceSetterNode* node) { |
+ Bailout("ValueBuilder::VisitInstanceSetterNode"); |
+} |
+void TestBuilder::VisitInstanceSetterNode(InstanceSetterNode* node) { |
+ Bailout("TestBuilder::VisitInstanceSetterNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitStaticGetterNode(StaticGetterNode* node) { |
+ Bailout("EffectBuilder::VisitStaticGetterNode"); |
+} |
+void ValueBuilder::VisitStaticGetterNode(StaticGetterNode* node) { |
+ Bailout("ValueBuilder::VisitStaticGetterNode"); |
+} |
+void TestBuilder::VisitStaticGetterNode(StaticGetterNode* node) { |
+ Bailout("TestBuilder::VisitStaticGetterNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitStaticSetterNode(StaticSetterNode* node) { |
+ Bailout("EffectBuilder::VisitStaticSetterNode"); |
+} |
+void ValueBuilder::VisitStaticSetterNode(StaticSetterNode* node) { |
+ Bailout("ValueBuilder::VisitStaticSetterNode"); |
+} |
+void TestBuilder::VisitStaticSetterNode(StaticSetterNode* node) { |
+ Bailout("TestBuilder::VisitStaticSetterNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitNativeBodyNode(NativeBodyNode* node) { |
+ Bailout("EffectBuilder::VisitNativeBodyNode"); |
+} |
+void ValueBuilder::VisitNativeBodyNode(NativeBodyNode* node) { |
+ Bailout("ValueBuilder::VisitNativeBodyNode"); |
+} |
+void TestBuilder::VisitNativeBodyNode(NativeBodyNode* node) { |
+ Bailout("TestBuilder::VisitNativeBodyNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitPrimaryNode(PrimaryNode* node) { |
+ Bailout("EffectBuilder::VisitPrimaryNode"); |
+} |
+void ValueBuilder::VisitPrimaryNode(PrimaryNode* node) { |
+ Bailout("ValueBuilder::VisitPrimaryNode"); |
+} |
+void TestBuilder::VisitPrimaryNode(PrimaryNode* node) { |
+ Bailout("TestBuilder::VisitPrimaryNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitLoadLocalNode(LoadLocalNode* node) { |
+ Bailout("EffectBuilder::VisitLoadLocalNode"); |
+} |
+void ValueBuilder::VisitLoadLocalNode(LoadLocalNode* node) { |
+ Bailout("ValueBuilder::VisitLoadLocalNode"); |
+} |
+void TestBuilder::VisitLoadLocalNode(LoadLocalNode* node) { |
+ Bailout("TestBuilder::VisitLoadLocalNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitStoreLocalNode(StoreLocalNode* node) { |
+ Bailout("EffectBuilder::VisitStoreLocalNode"); |
+} |
+void ValueBuilder::VisitStoreLocalNode(StoreLocalNode* node) { |
+ Bailout("ValueBuilder::VisitStoreLocalNode"); |
+} |
+void TestBuilder::VisitStoreLocalNode(StoreLocalNode* node) { |
+ Bailout("TestBuilder::VisitStoreLocalNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitLoadInstanceFieldNode(LoadInstanceFieldNode* node) { |
+ Bailout("EffectBuilder::VisitLoadInstanceFieldNode"); |
+} |
+void ValueBuilder::VisitLoadInstanceFieldNode(LoadInstanceFieldNode* node) { |
+ Bailout("ValueBuilder::VisitLoadInstanceFieldNode"); |
+} |
+void TestBuilder::VisitLoadInstanceFieldNode(LoadInstanceFieldNode* node) { |
+ Bailout("TestBuilder::VisitLoadInstanceFieldNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitStoreInstanceFieldNode(StoreInstanceFieldNode* node) { |
+ Bailout("EffectBuilder::VisitStoreInstanceFieldNode"); |
+} |
+void ValueBuilder::VisitStoreInstanceFieldNode(StoreInstanceFieldNode* node) { |
+ Bailout("ValueBuilder::VisitStoreInstanceFieldNode"); |
+} |
+void TestBuilder::VisitStoreInstanceFieldNode(StoreInstanceFieldNode* node) { |
+ Bailout("TestBuilder::VisitStoreInstanceFieldNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
+ Bailout("EffectBuilder::VisitLoadStaticFieldNode"); |
+} |
+void ValueBuilder::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
+ Bailout("ValueBuilder::VisitLoadStaticFieldNode"); |
+} |
+void TestBuilder::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
+ Bailout("TestBuilder::VisitLoadStaticFieldNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
+ Bailout("EffectBuilder::VisitStoreStaticFieldNode"); |
+} |
+void ValueBuilder::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
+ Bailout("ValueBuilder::VisitStoreStaticFieldNode"); |
+} |
+void TestBuilder::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
+ Bailout("TestBuilder::VisitStoreStaticFieldNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitLoadIndexedNode(LoadIndexedNode* node) { |
+ Bailout("EffectBuilder::VisitLoadIndexedNode"); |
+} |
+void ValueBuilder::VisitLoadIndexedNode(LoadIndexedNode* node) { |
+ Bailout("ValueBuilder::VisitLoadIndexedNode"); |
+} |
+void TestBuilder::VisitLoadIndexedNode(LoadIndexedNode* node) { |
+ Bailout("TestBuilder::VisitLoadIndexedNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitStoreIndexedNode(StoreIndexedNode* node) { |
+ Bailout("EffectBuilder::VisitStoreIndexedNode"); |
+} |
+void ValueBuilder::VisitStoreIndexedNode(StoreIndexedNode* node) { |
+ Bailout("ValueBuilder::VisitStoreIndexedNode"); |
+} |
+void TestBuilder::VisitStoreIndexedNode(StoreIndexedNode* node) { |
+ Bailout("TestBuilder::VisitStoreIndexedNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitSequenceNode(SequenceNode* node) { |
+ Bailout("EffectBuilder::VisitSequenceNode"); |
+} |
+void ValueBuilder::VisitSequenceNode(SequenceNode* node) { |
+ Bailout("ValueBuilder::VisitSequenceNode"); |
+} |
+void TestBuilder::VisitSequenceNode(SequenceNode* node) { |
+ Bailout("TestBuilder::VisitSequenceNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitCatchClauseNode(CatchClauseNode* node) { |
+ Bailout("EffectBuilder::VisitCatchClauseNode"); |
+} |
+void ValueBuilder::VisitCatchClauseNode(CatchClauseNode* node) { |
+ Bailout("ValueBuilder::VisitCatchClauseNode"); |
+} |
+void TestBuilder::VisitCatchClauseNode(CatchClauseNode* node) { |
+ Bailout("TestBuilder::VisitCatchClauseNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitTryCatchNode(TryCatchNode* node) { |
+ Bailout("EffectBuilder::VisitTryCatchNode"); |
+} |
+void ValueBuilder::VisitTryCatchNode(TryCatchNode* node) { |
+ Bailout("ValueBuilder::VisitTryCatchNode"); |
+} |
+void TestBuilder::VisitTryCatchNode(TryCatchNode* node) { |
+ Bailout("TestBuilder::VisitTryCatchNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitThrowNode(ThrowNode* node) { |
+ Bailout("EffectBuilder::VisitThrowNode"); |
+} |
+void ValueBuilder::VisitThrowNode(ThrowNode* node) { |
+ Bailout("ValueBuilder::VisitThrowNode"); |
+} |
+void TestBuilder::VisitThrowNode(ThrowNode* node) { |
+ Bailout("TestBuilder::VisitThrowNode"); |
+} |
+ |
+ |
+void EffectBuilder::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
+ Bailout("EffectBuilder::VisitInlinedFinallyNode"); |
+} |
+void ValueBuilder::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
+ Bailout("ValueBuilder::VisitInlinedFinallyNode"); |
+} |
+void TestBuilder::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
+ Bailout("TestBuilder::VisitInlinedFinallyNode"); |
+} |
+ |
+ |
+void FlowGraphBuilder::TraceBailout() const { |
+ if (FLAG_trace_bailout && bailout_reason_ != NULL) { |
+ OS::Print("%s", bailout_reason_); |
+ } |
+} |
+ |
+ |
+void FlowGraphBuilder::BuildGraph() { |
+ EffectBuilder for_effect(*this, 0); |
+ parsed_function().node_sequence()->Visit(&for_effect); |
+} |
+ |
+} // namespace dart |