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

Side by Side Diff: runtime/vm/constant_propagator.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 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
« no previous file with comments | « runtime/vm/constant_propagator.h ('k') | runtime/vm/constants_arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/constant_propagator.h" 5 #include "vm/constant_propagator.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/flow_graph_compiler.h" 9 #include "vm/flow_graph_compiler.h"
10 #include "vm/flow_graph_range_analysis.h" 10 #include "vm/flow_graph_range_analysis.h"
11 #include "vm/il_printer.h" 11 #include "vm/il_printer.h"
12 #include "vm/intermediate_language.h" 12 #include "vm/intermediate_language.h"
13 #include "vm/parser.h" 13 #include "vm/parser.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis."); 18 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis.");
19 DEFINE_FLAG(bool, 19 DEFINE_FLAG(bool,
20 trace_constant_propagation, 20 trace_constant_propagation,
21 false, 21 false,
22 "Print constant propagation and useless code elimination."); 22 "Print constant propagation and useless code elimination.");
23 23
24 // Quick access to the current zone and isolate. 24 // Quick access to the current zone and isolate.
25 #define I (isolate()) 25 #define I (isolate())
26 #define Z (graph_->zone()) 26 #define Z (graph_->zone())
27 27
28
29 ConstantPropagator::ConstantPropagator( 28 ConstantPropagator::ConstantPropagator(
30 FlowGraph* graph, 29 FlowGraph* graph,
31 const GrowableArray<BlockEntryInstr*>& ignored) 30 const GrowableArray<BlockEntryInstr*>& ignored)
32 : FlowGraphVisitor(ignored), 31 : FlowGraphVisitor(ignored),
33 graph_(graph), 32 graph_(graph),
34 unknown_(Object::unknown_constant()), 33 unknown_(Object::unknown_constant()),
35 non_constant_(Object::non_constant()), 34 non_constant_(Object::non_constant()),
36 reachable_(new (Z) BitVector(Z, graph->preorder().length())), 35 reachable_(new (Z) BitVector(Z, graph->preorder().length())),
37 marked_phis_(new (Z) BitVector(Z, graph->max_virtual_register_number())), 36 marked_phis_(new (Z) BitVector(Z, graph->max_virtual_register_number())),
38 block_worklist_(), 37 block_worklist_(),
39 definition_worklist_(graph, 10) {} 38 definition_worklist_(graph, 10) {}
40 39
41
42 void ConstantPropagator::Optimize(FlowGraph* graph) { 40 void ConstantPropagator::Optimize(FlowGraph* graph) {
43 GrowableArray<BlockEntryInstr*> ignored; 41 GrowableArray<BlockEntryInstr*> ignored;
44 ConstantPropagator cp(graph, ignored); 42 ConstantPropagator cp(graph, ignored);
45 cp.Analyze(); 43 cp.Analyze();
46 cp.Transform(); 44 cp.Transform();
47 } 45 }
48 46
49
50 void ConstantPropagator::OptimizeBranches(FlowGraph* graph) { 47 void ConstantPropagator::OptimizeBranches(FlowGraph* graph) {
51 GrowableArray<BlockEntryInstr*> ignored; 48 GrowableArray<BlockEntryInstr*> ignored;
52 ConstantPropagator cp(graph, ignored); 49 ConstantPropagator cp(graph, ignored);
53 cp.Analyze(); 50 cp.Analyze();
54 cp.Transform(); 51 cp.Transform();
55 cp.EliminateRedundantBranches(); 52 cp.EliminateRedundantBranches();
56 } 53 }
57 54
58
59 void ConstantPropagator::SetReachable(BlockEntryInstr* block) { 55 void ConstantPropagator::SetReachable(BlockEntryInstr* block) {
60 if (!reachable_->Contains(block->preorder_number())) { 56 if (!reachable_->Contains(block->preorder_number())) {
61 reachable_->Add(block->preorder_number()); 57 reachable_->Add(block->preorder_number());
62 block_worklist_.Add(block); 58 block_worklist_.Add(block);
63 } 59 }
64 } 60 }
65 61
66
67 bool ConstantPropagator::SetValue(Definition* definition, const Object& value) { 62 bool ConstantPropagator::SetValue(Definition* definition, const Object& value) {
68 // We would like to assert we only go up (toward non-constant) in the lattice. 63 // We would like to assert we only go up (toward non-constant) in the lattice.
69 // 64 //
70 // ASSERT(IsUnknown(definition->constant_value()) || 65 // ASSERT(IsUnknown(definition->constant_value()) ||
71 // IsNonConstant(value) || 66 // IsNonConstant(value) ||
72 // (definition->constant_value().raw() == value.raw())); 67 // (definition->constant_value().raw() == value.raw()));
73 // 68 //
74 // But the final disjunct is not true (e.g., mint or double constants are 69 // But the final disjunct is not true (e.g., mint or double constants are
75 // heap-allocated and so not necessarily pointer-equal on each iteration). 70 // heap-allocated and so not necessarily pointer-equal on each iteration).
76 if (definition->constant_value().raw() != value.raw()) { 71 if (definition->constant_value().raw() != value.raw()) {
77 definition->constant_value() = value.raw(); 72 definition->constant_value() = value.raw();
78 if (definition->input_use_list() != NULL) { 73 if (definition->input_use_list() != NULL) {
79 definition_worklist_.Add(definition); 74 definition_worklist_.Add(definition);
80 } 75 }
81 return true; 76 return true;
82 } 77 }
83 return false; 78 return false;
84 } 79 }
85 80
86
87 // Compute the join of two values in the lattice, assign it to the first. 81 // Compute the join of two values in the lattice, assign it to the first.
88 void ConstantPropagator::Join(Object* left, const Object& right) { 82 void ConstantPropagator::Join(Object* left, const Object& right) {
89 // Join(non-constant, X) = non-constant 83 // Join(non-constant, X) = non-constant
90 // Join(X, unknown) = X 84 // Join(X, unknown) = X
91 if (IsNonConstant(*left) || IsUnknown(right)) return; 85 if (IsNonConstant(*left) || IsUnknown(right)) return;
92 86
93 // Join(unknown, X) = X 87 // Join(unknown, X) = X
94 // Join(X, non-constant) = non-constant 88 // Join(X, non-constant) = non-constant
95 if (IsUnknown(*left) || IsNonConstant(right)) { 89 if (IsUnknown(*left) || IsNonConstant(right)) {
96 *left = right.raw(); 90 *left = right.raw();
97 return; 91 return;
98 } 92 }
99 93
100 // Join(X, X) = X 94 // Join(X, X) = X
101 // TODO(kmillikin): support equality for doubles, mints, etc. 95 // TODO(kmillikin): support equality for doubles, mints, etc.
102 if (left->raw() == right.raw()) return; 96 if (left->raw() == right.raw()) return;
103 97
104 // Join(X, Y) = non-constant 98 // Join(X, Y) = non-constant
105 *left = non_constant_.raw(); 99 *left = non_constant_.raw();
106 } 100 }
107 101
108
109 // -------------------------------------------------------------------------- 102 // --------------------------------------------------------------------------
110 // Analysis of blocks. Called at most once per block. The block is already 103 // Analysis of blocks. Called at most once per block. The block is already
111 // marked as reachable. All instructions in the block are analyzed. 104 // marked as reachable. All instructions in the block are analyzed.
112 void ConstantPropagator::VisitGraphEntry(GraphEntryInstr* block) { 105 void ConstantPropagator::VisitGraphEntry(GraphEntryInstr* block) {
113 const GrowableArray<Definition*>& defs = *block->initial_definitions(); 106 const GrowableArray<Definition*>& defs = *block->initial_definitions();
114 for (intptr_t i = 0; i < defs.length(); ++i) { 107 for (intptr_t i = 0; i < defs.length(); ++i) {
115 defs[i]->Accept(this); 108 defs[i]->Accept(this);
116 } 109 }
117 ASSERT(ForwardInstructionIterator(block).Done()); 110 ASSERT(ForwardInstructionIterator(block).Done());
118 111
119 // TODO(fschneider): Improve this approximation. The catch entry is only 112 // TODO(fschneider): Improve this approximation. The catch entry is only
120 // reachable if a call in the try-block is reachable. 113 // reachable if a call in the try-block is reachable.
121 for (intptr_t i = 0; i < block->SuccessorCount(); ++i) { 114 for (intptr_t i = 0; i < block->SuccessorCount(); ++i) {
122 SetReachable(block->SuccessorAt(i)); 115 SetReachable(block->SuccessorAt(i));
123 } 116 }
124 } 117 }
125 118
126
127 void ConstantPropagator::VisitJoinEntry(JoinEntryInstr* block) { 119 void ConstantPropagator::VisitJoinEntry(JoinEntryInstr* block) {
128 // Phis are visited when visiting Goto at a predecessor. See VisitGoto. 120 // Phis are visited when visiting Goto at a predecessor. See VisitGoto.
129 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 121 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
130 it.Current()->Accept(this); 122 it.Current()->Accept(this);
131 } 123 }
132 } 124 }
133 125
134
135 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) { 126 void ConstantPropagator::VisitTargetEntry(TargetEntryInstr* block) {
136 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 127 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
137 it.Current()->Accept(this); 128 it.Current()->Accept(this);
138 } 129 }
139 } 130 }
140 131
141
142 void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) { 132 void ConstantPropagator::VisitIndirectEntry(IndirectEntryInstr* block) {
143 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 133 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
144 it.Current()->Accept(this); 134 it.Current()->Accept(this);
145 } 135 }
146 } 136 }
147 137
148
149 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) { 138 void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) {
150 const GrowableArray<Definition*>& defs = *block->initial_definitions(); 139 const GrowableArray<Definition*>& defs = *block->initial_definitions();
151 for (intptr_t i = 0; i < defs.length(); ++i) { 140 for (intptr_t i = 0; i < defs.length(); ++i) {
152 defs[i]->Accept(this); 141 defs[i]->Accept(this);
153 } 142 }
154 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 143 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
155 it.Current()->Accept(this); 144 it.Current()->Accept(this);
156 } 145 }
157 } 146 }
158 147
159
160 void ConstantPropagator::VisitParallelMove(ParallelMoveInstr* instr) { 148 void ConstantPropagator::VisitParallelMove(ParallelMoveInstr* instr) {
161 // Parallel moves have not yet been inserted in the graph. 149 // Parallel moves have not yet been inserted in the graph.
162 UNREACHABLE(); 150 UNREACHABLE();
163 } 151 }
164 152
165
166 // -------------------------------------------------------------------------- 153 // --------------------------------------------------------------------------
167 // Analysis of control instructions. Unconditional successors are 154 // Analysis of control instructions. Unconditional successors are
168 // reachable. Conditional successors are reachable depending on the 155 // reachable. Conditional successors are reachable depending on the
169 // constant value of the condition. 156 // constant value of the condition.
170 void ConstantPropagator::VisitReturn(ReturnInstr* instr) { 157 void ConstantPropagator::VisitReturn(ReturnInstr* instr) {
171 // Nothing to do. 158 // Nothing to do.
172 } 159 }
173 160
174
175 void ConstantPropagator::VisitThrow(ThrowInstr* instr) { 161 void ConstantPropagator::VisitThrow(ThrowInstr* instr) {
176 // Nothing to do. 162 // Nothing to do.
177 } 163 }
178 164
179
180 void ConstantPropagator::VisitReThrow(ReThrowInstr* instr) { 165 void ConstantPropagator::VisitReThrow(ReThrowInstr* instr) {
181 // Nothing to do. 166 // Nothing to do.
182 } 167 }
183 168
184
185 void ConstantPropagator::VisitStop(StopInstr* instr) { 169 void ConstantPropagator::VisitStop(StopInstr* instr) {
186 // Nothing to do. 170 // Nothing to do.
187 } 171 }
188 172
189
190 void ConstantPropagator::VisitGoto(GotoInstr* instr) { 173 void ConstantPropagator::VisitGoto(GotoInstr* instr) {
191 SetReachable(instr->successor()); 174 SetReachable(instr->successor());
192 175
193 // Phi value depends on the reachability of a predecessor. We have 176 // Phi value depends on the reachability of a predecessor. We have
194 // to revisit phis every time a predecessor becomes reachable. 177 // to revisit phis every time a predecessor becomes reachable.
195 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) { 178 for (PhiIterator it(instr->successor()); !it.Done(); it.Advance()) {
196 it.Current()->Accept(this); 179 it.Current()->Accept(this);
197 } 180 }
198 } 181 }
199 182
200
201 void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) { 183 void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) {
202 for (intptr_t i = 0; i < instr->SuccessorCount(); i++) { 184 for (intptr_t i = 0; i < instr->SuccessorCount(); i++) {
203 SetReachable(instr->SuccessorAt(i)); 185 SetReachable(instr->SuccessorAt(i));
204 } 186 }
205 } 187 }
206 188
207
208 void ConstantPropagator::VisitBranch(BranchInstr* instr) { 189 void ConstantPropagator::VisitBranch(BranchInstr* instr) {
209 instr->comparison()->Accept(this); 190 instr->comparison()->Accept(this);
210 191
211 // The successors may be reachable, but only if this instruction is. (We 192 // The successors may be reachable, but only if this instruction is. (We
212 // might be analyzing it because the constant value of one of its inputs 193 // might be analyzing it because the constant value of one of its inputs
213 // has changed.) 194 // has changed.)
214 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { 195 if (reachable_->Contains(instr->GetBlock()->preorder_number())) {
215 if (instr->constant_target() != NULL) { 196 if (instr->constant_target() != NULL) {
216 ASSERT((instr->constant_target() == instr->true_successor()) || 197 ASSERT((instr->constant_target() == instr->true_successor()) ||
217 (instr->constant_target() == instr->false_successor())); 198 (instr->constant_target() == instr->false_successor()));
218 SetReachable(instr->constant_target()); 199 SetReachable(instr->constant_target());
219 } else { 200 } else {
220 const Object& value = instr->comparison()->constant_value(); 201 const Object& value = instr->comparison()->constant_value();
221 if (IsNonConstant(value)) { 202 if (IsNonConstant(value)) {
222 SetReachable(instr->true_successor()); 203 SetReachable(instr->true_successor());
223 SetReachable(instr->false_successor()); 204 SetReachable(instr->false_successor());
224 } else if (value.raw() == Bool::True().raw()) { 205 } else if (value.raw() == Bool::True().raw()) {
225 SetReachable(instr->true_successor()); 206 SetReachable(instr->true_successor());
226 } else if (!IsUnknown(value)) { // Any other constant. 207 } else if (!IsUnknown(value)) { // Any other constant.
227 SetReachable(instr->false_successor()); 208 SetReachable(instr->false_successor());
228 } 209 }
229 } 210 }
230 } 211 }
231 } 212 }
232 213
233
234 // -------------------------------------------------------------------------- 214 // --------------------------------------------------------------------------
235 // Analysis of non-definition instructions. They do not have values so they 215 // Analysis of non-definition instructions. They do not have values so they
236 // cannot have constant values. 216 // cannot have constant values.
237 void ConstantPropagator::VisitCheckStackOverflow( 217 void ConstantPropagator::VisitCheckStackOverflow(
238 CheckStackOverflowInstr* instr) {} 218 CheckStackOverflowInstr* instr) {}
239 219
240
241 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) {} 220 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) {}
242 221
243
244 void ConstantPropagator::VisitCheckClassId(CheckClassIdInstr* instr) {} 222 void ConstantPropagator::VisitCheckClassId(CheckClassIdInstr* instr) {}
245 223
246
247 void ConstantPropagator::VisitGuardFieldClass(GuardFieldClassInstr* instr) {} 224 void ConstantPropagator::VisitGuardFieldClass(GuardFieldClassInstr* instr) {}
248 225
249
250 void ConstantPropagator::VisitGuardFieldLength(GuardFieldLengthInstr* instr) {} 226 void ConstantPropagator::VisitGuardFieldLength(GuardFieldLengthInstr* instr) {}
251 227
252
253 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) {} 228 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) {}
254 229
255
256 void ConstantPropagator::VisitGenericCheckBound(GenericCheckBoundInstr* instr) { 230 void ConstantPropagator::VisitGenericCheckBound(GenericCheckBoundInstr* instr) {
257 } 231 }
258 232
259
260 void ConstantPropagator::VisitCheckEitherNonSmi(CheckEitherNonSmiInstr* instr) { 233 void ConstantPropagator::VisitCheckEitherNonSmi(CheckEitherNonSmiInstr* instr) {
261 } 234 }
262 235
263
264 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) {} 236 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) {}
265 237
266
267 void ConstantPropagator::VisitDeoptimize(DeoptimizeInstr* instr) { 238 void ConstantPropagator::VisitDeoptimize(DeoptimizeInstr* instr) {
268 // TODO(vegorov) remove all code after DeoptimizeInstr as dead. 239 // TODO(vegorov) remove all code after DeoptimizeInstr as dead.
269 } 240 }
270 241
271
272 Definition* ConstantPropagator::UnwrapPhi(Definition* defn) { 242 Definition* ConstantPropagator::UnwrapPhi(Definition* defn) {
273 if (defn->IsPhi()) { 243 if (defn->IsPhi()) {
274 JoinEntryInstr* block = defn->AsPhi()->block(); 244 JoinEntryInstr* block = defn->AsPhi()->block();
275 245
276 Definition* input = NULL; 246 Definition* input = NULL;
277 for (intptr_t i = 0; i < defn->InputCount(); ++i) { 247 for (intptr_t i = 0; i < defn->InputCount(); ++i) {
278 if (reachable_->Contains(block->PredecessorAt(i)->preorder_number())) { 248 if (reachable_->Contains(block->PredecessorAt(i)->preorder_number())) {
279 if (input == NULL) { 249 if (input == NULL) {
280 input = defn->InputAt(i)->definition(); 250 input = defn->InputAt(i)->definition();
281 } else { 251 } else {
282 return defn; 252 return defn;
283 } 253 }
284 } 254 }
285 } 255 }
286 256
287 return input; 257 return input;
288 } 258 }
289 259
290 return defn; 260 return defn;
291 } 261 }
292 262
293
294 void ConstantPropagator::MarkPhi(Definition* phi) { 263 void ConstantPropagator::MarkPhi(Definition* phi) {
295 ASSERT(phi->IsPhi()); 264 ASSERT(phi->IsPhi());
296 marked_phis_->Add(phi->ssa_temp_index()); 265 marked_phis_->Add(phi->ssa_temp_index());
297 } 266 }
298 267
299
300 // -------------------------------------------------------------------------- 268 // --------------------------------------------------------------------------
301 // Analysis of definitions. Compute the constant value. If it has changed 269 // Analysis of definitions. Compute the constant value. If it has changed
302 // and the definition has input uses, add the definition to the definition 270 // and the definition has input uses, add the definition to the definition
303 // worklist so that the used can be processed. 271 // worklist so that the used can be processed.
304 void ConstantPropagator::VisitPhi(PhiInstr* instr) { 272 void ConstantPropagator::VisitPhi(PhiInstr* instr) {
305 // Compute the join over all the reachable predecessor values. 273 // Compute the join over all the reachable predecessor values.
306 JoinEntryInstr* block = instr->block(); 274 JoinEntryInstr* block = instr->block();
307 Object& value = Object::ZoneHandle(Z, Unknown()); 275 Object& value = Object::ZoneHandle(Z, Unknown());
308 for (intptr_t pred_idx = 0; pred_idx < instr->InputCount(); ++pred_idx) { 276 for (intptr_t pred_idx = 0; pred_idx < instr->InputCount(); ++pred_idx) {
309 if (reachable_->Contains( 277 if (reachable_->Contains(
310 block->PredecessorAt(pred_idx)->preorder_number())) { 278 block->PredecessorAt(pred_idx)->preorder_number())) {
311 Join(&value, instr->InputAt(pred_idx)->definition()->constant_value()); 279 Join(&value, instr->InputAt(pred_idx)->definition()->constant_value());
312 } 280 }
313 } 281 }
314 if (!SetValue(instr, value) && 282 if (!SetValue(instr, value) &&
315 marked_phis_->Contains(instr->ssa_temp_index())) { 283 marked_phis_->Contains(instr->ssa_temp_index())) {
316 marked_phis_->Remove(instr->ssa_temp_index()); 284 marked_phis_->Remove(instr->ssa_temp_index());
317 definition_worklist_.Add(instr); 285 definition_worklist_.Add(instr);
318 } 286 }
319 } 287 }
320 288
321
322 void ConstantPropagator::VisitRedefinition(RedefinitionInstr* instr) { 289 void ConstantPropagator::VisitRedefinition(RedefinitionInstr* instr) {
323 // Ensure that we never remove redefinition of a constant unless we are also 290 // Ensure that we never remove redefinition of a constant unless we are also
324 // are guaranteed to fold away code paths that correspond to non-matching 291 // are guaranteed to fold away code paths that correspond to non-matching
325 // class ids. Otherwise LICM might potentially hoist incorrect code. 292 // class ids. Otherwise LICM might potentially hoist incorrect code.
326 const Object& value = instr->value()->definition()->constant_value(); 293 const Object& value = instr->value()->definition()->constant_value();
327 if (IsConstant(value) && !Field::IsExternalizableCid(value.GetClassId())) { 294 if (IsConstant(value) && !Field::IsExternalizableCid(value.GetClassId())) {
328 SetValue(instr, value); 295 SetValue(instr, value);
329 } else { 296 } else {
330 SetValue(instr, non_constant_); 297 SetValue(instr, non_constant_);
331 } 298 }
332 } 299 }
333 300
334
335 void ConstantPropagator::VisitParameter(ParameterInstr* instr) { 301 void ConstantPropagator::VisitParameter(ParameterInstr* instr) {
336 SetValue(instr, non_constant_); 302 SetValue(instr, non_constant_);
337 } 303 }
338 304
339
340 void ConstantPropagator::VisitPushArgument(PushArgumentInstr* instr) { 305 void ConstantPropagator::VisitPushArgument(PushArgumentInstr* instr) {
341 SetValue(instr, instr->value()->definition()->constant_value()); 306 SetValue(instr, instr->value()->definition()->constant_value());
342 } 307 }
343 308
344
345 void ConstantPropagator::VisitAssertAssignable(AssertAssignableInstr* instr) { 309 void ConstantPropagator::VisitAssertAssignable(AssertAssignableInstr* instr) {
346 const Object& value = instr->value()->definition()->constant_value(); 310 const Object& value = instr->value()->definition()->constant_value();
347 if (IsNonConstant(value)) { 311 if (IsNonConstant(value)) {
348 SetValue(instr, non_constant_); 312 SetValue(instr, non_constant_);
349 } else if (IsConstant(value)) { 313 } else if (IsConstant(value)) {
350 // We are ignoring the instantiator and instantiator_type_arguments, but 314 // We are ignoring the instantiator and instantiator_type_arguments, but
351 // still monotonic and safe. 315 // still monotonic and safe.
352 if (instr->value()->Type()->IsAssignableTo(instr->dst_type())) { 316 if (instr->value()->Type()->IsAssignableTo(instr->dst_type())) {
353 SetValue(instr, value); 317 SetValue(instr, value);
354 } else { 318 } else {
355 SetValue(instr, non_constant_); 319 SetValue(instr, non_constant_);
356 } 320 }
357 } 321 }
358 } 322 }
359 323
360
361 void ConstantPropagator::VisitAssertBoolean(AssertBooleanInstr* instr) { 324 void ConstantPropagator::VisitAssertBoolean(AssertBooleanInstr* instr) {
362 const Object& value = instr->value()->definition()->constant_value(); 325 const Object& value = instr->value()->definition()->constant_value();
363 if (IsNonConstant(value)) { 326 if (IsNonConstant(value)) {
364 SetValue(instr, non_constant_); 327 SetValue(instr, non_constant_);
365 } else if (IsConstant(value)) { 328 } else if (IsConstant(value)) {
366 if (value.IsBool()) { 329 if (value.IsBool()) {
367 SetValue(instr, value); 330 SetValue(instr, value);
368 } else { 331 } else {
369 SetValue(instr, non_constant_); 332 SetValue(instr, non_constant_);
370 } 333 }
371 } 334 }
372 } 335 }
373 336
374
375 void ConstantPropagator::VisitSpecialParameter(SpecialParameterInstr* instr) { 337 void ConstantPropagator::VisitSpecialParameter(SpecialParameterInstr* instr) {
376 SetValue(instr, non_constant_); 338 SetValue(instr, non_constant_);
377 } 339 }
378 340
379
380 void ConstantPropagator::VisitClosureCall(ClosureCallInstr* instr) { 341 void ConstantPropagator::VisitClosureCall(ClosureCallInstr* instr) {
381 SetValue(instr, non_constant_); 342 SetValue(instr, non_constant_);
382 } 343 }
383 344
384
385 void ConstantPropagator::VisitInstanceCall(InstanceCallInstr* instr) { 345 void ConstantPropagator::VisitInstanceCall(InstanceCallInstr* instr) {
386 SetValue(instr, non_constant_); 346 SetValue(instr, non_constant_);
387 } 347 }
388 348
389
390 void ConstantPropagator::VisitPolymorphicInstanceCall( 349 void ConstantPropagator::VisitPolymorphicInstanceCall(
391 PolymorphicInstanceCallInstr* instr) { 350 PolymorphicInstanceCallInstr* instr) {
392 SetValue(instr, non_constant_); 351 SetValue(instr, non_constant_);
393 } 352 }
394 353
395
396 void ConstantPropagator::VisitStaticCall(StaticCallInstr* instr) { 354 void ConstantPropagator::VisitStaticCall(StaticCallInstr* instr) {
397 SetValue(instr, non_constant_); 355 SetValue(instr, non_constant_);
398 } 356 }
399 357
400
401 void ConstantPropagator::VisitLoadLocal(LoadLocalInstr* instr) { 358 void ConstantPropagator::VisitLoadLocal(LoadLocalInstr* instr) {
402 // Instruction is eliminated when translating to SSA. 359 // Instruction is eliminated when translating to SSA.
403 UNREACHABLE(); 360 UNREACHABLE();
404 } 361 }
405 362
406
407 void ConstantPropagator::VisitDropTemps(DropTempsInstr* instr) { 363 void ConstantPropagator::VisitDropTemps(DropTempsInstr* instr) {
408 // Instruction is eliminated when translating to SSA. 364 // Instruction is eliminated when translating to SSA.
409 UNREACHABLE(); 365 UNREACHABLE();
410 } 366 }
411 367
412
413 void ConstantPropagator::VisitStoreLocal(StoreLocalInstr* instr) { 368 void ConstantPropagator::VisitStoreLocal(StoreLocalInstr* instr) {
414 // Instruction is eliminated when translating to SSA. 369 // Instruction is eliminated when translating to SSA.
415 UNREACHABLE(); 370 UNREACHABLE();
416 } 371 }
417 372
418
419 void ConstantPropagator::VisitIfThenElse(IfThenElseInstr* instr) { 373 void ConstantPropagator::VisitIfThenElse(IfThenElseInstr* instr) {
420 instr->comparison()->Accept(this); 374 instr->comparison()->Accept(this);
421 const Object& value = instr->comparison()->constant_value(); 375 const Object& value = instr->comparison()->constant_value();
422 if (IsNonConstant(value)) { 376 if (IsNonConstant(value)) {
423 SetValue(instr, non_constant_); 377 SetValue(instr, non_constant_);
424 } else if (IsConstant(value)) { 378 } else if (IsConstant(value)) {
425 ASSERT(!value.IsNull()); 379 ASSERT(!value.IsNull());
426 ASSERT(value.IsBool()); 380 ASSERT(value.IsBool());
427 bool result = Bool::Cast(value).value(); 381 bool result = Bool::Cast(value).value();
428 SetValue(instr, Smi::Handle(Z, Smi::New(result ? instr->if_true() 382 SetValue(instr, Smi::Handle(Z, Smi::New(result ? instr->if_true()
429 : instr->if_false()))); 383 : instr->if_false())));
430 } 384 }
431 } 385 }
432 386
433
434 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) { 387 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) {
435 Definition* left_defn = instr->left()->definition(); 388 Definition* left_defn = instr->left()->definition();
436 Definition* right_defn = instr->right()->definition(); 389 Definition* right_defn = instr->right()->definition();
437 390
438 Definition* unwrapped_left_defn = UnwrapPhi(left_defn); 391 Definition* unwrapped_left_defn = UnwrapPhi(left_defn);
439 Definition* unwrapped_right_defn = UnwrapPhi(right_defn); 392 Definition* unwrapped_right_defn = UnwrapPhi(right_defn);
440 if (unwrapped_left_defn == unwrapped_right_defn) { 393 if (unwrapped_left_defn == unwrapped_right_defn) {
441 // Fold x === x, and x !== x to true/false. 394 // Fold x === x, and x !== x to true/false.
442 SetValue(instr, Bool::Get(instr->kind() == Token::kEQ_STRICT)); 395 SetValue(instr, Bool::Get(instr->kind() == Token::kEQ_STRICT));
443 if (unwrapped_left_defn != left_defn) { 396 if (unwrapped_left_defn != left_defn) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 } 429 }
477 } else if (IsConstant(left) && IsConstant(right)) { 430 } else if (IsConstant(left) && IsConstant(right)) {
478 bool result = (left.raw() == right.raw()); 431 bool result = (left.raw() == right.raw());
479 if (instr->kind() == Token::kNE_STRICT) { 432 if (instr->kind() == Token::kNE_STRICT) {
480 result = !result; 433 result = !result;
481 } 434 }
482 SetValue(instr, Bool::Get(result)); 435 SetValue(instr, Bool::Get(result));
483 } 436 }
484 } 437 }
485 438
486
487 static bool CompareIntegers(Token::Kind kind, 439 static bool CompareIntegers(Token::Kind kind,
488 const Integer& left, 440 const Integer& left,
489 const Integer& right) { 441 const Integer& right) {
490 const int result = left.CompareWith(right); 442 const int result = left.CompareWith(right);
491 switch (kind) { 443 switch (kind) {
492 case Token::kEQ: 444 case Token::kEQ:
493 return (result == 0); 445 return (result == 0);
494 case Token::kNE: 446 case Token::kNE:
495 return (result != 0); 447 return (result != 0);
496 case Token::kLT: 448 case Token::kLT:
497 return (result < 0); 449 return (result < 0);
498 case Token::kGT: 450 case Token::kGT:
499 return (result > 0); 451 return (result > 0);
500 case Token::kLTE: 452 case Token::kLTE:
501 return (result <= 0); 453 return (result <= 0);
502 case Token::kGTE: 454 case Token::kGTE:
503 return (result >= 0); 455 return (result >= 0);
504 default: 456 default:
505 UNREACHABLE(); 457 UNREACHABLE();
506 return false; 458 return false;
507 } 459 }
508 } 460 }
509 461
510
511 // Comparison instruction that is equivalent to the (left & right) == 0 462 // Comparison instruction that is equivalent to the (left & right) == 0
512 // comparison pattern. 463 // comparison pattern.
513 void ConstantPropagator::VisitTestSmi(TestSmiInstr* instr) { 464 void ConstantPropagator::VisitTestSmi(TestSmiInstr* instr) {
514 const Object& left = instr->left()->definition()->constant_value(); 465 const Object& left = instr->left()->definition()->constant_value();
515 const Object& right = instr->right()->definition()->constant_value(); 466 const Object& right = instr->right()->definition()->constant_value();
516 if (IsNonConstant(left) || IsNonConstant(right)) { 467 if (IsNonConstant(left) || IsNonConstant(right)) {
517 SetValue(instr, non_constant_); 468 SetValue(instr, non_constant_);
518 } else if (IsConstant(left) && IsConstant(right)) { 469 } else if (IsConstant(left) && IsConstant(right)) {
519 // BitOp does not work on Bigints. 470 // BitOp does not work on Bigints.
520 if (left.IsInteger() && right.IsInteger() && !left.IsBigint() && 471 if (left.IsInteger() && right.IsInteger() && !left.IsBigint() &&
521 !right.IsBigint()) { 472 !right.IsBigint()) {
522 const bool result = CompareIntegers( 473 const bool result = CompareIntegers(
523 instr->kind(), 474 instr->kind(),
524 Integer::Handle(Z, Integer::Cast(left).BitOp(Token::kBIT_AND, 475 Integer::Handle(Z, Integer::Cast(left).BitOp(Token::kBIT_AND,
525 Integer::Cast(right))), 476 Integer::Cast(right))),
526 Smi::Handle(Z, Smi::New(0))); 477 Smi::Handle(Z, Smi::New(0)));
527 SetValue(instr, result ? Bool::True() : Bool::False()); 478 SetValue(instr, result ? Bool::True() : Bool::False());
528 } else { 479 } else {
529 SetValue(instr, non_constant_); 480 SetValue(instr, non_constant_);
530 } 481 }
531 } 482 }
532 } 483 }
533 484
534
535 void ConstantPropagator::VisitTestCids(TestCidsInstr* instr) { 485 void ConstantPropagator::VisitTestCids(TestCidsInstr* instr) {
536 // TODO(sra): Constant fold test. 486 // TODO(sra): Constant fold test.
537 SetValue(instr, non_constant_); 487 SetValue(instr, non_constant_);
538 } 488 }
539 489
540
541 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) { 490 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) {
542 Definition* left_defn = instr->left()->definition(); 491 Definition* left_defn = instr->left()->definition();
543 Definition* right_defn = instr->right()->definition(); 492 Definition* right_defn = instr->right()->definition();
544 493
545 if (RawObject::IsIntegerClassId(instr->operation_cid())) { 494 if (RawObject::IsIntegerClassId(instr->operation_cid())) {
546 // Fold x == x, and x != x to true/false for numbers comparisons. 495 // Fold x == x, and x != x to true/false for numbers comparisons.
547 Definition* unwrapped_left_defn = UnwrapPhi(left_defn); 496 Definition* unwrapped_left_defn = UnwrapPhi(left_defn);
548 Definition* unwrapped_right_defn = UnwrapPhi(right_defn); 497 Definition* unwrapped_right_defn = UnwrapPhi(right_defn);
549 if (unwrapped_left_defn == unwrapped_right_defn) { 498 if (unwrapped_left_defn == unwrapped_right_defn) {
550 // Fold x === x, and x !== x to true/false. 499 // Fold x === x, and x !== x to true/false.
(...skipping 19 matching lines...) Expand all
570 SetValue(instr, Bool::Get(result)); 519 SetValue(instr, Bool::Get(result));
571 } else if (left.IsString() && right.IsString()) { 520 } else if (left.IsString() && right.IsString()) {
572 const bool result = String::Cast(left).Equals(String::Cast(right)); 521 const bool result = String::Cast(left).Equals(String::Cast(right));
573 SetValue(instr, Bool::Get((instr->kind() == Token::kEQ) == result)); 522 SetValue(instr, Bool::Get((instr->kind() == Token::kEQ) == result));
574 } else { 523 } else {
575 SetValue(instr, non_constant_); 524 SetValue(instr, non_constant_);
576 } 525 }
577 } 526 }
578 } 527 }
579 528
580
581 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) { 529 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) {
582 const Object& left = instr->left()->definition()->constant_value(); 530 const Object& left = instr->left()->definition()->constant_value();
583 const Object& right = instr->right()->definition()->constant_value(); 531 const Object& right = instr->right()->definition()->constant_value();
584 if (IsNonConstant(left) || IsNonConstant(right)) { 532 if (IsNonConstant(left) || IsNonConstant(right)) {
585 SetValue(instr, non_constant_); 533 SetValue(instr, non_constant_);
586 } else if (IsConstant(left) && IsConstant(right)) { 534 } else if (IsConstant(left) && IsConstant(right)) {
587 if (left.IsInteger() && right.IsInteger()) { 535 if (left.IsInteger() && right.IsInteger()) {
588 const bool result = CompareIntegers(instr->kind(), Integer::Cast(left), 536 const bool result = CompareIntegers(instr->kind(), Integer::Cast(left),
589 Integer::Cast(right)); 537 Integer::Cast(right));
590 SetValue(instr, Bool::Get(result)); 538 SetValue(instr, Bool::Get(result));
591 } else if (left.IsDouble() && right.IsDouble()) { 539 } else if (left.IsDouble() && right.IsDouble()) {
592 // TODO(srdjan): Implement. 540 // TODO(srdjan): Implement.
593 SetValue(instr, non_constant_); 541 SetValue(instr, non_constant_);
594 } else { 542 } else {
595 SetValue(instr, non_constant_); 543 SetValue(instr, non_constant_);
596 } 544 }
597 } 545 }
598 } 546 }
599 547
600
601 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { 548 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) {
602 SetValue(instr, non_constant_); 549 SetValue(instr, non_constant_);
603 } 550 }
604 551
605
606 void ConstantPropagator::VisitDebugStepCheck(DebugStepCheckInstr* instr) { 552 void ConstantPropagator::VisitDebugStepCheck(DebugStepCheckInstr* instr) {
607 // Nothing to do. 553 // Nothing to do.
608 } 554 }
609 555
610
611 void ConstantPropagator::VisitOneByteStringFromCharCode( 556 void ConstantPropagator::VisitOneByteStringFromCharCode(
612 OneByteStringFromCharCodeInstr* instr) { 557 OneByteStringFromCharCodeInstr* instr) {
613 const Object& o = instr->char_code()->definition()->constant_value(); 558 const Object& o = instr->char_code()->definition()->constant_value();
614 if (o.IsNull() || IsNonConstant(o)) { 559 if (o.IsNull() || IsNonConstant(o)) {
615 SetValue(instr, non_constant_); 560 SetValue(instr, non_constant_);
616 } else if (IsConstant(o)) { 561 } else if (IsConstant(o)) {
617 const intptr_t ch_code = Smi::Cast(o).Value(); 562 const intptr_t ch_code = Smi::Cast(o).Value();
618 ASSERT(ch_code >= 0); 563 ASSERT(ch_code >= 0);
619 if (ch_code < Symbols::kMaxOneCharCodeSymbol) { 564 if (ch_code < Symbols::kMaxOneCharCodeSymbol) {
620 RawString** table = Symbols::PredefinedAddress(); 565 RawString** table = Symbols::PredefinedAddress();
621 SetValue(instr, String::ZoneHandle(Z, table[ch_code])); 566 SetValue(instr, String::ZoneHandle(Z, table[ch_code]));
622 } else { 567 } else {
623 SetValue(instr, non_constant_); 568 SetValue(instr, non_constant_);
624 } 569 }
625 } 570 }
626 } 571 }
627 572
628
629 void ConstantPropagator::VisitStringToCharCode(StringToCharCodeInstr* instr) { 573 void ConstantPropagator::VisitStringToCharCode(StringToCharCodeInstr* instr) {
630 const Object& o = instr->str()->definition()->constant_value(); 574 const Object& o = instr->str()->definition()->constant_value();
631 if (o.IsNull() || IsNonConstant(o)) { 575 if (o.IsNull() || IsNonConstant(o)) {
632 SetValue(instr, non_constant_); 576 SetValue(instr, non_constant_);
633 } else if (IsConstant(o)) { 577 } else if (IsConstant(o)) {
634 const String& str = String::Cast(o); 578 const String& str = String::Cast(o);
635 const intptr_t result = 579 const intptr_t result =
636 (str.Length() == 1) ? static_cast<intptr_t>(str.CharAt(0)) : -1; 580 (str.Length() == 1) ? static_cast<intptr_t>(str.CharAt(0)) : -1;
637 SetValue(instr, Smi::ZoneHandle(Z, Smi::New(result))); 581 SetValue(instr, Smi::ZoneHandle(Z, Smi::New(result)));
638 } 582 }
639 } 583 }
640 584
641
642 void ConstantPropagator::VisitStringInterpolate(StringInterpolateInstr* instr) { 585 void ConstantPropagator::VisitStringInterpolate(StringInterpolateInstr* instr) {
643 SetValue(instr, non_constant_); 586 SetValue(instr, non_constant_);
644 } 587 }
645 588
646
647 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { 589 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) {
648 const Object& array_obj = instr->array()->definition()->constant_value(); 590 const Object& array_obj = instr->array()->definition()->constant_value();
649 const Object& index_obj = instr->index()->definition()->constant_value(); 591 const Object& index_obj = instr->index()->definition()->constant_value();
650 if (IsNonConstant(array_obj) || IsNonConstant(index_obj)) { 592 if (IsNonConstant(array_obj) || IsNonConstant(index_obj)) {
651 SetValue(instr, non_constant_); 593 SetValue(instr, non_constant_);
652 } else if (IsConstant(array_obj) && IsConstant(index_obj)) { 594 } else if (IsConstant(array_obj) && IsConstant(index_obj)) {
653 // Need index to be Smi and array to be either String or an immutable array. 595 // Need index to be Smi and array to be either String or an immutable array.
654 if (!index_obj.IsSmi()) { 596 if (!index_obj.IsSmi()) {
655 // Should not occur. 597 // Should not occur.
656 SetValue(instr, non_constant_); 598 SetValue(instr, non_constant_);
(...skipping 16 matching lines...) Expand all
673 result ^= a.At(index); 615 result ^= a.At(index);
674 SetValue(instr, result); 616 SetValue(instr, result);
675 return; 617 return;
676 } 618 }
677 } 619 }
678 } 620 }
679 SetValue(instr, non_constant_); 621 SetValue(instr, non_constant_);
680 } 622 }
681 } 623 }
682 624
683
684 void ConstantPropagator::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { 625 void ConstantPropagator::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) {
685 // TODO(zerny): Implement constant propagation. 626 // TODO(zerny): Implement constant propagation.
686 SetValue(instr, non_constant_); 627 SetValue(instr, non_constant_);
687 } 628 }
688 629
689
690 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { 630 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {
691 SetValue(instr, instr->value()->definition()->constant_value()); 631 SetValue(instr, instr->value()->definition()->constant_value());
692 } 632 }
693 633
694
695 void ConstantPropagator::VisitStoreInstanceField( 634 void ConstantPropagator::VisitStoreInstanceField(
696 StoreInstanceFieldInstr* instr) { 635 StoreInstanceFieldInstr* instr) {
697 SetValue(instr, instr->value()->definition()->constant_value()); 636 SetValue(instr, instr->value()->definition()->constant_value());
698 } 637 }
699 638
700
701 void ConstantPropagator::VisitInitStaticField(InitStaticFieldInstr* instr) { 639 void ConstantPropagator::VisitInitStaticField(InitStaticFieldInstr* instr) {
702 // Nothing to do. 640 // Nothing to do.
703 } 641 }
704 642
705
706 void ConstantPropagator::VisitLoadStaticField(LoadStaticFieldInstr* instr) { 643 void ConstantPropagator::VisitLoadStaticField(LoadStaticFieldInstr* instr) {
707 if (!FLAG_fields_may_be_reset) { 644 if (!FLAG_fields_may_be_reset) {
708 const Field& field = instr->StaticField(); 645 const Field& field = instr->StaticField();
709 ASSERT(field.is_static()); 646 ASSERT(field.is_static());
710 Instance& obj = Instance::Handle(Z, field.StaticValue()); 647 Instance& obj = Instance::Handle(Z, field.StaticValue());
711 if (field.is_final() && (obj.raw() != Object::sentinel().raw()) && 648 if (field.is_final() && (obj.raw() != Object::sentinel().raw()) &&
712 (obj.raw() != Object::transition_sentinel().raw())) { 649 (obj.raw() != Object::transition_sentinel().raw())) {
713 if (obj.IsSmi() || obj.IsOld()) { 650 if (obj.IsSmi() || obj.IsOld()) {
714 SetValue(instr, obj); 651 SetValue(instr, obj);
715 return; 652 return;
716 } 653 }
717 } 654 }
718 } 655 }
719 SetValue(instr, non_constant_); 656 SetValue(instr, non_constant_);
720 } 657 }
721 658
722
723 void ConstantPropagator::VisitStoreStaticField(StoreStaticFieldInstr* instr) { 659 void ConstantPropagator::VisitStoreStaticField(StoreStaticFieldInstr* instr) {
724 SetValue(instr, instr->value()->definition()->constant_value()); 660 SetValue(instr, instr->value()->definition()->constant_value());
725 } 661 }
726 662
727
728 void ConstantPropagator::VisitBooleanNegate(BooleanNegateInstr* instr) { 663 void ConstantPropagator::VisitBooleanNegate(BooleanNegateInstr* instr) {
729 const Object& value = instr->value()->definition()->constant_value(); 664 const Object& value = instr->value()->definition()->constant_value();
730 if (IsNonConstant(value)) { 665 if (IsNonConstant(value)) {
731 SetValue(instr, non_constant_); 666 SetValue(instr, non_constant_);
732 } else if (IsConstant(value)) { 667 } else if (IsConstant(value)) {
733 bool val = value.raw() != Bool::True().raw(); 668 bool val = value.raw() != Bool::True().raw();
734 SetValue(instr, Bool::Get(val)); 669 SetValue(instr, Bool::Get(val));
735 } 670 }
736 } 671 }
737 672
738
739 void ConstantPropagator::VisitInstanceOf(InstanceOfInstr* instr) { 673 void ConstantPropagator::VisitInstanceOf(InstanceOfInstr* instr) {
740 Definition* def = instr->value()->definition(); 674 Definition* def = instr->value()->definition();
741 const Object& value = def->constant_value(); 675 const Object& value = def->constant_value();
742 if (IsNonConstant(value)) { 676 if (IsNonConstant(value)) {
743 const AbstractType& checked_type = instr->type(); 677 const AbstractType& checked_type = instr->type();
744 intptr_t value_cid = instr->value()->definition()->Type()->ToCid(); 678 intptr_t value_cid = instr->value()->definition()->Type()->ToCid();
745 Representation rep = def->representation(); 679 Representation rep = def->representation();
746 if ((checked_type.IsFloat32x4Type() && (rep == kUnboxedFloat32x4)) || 680 if ((checked_type.IsFloat32x4Type() && (rep == kUnboxedFloat32x4)) ||
747 (checked_type.IsInt32x4Type() && (rep == kUnboxedInt32x4)) || 681 (checked_type.IsInt32x4Type() && (rep == kUnboxedInt32x4)) ||
748 (checked_type.IsDoubleType() && (rep == kUnboxedDouble) && 682 (checked_type.IsDoubleType() && (rep == kUnboxedDouble) &&
(...skipping 22 matching lines...) Expand all
771 // Can only have bound error with generics. 705 // Can only have bound error with generics.
772 ASSERT(bound_error.IsNull()); 706 ASSERT(bound_error.IsNull());
773 SetValue(instr, Bool::Get(is_instance)); 707 SetValue(instr, Bool::Get(is_instance));
774 return; 708 return;
775 } 709 }
776 } 710 }
777 SetValue(instr, non_constant_); 711 SetValue(instr, non_constant_);
778 } 712 }
779 } 713 }
780 714
781
782 void ConstantPropagator::VisitCreateArray(CreateArrayInstr* instr) { 715 void ConstantPropagator::VisitCreateArray(CreateArrayInstr* instr) {
783 SetValue(instr, non_constant_); 716 SetValue(instr, non_constant_);
784 } 717 }
785 718
786
787 void ConstantPropagator::VisitAllocateObject(AllocateObjectInstr* instr) { 719 void ConstantPropagator::VisitAllocateObject(AllocateObjectInstr* instr) {
788 SetValue(instr, non_constant_); 720 SetValue(instr, non_constant_);
789 } 721 }
790 722
791
792 void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) { 723 void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) {
793 SetValue(instr, non_constant_); 724 SetValue(instr, non_constant_);
794 } 725 }
795 726
796
797 void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) { 727 void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) {
798 intptr_t cid = instr->object()->Type()->ToCid(); 728 intptr_t cid = instr->object()->Type()->ToCid();
799 if (cid != kDynamicCid) { 729 if (cid != kDynamicCid) {
800 SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid))); 730 SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid)));
801 return; 731 return;
802 } 732 }
803 733
804 const Object& object = instr->object()->definition()->constant_value(); 734 const Object& object = instr->object()->definition()->constant_value();
805 if (IsConstant(object)) { 735 if (IsConstant(object)) {
806 cid = object.GetClassId(); 736 cid = object.GetClassId();
807 if (!Field::IsExternalizableCid(cid)) { 737 if (!Field::IsExternalizableCid(cid)) {
808 SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid))); 738 SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid)));
809 return; 739 return;
810 } 740 }
811 } 741 }
812 SetValue(instr, non_constant_); 742 SetValue(instr, non_constant_);
813 } 743 }
814 744
815
816 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { 745 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) {
817 Value* instance = instr->instance(); 746 Value* instance = instr->instance();
818 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && 747 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) &&
819 instance->definition()->OriginalDefinition()->IsCreateArray()) { 748 instance->definition()->OriginalDefinition()->IsCreateArray()) {
820 Value* num_elements = instance->definition() 749 Value* num_elements = instance->definition()
821 ->OriginalDefinition() 750 ->OriginalDefinition()
822 ->AsCreateArray() 751 ->AsCreateArray()
823 ->num_elements(); 752 ->num_elements();
824 if (num_elements->BindsToConstant() && 753 if (num_elements->BindsToConstant() &&
825 num_elements->BoundConstant().IsSmi()) { 754 num_elements->BoundConstant().IsSmi()) {
(...skipping 27 matching lines...) Expand all
853 if (instr->Evaluate(constant, &value)) { 782 if (instr->Evaluate(constant, &value)) {
854 SetValue(instr, Object::ZoneHandle(Z, value.raw())); 783 SetValue(instr, Object::ZoneHandle(Z, value.raw()));
855 return; 784 return;
856 } 785 }
857 } 786 }
858 } 787 }
859 788
860 SetValue(instr, non_constant_); 789 SetValue(instr, non_constant_);
861 } 790 }
862 791
863
864 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) { 792 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) {
865 const Object& object = 793 const Object& object =
866 instr->instantiator_type_arguments()->definition()->constant_value(); 794 instr->instantiator_type_arguments()->definition()->constant_value();
867 if (IsNonConstant(object)) { 795 if (IsNonConstant(object)) {
868 SetValue(instr, non_constant_); 796 SetValue(instr, non_constant_);
869 return; 797 return;
870 } 798 }
871 if (IsConstant(object)) { 799 if (IsConstant(object)) {
872 if (instr->type().IsTypeParameter() && 800 if (instr->type().IsTypeParameter() &&
873 TypeParameter::Cast(instr->type()).IsClassTypeParameter()) { 801 TypeParameter::Cast(instr->type()).IsClassTypeParameter()) {
874 if (object.IsNull()) { 802 if (object.IsNull()) {
875 SetValue(instr, Object::dynamic_type()); 803 SetValue(instr, Object::dynamic_type());
876 return; 804 return;
877 } 805 }
878 // We could try to instantiate the type parameter and return it if no 806 // We could try to instantiate the type parameter and return it if no
879 // malformed error is reported. 807 // malformed error is reported.
880 } 808 }
881 SetValue(instr, non_constant_); 809 SetValue(instr, non_constant_);
882 } 810 }
883 // TODO(regis): We can do the same as above for a function type parameter. 811 // TODO(regis): We can do the same as above for a function type parameter.
884 // Better: If both instantiator type arguments and function type arguments are 812 // Better: If both instantiator type arguments and function type arguments are
885 // constant, instantiate the type if no bound error is reported. 813 // constant, instantiate the type if no bound error is reported.
886 } 814 }
887 815
888
889 void ConstantPropagator::VisitInstantiateTypeArguments( 816 void ConstantPropagator::VisitInstantiateTypeArguments(
890 InstantiateTypeArgumentsInstr* instr) { 817 InstantiateTypeArgumentsInstr* instr) {
891 const Object& instantiator_type_args = 818 const Object& instantiator_type_args =
892 instr->instantiator_type_arguments()->definition()->constant_value(); 819 instr->instantiator_type_arguments()->definition()->constant_value();
893 const Object& function_type_args = 820 const Object& function_type_args =
894 instr->function_type_arguments()->definition()->constant_value(); 821 instr->function_type_arguments()->definition()->constant_value();
895 if (IsNonConstant(instantiator_type_args) || 822 if (IsNonConstant(instantiator_type_args) ||
896 IsNonConstant(function_type_args)) { 823 IsNonConstant(function_type_args)) {
897 SetValue(instr, non_constant_); 824 SetValue(instr, non_constant_);
898 return; 825 return;
(...skipping 16 matching lines...) Expand all
915 } 842 }
916 // TODO(regis): If both instantiator type arguments and function type 843 // TODO(regis): If both instantiator type arguments and function type
917 // arguments are constant, instantiate the type arguments if no bound error 844 // arguments are constant, instantiate the type arguments if no bound error
918 // is reported. 845 // is reported.
919 // TODO(regis): If either instantiator type arguments or function type 846 // TODO(regis): If either instantiator type arguments or function type
920 // arguments are constant null, check 847 // arguments are constant null, check
921 // type_arguments().IsRawWhenInstantiatedFromRaw() separately for each 848 // type_arguments().IsRawWhenInstantiatedFromRaw() separately for each
922 // genericity. 849 // genericity.
923 } 850 }
924 851
925
926 void ConstantPropagator::VisitAllocateContext(AllocateContextInstr* instr) { 852 void ConstantPropagator::VisitAllocateContext(AllocateContextInstr* instr) {
927 SetValue(instr, non_constant_); 853 SetValue(instr, non_constant_);
928 } 854 }
929 855
930
931 void ConstantPropagator::VisitAllocateUninitializedContext( 856 void ConstantPropagator::VisitAllocateUninitializedContext(
932 AllocateUninitializedContextInstr* instr) { 857 AllocateUninitializedContextInstr* instr) {
933 SetValue(instr, non_constant_); 858 SetValue(instr, non_constant_);
934 } 859 }
935 860
936
937 void ConstantPropagator::VisitCloneContext(CloneContextInstr* instr) { 861 void ConstantPropagator::VisitCloneContext(CloneContextInstr* instr) {
938 SetValue(instr, non_constant_); 862 SetValue(instr, non_constant_);
939 } 863 }
940 864
941
942 void ConstantPropagator::VisitBinaryIntegerOp(BinaryIntegerOpInstr* binary_op) { 865 void ConstantPropagator::VisitBinaryIntegerOp(BinaryIntegerOpInstr* binary_op) {
943 const Object& left = binary_op->left()->definition()->constant_value(); 866 const Object& left = binary_op->left()->definition()->constant_value();
944 const Object& right = binary_op->right()->definition()->constant_value(); 867 const Object& right = binary_op->right()->definition()->constant_value();
945 if (IsConstant(left) && IsConstant(right)) { 868 if (IsConstant(left) && IsConstant(right)) {
946 if (left.IsInteger() && right.IsInteger()) { 869 if (left.IsInteger() && right.IsInteger()) {
947 const Integer& left_int = Integer::Cast(left); 870 const Integer& left_int = Integer::Cast(left);
948 const Integer& right_int = Integer::Cast(right); 871 const Integer& right_int = Integer::Cast(right);
949 const Integer& result = 872 const Integer& result =
950 Integer::Handle(Z, binary_op->Evaluate(left_int, right_int)); 873 Integer::Handle(Z, binary_op->Evaluate(left_int, right_int));
951 if (!result.IsNull()) { 874 if (!result.IsNull()) {
952 SetValue(binary_op, Integer::ZoneHandle(Z, result.raw())); 875 SetValue(binary_op, Integer::ZoneHandle(Z, result.raw()));
953 return; 876 return;
954 } 877 }
955 } 878 }
956 } 879 }
957 880
958 SetValue(binary_op, non_constant_); 881 SetValue(binary_op, non_constant_);
959 } 882 }
960 883
961
962 void ConstantPropagator::VisitCheckedSmiOp(CheckedSmiOpInstr* instr) { 884 void ConstantPropagator::VisitCheckedSmiOp(CheckedSmiOpInstr* instr) {
963 SetValue(instr, non_constant_); 885 SetValue(instr, non_constant_);
964 } 886 }
965 887
966
967 void ConstantPropagator::VisitCheckedSmiComparison( 888 void ConstantPropagator::VisitCheckedSmiComparison(
968 CheckedSmiComparisonInstr* instr) { 889 CheckedSmiComparisonInstr* instr) {
969 SetValue(instr, non_constant_); 890 SetValue(instr, non_constant_);
970 } 891 }
971 892
972
973 void ConstantPropagator::VisitBinarySmiOp(BinarySmiOpInstr* instr) { 893 void ConstantPropagator::VisitBinarySmiOp(BinarySmiOpInstr* instr) {
974 VisitBinaryIntegerOp(instr); 894 VisitBinaryIntegerOp(instr);
975 } 895 }
976 896
977
978 void ConstantPropagator::VisitBinaryInt32Op(BinaryInt32OpInstr* instr) { 897 void ConstantPropagator::VisitBinaryInt32Op(BinaryInt32OpInstr* instr) {
979 VisitBinaryIntegerOp(instr); 898 VisitBinaryIntegerOp(instr);
980 } 899 }
981 900
982
983 void ConstantPropagator::VisitBinaryUint32Op(BinaryUint32OpInstr* instr) { 901 void ConstantPropagator::VisitBinaryUint32Op(BinaryUint32OpInstr* instr) {
984 VisitBinaryIntegerOp(instr); 902 VisitBinaryIntegerOp(instr);
985 } 903 }
986 904
987
988 void ConstantPropagator::VisitShiftUint32Op(ShiftUint32OpInstr* instr) { 905 void ConstantPropagator::VisitShiftUint32Op(ShiftUint32OpInstr* instr) {
989 VisitBinaryIntegerOp(instr); 906 VisitBinaryIntegerOp(instr);
990 } 907 }
991 908
992
993 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) { 909 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) {
994 VisitBinaryIntegerOp(instr); 910 VisitBinaryIntegerOp(instr);
995 } 911 }
996 912
997
998 void ConstantPropagator::VisitShiftMintOp(ShiftMintOpInstr* instr) { 913 void ConstantPropagator::VisitShiftMintOp(ShiftMintOpInstr* instr) {
999 VisitBinaryIntegerOp(instr); 914 VisitBinaryIntegerOp(instr);
1000 } 915 }
1001 916
1002
1003 void ConstantPropagator::VisitBoxInt64(BoxInt64Instr* instr) { 917 void ConstantPropagator::VisitBoxInt64(BoxInt64Instr* instr) {
1004 // TODO(kmillikin): Handle box operation. 918 // TODO(kmillikin): Handle box operation.
1005 SetValue(instr, non_constant_); 919 SetValue(instr, non_constant_);
1006 } 920 }
1007 921
1008
1009 void ConstantPropagator::VisitUnboxInt64(UnboxInt64Instr* instr) { 922 void ConstantPropagator::VisitUnboxInt64(UnboxInt64Instr* instr) {
1010 // TODO(kmillikin): Handle unbox operation. 923 // TODO(kmillikin): Handle unbox operation.
1011 SetValue(instr, non_constant_); 924 SetValue(instr, non_constant_);
1012 } 925 }
1013 926
1014
1015 void ConstantPropagator::VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op) { 927 void ConstantPropagator::VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op) {
1016 const Object& value = unary_op->value()->definition()->constant_value(); 928 const Object& value = unary_op->value()->definition()->constant_value();
1017 if (IsConstant(value) && value.IsInteger()) { 929 if (IsConstant(value) && value.IsInteger()) {
1018 const Integer& value_int = Integer::Cast(value); 930 const Integer& value_int = Integer::Cast(value);
1019 const Integer& result = Integer::Handle(Z, unary_op->Evaluate(value_int)); 931 const Integer& result = Integer::Handle(Z, unary_op->Evaluate(value_int));
1020 if (!result.IsNull()) { 932 if (!result.IsNull()) {
1021 SetValue(unary_op, Integer::ZoneHandle(Z, result.raw())); 933 SetValue(unary_op, Integer::ZoneHandle(Z, result.raw()));
1022 return; 934 return;
1023 } 935 }
1024 } 936 }
1025 937
1026 SetValue(unary_op, non_constant_); 938 SetValue(unary_op, non_constant_);
1027 } 939 }
1028 940
1029
1030 void ConstantPropagator::VisitUnaryMintOp(UnaryMintOpInstr* instr) { 941 void ConstantPropagator::VisitUnaryMintOp(UnaryMintOpInstr* instr) {
1031 VisitUnaryIntegerOp(instr); 942 VisitUnaryIntegerOp(instr);
1032 } 943 }
1033 944
1034
1035 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) { 945 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) {
1036 VisitUnaryIntegerOp(instr); 946 VisitUnaryIntegerOp(instr);
1037 } 947 }
1038 948
1039
1040 void ConstantPropagator::VisitUnaryDoubleOp(UnaryDoubleOpInstr* instr) { 949 void ConstantPropagator::VisitUnaryDoubleOp(UnaryDoubleOpInstr* instr) {
1041 const Object& value = instr->value()->definition()->constant_value(); 950 const Object& value = instr->value()->definition()->constant_value();
1042 if (IsNonConstant(value)) { 951 if (IsNonConstant(value)) {
1043 SetValue(instr, non_constant_); 952 SetValue(instr, non_constant_);
1044 } else if (IsConstant(value)) { 953 } else if (IsConstant(value)) {
1045 // TODO(kmillikin): Handle unary operations. 954 // TODO(kmillikin): Handle unary operations.
1046 SetValue(instr, non_constant_); 955 SetValue(instr, non_constant_);
1047 } 956 }
1048 } 957 }
1049 958
1050
1051 void ConstantPropagator::VisitSmiToDouble(SmiToDoubleInstr* instr) { 959 void ConstantPropagator::VisitSmiToDouble(SmiToDoubleInstr* instr) {
1052 const Object& value = instr->value()->definition()->constant_value(); 960 const Object& value = instr->value()->definition()->constant_value();
1053 if (IsConstant(value) && value.IsInteger()) { 961 if (IsConstant(value) && value.IsInteger()) {
1054 SetValue(instr, 962 SetValue(instr,
1055 Double::Handle(Z, Double::New(Integer::Cast(value).AsDoubleValue(), 963 Double::Handle(Z, Double::New(Integer::Cast(value).AsDoubleValue(),
1056 Heap::kOld))); 964 Heap::kOld)));
1057 } else if (!IsUnknown(value)) { 965 } else if (!IsUnknown(value)) {
1058 SetValue(instr, non_constant_); 966 SetValue(instr, non_constant_);
1059 } 967 }
1060 } 968 }
1061 969
1062
1063 void ConstantPropagator::VisitMintToDouble(MintToDoubleInstr* instr) { 970 void ConstantPropagator::VisitMintToDouble(MintToDoubleInstr* instr) {
1064 const Object& value = instr->value()->definition()->constant_value(); 971 const Object& value = instr->value()->definition()->constant_value();
1065 if (IsConstant(value) && value.IsInteger()) { 972 if (IsConstant(value) && value.IsInteger()) {
1066 SetValue(instr, 973 SetValue(instr,
1067 Double::Handle(Z, Double::New(Integer::Cast(value).AsDoubleValue(), 974 Double::Handle(Z, Double::New(Integer::Cast(value).AsDoubleValue(),
1068 Heap::kOld))); 975 Heap::kOld)));
1069 } else if (!IsUnknown(value)) { 976 } else if (!IsUnknown(value)) {
1070 SetValue(instr, non_constant_); 977 SetValue(instr, non_constant_);
1071 } 978 }
1072 } 979 }
1073 980
1074
1075 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) { 981 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) {
1076 const Object& value = instr->value()->definition()->constant_value(); 982 const Object& value = instr->value()->definition()->constant_value();
1077 if (IsConstant(value) && value.IsInteger()) { 983 if (IsConstant(value) && value.IsInteger()) {
1078 SetValue(instr, 984 SetValue(instr,
1079 Double::Handle(Z, Double::New(Integer::Cast(value).AsDoubleValue(), 985 Double::Handle(Z, Double::New(Integer::Cast(value).AsDoubleValue(),
1080 Heap::kOld))); 986 Heap::kOld)));
1081 } else if (!IsUnknown(value)) { 987 } else if (!IsUnknown(value)) {
1082 SetValue(instr, non_constant_); 988 SetValue(instr, non_constant_);
1083 } 989 }
1084 } 990 }
1085 991
1086
1087 void ConstantPropagator::VisitDoubleToInteger(DoubleToIntegerInstr* instr) { 992 void ConstantPropagator::VisitDoubleToInteger(DoubleToIntegerInstr* instr) {
1088 // TODO(kmillikin): Handle conversion. 993 // TODO(kmillikin): Handle conversion.
1089 SetValue(instr, non_constant_); 994 SetValue(instr, non_constant_);
1090 } 995 }
1091 996
1092
1093 void ConstantPropagator::VisitDoubleToSmi(DoubleToSmiInstr* instr) { 997 void ConstantPropagator::VisitDoubleToSmi(DoubleToSmiInstr* instr) {
1094 // TODO(kmillikin): Handle conversion. 998 // TODO(kmillikin): Handle conversion.
1095 SetValue(instr, non_constant_); 999 SetValue(instr, non_constant_);
1096 } 1000 }
1097 1001
1098
1099 void ConstantPropagator::VisitDoubleToDouble(DoubleToDoubleInstr* instr) { 1002 void ConstantPropagator::VisitDoubleToDouble(DoubleToDoubleInstr* instr) {
1100 // TODO(kmillikin): Handle conversion. 1003 // TODO(kmillikin): Handle conversion.
1101 SetValue(instr, non_constant_); 1004 SetValue(instr, non_constant_);
1102 } 1005 }
1103 1006
1104
1105 void ConstantPropagator::VisitDoubleToFloat(DoubleToFloatInstr* instr) { 1007 void ConstantPropagator::VisitDoubleToFloat(DoubleToFloatInstr* instr) {
1106 // TODO(kmillikin): Handle conversion. 1008 // TODO(kmillikin): Handle conversion.
1107 SetValue(instr, non_constant_); 1009 SetValue(instr, non_constant_);
1108 } 1010 }
1109 1011
1110
1111 void ConstantPropagator::VisitFloatToDouble(FloatToDoubleInstr* instr) { 1012 void ConstantPropagator::VisitFloatToDouble(FloatToDoubleInstr* instr) {
1112 // TODO(kmillikin): Handle conversion. 1013 // TODO(kmillikin): Handle conversion.
1113 SetValue(instr, non_constant_); 1014 SetValue(instr, non_constant_);
1114 } 1015 }
1115 1016
1116
1117 void ConstantPropagator::VisitInvokeMathCFunction( 1017 void ConstantPropagator::VisitInvokeMathCFunction(
1118 InvokeMathCFunctionInstr* instr) { 1018 InvokeMathCFunctionInstr* instr) {
1119 // TODO(kmillikin): Handle conversion. 1019 // TODO(kmillikin): Handle conversion.
1120 SetValue(instr, non_constant_); 1020 SetValue(instr, non_constant_);
1121 } 1021 }
1122 1022
1123
1124 void ConstantPropagator::VisitTruncDivMod(TruncDivModInstr* instr) { 1023 void ConstantPropagator::VisitTruncDivMod(TruncDivModInstr* instr) {
1125 // TODO(srdjan): Handle merged instruction. 1024 // TODO(srdjan): Handle merged instruction.
1126 SetValue(instr, non_constant_); 1025 SetValue(instr, non_constant_);
1127 } 1026 }
1128 1027
1129
1130 void ConstantPropagator::VisitExtractNthOutput(ExtractNthOutputInstr* instr) { 1028 void ConstantPropagator::VisitExtractNthOutput(ExtractNthOutputInstr* instr) {
1131 SetValue(instr, non_constant_); 1029 SetValue(instr, non_constant_);
1132 } 1030 }
1133 1031
1134
1135 void ConstantPropagator::VisitConstant(ConstantInstr* instr) { 1032 void ConstantPropagator::VisitConstant(ConstantInstr* instr) {
1136 SetValue(instr, instr->value()); 1033 SetValue(instr, instr->value());
1137 } 1034 }
1138 1035
1139
1140 void ConstantPropagator::VisitUnboxedConstant(UnboxedConstantInstr* instr) { 1036 void ConstantPropagator::VisitUnboxedConstant(UnboxedConstantInstr* instr) {
1141 SetValue(instr, instr->value()); 1037 SetValue(instr, instr->value());
1142 } 1038 }
1143 1039
1144
1145 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) { 1040 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) {
1146 // Should not be used outside of range analysis. 1041 // Should not be used outside of range analysis.
1147 UNREACHABLE(); 1042 UNREACHABLE();
1148 } 1043 }
1149 1044
1150
1151 void ConstantPropagator::VisitMaterializeObject(MaterializeObjectInstr* instr) { 1045 void ConstantPropagator::VisitMaterializeObject(MaterializeObjectInstr* instr) {
1152 // Should not be used outside of allocation elimination pass. 1046 // Should not be used outside of allocation elimination pass.
1153 UNREACHABLE(); 1047 UNREACHABLE();
1154 } 1048 }
1155 1049
1156
1157 static bool IsIntegerOrDouble(const Object& value) { 1050 static bool IsIntegerOrDouble(const Object& value) {
1158 return value.IsInteger() || value.IsDouble(); 1051 return value.IsInteger() || value.IsDouble();
1159 } 1052 }
1160 1053
1161
1162 static double ToDouble(const Object& value) { 1054 static double ToDouble(const Object& value) {
1163 return value.IsInteger() ? Integer::Cast(value).AsDoubleValue() 1055 return value.IsInteger() ? Integer::Cast(value).AsDoubleValue()
1164 : Double::Cast(value).value(); 1056 : Double::Cast(value).value();
1165 } 1057 }
1166 1058
1167
1168 void ConstantPropagator::VisitBinaryDoubleOp(BinaryDoubleOpInstr* instr) { 1059 void ConstantPropagator::VisitBinaryDoubleOp(BinaryDoubleOpInstr* instr) {
1169 const Object& left = instr->left()->definition()->constant_value(); 1060 const Object& left = instr->left()->definition()->constant_value();
1170 const Object& right = instr->right()->definition()->constant_value(); 1061 const Object& right = instr->right()->definition()->constant_value();
1171 if (IsNonConstant(left) || IsNonConstant(right)) { 1062 if (IsNonConstant(left) || IsNonConstant(right)) {
1172 SetValue(instr, non_constant_); 1063 SetValue(instr, non_constant_);
1173 } else if (left.IsInteger() && right.IsInteger()) { 1064 } else if (left.IsInteger() && right.IsInteger()) {
1174 SetValue(instr, non_constant_); 1065 SetValue(instr, non_constant_);
1175 } else if (IsIntegerOrDouble(left) && IsIntegerOrDouble(right)) { 1066 } else if (IsIntegerOrDouble(left) && IsIntegerOrDouble(right)) {
1176 const double left_val = ToDouble(left); 1067 const double left_val = ToDouble(left);
1177 const double right_val = ToDouble(right); 1068 const double right_val = ToDouble(right);
(...skipping 12 matching lines...) Expand all
1190 result_val = left_val / right_val; 1081 result_val = left_val / right_val;
1191 break; 1082 break;
1192 default: 1083 default:
1193 UNREACHABLE(); 1084 UNREACHABLE();
1194 } 1085 }
1195 const Double& result = Double::ZoneHandle(Double::NewCanonical(result_val)); 1086 const Double& result = Double::ZoneHandle(Double::NewCanonical(result_val));
1196 SetValue(instr, result); 1087 SetValue(instr, result);
1197 } 1088 }
1198 } 1089 }
1199 1090
1200
1201 void ConstantPropagator::VisitDoubleTestOp(DoubleTestOpInstr* instr) { 1091 void ConstantPropagator::VisitDoubleTestOp(DoubleTestOpInstr* instr) {
1202 const Object& value = instr->value()->definition()->constant_value(); 1092 const Object& value = instr->value()->definition()->constant_value();
1203 const bool is_negated = instr->kind() != Token::kEQ; 1093 const bool is_negated = instr->kind() != Token::kEQ;
1204 if (value.IsInteger()) { 1094 if (value.IsInteger()) {
1205 SetValue(instr, is_negated ? Bool::True() : Bool::False()); 1095 SetValue(instr, is_negated ? Bool::True() : Bool::False());
1206 } else if (IsIntegerOrDouble(value)) { 1096 } else if (IsIntegerOrDouble(value)) {
1207 switch (instr->op_kind()) { 1097 switch (instr->op_kind()) {
1208 case MethodRecognizer::kDouble_getIsNaN: { 1098 case MethodRecognizer::kDouble_getIsNaN: {
1209 const bool is_nan = isnan(ToDouble(value)); 1099 const bool is_nan = isnan(ToDouble(value));
1210 SetValue(instr, Bool::Get(is_negated ? !is_nan : is_nan)); 1100 SetValue(instr, Bool::Get(is_negated ? !is_nan : is_nan));
1211 break; 1101 break;
1212 } 1102 }
1213 case MethodRecognizer::kDouble_getIsInfinite: { 1103 case MethodRecognizer::kDouble_getIsInfinite: {
1214 const bool is_inf = isinf(ToDouble(value)); 1104 const bool is_inf = isinf(ToDouble(value));
1215 SetValue(instr, Bool::Get(is_negated ? !is_inf : is_inf)); 1105 SetValue(instr, Bool::Get(is_negated ? !is_inf : is_inf));
1216 break; 1106 break;
1217 } 1107 }
1218 default: 1108 default:
1219 UNREACHABLE(); 1109 UNREACHABLE();
1220 } 1110 }
1221 } else { 1111 } else {
1222 SetValue(instr, non_constant_); 1112 SetValue(instr, non_constant_);
1223 } 1113 }
1224 } 1114 }
1225 1115
1226
1227 void ConstantPropagator::VisitBinaryFloat32x4Op(BinaryFloat32x4OpInstr* instr) { 1116 void ConstantPropagator::VisitBinaryFloat32x4Op(BinaryFloat32x4OpInstr* instr) {
1228 const Object& left = instr->left()->definition()->constant_value(); 1117 const Object& left = instr->left()->definition()->constant_value();
1229 const Object& right = instr->right()->definition()->constant_value(); 1118 const Object& right = instr->right()->definition()->constant_value();
1230 if (IsNonConstant(left) || IsNonConstant(right)) { 1119 if (IsNonConstant(left) || IsNonConstant(right)) {
1231 SetValue(instr, non_constant_); 1120 SetValue(instr, non_constant_);
1232 } else if (IsConstant(left) && IsConstant(right)) { 1121 } else if (IsConstant(left) && IsConstant(right)) {
1233 // TODO(kmillikin): Handle binary operation. 1122 // TODO(kmillikin): Handle binary operation.
1234 SetValue(instr, non_constant_); 1123 SetValue(instr, non_constant_);
1235 } 1124 }
1236 } 1125 }
1237 1126
1238
1239 void ConstantPropagator::VisitFloat32x4Constructor( 1127 void ConstantPropagator::VisitFloat32x4Constructor(
1240 Float32x4ConstructorInstr* instr) { 1128 Float32x4ConstructorInstr* instr) {
1241 SetValue(instr, non_constant_); 1129 SetValue(instr, non_constant_);
1242 } 1130 }
1243 1131
1244
1245 void ConstantPropagator::VisitSimd32x4Shuffle(Simd32x4ShuffleInstr* instr) { 1132 void ConstantPropagator::VisitSimd32x4Shuffle(Simd32x4ShuffleInstr* instr) {
1246 SetValue(instr, non_constant_); 1133 SetValue(instr, non_constant_);
1247 } 1134 }
1248 1135
1249
1250 void ConstantPropagator::VisitSimd32x4ShuffleMix( 1136 void ConstantPropagator::VisitSimd32x4ShuffleMix(
1251 Simd32x4ShuffleMixInstr* instr) { 1137 Simd32x4ShuffleMixInstr* instr) {
1252 SetValue(instr, non_constant_); 1138 SetValue(instr, non_constant_);
1253 } 1139 }
1254 1140
1255
1256 void ConstantPropagator::VisitSimd32x4GetSignMask( 1141 void ConstantPropagator::VisitSimd32x4GetSignMask(
1257 Simd32x4GetSignMaskInstr* instr) { 1142 Simd32x4GetSignMaskInstr* instr) {
1258 SetValue(instr, non_constant_); 1143 SetValue(instr, non_constant_);
1259 } 1144 }
1260 1145
1261
1262 void ConstantPropagator::VisitFloat32x4Zero(Float32x4ZeroInstr* instr) { 1146 void ConstantPropagator::VisitFloat32x4Zero(Float32x4ZeroInstr* instr) {
1263 SetValue(instr, non_constant_); 1147 SetValue(instr, non_constant_);
1264 } 1148 }
1265 1149
1266
1267 void ConstantPropagator::VisitFloat32x4Splat(Float32x4SplatInstr* instr) { 1150 void ConstantPropagator::VisitFloat32x4Splat(Float32x4SplatInstr* instr) {
1268 SetValue(instr, non_constant_); 1151 SetValue(instr, non_constant_);
1269 } 1152 }
1270 1153
1271
1272 void ConstantPropagator::VisitFloat32x4Comparison( 1154 void ConstantPropagator::VisitFloat32x4Comparison(
1273 Float32x4ComparisonInstr* instr) { 1155 Float32x4ComparisonInstr* instr) {
1274 SetValue(instr, non_constant_); 1156 SetValue(instr, non_constant_);
1275 } 1157 }
1276 1158
1277
1278 void ConstantPropagator::VisitFloat32x4MinMax(Float32x4MinMaxInstr* instr) { 1159 void ConstantPropagator::VisitFloat32x4MinMax(Float32x4MinMaxInstr* instr) {
1279 SetValue(instr, non_constant_); 1160 SetValue(instr, non_constant_);
1280 } 1161 }
1281 1162
1282
1283 void ConstantPropagator::VisitFloat32x4Scale(Float32x4ScaleInstr* instr) { 1163 void ConstantPropagator::VisitFloat32x4Scale(Float32x4ScaleInstr* instr) {
1284 SetValue(instr, non_constant_); 1164 SetValue(instr, non_constant_);
1285 } 1165 }
1286 1166
1287
1288 void ConstantPropagator::VisitFloat32x4Sqrt(Float32x4SqrtInstr* instr) { 1167 void ConstantPropagator::VisitFloat32x4Sqrt(Float32x4SqrtInstr* instr) {
1289 SetValue(instr, non_constant_); 1168 SetValue(instr, non_constant_);
1290 } 1169 }
1291 1170
1292
1293 void ConstantPropagator::VisitFloat32x4ZeroArg(Float32x4ZeroArgInstr* instr) { 1171 void ConstantPropagator::VisitFloat32x4ZeroArg(Float32x4ZeroArgInstr* instr) {
1294 SetValue(instr, non_constant_); 1172 SetValue(instr, non_constant_);
1295 } 1173 }
1296 1174
1297
1298 void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) { 1175 void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) {
1299 SetValue(instr, non_constant_); 1176 SetValue(instr, non_constant_);
1300 } 1177 }
1301 1178
1302
1303 void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) { 1179 void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) {
1304 SetValue(instr, non_constant_); 1180 SetValue(instr, non_constant_);
1305 } 1181 }
1306 1182
1307
1308 void ConstantPropagator::VisitFloat32x4ToInt32x4( 1183 void ConstantPropagator::VisitFloat32x4ToInt32x4(
1309 Float32x4ToInt32x4Instr* instr) { 1184 Float32x4ToInt32x4Instr* instr) {
1310 SetValue(instr, non_constant_); 1185 SetValue(instr, non_constant_);
1311 } 1186 }
1312 1187
1313
1314 void ConstantPropagator::VisitInt32x4Constructor( 1188 void ConstantPropagator::VisitInt32x4Constructor(
1315 Int32x4ConstructorInstr* instr) { 1189 Int32x4ConstructorInstr* instr) {
1316 SetValue(instr, non_constant_); 1190 SetValue(instr, non_constant_);
1317 } 1191 }
1318 1192
1319
1320 void ConstantPropagator::VisitInt32x4BoolConstructor( 1193 void ConstantPropagator::VisitInt32x4BoolConstructor(
1321 Int32x4BoolConstructorInstr* instr) { 1194 Int32x4BoolConstructorInstr* instr) {
1322 SetValue(instr, non_constant_); 1195 SetValue(instr, non_constant_);
1323 } 1196 }
1324 1197
1325
1326 void ConstantPropagator::VisitInt32x4GetFlag(Int32x4GetFlagInstr* instr) { 1198 void ConstantPropagator::VisitInt32x4GetFlag(Int32x4GetFlagInstr* instr) {
1327 SetValue(instr, non_constant_); 1199 SetValue(instr, non_constant_);
1328 } 1200 }
1329 1201
1330
1331 void ConstantPropagator::VisitInt32x4SetFlag(Int32x4SetFlagInstr* instr) { 1202 void ConstantPropagator::VisitInt32x4SetFlag(Int32x4SetFlagInstr* instr) {
1332 SetValue(instr, non_constant_); 1203 SetValue(instr, non_constant_);
1333 } 1204 }
1334 1205
1335
1336 void ConstantPropagator::VisitInt32x4Select(Int32x4SelectInstr* instr) { 1206 void ConstantPropagator::VisitInt32x4Select(Int32x4SelectInstr* instr) {
1337 SetValue(instr, non_constant_); 1207 SetValue(instr, non_constant_);
1338 } 1208 }
1339 1209
1340
1341 void ConstantPropagator::VisitInt32x4ToFloat32x4( 1210 void ConstantPropagator::VisitInt32x4ToFloat32x4(
1342 Int32x4ToFloat32x4Instr* instr) { 1211 Int32x4ToFloat32x4Instr* instr) {
1343 SetValue(instr, non_constant_); 1212 SetValue(instr, non_constant_);
1344 } 1213 }
1345 1214
1346
1347 void ConstantPropagator::VisitBinaryInt32x4Op(BinaryInt32x4OpInstr* instr) { 1215 void ConstantPropagator::VisitBinaryInt32x4Op(BinaryInt32x4OpInstr* instr) {
1348 SetValue(instr, non_constant_); 1216 SetValue(instr, non_constant_);
1349 } 1217 }
1350 1218
1351
1352 void ConstantPropagator::VisitSimd64x2Shuffle(Simd64x2ShuffleInstr* instr) { 1219 void ConstantPropagator::VisitSimd64x2Shuffle(Simd64x2ShuffleInstr* instr) {
1353 SetValue(instr, non_constant_); 1220 SetValue(instr, non_constant_);
1354 } 1221 }
1355 1222
1356
1357 void ConstantPropagator::VisitBinaryFloat64x2Op(BinaryFloat64x2OpInstr* instr) { 1223 void ConstantPropagator::VisitBinaryFloat64x2Op(BinaryFloat64x2OpInstr* instr) {
1358 SetValue(instr, non_constant_); 1224 SetValue(instr, non_constant_);
1359 } 1225 }
1360 1226
1361
1362 void ConstantPropagator::VisitFloat32x4ToFloat64x2( 1227 void ConstantPropagator::VisitFloat32x4ToFloat64x2(
1363 Float32x4ToFloat64x2Instr* instr) { 1228 Float32x4ToFloat64x2Instr* instr) {
1364 SetValue(instr, non_constant_); 1229 SetValue(instr, non_constant_);
1365 } 1230 }
1366 1231
1367
1368 void ConstantPropagator::VisitFloat64x2ToFloat32x4( 1232 void ConstantPropagator::VisitFloat64x2ToFloat32x4(
1369 Float64x2ToFloat32x4Instr* instr) { 1233 Float64x2ToFloat32x4Instr* instr) {
1370 SetValue(instr, non_constant_); 1234 SetValue(instr, non_constant_);
1371 } 1235 }
1372 1236
1373
1374 void ConstantPropagator::VisitFloat64x2Zero(Float64x2ZeroInstr* instr) { 1237 void ConstantPropagator::VisitFloat64x2Zero(Float64x2ZeroInstr* instr) {
1375 SetValue(instr, non_constant_); 1238 SetValue(instr, non_constant_);
1376 } 1239 }
1377 1240
1378
1379 void ConstantPropagator::VisitFloat64x2Splat(Float64x2SplatInstr* instr) { 1241 void ConstantPropagator::VisitFloat64x2Splat(Float64x2SplatInstr* instr) {
1380 SetValue(instr, non_constant_); 1242 SetValue(instr, non_constant_);
1381 } 1243 }
1382 1244
1383
1384 void ConstantPropagator::VisitFloat64x2Constructor( 1245 void ConstantPropagator::VisitFloat64x2Constructor(
1385 Float64x2ConstructorInstr* instr) { 1246 Float64x2ConstructorInstr* instr) {
1386 SetValue(instr, non_constant_); 1247 SetValue(instr, non_constant_);
1387 } 1248 }
1388 1249
1389
1390 void ConstantPropagator::VisitFloat64x2ZeroArg(Float64x2ZeroArgInstr* instr) { 1250 void ConstantPropagator::VisitFloat64x2ZeroArg(Float64x2ZeroArgInstr* instr) {
1391 // TODO(johnmccutchan): Implement constant propagation. 1251 // TODO(johnmccutchan): Implement constant propagation.
1392 SetValue(instr, non_constant_); 1252 SetValue(instr, non_constant_);
1393 } 1253 }
1394 1254
1395
1396 void ConstantPropagator::VisitFloat64x2OneArg(Float64x2OneArgInstr* instr) { 1255 void ConstantPropagator::VisitFloat64x2OneArg(Float64x2OneArgInstr* instr) {
1397 // TODO(johnmccutchan): Implement constant propagation. 1256 // TODO(johnmccutchan): Implement constant propagation.
1398 SetValue(instr, non_constant_); 1257 SetValue(instr, non_constant_);
1399 } 1258 }
1400 1259
1401
1402 void ConstantPropagator::VisitMathUnary(MathUnaryInstr* instr) { 1260 void ConstantPropagator::VisitMathUnary(MathUnaryInstr* instr) {
1403 const Object& value = instr->value()->definition()->constant_value(); 1261 const Object& value = instr->value()->definition()->constant_value();
1404 if (IsNonConstant(value)) { 1262 if (IsNonConstant(value)) {
1405 SetValue(instr, non_constant_); 1263 SetValue(instr, non_constant_);
1406 } else if (IsConstant(value)) { 1264 } else if (IsConstant(value)) {
1407 // TODO(kmillikin): Handle Math's unary operations (sqrt, cos, sin). 1265 // TODO(kmillikin): Handle Math's unary operations (sqrt, cos, sin).
1408 SetValue(instr, non_constant_); 1266 SetValue(instr, non_constant_);
1409 } 1267 }
1410 } 1268 }
1411 1269
1412
1413 void ConstantPropagator::VisitMathMinMax(MathMinMaxInstr* instr) { 1270 void ConstantPropagator::VisitMathMinMax(MathMinMaxInstr* instr) {
1414 const Object& left = instr->left()->definition()->constant_value(); 1271 const Object& left = instr->left()->definition()->constant_value();
1415 const Object& right = instr->right()->definition()->constant_value(); 1272 const Object& right = instr->right()->definition()->constant_value();
1416 if (IsNonConstant(left) || IsNonConstant(right)) { 1273 if (IsNonConstant(left) || IsNonConstant(right)) {
1417 SetValue(instr, non_constant_); 1274 SetValue(instr, non_constant_);
1418 } else if (IsConstant(left) && IsConstant(right)) { 1275 } else if (IsConstant(left) && IsConstant(right)) {
1419 // TODO(srdjan): Handle min and max. 1276 // TODO(srdjan): Handle min and max.
1420 SetValue(instr, non_constant_); 1277 SetValue(instr, non_constant_);
1421 } 1278 }
1422 } 1279 }
1423 1280
1424
1425 void ConstantPropagator::VisitCaseInsensitiveCompareUC16( 1281 void ConstantPropagator::VisitCaseInsensitiveCompareUC16(
1426 CaseInsensitiveCompareUC16Instr* instr) { 1282 CaseInsensitiveCompareUC16Instr* instr) {
1427 SetValue(instr, non_constant_); 1283 SetValue(instr, non_constant_);
1428 } 1284 }
1429 1285
1430
1431 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) { 1286 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) {
1432 const Object& value = instr->value()->definition()->constant_value(); 1287 const Object& value = instr->value()->definition()->constant_value();
1433 if (IsNonConstant(value)) { 1288 if (IsNonConstant(value)) {
1434 SetValue(instr, non_constant_); 1289 SetValue(instr, non_constant_);
1435 } else if (IsConstant(value)) { 1290 } else if (IsConstant(value)) {
1436 // TODO(kmillikin): Handle conversion. 1291 // TODO(kmillikin): Handle conversion.
1437 SetValue(instr, non_constant_); 1292 SetValue(instr, non_constant_);
1438 } 1293 }
1439 } 1294 }
1440 1295
1441
1442 void ConstantPropagator::VisitBox(BoxInstr* instr) { 1296 void ConstantPropagator::VisitBox(BoxInstr* instr) {
1443 const Object& value = instr->value()->definition()->constant_value(); 1297 const Object& value = instr->value()->definition()->constant_value();
1444 if (IsNonConstant(value)) { 1298 if (IsNonConstant(value)) {
1445 SetValue(instr, non_constant_); 1299 SetValue(instr, non_constant_);
1446 } else if (IsConstant(value)) { 1300 } else if (IsConstant(value)) {
1447 // TODO(kmillikin): Handle conversion. 1301 // TODO(kmillikin): Handle conversion.
1448 SetValue(instr, non_constant_); 1302 SetValue(instr, non_constant_);
1449 } 1303 }
1450 } 1304 }
1451 1305
1452
1453 void ConstantPropagator::VisitBoxUint32(BoxUint32Instr* instr) { 1306 void ConstantPropagator::VisitBoxUint32(BoxUint32Instr* instr) {
1454 // TODO(kmillikin): Handle box operation. 1307 // TODO(kmillikin): Handle box operation.
1455 SetValue(instr, non_constant_); 1308 SetValue(instr, non_constant_);
1456 } 1309 }
1457 1310
1458
1459 void ConstantPropagator::VisitUnboxUint32(UnboxUint32Instr* instr) { 1311 void ConstantPropagator::VisitUnboxUint32(UnboxUint32Instr* instr) {
1460 // TODO(kmillikin): Handle unbox operation. 1312 // TODO(kmillikin): Handle unbox operation.
1461 SetValue(instr, non_constant_); 1313 SetValue(instr, non_constant_);
1462 } 1314 }
1463 1315
1464
1465 void ConstantPropagator::VisitBoxInt32(BoxInt32Instr* instr) { 1316 void ConstantPropagator::VisitBoxInt32(BoxInt32Instr* instr) {
1466 // TODO(kmillikin): Handle box operation. 1317 // TODO(kmillikin): Handle box operation.
1467 SetValue(instr, non_constant_); 1318 SetValue(instr, non_constant_);
1468 } 1319 }
1469 1320
1470
1471 void ConstantPropagator::VisitUnboxInt32(UnboxInt32Instr* instr) { 1321 void ConstantPropagator::VisitUnboxInt32(UnboxInt32Instr* instr) {
1472 // TODO(kmillikin): Handle unbox operation. 1322 // TODO(kmillikin): Handle unbox operation.
1473 SetValue(instr, non_constant_); 1323 SetValue(instr, non_constant_);
1474 } 1324 }
1475 1325
1476
1477 void ConstantPropagator::VisitUnboxedIntConverter( 1326 void ConstantPropagator::VisitUnboxedIntConverter(
1478 UnboxedIntConverterInstr* instr) { 1327 UnboxedIntConverterInstr* instr) {
1479 SetValue(instr, non_constant_); 1328 SetValue(instr, non_constant_);
1480 } 1329 }
1481 1330
1482
1483 void ConstantPropagator::VisitUnaryUint32Op(UnaryUint32OpInstr* instr) { 1331 void ConstantPropagator::VisitUnaryUint32Op(UnaryUint32OpInstr* instr) {
1484 // TODO(kmillikin): Handle unary operations. 1332 // TODO(kmillikin): Handle unary operations.
1485 SetValue(instr, non_constant_); 1333 SetValue(instr, non_constant_);
1486 } 1334 }
1487 1335
1488
1489 void ConstantPropagator::Analyze() { 1336 void ConstantPropagator::Analyze() {
1490 GraphEntryInstr* entry = graph_->graph_entry(); 1337 GraphEntryInstr* entry = graph_->graph_entry();
1491 reachable_->Add(entry->preorder_number()); 1338 reachable_->Add(entry->preorder_number());
1492 block_worklist_.Add(entry); 1339 block_worklist_.Add(entry);
1493 1340
1494 while (true) { 1341 while (true) {
1495 if (block_worklist_.is_empty()) { 1342 if (block_worklist_.is_empty()) {
1496 if (definition_worklist_.IsEmpty()) break; 1343 if (definition_worklist_.IsEmpty()) break;
1497 Definition* definition = definition_worklist_.RemoveLast(); 1344 Definition* definition = definition_worklist_.RemoveLast();
1498 Value* use = definition->input_use_list(); 1345 Value* use = definition->input_use_list();
1499 while (use != NULL) { 1346 while (use != NULL) {
1500 use->instruction()->Accept(this); 1347 use->instruction()->Accept(this);
1501 use = use->next_use(); 1348 use = use->next_use();
1502 } 1349 }
1503 } else { 1350 } else {
1504 BlockEntryInstr* block = block_worklist_.RemoveLast(); 1351 BlockEntryInstr* block = block_worklist_.RemoveLast();
1505 block->Accept(this); 1352 block->Accept(this);
1506 } 1353 }
1507 } 1354 }
1508 } 1355 }
1509 1356
1510
1511 static bool IsEmptyBlock(BlockEntryInstr* block) { 1357 static bool IsEmptyBlock(BlockEntryInstr* block) {
1512 return block->next()->IsGoto() && 1358 return block->next()->IsGoto() &&
1513 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) && 1359 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) &&
1514 !block->IsIndirectEntry(); 1360 !block->IsIndirectEntry();
1515 } 1361 }
1516 1362
1517
1518 // Traverses a chain of empty blocks and returns the first reachable non-empty 1363 // Traverses a chain of empty blocks and returns the first reachable non-empty
1519 // block that is not dominated by the start block. The empty blocks are added 1364 // block that is not dominated by the start block. The empty blocks are added
1520 // to the supplied bit vector. 1365 // to the supplied bit vector.
1521 static BlockEntryInstr* FindFirstNonEmptySuccessor(TargetEntryInstr* block, 1366 static BlockEntryInstr* FindFirstNonEmptySuccessor(TargetEntryInstr* block,
1522 BitVector* empty_blocks) { 1367 BitVector* empty_blocks) {
1523 BlockEntryInstr* current = block; 1368 BlockEntryInstr* current = block;
1524 while (IsEmptyBlock(current) && block->Dominates(current)) { 1369 while (IsEmptyBlock(current) && block->Dominates(current)) {
1525 ASSERT(!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); 1370 ASSERT(!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL));
1526 empty_blocks->Add(current->preorder_number()); 1371 empty_blocks->Add(current->preorder_number());
1527 current = current->next()->AsGoto()->successor(); 1372 current = current->next()->AsGoto()->successor();
1528 } 1373 }
1529 return current; 1374 return current;
1530 } 1375 }
1531 1376
1532
1533 void ConstantPropagator::EliminateRedundantBranches() { 1377 void ConstantPropagator::EliminateRedundantBranches() {
1534 // Canonicalize branches that have no side-effects and where true- and 1378 // Canonicalize branches that have no side-effects and where true- and
1535 // false-targets are the same. 1379 // false-targets are the same.
1536 bool changed = false; 1380 bool changed = false;
1537 BitVector* empty_blocks = new (Z) BitVector(Z, graph_->preorder().length()); 1381 BitVector* empty_blocks = new (Z) BitVector(Z, graph_->preorder().length());
1538 for (BlockIterator b = graph_->postorder_iterator(); !b.Done(); b.Advance()) { 1382 for (BlockIterator b = graph_->postorder_iterator(); !b.Done(); b.Advance()) {
1539 BlockEntryInstr* block = b.Current(); 1383 BlockEntryInstr* block = b.Current();
1540 BranchInstr* branch = block->last_instruction()->AsBranch(); 1384 BranchInstr* branch = block->last_instruction()->AsBranch();
1541 empty_blocks->Clear(); 1385 empty_blocks->Clear();
1542 if ((branch != NULL) && branch->Effects().IsNone()) { 1386 if ((branch != NULL) && branch->Effects().IsNone()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 } 1423 }
1580 1424
1581 if (changed) { 1425 if (changed) {
1582 graph_->DiscoverBlocks(); 1426 graph_->DiscoverBlocks();
1583 // TODO(fschneider): Update dominator tree in place instead of recomputing. 1427 // TODO(fschneider): Update dominator tree in place instead of recomputing.
1584 GrowableArray<BitVector*> dominance_frontier; 1428 GrowableArray<BitVector*> dominance_frontier;
1585 graph_->ComputeDominators(&dominance_frontier); 1429 graph_->ComputeDominators(&dominance_frontier);
1586 } 1430 }
1587 } 1431 }
1588 1432
1589
1590 void ConstantPropagator::Transform() { 1433 void ConstantPropagator::Transform() {
1591 if (FLAG_trace_constant_propagation && 1434 if (FLAG_trace_constant_propagation &&
1592 FlowGraphPrinter::ShouldPrint(graph_->function())) { 1435 FlowGraphPrinter::ShouldPrint(graph_->function())) {
1593 FlowGraphPrinter::PrintGraph("Before CP", graph_); 1436 FlowGraphPrinter::PrintGraph("Before CP", graph_);
1594 } 1437 }
1595 1438
1596 // We will recompute dominators, block ordering, block ids, block last 1439 // We will recompute dominators, block ordering, block ids, block last
1597 // instructions, previous pointers, predecessors, etc. after eliminating 1440 // instructions, previous pointers, predecessors, etc. after eliminating
1598 // unreachable code. We do not maintain those properties during the 1441 // unreachable code. We do not maintain those properties during the
1599 // transformation. 1442 // transformation.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 GrowableArray<BitVector*> dominance_frontier; 1577 GrowableArray<BitVector*> dominance_frontier;
1735 graph_->ComputeDominators(&dominance_frontier); 1578 graph_->ComputeDominators(&dominance_frontier);
1736 1579
1737 if (FLAG_trace_constant_propagation && 1580 if (FLAG_trace_constant_propagation &&
1738 FlowGraphPrinter::ShouldPrint(graph_->function())) { 1581 FlowGraphPrinter::ShouldPrint(graph_->function())) {
1739 FlowGraphPrinter::PrintGraph("After CP", graph_); 1582 FlowGraphPrinter::PrintGraph("After CP", graph_);
1740 } 1583 }
1741 } 1584 }
1742 1585
1743 } // namespace dart 1586 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/constant_propagator.h ('k') | runtime/vm/constants_arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698