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.cc69
1 files changed, 40 insertions, 29 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index d8a8554610..5fca4fab22 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -51,9 +51,7 @@ void HGraph::RemoveInstructionsAsUsersFromDeadBlocks(const ArenaBitVector& visit
for (size_t i = 0; i < blocks_.Size(); ++i) {
if (!visited.IsBitSet(i)) {
HBasicBlock* block = blocks_.Get(i);
- for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
- RemoveAsUser(it.Current());
- }
+ DCHECK(block->GetPhis().IsEmpty()) << "Phis are not inserted at this stage";
for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
RemoveAsUser(it.Current());
}
@@ -61,19 +59,17 @@ void HGraph::RemoveInstructionsAsUsersFromDeadBlocks(const ArenaBitVector& visit
}
}
-void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) const {
+void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) {
for (size_t i = 0; i < blocks_.Size(); ++i) {
if (!visited.IsBitSet(i)) {
HBasicBlock* block = blocks_.Get(i);
+ // We only need to update the successor, which might be live.
for (size_t j = 0; j < block->GetSuccessors().Size(); ++j) {
block->GetSuccessors().Get(j)->RemovePredecessor(block);
}
- for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
- block->RemovePhi(it.Current()->AsPhi(), /*ensure_safety=*/ false);
- }
- for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
- block->RemoveInstruction(it.Current(), /*ensure_safety=*/ false);
- }
+ // Remove the block from the list of blocks, so that further analyses
+ // never see it.
+ blocks_.Put(i, nullptr);
}
}
}
@@ -258,6 +254,7 @@ void HGraph::SimplifyCFG() {
// (2): Simplify loops by having only one back edge, and one preheader.
for (size_t i = 0; i < blocks_.Size(); ++i) {
HBasicBlock* block = blocks_.Get(i);
+ if (block == nullptr) continue;
if (block->GetSuccessors().Size() > 1) {
for (size_t j = 0; j < block->GetSuccessors().Size(); ++j) {
HBasicBlock* successor = block->GetSuccessors().Get(j);
@@ -274,8 +271,9 @@ void HGraph::SimplifyCFG() {
}
bool HGraph::AnalyzeNaturalLoops() const {
- for (size_t i = 0; i < blocks_.Size(); ++i) {
- HBasicBlock* block = blocks_.Get(i);
+ // Order does not matter.
+ for (HReversePostOrderIterator it(*this); !it.Done(); it.Advance()) {
+ HBasicBlock* block = it.Current();
if (block->IsLoopHeader()) {
HLoopInformation* info = block->GetLoopInformation();
if (!info->Populate()) {
@@ -964,23 +962,6 @@ static void MakeRoomFor(GrowableArray<HBasicBlock*>* blocks,
}
void HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {
- // Walk over the entry block and:
- // - Move constants from the entry block to the outer_graph's entry block,
- // - Replace HParameterValue instructions with their real value.
- // - Remove suspend checks, that hold an environment.
- int parameter_index = 0;
- for (HInstructionIterator it(entry_block_->GetInstructions()); !it.Done(); it.Advance()) {
- HInstruction* current = it.Current();
- if (current->IsConstant()) {
- current->MoveBefore(outer_graph->GetEntryBlock()->GetLastInstruction());
- } else if (current->IsParameterValue()) {
- current->ReplaceWith(invoke->InputAt(parameter_index++));
- } else {
- DCHECK(current->IsGoto() || current->IsSuspendCheck());
- entry_block_->RemoveInstruction(current);
- }
- }
-
if (GetBlocks().Size() == 3) {
// Simple case of an entry block, a body block, and an exit block.
// Put the body block's instruction into `invoke`'s block.
@@ -1106,6 +1087,36 @@ void HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {
}
}
+ // Update the next instruction id of the outer graph, so that instructions
+ // added later get bigger ids than those in the inner graph.
+ outer_graph->SetCurrentInstructionId(GetNextInstructionId());
+
+ // Walk over the entry block and:
+ // - Move constants from the entry block to the outer_graph's entry block,
+ // - Replace HParameterValue instructions with their real value.
+ // - Remove suspend checks, that hold an environment.
+ // We must do this after the other blocks have been inlined, otherwise ids of
+ // constants could overlap with the inner graph.
+ int parameter_index = 0;
+ for (HInstructionIterator it(entry_block_->GetInstructions()); !it.Done(); it.Advance()) {
+ HInstruction* current = it.Current();
+ if (current->IsNullConstant()) {
+ current->ReplaceWith(outer_graph->GetNullConstant());
+ } else if (current->IsIntConstant()) {
+ current->ReplaceWith(outer_graph->GetIntConstant(current->AsIntConstant()->GetValue()));
+ } else if (current->IsLongConstant()) {
+ current->ReplaceWith(outer_graph->GetLongConstant(current->AsLongConstant()->GetValue()));
+ } else if (current->IsFloatConstant() || current->IsDoubleConstant()) {
+ // TODO: Don't duplicate floating-point constants.
+ current->MoveBefore(outer_graph->GetEntryBlock()->GetLastInstruction());
+ } else if (current->IsParameterValue()) {
+ current->ReplaceWith(invoke->InputAt(parameter_index++));
+ } else {
+ DCHECK(current->IsGoto() || current->IsSuspendCheck());
+ entry_block_->RemoveInstruction(current);
+ }
+ }
+
// Finally remove the invoke from the caller.
invoke->GetBlock()->RemoveInstruction(invoke);
}