diff options
Diffstat (limited to 'compiler/optimizing/nodes.cc')
| -rw-r--r-- | compiler/optimizing/nodes.cc | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index a058dea6b4..d624ad5e5e 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -363,6 +363,25 @@ void HBasicBlock::AddPhi(HPhi* phi) { Add(&phis_, this, phi); } +void HBasicBlock::InsertPhiAfter(HPhi* phi, HPhi* cursor) { + DCHECK_EQ(phi->GetId(), -1); + DCHECK_NE(cursor->GetId(), -1); + DCHECK_EQ(cursor->GetBlock(), this); + if (cursor->next_ == nullptr) { + cursor->next_ = phi; + phi->previous_ = cursor; + DCHECK(phi->next_ == nullptr); + } else { + phi->next_ = cursor->next_; + phi->previous_ = cursor; + cursor->next_ = phi; + phi->next_->previous_ = phi; + } + phi->SetBlock(this); + phi->SetId(GetGraph()->GetNextInstructionId()); + UpdateInputsUsers(phi); +} + static void Remove(HInstructionList* instruction_list, HBasicBlock* block, HInstruction* instruction) { @@ -472,7 +491,11 @@ bool HInstructionList::FoundBefore(const HInstruction* instruction1, return true; } -bool HInstruction::Dominates(HInstruction* other_instruction) const { +bool HInstruction::StrictlyDominates(HInstruction* other_instruction) const { + if (other_instruction == this) { + // An instruction does not strictly dominate itself. + return false; + } HBasicBlock* block = GetBlock(); HBasicBlock* other_block = other_instruction->GetBlock(); if (block != other_block) { @@ -527,6 +550,12 @@ void HInstruction::ReplaceWith(HInstruction* other) { env_uses_ = nullptr; } +void HInstruction::ReplaceInput(HInstruction* replacement, size_t index) { + InputAt(index)->RemoveUser(this, index); + SetRawInputAt(index, replacement); + replacement->AddUseAt(this, index); +} + size_t HInstruction::EnvironmentSize() const { return HasEnvironment() ? environment_->Size() : 0; } @@ -553,6 +582,12 @@ void HGraphVisitor::VisitInsertionOrder() { } } +void HGraphVisitor::VisitReversePostOrder() { + for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { + VisitBasicBlock(it.Current()); + } +} + void HGraphVisitor::VisitBasicBlock(HBasicBlock* block) { for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { it.Current()->Accept(this); @@ -562,15 +597,30 @@ void HGraphVisitor::VisitBasicBlock(HBasicBlock* block) { } } -HConstant* HBinaryOperation::TryStaticEvaluation(ArenaAllocator* allocator) const { +HConstant* HUnaryOperation::TryStaticEvaluation() const { + if (GetInput()->IsIntConstant()) { + int32_t value = Evaluate(GetInput()->AsIntConstant()->GetValue()); + return new(GetBlock()->GetGraph()->GetArena()) HIntConstant(value); + } else if (GetInput()->IsLongConstant()) { + // TODO: Implement static evaluation of long unary operations. + // + // Do not exit with a fatal condition here. Instead, simply + // return `nullptr' to notify the caller that this instruction + // cannot (yet) be statically evaluated. + return nullptr; + } + return nullptr; +} + +HConstant* HBinaryOperation::TryStaticEvaluation() const { if (GetLeft()->IsIntConstant() && GetRight()->IsIntConstant()) { int32_t value = Evaluate(GetLeft()->AsIntConstant()->GetValue(), GetRight()->AsIntConstant()->GetValue()); - return new(allocator) HIntConstant(value); + return new(GetBlock()->GetGraph()->GetArena()) HIntConstant(value); } else if (GetLeft()->IsLongConstant() && GetRight()->IsLongConstant()) { int64_t value = Evaluate(GetLeft()->AsLongConstant()->GetValue(), GetRight()->AsLongConstant()->GetValue()); - return new(allocator) HLongConstant(value); + return new(GetBlock()->GetGraph()->GetArena()) HLongConstant(value); } return nullptr; } |