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

Unified Diff: runtime/vm/flow_graph_builder.cc

Issue 9414003: Initial implementation of a flow-graph builder for Dart's AST. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rely on assumption that code can reach both branches of a condition. Created 8 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/handles_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..93469b9587f98f287c18590ee1cce95892fc60d7
--- /dev/null
+++ b/runtime/vm/flow_graph_builder.cc
@@ -0,0 +1,893 @@
+// 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/flags.h"
+#include "vm/intermediate_language.h"
+#include "vm/os.h"
+#include "vm/parser.h"
+
+namespace dart {
+
+DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from graph builder.");
+DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph.");
+DECLARE_FLAG(bool, enable_type_checks);
+
+void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) {
+ ASSERT(is_open());
+ if (other_fragment.is_empty()) return;
+ if (is_empty()) {
+ entry_ = other_fragment.entry();
+ exit_ = other_fragment.exit();
+ } else {
+ exit()->set_successor(other_fragment.entry());
+ exit_ = other_fragment.exit();
+ }
+}
+
+
+void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
+ ASSERT(is_open());
+ if (is_empty()) {
+ entry_ = exit_ = instruction;
+ } else {
+ exit()->set_successor(instruction);
+ exit_ = instruction;
+ }
+}
+
+
+void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment,
+ const EffectGraphVisitor& true_fragment,
+ const EffectGraphVisitor& false_fragment) {
+ // We have: a test graph fragment with zero, one, or two available exits;
+ // and a pair of effect graph fragments with zero or one available exits.
+ // We want to append the branch and (if necessary) a join node to this
+ // graph fragment.
+ ASSERT(is_open());
+
+ // 1. Connect the test to this graph.
+ Append(test_fragment);
+
+ // 2. Connect the true and false bodies to the test if they are reachable,
+ // and if so record their exits (if any).
+ if (test_fragment.can_be_true()) {
+ Instruction* true_exit = NULL;
+ Instruction* false_exit = NULL;
+ TargetEntryInstr* true_entry = new TargetEntryInstr();
+ *test_fragment.true_successor_address() = true_entry;
+ true_entry->set_successor(true_fragment.entry());
+ true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit();
+
+ TargetEntryInstr* false_entry = new TargetEntryInstr();
+ *test_fragment.false_successor_address() = false_entry;
+ false_entry->set_successor(false_fragment.entry());
+ false_exit =
+ false_fragment.is_empty() ? false_entry : false_fragment.exit();
+
+ exit_ = new JoinEntryInstr();
+ true_exit->set_successor(exit_);
+ false_exit->set_successor(exit_);
+ }
+}
+
+
+void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
+ const EffectGraphVisitor& body_fragment) {
+ // We have: a test graph fragment with zero, one, or two available exits;
+ // and an effect graph fragment with zero or one available exits. We want
+ // to append the 'while loop' consisting of the test graph fragment as
+ // condition and the effect graph fragment as body.
+ ASSERT(is_open());
+
+ // 1. Connect the body to the test if it is reachable, and if so record
+ // its exit (if any).
+ Instruction* body_exit = NULL;
+ if (test_fragment.can_be_true()) {
+ TargetEntryInstr* body_entry = new TargetEntryInstr();
+ *test_fragment.true_successor_address() = body_entry;
+ body_entry->set_successor(body_fragment.entry());
+ body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit();
+ }
+
+ // 2. Connect the test to this graph, including the body if reachable and
+ // using a fresh join node if the body is reachable and has an open exit.
+ if (body_exit == NULL) {
+ Append(test_fragment);
+ } else {
+ JoinEntryInstr* join = new JoinEntryInstr();
+ AddInstruction(join);
+ join->set_successor(test_fragment.entry());
+ body_exit->set_successor(join);
+ }
+
+ // 3. Set the exit to the graph to be empty or a fresh target node
+ // depending on whether the false branch of the test is reachable.
+ if (test_fragment.can_be_false()) {
+ exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr();
+ } else {
+ exit_ = NULL;
+ }
+}
+
+
+void TestGraphVisitor::BranchOnValue(Value* value) {
+ BranchInstr* branch = new BranchInstr(value);
+ AddInstruction(branch);
+ CloseFragment();
+ true_successor_address_ = branch->true_successor_address();
+ false_successor_address_ = branch->false_successor_address();
+}
+
+
+void EffectGraphVisitor::Bailout(const char* reason) {
+ if (FLAG_trace_bailout) {
+ OS::Print("Flow Graph Bailout: %s\n", reason);
+ }
+ owner()->Bailout(reason);
+}
+
+
+// 'bailout' is a statement (without a semicolon), typically a return.
+#define CHECK_ALIVE(bailout) \
+ do { \
+ if (owner()->HasBailedOut() || !is_open()) { \
+ bailout; \
+ } \
+ } while (false)
+
+
+// <Statement> ::= Return { value: <Expression>
+// inlined_finally_list: <InlinedFinally>* }
+void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
+ ValueGraphVisitor 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++) {
+ EffectGraphVisitor 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)) {
+ const AbstractType& type =
+ AbstractType::ZoneHandle(
+ owner()->parsed_function().function().result_type());
+ AssertAssignableComp* assert =
+ new AssertAssignableComp(return_value, type);
+ AddInstruction(new BindInstr(temp_index(), assert));
+ return_value = new TempValue(temp_index());
+ }
+ }
+
+ AddInstruction(new ReturnInstr(return_value));
+ CloseFragment();
+}
+
+void ValueGraphVisitor::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); }
+void TestGraphVisitor::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); }
+
+
+// <Expression> ::= Literal { literal: Instance }
+void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
+ return;
+}
+
+void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) {
+ ReturnValue(new ConstantValue(node->literal()));
+}
+
+void TestGraphVisitor::VisitLiteralNode(LiteralNode* node) {
+ BranchOnValue(new ConstantValue(node->literal()));
+}
+
+
+// Type nodes only occur as the right-hand side of instanceof comparisons,
+// and they are handled specially in that context.
+void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
+void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
+void TestGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
+
+
+// <Expression> :: Assignable { expr: <Expression>
+// type: AbstractType
+// dst_name: String }
+AssertAssignableComp* EffectGraphVisitor::TranslateAssignable(
+ const AssignableNode& node) {
+ ValueGraphVisitor for_value(owner(), temp_index());
+ node.expr()->Visit(&for_value);
+ Append(for_value);
+ CHECK_ALIVE(return NULL);
+
+ return new AssertAssignableComp(for_value.value(), node.type());
+}
+
+void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) {
+ AssertAssignableComp* assert = TranslateAssignable(*node);
+ CHECK_ALIVE(return);
+ DoComputation(assert);
+}
+
+void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) {
+ AssertAssignableComp* assert = TranslateAssignable(*node);
+ CHECK_ALIVE(return);
+ ReturnValueOf(assert);
+}
+
+
+void TestGraphVisitor::VisitAssignableNode(AssignableNode* node) {
+ AssertAssignableComp* assert = TranslateAssignable(*node);
+ CHECK_ALIVE(return);
+ BranchOnValueOf(assert);
+}
+
+
+// <Expression> :: BinaryOp { kind: Token::Kind
+// left: <Expression>
+// right: <Expression> }
+InstanceCallComp* EffectGraphVisitor::TranslateBinaryOp(
+ const BinaryOpNode& node) {
+ if ((node.kind() == Token::kAND) || (node.kind() == Token::kOR)) {
+ Bailout("EffectGraphVisitor::VisitBinaryOpNode");
+ return NULL;
+ }
+ ValueGraphVisitor for_left_value(owner(), temp_index());
+ node.left()->Visit(&for_left_value);
+ Append(for_left_value);
+ CHECK_ALIVE(return NULL);
+ ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index());
+ node.right()->Visit(&for_right_value);
+ Append(for_right_value);
+ CHECK_ALIVE(return NULL);
+ ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
+ arguments->Add(for_left_value.value());
+ arguments->Add(for_right_value.value());
+ return new InstanceCallComp(node.Name(), arguments);
+}
+
+void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
+ InstanceCallComp* call = TranslateBinaryOp(*node);
+ CHECK_ALIVE(return);
+ DoComputation(call);
+}
+
+void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
+ InstanceCallComp* call = TranslateBinaryOp(*node);
+ CHECK_ALIVE(return);
+ ReturnValueOf(call);
+}
+
+void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
+ InstanceCallComp* call = TranslateBinaryOp(*node);
+ CHECK_ALIVE(return);
+ BranchOnValueOf(call);
+}
+
+
+void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) {
+ Bailout("EffectGraphVisitor::VisitStringConcatNode");
+}
+void ValueGraphVisitor::VisitStringConcatNode(StringConcatNode* node) {
+ Bailout("ValueGraphVisitor::VisitStringConcatNode");
+}
+void TestGraphVisitor::VisitStringConcatNode(StringConcatNode* node) {
+ Bailout("TestGraphVisitor::VisitStringConcatNode");
+}
+
+
+// <Expression> :: Comparison { kind: Token::Kind
+// left: <Expression>
+// right: <Expression> }
+InstanceCallComp* EffectGraphVisitor::TranslateComparison(
+ const ComparisonNode& node) {
+ if (Token::IsInstanceofOperator(node.kind()) ||
+ Token::IsEqualityOperator(node.kind())) {
+ Bailout("Some kind of comparison we don't handle yet");
+ return NULL;
+ }
+ ValueGraphVisitor for_left_value(owner(), temp_index());
+ node.left()->Visit(&for_left_value);
+ Append(for_left_value);
+ CHECK_ALIVE(return NULL);
+ ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index());
+ node.right()->Visit(&for_right_value);
+ Append(for_right_value);
+ CHECK_ALIVE(return NULL);
+ ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
+ arguments->Add(for_left_value.value());
+ arguments->Add(for_right_value.value());
+ return new InstanceCallComp(node.Name(), arguments);
+}
+
+void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
+ InstanceCallComp* call = TranslateComparison(*node);
+ CHECK_ALIVE(return);
+ DoComputation(call);
+}
+
+void ValueGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
+ InstanceCallComp* call = TranslateComparison(*node);
+ CHECK_ALIVE(return);
+ ReturnValueOf(call);
+}
+
+void TestGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
+ InstanceCallComp* call = TranslateComparison(*node);
+ CHECK_ALIVE(return);
+ BranchOnValueOf(call);
+}
+
+
+void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
+ Bailout("EffectGraphVisitor::VisitUnaryOpNode");
+}
+void ValueGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
+ Bailout("ValueGraphVisitor::VisitUnaryOpNode");
+}
+void TestGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
+ Bailout("TestGraphVisitor::VisitUnaryOpNode");
+}
+
+
+void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) {
+ Bailout("EffectGraphVisitor::VisitIncrOpLocalNode");
+}
+void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) {
+ Bailout("ValueGraphVisitor::VisitIncrOpLocalNode");
+}
+void TestGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) {
+ Bailout("TestGraphVisitor::VisitIncrOpLocalNode");
+}
+
+
+void EffectGraphVisitor::VisitIncrOpInstanceFieldNode(
+ IncrOpInstanceFieldNode* node) {
+ Bailout("EffectGraphVisitor::VisitIncrOpInstanceFieldNode");
+}
+void ValueGraphVisitor::VisitIncrOpInstanceFieldNode(
+ IncrOpInstanceFieldNode* node) {
+ Bailout("ValueGraphVisitor::VisitIncrOpInstanceFieldNode");
+}
+void TestGraphVisitor::VisitIncrOpInstanceFieldNode(
+ IncrOpInstanceFieldNode* node) {
+ Bailout("TestGraphVisitor::VisitIncrOpInstanceFieldNode");
+}
+
+
+void EffectGraphVisitor::VisitIncrOpStaticFieldNode(
+ IncrOpStaticFieldNode* node) {
+ Bailout("EffectGraphVisitor::VisitIncrOpStaticFieldNode");
+}
+void ValueGraphVisitor::VisitIncrOpStaticFieldNode(
+ IncrOpStaticFieldNode* node) {
+ Bailout("ValueGraphVisitor::VisitIncrOpStaticFieldNode");
+}
+void TestGraphVisitor::VisitIncrOpStaticFieldNode(IncrOpStaticFieldNode* node) {
+ Bailout("TestGraphVisitor::VisitIncrOpStaticFieldNode");
+}
+
+
+void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
+ Bailout("EffectGraphVisitor::VisitIncrOpIndexedNode");
+}
+void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
+ Bailout("ValueGraphVisitor::VisitIncrOpIndexedNode");
+}
+void TestGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
+ Bailout("TestGraphVisitor::VisitIncrOpIndexedNode");
+}
+
+
+void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
+ Bailout("EffectGraphVisitor::VisitConditionalExprNode");
+}
+void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
+ Bailout("ValueGraphVisitor::VisitConditionalExprNode");
+}
+void TestGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
+ Bailout("TestGraphVisitor::VisitConditionalExprNode");
+}
+
+
+// <Statement> ::= If { condition: <Expression>
+// true_branch: <Sequence>
+// false_branch: <Sequence> }
+void EffectGraphVisitor::VisitIfNode(IfNode* node) {
+ TestGraphVisitor for_test(owner(), temp_index());
+ node->condition()->Visit(&for_test);
+ Append(for_test);
+
+ EffectGraphVisitor for_true(owner(), temp_index());
+ EffectGraphVisitor for_false(owner(), temp_index());
+
+ if (for_test.can_be_true()) {
+ node->true_branch()->Visit(&for_true);
+ // The for_false graph fragment will be empty (default graph fragment)
+ // if we do not call Visit.
+ if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false);
+ }
+ Join(for_test, for_true, for_false);
+}
+
+void ValueGraphVisitor::VisitIfNode(IfNode* node) { UNREACHABLE(); }
+void TestGraphVisitor::VisitIfNode(IfNode* node) { UNREACHABLE(); }
+
+
+void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) {
+ Bailout("EffectGraphVisitor::VisitSwitchNode");
+}
+void ValueGraphVisitor::VisitSwitchNode(SwitchNode* node) {
+ Bailout("ValueGraphVisitor::VisitSwitchNode");
+}
+void TestGraphVisitor::VisitSwitchNode(SwitchNode* node) {
+ Bailout("TestGraphVisitor::VisitSwitchNode");
+}
+
+
+void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
+ Bailout("EffectGraphVisitor::VisitCaseNode");
+}
+void ValueGraphVisitor::VisitCaseNode(CaseNode* node) {
+ Bailout("ValueGraphVisitor::VisitCaseNode");
+}
+void TestGraphVisitor::VisitCaseNode(CaseNode* node) {
+ Bailout("TestGraphVisitor::VisitCaseNode");
+}
+
+
+// <Statement> ::= While { label: SourceLabel
+// condition: <Expression>
+// body: <Sequence> }
+void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
+ TestGraphVisitor for_test(owner(), temp_index());
+ node->condition()->Visit(&for_test);
+
+ EffectGraphVisitor for_body(owner(), temp_index());
+ if (for_test.can_be_true()) node->body()->Visit(&for_body);
+ TieLoop(for_test, for_body);
+}
+
+void ValueGraphVisitor::VisitWhileNode(WhileNode* node) { UNREACHABLE(); }
+void TestGraphVisitor::VisitWhileNode(WhileNode* node) { UNREACHABLE(); }
+
+
+void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
+ Bailout("EffectGraphVisitor::VisitDoWhileNode");
+}
+void ValueGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
+ Bailout("ValueGraphVisitor::VisitDoWhileNode");
+}
+void TestGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
+ Bailout("TestGraphVisitor::VisitDoWhileNode");
+}
+
+
+void EffectGraphVisitor::VisitForNode(ForNode* node) {
+ Bailout("EffectGraphVisitor::VisitForNode");
+}
+void ValueGraphVisitor::VisitForNode(ForNode* node) {
+ Bailout("ValueGraphVisitor::VisitForNode");
+}
+void TestGraphVisitor::VisitForNode(ForNode* node) {
+ Bailout("TestGraphVisitor::VisitForNode");
+}
+
+
+void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
+ Bailout("EffectGraphVisitor::VisitJumpNode");
+}
+void ValueGraphVisitor::VisitJumpNode(JumpNode* node) {
+ Bailout("ValueGraphVisitor::VisitJumpNode");
+}
+void TestGraphVisitor::VisitJumpNode(JumpNode* node) {
+ Bailout("TestGraphVisitor::VisitJumpNode");
+}
+
+
+void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
+ UNREACHABLE();
+}
+void ValueGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
+ UNREACHABLE();
+}
+void TestGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
+ UNREACHABLE();
+}
+
+
+void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
+ Bailout("EffectGraphVisitor::VisitArrayNode");
+}
+void ValueGraphVisitor::VisitArrayNode(ArrayNode* node) {
+ Bailout("ValueGraphVisitor::VisitArrayNode");
+}
+void TestGraphVisitor::VisitArrayNode(ArrayNode* node) {
+ Bailout("TestGraphVisitor::VisitArrayNode");
+}
+
+
+void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
+ Bailout("EffectGraphVisitor::VisitClosureNode");
+}
+void ValueGraphVisitor::VisitClosureNode(ClosureNode* node) {
+ Bailout("ValueGraphVisitor::VisitClosureNode");
+}
+void TestGraphVisitor::VisitClosureNode(ClosureNode* node) {
+ Bailout("TestGraphVisitor::VisitClosureNode");
+}
+
+
+void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
+ Bailout("EffectGraphVisitor::VisitInstanceCallNode");
+}
+void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
+ Bailout("ValueGraphVisitor::VisitInstanceCallNode");
+}
+void TestGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
+ Bailout("TestGraphVisitor::VisitInstanceCallNode");
+}
+
+
+// <Expression> ::= StaticCall { function: Function
+// arguments: <ArgumentList> }
+StaticCallComp* EffectGraphVisitor::TranslateStaticCall(
+ const StaticCallNode& node) {
+ ArgumentListNode* arguments = node.arguments();
+ int length = arguments->length();
+ ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length);
+ int index = temp_index();
+ for (intptr_t i = 0; i < length; ++i) {
+ ValueGraphVisitor for_value(owner(), index);
+ arguments->NodeAt(i)->Visit(&for_value);
+ Append(for_value);
+ CHECK_ALIVE(return NULL);
+ values->Add(for_value.value());
+ index = for_value.temp_index();
+ }
+ return new StaticCallComp(node.function(), values);
+}
+
+void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
+ StaticCallComp* call = TranslateStaticCall(*node);
+ CHECK_ALIVE(return);
+ DoComputation(call);
+}
+
+void ValueGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
+ StaticCallComp* call = TranslateStaticCall(*node);
+ CHECK_ALIVE(return);
+ ReturnValueOf(call);
+}
+
+void TestGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
+ StaticCallComp* call = TranslateStaticCall(*node);
+ CHECK_ALIVE(return);
+ BranchOnValueOf(call);
+}
+
+
+void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
+ Bailout("EffectGraphVisitor::VisitClosureCallNode");
+}
+void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
+ Bailout("ValueGraphVisitor::VisitClosureCallNode");
+}
+void TestGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
+ Bailout("TestGraphVisitor::VisitClosureCallNode");
+}
+
+
+void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
+ Bailout("EffectGraphVisitor::VisitCloneContextNode");
+}
+void ValueGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
+ Bailout("ValueGraphVisitor::VisitCloneContextNode");
+}
+void TestGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
+ Bailout("TestGraphVisitor::VisitCloneContextNode");
+}
+
+
+void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
+ Bailout("EffectGraphVisitor::VisitConstructorCallNode");
+}
+void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
+ Bailout("ValueGraphVisitor::VisitConstructorCallNode");
+}
+void TestGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
+ Bailout("TestGraphVisitor::VisitConstructorCallNode");
+}
+
+
+void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
+ Bailout("EffectGraphVisitor::VisitInstanceGetterNode");
+}
+void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
+ Bailout("ValueGraphVisitor::VisitInstanceGetterNode");
+}
+void TestGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
+ Bailout("TestGraphVisitor::VisitInstanceGetterNode");
+}
+
+
+void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
+ Bailout("EffectGraphVisitor::VisitInstanceSetterNode");
+}
+void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
+ Bailout("ValueGraphVisitor::VisitInstanceSetterNode");
+}
+void TestGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
+ Bailout("TestGraphVisitor::VisitInstanceSetterNode");
+}
+
+
+void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
+ Bailout("EffectGraphVisitor::VisitStaticGetterNode");
+}
+void ValueGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
+ Bailout("ValueGraphVisitor::VisitStaticGetterNode");
+}
+void TestGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
+ Bailout("TestGraphVisitor::VisitStaticGetterNode");
+}
+
+
+void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
+ Bailout("EffectGraphVisitor::VisitStaticSetterNode");
+}
+void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
+ Bailout("ValueGraphVisitor::VisitStaticSetterNode");
+}
+void TestGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
+ Bailout("TestGraphVisitor::VisitStaticSetterNode");
+}
+
+
+void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
+ Bailout("EffectGraphVisitor::VisitNativeBodyNode");
+}
+void ValueGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
+ Bailout("ValueGraphVisitor::VisitNativeBodyNode");
+}
+void TestGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
+ Bailout("TestGraphVisitor::VisitNativeBodyNode");
+}
+
+
+void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
+ Bailout("EffectGraphVisitor::VisitPrimaryNode");
+}
+void ValueGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
+ Bailout("ValueGraphVisitor::VisitPrimaryNode");
+}
+void TestGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
+ Bailout("TestGraphVisitor::VisitPrimaryNode");
+}
+
+
+// <Expression> ::= LoadLocal { local: LocalVariable }
+void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
+ return;
+}
+
+void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
+ LoadLocalComp* load = new LoadLocalComp(node->local());
+ ReturnValueOf(load);
+}
+
+void TestGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
+ LoadLocalComp* load = new LoadLocalComp(node->local());
+ BranchOnValueOf(load);
+}
+
+
+// <Expression> ::= StoreLocal { local: LocalVariable
+// value: <Expression> }
+StoreLocalComp* EffectGraphVisitor::TranslateStoreLocal(
+ const StoreLocalNode& node) {
+ ValueGraphVisitor for_value(owner(), temp_index());
+ node.value()->Visit(&for_value);
+ Append(for_value);
+ CHECK_ALIVE(return NULL);
+ return new StoreLocalComp(node.local(), for_value.value());
+}
+
+void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
+ StoreLocalComp* store = TranslateStoreLocal(*node);
+ CHECK_ALIVE(return);
+ DoComputation(store);
+}
+
+void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
+ StoreLocalComp* store = TranslateStoreLocal(*node);
+ CHECK_ALIVE(return);
+ ReturnValueOf(store);
+}
+
+void TestGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
+ StoreLocalComp* store = TranslateStoreLocal(*node);
+ CHECK_ALIVE(return);
+ BranchOnValueOf(store);
+}
+
+
+void EffectGraphVisitor::VisitLoadInstanceFieldNode(
+ LoadInstanceFieldNode* node) {
+ Bailout("EffectGraphVisitor::VisitLoadInstanceFieldNode");
+}
+void ValueGraphVisitor::VisitLoadInstanceFieldNode(
+ LoadInstanceFieldNode* node) {
+ Bailout("ValueGraphVisitor::VisitLoadInstanceFieldNode");
+}
+void TestGraphVisitor::VisitLoadInstanceFieldNode(LoadInstanceFieldNode* node) {
+ Bailout("TestGraphVisitor::VisitLoadInstanceFieldNode");
+}
+
+
+void EffectGraphVisitor::VisitStoreInstanceFieldNode(
+ StoreInstanceFieldNode* node) {
+ Bailout("EffectGraphVisitor::VisitStoreInstanceFieldNode");
+}
+void ValueGraphVisitor::VisitStoreInstanceFieldNode(
+ StoreInstanceFieldNode* node) {
+ Bailout("ValueGraphVisitor::VisitStoreInstanceFieldNode");
+}
+void TestGraphVisitor::VisitStoreInstanceFieldNode(
+ StoreInstanceFieldNode* node) {
+ Bailout("TestGraphVisitor::VisitStoreInstanceFieldNode");
+}
+
+
+void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
+ Bailout("EffectGraphVisitor::VisitLoadStaticFieldNode");
+}
+void ValueGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
+ Bailout("ValueGraphVisitor::VisitLoadStaticFieldNode");
+}
+void TestGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
+ Bailout("TestGraphVisitor::VisitLoadStaticFieldNode");
+}
+
+
+void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
+ Bailout("EffectGraphVisitor::VisitStoreStaticFieldNode");
+}
+void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
+ Bailout("ValueGraphVisitor::VisitStoreStaticFieldNode");
+}
+void TestGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
+ Bailout("TestGraphVisitor::VisitStoreStaticFieldNode");
+}
+
+
+void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
+ Bailout("EffectGraphVisitor::VisitLoadIndexedNode");
+}
+void ValueGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
+ Bailout("ValueGraphVisitor::VisitLoadIndexedNode");
+}
+void TestGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
+ Bailout("TestGraphVisitor::VisitLoadIndexedNode");
+}
+
+
+void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
+ Bailout("EffectGraphVisitor::VisitStoreIndexedNode");
+}
+void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
+ Bailout("ValueGraphVisitor::VisitStoreIndexedNode");
+}
+void TestGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
+ Bailout("TestGraphVisitor::VisitStoreIndexedNode");
+}
+
+
+// <Statement> ::= Sequence { scope: LocalScope
+// nodes: <Statement>*
+// label: SourceLabel }
+void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
+ if ((node->scope() != NULL) &&
+ (node->scope()->num_context_variables() != 0)) {
+ Bailout("Sequence needs a context. Gotta have a context.");
+ }
+ for (intptr_t i = 0; i < node->length(); ++i) {
+ EffectGraphVisitor for_effect(owner(), temp_index());
+ node->NodeAt(i)->Visit(&for_effect);
+ Append(for_effect);
+ CHECK_ALIVE(return);
+ }
+}
+
+void ValueGraphVisitor::VisitSequenceNode(SequenceNode* node) { UNREACHABLE(); }
+void TestGraphVisitor::VisitSequenceNode(SequenceNode* node) { UNREACHABLE(); }
+
+
+void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
+ Bailout("EffectGraphVisitor::VisitCatchClauseNode");
+}
+void ValueGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
+ Bailout("ValueGraphVisitor::VisitCatchClauseNode");
+}
+void TestGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
+ Bailout("TestGraphVisitor::VisitCatchClauseNode");
+}
+
+
+void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
+ Bailout("EffectGraphVisitor::VisitTryCatchNode");
+}
+void ValueGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
+ Bailout("ValueGraphVisitor::VisitTryCatchNode");
+}
+void TestGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
+ Bailout("TestGraphVisitor::VisitTryCatchNode");
+}
+
+
+void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
+ Bailout("EffectGraphVisitor::VisitThrowNode");
+}
+void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) {
+ Bailout("ValueGraphVisitor::VisitThrowNode");
+}
+void TestGraphVisitor::VisitThrowNode(ThrowNode* node) {
+ Bailout("TestGraphVisitor::VisitThrowNode");
+}
+
+
+void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
+ Bailout("EffectGraphVisitor::VisitInlinedFinallyNode");
+}
+void ValueGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
+ Bailout("ValueGraphVisitor::VisitInlinedFinallyNode");
+}
+void TestGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
+ Bailout("TestGraphVisitor::VisitInlinedFinallyNode");
+}
+
+
+void FlowGraphBuilder::TraceBailout() const {
+ if (FLAG_trace_bailout && HasBailedOut()) {
+ OS::Print("Failed: %s in %s\n",
+ bailout_reason_,
+ parsed_function().function().ToFullyQualifiedCString());
+ }
+}
+
+
+void FlowGraphBuilder::PrintGraph() const {
+ if (!FLAG_print_flow_graph || HasBailedOut()) return;
+
+ OS::Print("==== %s\n",
+ parsed_function().function().ToFullyQualifiedCString());
+
+ for (intptr_t i = postorder_.length() - 1; i >= 0; --i) {
+ OS::Print("%8d: ", postorder_.length() - i);
+ postorder_[i]->Print(i, postorder_);
+ OS::Print("\n");
+ }
+ OS::Print("\n");
+}
+
+
+void FlowGraphBuilder::BuildGraph() {
+ EffectGraphVisitor for_effect(this, 0);
+ parsed_function().node_sequence()->Visit(&for_effect);
+ TraceBailout();
+ if (!HasBailedOut() && (for_effect.entry() != NULL)) {
+ for_effect.entry()->Postorder(&postorder_);
+ }
+ PrintGraph();
+}
+
+} // namespace dart
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/handles_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698