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

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

Issue 345563007: Add Uint32 representation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 | Annotate | Revision Log
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/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 26 matching lines...) Expand all
37 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis."); 37 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis.");
38 DEFINE_FLAG(bool, trace_constant_propagation, false, 38 DEFINE_FLAG(bool, trace_constant_propagation, false,
39 "Print constant propagation and useless code elimination."); 39 "Print constant propagation and useless code elimination.");
40 DEFINE_FLAG(bool, trace_load_optimization, false, 40 DEFINE_FLAG(bool, trace_load_optimization, false,
41 "Print live sets for load optimization pass."); 41 "Print live sets for load optimization pass.");
42 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); 42 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details.");
43 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress"); 43 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress");
44 DEFINE_FLAG(bool, truncating_left_shift, true, 44 DEFINE_FLAG(bool, truncating_left_shift, true,
45 "Optimize left shift to truncate if possible"); 45 "Optimize left shift to truncate if possible");
46 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis."); 46 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis.");
47 DEFINE_FLAG(bool, trace_integer_ir_selection, false,
48 "Print integer IR selection optimization pass.");
47 DECLARE_FLAG(bool, enable_type_checks); 49 DECLARE_FLAG(bool, enable_type_checks);
48 DECLARE_FLAG(bool, source_lines); 50 DECLARE_FLAG(bool, source_lines);
49 DECLARE_FLAG(bool, trace_type_check_elimination); 51 DECLARE_FLAG(bool, trace_type_check_elimination);
50 DECLARE_FLAG(bool, warn_on_javascript_compatibility); 52 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
51 53
52 // Quick access to the locally defined isolate() method. 54 // Quick access to the locally defined isolate() method.
53 #define I (isolate()) 55 #define I (isolate())
54 56
55 static bool ShouldInlineSimd() { 57 static bool ShouldInlineSimd() {
56 return FlowGraphCompiler::SupportsUnboxedSimd128(); 58 return FlowGraphCompiler::SupportsUnboxedSimd128();
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 deopt_target = insert_before = use->instruction(); 603 deopt_target = insert_before = use->instruction();
602 } 604 }
603 605
604 Definition* converted = NULL; 606 Definition* converted = NULL;
605 if ((from == kTagged) && (to == kUnboxedMint)) { 607 if ((from == kTagged) && (to == kUnboxedMint)) {
606 ASSERT((deopt_target != NULL) || 608 ASSERT((deopt_target != NULL) ||
607 (use->Type()->ToCid() == kUnboxedMint)); 609 (use->Type()->ToCid() == kUnboxedMint));
608 const intptr_t deopt_id = (deopt_target != NULL) ? 610 const intptr_t deopt_id = (deopt_target != NULL) ?
609 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 611 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
610 converted = new(I) UnboxIntegerInstr(use->CopyWithType(), deopt_id); 612 converted = new(I) UnboxIntegerInstr(use->CopyWithType(), deopt_id);
611
612 } else if ((from == kUnboxedMint) && (to == kTagged)) { 613 } else if ((from == kUnboxedMint) && (to == kTagged)) {
613 converted = new(I) BoxIntegerInstr(use->CopyWithType()); 614 converted = new(I) BoxIntegerInstr(use->CopyWithType());
614 615 } else if ((from == kUnboxedMint) && (to == kUnboxedUint32)) {
616 converted = new(I) UnboxedIntConverterInstr(from, to, use->CopyWithType());
617 } else if ((from == kUnboxedUint32) && (to == kUnboxedMint)) {
618 converted = new(I) UnboxedIntConverterInstr(from, to, use->CopyWithType());
615 } else if (from == kUnboxedMint && to == kUnboxedDouble) { 619 } else if (from == kUnboxedMint && to == kUnboxedDouble) {
616 ASSERT(CanUnboxDouble()); 620 ASSERT(CanUnboxDouble());
617 // Convert by boxing/unboxing. 621 // Convert by boxing/unboxing.
618 // TODO(fschneider): Implement direct unboxed mint-to-double conversion. 622 // TODO(fschneider): Implement direct unboxed mint-to-double conversion.
619 BoxIntegerInstr* boxed = 623 BoxIntegerInstr* boxed =
620 new(I) BoxIntegerInstr(use->CopyWithType()); 624 new(I) BoxIntegerInstr(use->CopyWithType());
621 use->BindTo(boxed); 625 use->BindTo(boxed);
622 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue); 626 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
623 627
624 const intptr_t deopt_id = (deopt_target != NULL) ? 628 const intptr_t deopt_id = (deopt_target != NULL) ?
(...skipping 4515 matching lines...) Expand 10 before | Expand all | Expand 10 after
5140 } 5144 }
5141 } 5145 }
5142 5146
5143 5147
5144 void FlowGraphOptimizer::InferIntRanges() { 5148 void FlowGraphOptimizer::InferIntRanges() {
5145 RangeAnalysis range_analysis(flow_graph_); 5149 RangeAnalysis range_analysis(flow_graph_);
5146 range_analysis.Analyze(); 5150 range_analysis.Analyze();
5147 } 5151 }
5148 5152
5149 5153
5154 // Replaces Mint IL instructions with Uint32 IL instructions
5155 // when possible. Uses output of RangeAnalysis.
5156 class IntegerInstructionSelector : public ValueObject {
5157 public:
5158 explicit IntegerInstructionSelector(FlowGraph* flow_graph)
5159 : flow_graph_(flow_graph),
5160 isolate_(NULL),
5161 changed_(true) {
5162 ASSERT(flow_graph_ != NULL);
5163 isolate_ = flow_graph_->isolate();
5164 ASSERT(isolate_ != NULL);
5165 selected_uint32_defs_ =
5166 new(I) BitVector(flow_graph_->current_ssa_temp_index());
5167 }
5168
5169 void Select();
5170
5171 private:
5172 bool IsPotentialUint32Definition(Definition* def);
5173 void FindPotentialUint32Definitions();
5174 bool IsInitialUint32Candidate(Definition* def);
5175 void SelectInitialUint32Definitions();
5176 bool IsUint32Candidate(Definition* def);
5177 void Iterate();
5178 Definition* ConstructReplacementFor(Definition* def);
5179 void ReplaceInstructions();
5180
5181 Isolate* isolate() const { return isolate_; }
5182
5183 GrowableArray<Definition*> potential_uint32_defs_;
5184 BitVector* selected_uint32_defs_;
5185
5186 FlowGraph* flow_graph_;
5187 Isolate* isolate_;
5188 bool changed_;
5189 };
5190
5191
5192 void IntegerInstructionSelector::Select() {
5193 if (FLAG_trace_integer_ir_selection) {
5194 OS::Print("---- starting integer ir selection -------\n");
5195 }
5196 FindPotentialUint32Definitions();
5197 SelectInitialUint32Definitions();
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 "InitialDefinition" is a confusing name. I would c
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 "InitialDefinition" is a confusing name. I would c
5198 Iterate();
5199 ReplaceInstructions();
5200 if (FLAG_trace_integer_ir_selection) {
5201 OS::Print("---- after integer ir selection -------\n");
5202 FlowGraphPrinter printer(*flow_graph_);
5203 printer.PrintBlocks();
5204 }
5205 }
5206
5207
5208 bool IntegerInstructionSelector::IsPotentialUint32Definition(Definition* def) {
5209 if (!def->IsMintDefinition()) {
5210 // Not a mint op.
5211 return false;
5212 }
5213 if (def->IsLoadField()) {
5214 // A load of a mint field.
5215 return false;
5216 }
5217 return true;
5218 }
5219
5220
5221 void IntegerInstructionSelector::FindPotentialUint32Definitions() {
5222 if (FLAG_trace_integer_ir_selection) {
5223 OS::Print("++++ Finding potential Uint32 definitions:\n");
5224 }
5225 const GrowableArray<Definition*>& initial =
5226 *flow_graph_->graph_entry()->initial_definitions();
5227 for (intptr_t i = 0; i < initial.length(); ++i) {
5228 Definition* current = initial[i];
5229 if (IsPotentialUint32Definition(current)) {
5230 if (FLAG_trace_integer_ir_selection) {
5231 OS::Print("Adding %s\n", current->ToCString());
5232 }
5233 potential_uint32_defs_.Add(current);
5234 }
5235 }
5236
5237 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
5238 !block_it.Done();
5239 block_it.Advance()) {
5240 BlockEntryInstr* block = block_it.Current();
5241
5242
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 remove empty line
Cutch 2014/07/07 22:34:28 Done.
5243 if (block->IsGraphEntry() || block->IsCatchBlockEntry()) {
5244 const GrowableArray<Definition*>& initial = block->IsGraphEntry()
5245 ? *block->AsGraphEntry()->initial_definitions()
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 Did not we already iterate over graph entry above?
Cutch 2014/07/07 22:34:28 Done.
5246 : *block->AsCatchBlockEntry()->initial_definitions();
5247 for (intptr_t i = 0; i < initial.length(); ++i) {
5248 Definition* current = initial[i];
5249 if (IsPotentialUint32Definition(current)) {
5250 if (FLAG_trace_integer_ir_selection) {
5251 OS::Print("Adding %s\n", current->ToCString());
5252 }
5253 potential_uint32_defs_.Add(current);
5254 }
5255 }
5256 }
5257
5258 for (ForwardInstructionIterator instr_it(block);
5259 !instr_it.Done();
5260 instr_it.Advance()) {
5261 Instruction* current = instr_it.Current();
5262 Definition* defn = current->AsDefinition();
5263 if ((defn != NULL) && (defn->ssa_temp_index() != -1)) {
5264 if (IsPotentialUint32Definition(defn)) {
5265 if (FLAG_trace_integer_ir_selection) {
5266 OS::Print("Adding %s\n", current->ToCString());
5267 }
5268 potential_uint32_defs_.Add(defn);
5269 }
5270 }
5271 }
5272 }
5273 }
5274
5275
5276 // BinaryMintOp masks and stores into unsigned typed arrays that truncate the
5277 // value into a Uint32 range.
5278 bool IntegerInstructionSelector::IsInitialUint32Candidate(Definition* def) {
5279 if (def->IsBinaryMintOp()) {
5280 BinaryMintOpInstr* op = def->AsBinaryMintOp();
5281 // Must be a mask operation.
5282 if (op->op_kind() != Token::kBIT_AND) {
5283 return false;
5284 }
5285 Range* range = op->range();
5286 if ((range == NULL) ||
5287 !range->IsWithin(0, static_cast<int64_t>(kMaxUint32))) {
5288 return false;
5289 }
5290 return true;
5291 }
5292 // TODO(johnmccutchan): Add typed array stores.
5293 return false;
5294 }
5295
5296
5297 void IntegerInstructionSelector::SelectInitialUint32Definitions() {
5298 ASSERT(selected_uint32_defs_ != NULL);
5299 if (FLAG_trace_integer_ir_selection) {
5300 OS::Print("++++ Selecting Uint32 definitions:\n");
5301 OS::Print("++++ Initial set:\n");
5302 }
5303 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) {
5304 Definition* defn = potential_uint32_defs_[i];
5305 if (IsInitialUint32Candidate(defn)) {
5306 if (FLAG_trace_integer_ir_selection) {
5307 OS::Print("Adding %s\n", defn->ToCString());
5308 }
5309 selected_uint32_defs_->Add(defn->ssa_temp_index());
5310 }
5311 }
5312 }
5313
5314
5315 bool IntegerInstructionSelector::IsUint32Candidate(Definition* def) {
5316 ASSERT(def->IsMintDefinition());
5317 if (def->IsBoxInteger()) {
5318 // If a BoxInteger's input is a candidate, the box is a candidate.
5319 BoxIntegerInstr* box = def->AsBoxInteger();
5320 Definition* box_input = box->value()->definition();
5321 return selected_uint32_defs_->Contains(box_input->ssa_temp_index());
5322 }
5323 // A right shift with a range outside Uint32 cannot be converted because we
5324 // may need the high bits.
5325 if (def->IsShiftMintOp()) {
5326 ShiftMintOpInstr* op = def->AsShiftMintOp();
5327 if (op->op_kind() == Token::kSHR) {
5328 Range* range = op->range();
5329 if ((range == NULL) ||
5330 !range->IsWithin(0, static_cast<int64_t>(kMaxUint32))) {
5331 return false;
5332 }
5333 }
5334 }
5335 if (!def->HasUses()) {
5336 // No uses, skip.
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 [sidenote: we should DCE those instructions :)]
5337 return false;
5338 }
5339 // All uses are candidates.
5340 Value* use = def->input_use_list();
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 What about environment uses? It is not safe to ign
5341 bool only_candidate_uses = true;
5342 while ((use != NULL) && only_candidate_uses) {
5343 Instruction* instr = use->instruction();
5344 if (!instr->IsDefinition()) {
5345 // Not a definition.
5346 only_candidate_uses = false;
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 return false;
Cutch 2014/07/07 22:34:28 Done.
5347 break;
5348 }
5349 Definition* defn = instr->AsDefinition();
5350 if (!defn->IsMintDefinition()) {
5351 // Not a mint definition.
5352 only_candidate_uses = false;
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 return false;
Cutch 2014/07/07 22:34:28 Done.
5353 break;
5354 }
5355 only_candidate_uses = only_candidate_uses &&
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 only_candidate_uses are true at this point no need
Cutch 2014/07/07 22:34:28 Done.
5356 selected_uint32_defs_->Contains(defn->ssa_temp_index());
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 You can just do: for (Value* use = def->input_use
Cutch 2014/07/07 22:34:28 Done.
5357 use = use->next_use();
5358 }
5359 return only_candidate_uses;
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 return true;
5360 }
5361
5362
5363 void IntegerInstructionSelector::Iterate() {
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 I would call it Propagate().
5364 ASSERT(selected_uint32_defs_ != NULL);
5365 ASSERT(changed_);
5366 intptr_t iteration = 0;
5367 while (changed_) {
5368 if (FLAG_trace_integer_ir_selection) {
5369 OS::Print("+++ Iteration: %" Pd "\n", iteration++);
5370 }
5371 changed_ = false;
5372 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) {
5373 Definition* defn = potential_uint32_defs_[i];
5374 if (selected_uint32_defs_->Contains(defn->ssa_temp_index())) {
5375 // Already marked as a candidate, skip.
5376 continue;
5377 }
5378 if (defn->IsConstant()) {
5379 // Skip constants.
5380 continue;
5381 }
5382 if (IsUint32Candidate(defn)) {
5383 if (FLAG_trace_integer_ir_selection) {
5384 OS::Print("Adding %s\n", defn->ToCString());
5385 }
5386 // Found a new candidate.
5387 selected_uint32_defs_->Add(defn->ssa_temp_index());
5388 // Haven't reached fixed point yet.
5389 changed_ = true;
5390 }
5391 }
5392 }
5393 if (FLAG_trace_integer_ir_selection) {
5394 OS::Print("Reached fixed point\n");
5395 }
5396 }
5397
5398
5399 Definition* IntegerInstructionSelector::ConstructReplacementFor(
5400 Definition* def) {
5401 // Should only see mint definitions.
5402 ASSERT(def->IsMintDefinition());
5403 // Should not see constant instructions.
5404 ASSERT(!def->IsConstant());
5405 if (def->IsBinaryMintOp()) {
5406 BinaryMintOpInstr* op = def->AsBinaryMintOp();
5407 Token::Kind op_kind = op->op_kind();
5408 Value* left = op->left()->CopyWithType();
5409 Value* right = op->right()->CopyWithType();
5410 intptr_t deopt_id = op->DeoptimizationTarget();
5411 return new(I) BinaryUint32OpInstr(op_kind, left, right, deopt_id);
5412 } else if (def->IsBoxInteger()) {
5413 BoxIntegerInstr* box = def->AsBoxInteger();
5414 Value* value = box->value()->CopyWithType();
5415 return new(I) BoxUint32Instr(value);
5416 } else if (def->IsUnboxInteger()) {
5417 UnboxIntegerInstr* unbox = def->AsUnboxInteger();
5418 Value* value = unbox->value()->CopyWithType();
5419 intptr_t deopt_id = unbox->deopt_id();
5420 return new(I) UnboxUint32Instr(value, deopt_id);
5421 } else if (def->IsUnaryMintOp()) {
5422 UnaryMintOpInstr* op = def->AsUnaryMintOp();
5423 Token::Kind op_kind = op->op_kind();
5424 Value* value = op->value()->CopyWithType();
5425 intptr_t deopt_id = op->DeoptimizationTarget();
5426 return new(I) UnaryUint32OpInstr(op_kind, value, deopt_id);
5427 } else if (def->IsShiftMintOp()) {
5428 ShiftMintOpInstr* op = def->AsShiftMintOp();
5429 Token::Kind op_kind = op->op_kind();
5430 Value* left = op->left()->CopyWithType();
5431 Value* right = op->right()->CopyWithType();
5432 intptr_t deopt_id = op->DeoptimizationTarget();
5433 return new(I) ShiftUint32OpInstr(op_kind, left, right, deopt_id);
5434 }
5435 printf("%s\n", def->ToCString());
5436 UNREACHABLE();
5437 return NULL;
5438 }
5439
5440
5441 void IntegerInstructionSelector::ReplaceInstructions() {
5442 if (FLAG_trace_integer_ir_selection) {
5443 OS::Print("++++ Replacing instructions:\n");
5444 }
5445 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) {
5446 Definition* defn = potential_uint32_defs_[i];
5447 if (!selected_uint32_defs_->Contains(defn->ssa_temp_index())) {
5448 // Not a candidate.
5449 continue;
5450 }
5451 Definition* replacement = ConstructReplacementFor(defn);
5452 ASSERT(replacement != NULL);
5453 if (FLAG_trace_integer_ir_selection) {
5454 OS::Print("Replacing %s with %s\n", defn->ToCString(),
5455 replacement->ToCString());
5456 }
5457 defn->ReplaceWith(replacement, NULL);
5458 ASSERT(flow_graph_->VerifyUseLists());
5459 }
5460 }
5461
5462 void FlowGraphOptimizer::SelectIntegerInstructions() {
5463 IntegerInstructionSelector iis(flow_graph_);
5464 iis.Select();
5465 }
5466
5467
5150 void TryCatchAnalyzer::Optimize(FlowGraph* flow_graph) { 5468 void TryCatchAnalyzer::Optimize(FlowGraph* flow_graph) {
5151 // For every catch-block: Iterate over all call instructions inside the 5469 // For every catch-block: Iterate over all call instructions inside the
5152 // corresponding try-block and figure out for each environment value if it 5470 // corresponding try-block and figure out for each environment value if it
5153 // is the same constant at all calls. If yes, replace the initial definition 5471 // is the same constant at all calls. If yes, replace the initial definition
5154 // at the catch-entry with this constant. 5472 // at the catch-entry with this constant.
5155 const GrowableArray<CatchBlockEntryInstr*>& catch_entries = 5473 const GrowableArray<CatchBlockEntryInstr*>& catch_entries =
5156 flow_graph->graph_entry()->catch_entries(); 5474 flow_graph->graph_entry()->catch_entries();
5157 intptr_t base = kFirstLocalSlotFromFp + flow_graph->num_non_copied_params(); 5475 intptr_t base = kFirstLocalSlotFromFp + flow_graph->num_non_copied_params();
5158 for (intptr_t catch_idx = 0; 5476 for (intptr_t catch_idx = 0;
5159 catch_idx < catch_entries.length(); 5477 catch_idx < catch_entries.length();
(...skipping 3745 matching lines...) Expand 10 before | Expand all | Expand 10 after
8905 const Object& value = instr->value()->definition()->constant_value(); 9223 const Object& value = instr->value()->definition()->constant_value();
8906 if (IsNonConstant(value)) { 9224 if (IsNonConstant(value)) {
8907 SetValue(instr, non_constant_); 9225 SetValue(instr, non_constant_);
8908 } else if (IsConstant(value)) { 9226 } else if (IsConstant(value)) {
8909 // TODO(kmillikin): Handle conversion. 9227 // TODO(kmillikin): Handle conversion.
8910 SetValue(instr, non_constant_); 9228 SetValue(instr, non_constant_);
8911 } 9229 }
8912 } 9230 }
8913 9231
8914 9232
9233 void ConstantPropagator::VisitBoxUint32(BoxUint32Instr* instr) {
9234 // TODO(kmillikin): Handle box operation.
9235 SetValue(instr, non_constant_);
9236 }
9237
9238
9239 void ConstantPropagator::VisitUnboxUint32(UnboxUint32Instr* instr) {
9240 // TODO(kmillikin): Handle unbox operation.
9241 SetValue(instr, non_constant_);
9242 }
9243
9244
9245 void ConstantPropagator::VisitUnboxedIntConverter(
9246 UnboxedIntConverterInstr* instr) {
9247 SetValue(instr, non_constant_);
9248 }
9249
9250
9251 void ConstantPropagator::VisitBinaryUint32Op(BinaryUint32OpInstr* instr) {
9252 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
Vyacheslav Egorov (Google) 2014/07/07 16:16:03 Should result of HandleBinaryOp be truncated to ma
9253 }
9254
9255
9256 void ConstantPropagator::VisitShiftUint32Op(ShiftUint32OpInstr* instr) {
9257 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
9258 }
9259
9260
9261 void ConstantPropagator::VisitUnaryUint32Op(UnaryUint32OpInstr* instr) {
9262 // TODO(kmillikin): Handle unary operations.
9263 SetValue(instr, non_constant_);
9264 }
9265
9266
8915 void ConstantPropagator::Analyze() { 9267 void ConstantPropagator::Analyze() {
8916 GraphEntryInstr* entry = graph_->graph_entry(); 9268 GraphEntryInstr* entry = graph_->graph_entry();
8917 reachable_->Add(entry->preorder_number()); 9269 reachable_->Add(entry->preorder_number());
8918 block_worklist_.Add(entry); 9270 block_worklist_.Add(entry);
8919 9271
8920 while (true) { 9272 while (true) {
8921 if (block_worklist_.is_empty()) { 9273 if (block_worklist_.is_empty()) {
8922 if (definition_worklist_.is_empty()) break; 9274 if (definition_worklist_.is_empty()) break;
8923 Definition* definition = definition_worklist_.RemoveLast(); 9275 Definition* definition = definition_worklist_.RemoveLast();
8924 definition_marks_->Remove(definition->ssa_temp_index()); 9276 definition_marks_->Remove(definition->ssa_temp_index());
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after
9818 } 10170 }
9819 10171
9820 // Insert materializations at environment uses. 10172 // Insert materializations at environment uses.
9821 for (intptr_t i = 0; i < exits.length(); i++) { 10173 for (intptr_t i = 0; i < exits.length(); i++) {
9822 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); 10174 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots);
9823 } 10175 }
9824 } 10176 }
9825 10177
9826 10178
9827 } // namespace dart 10179 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698