summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r--compiler/optimizing/nodes.cc58
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;
}