diff options
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r-- | compiler/optimizing/nodes.cc | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 207c605ddd..376d1af3ef 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -194,6 +194,11 @@ void HGraph::SimplifyLoop(HBasicBlock* header) { } pre_header->AddSuccessor(header); } + + // Make sure the second predecessor of a loop header is the back edge. + if (header->GetPredecessors().Get(1) != info->GetBackEdges().Get(0)) { + header->SwapPredecessors(); + } } void HGraph::SimplifyCFG() { @@ -307,6 +312,14 @@ void HBasicBlock::InsertInstructionBefore(HInstruction* instruction, HInstructio instruction->SetId(GetGraph()->GetNextInstructionId()); } +void HBasicBlock::ReplaceAndRemoveInstructionWith(HInstruction* initial, + HInstruction* replacement) { + DCHECK(initial->GetBlock() == this); + InsertInstructionBefore(replacement, initial); + initial->ReplaceWith(replacement); + RemoveInstruction(initial); +} + static void Add(HInstructionList* instruction_list, HBasicBlock* block, HInstruction* instruction) { @@ -392,6 +405,54 @@ void HInstructionList::RemoveInstruction(HInstruction* instruction) { } } +bool HInstructionList::FoundBefore(const HInstruction* instruction1, + const HInstruction* instruction2) const { + DCHECK_EQ(instruction1->GetBlock(), instruction2->GetBlock()); + for (HInstructionIterator it(*this); !it.Done(); it.Advance()) { + if (it.Current() == instruction1) { + return true; + } + if (it.Current() == instruction2) { + return false; + } + } + LOG(FATAL) << "Did not find an order between two instructions of the same block."; + return true; +} + +bool HInstruction::Dominates(HInstruction* other_instruction) const { + HBasicBlock* block = GetBlock(); + HBasicBlock* other_block = other_instruction->GetBlock(); + if (block != other_block) { + return GetBlock()->Dominates(other_instruction->GetBlock()); + } else { + // If both instructions are in the same block, ensure this + // instruction comes before `other_instruction`. + if (IsPhi()) { + if (!other_instruction->IsPhi()) { + // Phis appear before non phi-instructions so this instruction + // dominates `other_instruction`. + return true; + } else { + // There is no order among phis. + LOG(FATAL) << "There is no dominance between phis of a same block."; + return false; + } + } else { + // `this` is not a phi. + if (other_instruction->IsPhi()) { + // Phis appear before non phi-instructions so this instruction + // does not dominate `other_instruction`. + return false; + } else { + // Check whether this instruction comes before + // `other_instruction` in the instruction list. + return block->GetInstructions().FoundBefore(this, other_instruction); + } + } + } +} + void HInstruction::ReplaceWith(HInstruction* other) { DCHECK(other != nullptr); for (HUseIterator<HInstruction> it(GetUses()); !it.Done(); it.Advance()) { @@ -449,6 +510,18 @@ void HGraphVisitor::VisitBasicBlock(HBasicBlock* block) { } } +HConstant* HBinaryOperation::TryStaticEvaluation(ArenaAllocator* allocator) const { + if (GetLeft()->IsIntConstant() && GetRight()->IsIntConstant()) { + int32_t value = Evaluate(GetLeft()->AsIntConstant()->GetValue(), + GetRight()->AsIntConstant()->GetValue()); + return new(allocator) HIntConstant(value); + } else if (GetLeft()->IsLongConstant() && GetRight()->IsLongConstant()) { + int64_t value = Evaluate(GetLeft()->AsLongConstant()->GetValue(), + GetRight()->AsLongConstant()->GetValue()); + return new(allocator) HLongConstant(value); + } + return nullptr; +} bool HCondition::NeedsMaterialization() const { if (!HasOnlyOneUse()) { |