summaryrefslogtreecommitdiff
path: root/compiler/optimizing/ssa_builder.cc
diff options
context:
space:
mode:
authorDavid Brazdil <dbrazdil@google.com>2016-02-16 09:26:07 +0000
committerDavid Brazdil <dbrazdil@google.com>2016-04-04 11:21:20 +0100
commit86ea7eeabe30c98bbe1651a51d03cb89776724e7 (patch)
tree01702f6df5c39925b354a3152dd04289e7d97062 /compiler/optimizing/ssa_builder.cc
parent0cb5c86b7021e70cbf584c1455aad1ef383af786 (diff)
Build dominator tree before generating HInstructions
Second CL in the series of merging HGraphBuilder and SsaBuilder. This patch refactors the builders so that dominator tree can be built before any HInstructions are generated. This puts the SsaBuilder removal of HLoadLocals/HStoreLocals straight after HGraphBuilder's HInstruction generation phase. Next CL will therefore be able to merge them. This patch also adds util classes for iterating bytecode and switch tables which allowed to simplify the code. Bug: 27894376 Change-Id: Ic425d298b2e6e7980481ed697230b1a0b7904526
Diffstat (limited to 'compiler/optimizing/ssa_builder.cc')
-rw-r--r--compiler/optimizing/ssa_builder.cc29
1 files changed, 25 insertions, 4 deletions
diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc
index 294d00f8e2..5a05256628 100644
--- a/compiler/optimizing/ssa_builder.cc
+++ b/compiler/optimizing/ssa_builder.cc
@@ -16,6 +16,7 @@
#include "ssa_builder.h"
+#include "bytecode_utils.h"
#include "nodes.h"
#include "reference_type_propagation.h"
#include "ssa_phi_elimination.h"
@@ -627,7 +628,6 @@ void SsaBuilder::VisitBasicBlock(HBasicBlock* block) {
// Make sure there was at least one throwing instruction which initialized
// locals (guaranteed by HGraphBuilder) and that all try blocks have been
// visited already (from HTryBoundary scoping and reverse post order).
- bool throwing_instruction_found = false;
bool catch_block_visited = false;
for (HReversePostOrderIterator it(*GetGraph()); !it.Done(); it.Advance()) {
HBasicBlock* current = it.Current();
@@ -636,10 +636,10 @@ void SsaBuilder::VisitBasicBlock(HBasicBlock* block) {
} else if (current->IsTryBlock() &&
current->GetTryCatchInformation()->GetTryEntry().HasExceptionHandler(*block)) {
DCHECK(!catch_block_visited) << "Catch block visited before its try block.";
- throwing_instruction_found |= current->HasThrowingInstructions();
}
}
- DCHECK(throwing_instruction_found) << "No instructions throwing into a live catch block.";
+ DCHECK_EQ(current_locals_->size(), GetGraph()->GetNumberOfVRegs())
+ << "No instructions throwing into a live catch block.";
}
} else if (block->IsLoopHeader()) {
// If the block is a loop header, we know we only have visited the pre header
@@ -899,6 +899,27 @@ void SsaBuilder::VisitStoreLocal(HStoreLocal* store) {
store->GetBlock()->RemoveInstruction(store);
}
+bool SsaBuilder::IsFirstAtThrowingDexPc(HInstruction* instruction) const {
+ uint32_t dex_pc = instruction->GetDexPc();
+ if (dex_pc == kNoDexPc) {
+ return false;
+ }
+
+ // Needs to be the first HInstruction with this dex_pc.
+ HInstruction* previous = instruction->GetPrevious();
+ if (previous != nullptr && previous->GetDexPc() == dex_pc) {
+ return false;
+ }
+
+ if (instruction->IsControlFlow() && !instruction->IsThrow()) {
+ // Special-case non-throwing control-flow HInstruction because artifically
+ // created ones are given dex_pc of the nearest bytecode instructions.
+ return false;
+ }
+
+ return IsThrowingDexInstruction(GetDexInstructionAt(code_item_, dex_pc));
+}
+
void SsaBuilder::VisitInstruction(HInstruction* instruction) {
if (instruction->NeedsEnvironment()) {
HEnvironment* environment = new (GetGraph()->GetArena()) HEnvironment(
@@ -914,7 +935,7 @@ void SsaBuilder::VisitInstruction(HInstruction* instruction) {
}
// If in a try block, propagate values of locals into catch blocks.
- if (instruction->CanThrowIntoCatchBlock()) {
+ if (instruction->GetBlock()->IsTryBlock() && IsFirstAtThrowingDexPc(instruction)) {
const HTryBoundary& try_entry =
instruction->GetBlock()->GetTryCatchInformation()->GetTryEntry();
for (HBasicBlock* catch_block : try_entry.GetExceptionHandlers()) {