1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/crankshaft/hydrogen-canonicalize.h" 6 7 #include "src/counters.h" 8 #include "src/crankshaft/hydrogen-redundant-phi.h" 9 #include "src/objects-inl.h" 10 11 namespace v8 { 12 namespace internal { 13 14 void HCanonicalizePhase::Run() { 15 const ZoneList<HBasicBlock*>* blocks(graph()->blocks()); 16 // Before removing no-op instructions, save their semantic value. 17 // We must be careful not to set the flag unnecessarily, because GVN 18 // cannot identify two instructions when their flag value differs. 19 for (int i = 0; i < blocks->length(); ++i) { 20 for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) { 21 HInstruction* instr = it.Current(); 22 if (instr->IsArithmeticBinaryOperation()) { 23 if (instr->representation().IsInteger32()) { 24 if (instr->HasAtLeastOneUseWithFlagAndNoneWithout( 25 HInstruction::kTruncatingToInt32)) { 26 instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32); 27 } 28 } else if (instr->representation().IsSmi()) { 29 if (instr->HasAtLeastOneUseWithFlagAndNoneWithout( 30 HInstruction::kTruncatingToSmi)) { 31 instr->SetFlag(HInstruction::kAllUsesTruncatingToSmi); 32 } else if (instr->HasAtLeastOneUseWithFlagAndNoneWithout( 33 HInstruction::kTruncatingToInt32)) { 34 // Avoid redundant minus zero check 35 instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32); 36 } 37 } 38 } 39 } 40 } 41 42 // Perform actual Canonicalization pass. 43 HRedundantPhiEliminationPhase redundant_phi_eliminator(graph()); 44 for (int i = 0; i < blocks->length(); ++i) { 45 // Eliminate redundant phis in the block first; changes to their inputs 46 // might have made them redundant, and eliminating them creates more 47 // opportunities for constant folding and strength reduction. 48 redundant_phi_eliminator.ProcessBlock(blocks->at(i)); 49 // Now canonicalize each instruction. 50 for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) { 51 HInstruction* instr = it.Current(); 52 HValue* value = instr->Canonicalize(); 53 if (value != instr) instr->DeleteAndReplaceWith(value); 54 } 55 } 56 } 57 58 } // namespace internal 59 } // namespace v8 60