diff options
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r-- | compiler/optimizing/nodes.cc | 69 |
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); } |