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

Side by Side Diff: runtime/vm/flow_graph_builder.h

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: Big refactor to incorporate review comments. 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #ifndef VM_FLOW_GRAPH_BUILDER_H_
6 #define VM_FLOW_GRAPH_BUILDER_H_
7
8 #include "vm/allocation.h"
9 #include "vm/ast.h"
10 #include "vm/growable_array.h"
11 #include "vm/intermediate_language.h"
12
13 namespace dart {
14
15 class Instruction;
16 class ParsedFunction;
17
18 class FlowGraphBuilder: public ValueObject {
srdjan 2012/02/22 00:41:34 Please add a comment description to this class.
Kevin Millikin (Google) 2012/02/22 13:15:42 Done.
19 public:
20 explicit FlowGraphBuilder(const ParsedFunction& parsed_function)
21 : parsed_function_(parsed_function), bailout_reason_(NULL) { }
srdjan 2012/02/21 14:33:41 We like to list/initialize all instance fields in
Kevin Millikin (Google) 2012/02/22 13:15:42 Done.
22
23 void BuildGraph();
24
25 const ParsedFunction& parsed_function() const { return parsed_function_; }
26
27 void Bailout(const char* reason) { bailout_reason_ = reason; }
srdjan 2012/02/22 00:41:34 ASSERT(bailout_reason_ == NULL), otherwise the bai
Kevin Millikin (Google) 2012/02/22 13:15:42 Done.
28 void TraceBailout() const;
29 void PrintGraph() const;
30
31 private:
32 const ParsedFunction& parsed_function_;
33 const char* bailout_reason_;
34 GrowableArray<Instruction*> postorder_;
35 };
36
37
38 #define DEFINE_VISIT(type, name) virtual void Visit##type(type* node);
39
40 class TestGraphVisitor;
srdjan 2012/02/22 00:41:34 Comment: Class name TestGraphVisitor sounds like a
Kevin Millikin (Google) 2012/02/22 13:15:42 I agree, but it's nice and short. Alternatives ar
srdjan 2012/02/22 14:08:16 ? TestGraphVisitor and ConditionVisitor are longe
41
42 // Translate an AstNode to a control-flow graph fragment for its effects
43 // (e.g., a statement or an expression in an effect context). Implements a
44 // function from an AstNode and next temporary index to a graph fragment
45 // with a single entry and at most one exit. The fragment is represented by
46 // an (entry, exit) pair of Instruction pointers:
47 //
48 // - (NULL, NULL): an empty graph fragment
srdjan 2012/02/21 14:33:41 an empty and open graph fragment.
Kevin Millikin (Google) 2012/02/22 13:15:42 Done.
49 // - (i0, NULL): a closed graph fragment which has only non-local exits
50 // - (i0, i1): an open graph fragment
51 class EffectGraphVisitor : public AstNodeVisitor {
52 public:
53 EffectGraphVisitor(FlowGraphBuilder* owner, intptr_t temp_index)
54 : owner_(owner),
55 temp_index_(temp_index),
56 entry_(NULL),
57 exit_(NULL),
58 bailing_out_(false) { }
59
60 NODE_LIST(DEFINE_VISIT)
61
62 FlowGraphBuilder* owner() const { return owner_; }
63 intptr_t temp_index() const { return temp_index_; }
64 Instruction* entry() const { return entry_; }
65 Instruction* exit() const { return exit_; }
66
67 bool is_empty() const { return entry_ == NULL; }
68 bool is_open() const { return is_empty() || exit_ != NULL; }
69
70 void Bailout(const char* reason);
71
72 // Append a graph fragment to this graph. Assumes this graph is open.
73 void Append(const EffectGraphVisitor& other_fragment);
74 // Append a single instruction. Assumes this graph is open.
75 void AddInstruction(Instruction* instruction);
76
77 // Append a 'diamond' branch and join to this graph, depending on which
78 // parts are reachable. Assumes this graph is open.
79 void Join(const TestGraphVisitor& test_fragment,
80 const EffectGraphVisitor& true_fragment,
81 const EffectGraphVisitor& false_fragment);
82
83 // Append a 'while loop' test and back edge to this graph, depending on
84 // which parts are reachable. Afterward, the graph exit is the false
85 // successor of the loop condition.
86 void TieLoop(const TestGraphVisitor& test_fragment,
87 const EffectGraphVisitor& body_fragment);
88
89 protected:
90 bool bailing_out() const { return bailing_out_; }
91
92 // Implement the core part of the translation of expression node types.
93 AssertAssignableComp* TranslateAssignable(AssignableNode* node);
srdjan 2012/02/21 14:33:41 The node parameter in TranslateXXX could it be a c
Kevin Millikin (Google) 2012/02/22 13:15:42 Yup. Done. I think it looks strange to dereferen
srdjan 2012/02/22 14:08:16 By passing a reference you guarantee that the valu
94 InstanceCallComp* TranslateBinaryOp(BinaryOpNode* node);
95 InstanceCallComp* TranslateComparison(ComparisonNode* node);
96 StoreLocalComp* TranslateStoreLocal(StoreLocalNode* node);
97 StaticCallComp* TranslateStaticCall(StaticCallNode* node);
98
99 void CloseFragment() { exit_ = NULL; }
100 intptr_t AllocateTempIndex() { return temp_index_++; }
101
102 private:
103 // Helper to append a Do instruction to the graph.
104 void DoComputation(Computation* computation) {
105 AddInstruction(new DoInstr(computation));
106 }
107
108 // Shared global state.
109 FlowGraphBuilder* owner_;
110
111 // Input parameters.
112 intptr_t temp_index_;
113
114 // Output parameters.
115 Instruction* entry_;
116 Instruction* exit_;
117
118 // Local state.
119 bool bailing_out_;
120 };
121
122
123 // Translate an AstNode to a control-flow graph fragment for both its effects
124 // and value (e.g., for an expression in a value context). Implements a
125 // function from an AstNode and next temporary index to a graph fragment (as
126 // in the EffectGraphVisitor), a next temporary index, and a intermediate
srdjan 2012/02/21 14:33:41 "an intermediate"
Kevin Millikin (Google) 2012/02/22 13:15:42 Done.
127 // language Value.
128 class ValueGraphVisitor : public EffectGraphVisitor {
129 public:
130 ValueGraphVisitor(FlowGraphBuilder* owner, intptr_t temp_index)
131 : EffectGraphVisitor(owner, temp_index), value_(NULL) { }
132
133 NODE_LIST(DEFINE_VISIT)
134
135 Value* value() const { return value_; }
136
137 private:
138 // Helper to set the output state to return a Value.
139 void ReturnValue(Value* value) { value_ = value; }
140
141 // Helper to append a Bind instruction to the graph and return its
142 // temporary value (i.e., set the output parameters).
143 void ReturnValueOf(Computation* computation) {
144 AddInstruction(new BindInstr(temp_index(), computation));
145 value_ = new TempValue(AllocateTempIndex());
146 }
147
148 // Output parameters.
149 Value* value_;
150 };
151
152
153 // Translate an AstNode to a control-flow graph fragment for both its
154 // effects and true/false control flow (e.g., for an expression in a test
155 // context). The resulting graph is always closed (even if it is empty)
156 // Successor control flow is explicitly set by a pair of pointers to
157 // TargetEntryInstr*.
158 //
159 // To distinguish between the graphs with only nonlocal exits, graphs that
160 // are unconditionally true or else unconditionally false, and graphs with
161 // both true and false exits, there are a pair of TargetEntryInstr**:
162 //
163 // - Both NULL: only non-local exits, truly closed
164 // - One NULL: unconditionally true or else unconditionally false
165 // - Neither NULL: true and false successors at the given addresses
166 class TestGraphVisitor : public EffectGraphVisitor {
167 public:
168 TestGraphVisitor(FlowGraphBuilder* owner, intptr_t temp_index)
169 : EffectGraphVisitor(owner, temp_index),
170 true_successor_address_(NULL),
171 false_successor_address_(NULL) {
srdjan 2012/02/21 14:33:41 You need to initialize is_true_. Actually, I do no
Kevin Millikin (Google) 2012/02/22 13:15:42 Yeah, that's a leftover. Thanks for spotting it.
172 }
173
174 NODE_LIST(DEFINE_VISIT)
175
176 bool can_be_true() const {
177 return true_successor_address_ != NULL;
178 }
179 bool can_be_false() const {
180 return false_successor_address_ != NULL;
181 }
182
srdjan 2012/02/21 14:33:41 As mentioned, please remove can_be_true and can_be
183 TargetEntryInstr** true_successor_address() const {
184 return true_successor_address_;
185 }
186 TargetEntryInstr** false_successor_address() const {
187 return false_successor_address_;
188 }
189
190 private:
191 // Construct and concatenate a Branch instruction to this graph fragment.
192 // Closes the fragment and sets the output parameters.
193 void BranchOnValue(Value* value);
194
195 // Helper to bind a computation and branch on its value.
196 void BranchOnValueOf(Computation* computation) {
197 AddInstruction(new BindInstr(temp_index(), computation));
198 BranchOnValue(new TempValue(temp_index()));
199 }
200
201 // Output parameters.
202 bool is_true_;
203 TargetEntryInstr** true_successor_address_;
204 TargetEntryInstr** false_successor_address_;
205 };
206
207 #undef DEFINE_VISIT
208
209
210 } // namespace dart
211
212 #endif // VM_FLOW_GRAPH_BUILDER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698