summaryrefslogtreecommitdiff
path: root/compiler/optimizing/dead_code_elimination.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2023-04-25 16:40:06 +0000
committer Vladimir Marko <vmarko@google.com> 2023-04-27 10:53:55 +0000
commitcde6497d286337de2ed21c71c85157e2745b742b (patch)
tree087d790efb6987f5aab1da7cd91b89bedcdc5725 /compiler/optimizing/dead_code_elimination.cc
parent79dc217688a774fc532584f6551a0aec8b45bc4a (diff)
Optimizing: Add `HInstruction::As##type()`.
After the old implementation was renamed in https://android-review.googlesource.com/2526708 , we introduce a new function with the old name but new behavior, just `DCHECK()`-ing the instruction kind before casting down the pointer. We change appropriate calls from `As##type##OrNull()` to `As##type()` to avoid unncessary run-time checks and reduce the size of libart-compiler.so. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: run-gtests.sh Test: testrunner.py --target --optimizing Bug: 181943478 Change-Id: I025681612a77ca2157fed4886ca47f2053975d4e
Diffstat (limited to 'compiler/optimizing/dead_code_elimination.cc')
-rw-r--r--compiler/optimizing/dead_code_elimination.cc103
1 files changed, 34 insertions, 69 deletions
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index 5840651467..cf49e39849 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -47,29 +47,23 @@ static void MarkReachableBlocks(HGraph* graph, ArenaBitVector* visited) {
ArrayRef<HBasicBlock* const> live_successors(block->GetSuccessors());
HInstruction* last_instruction = block->GetLastInstruction();
if (last_instruction->IsIf()) {
- // TODO: Remove "OrNull".
- HIf* if_instruction = last_instruction->AsIfOrNull();
+ HIf* if_instruction = last_instruction->AsIf();
HInstruction* condition = if_instruction->InputAt(0);
if (condition->IsIntConstant()) {
- // TODO: Remove "OrNull".
- if (condition->AsIntConstantOrNull()->IsTrue()) {
+ if (condition->AsIntConstant()->IsTrue()) {
live_successors = live_successors.SubArray(0u, 1u);
DCHECK_EQ(live_successors[0], if_instruction->IfTrueSuccessor());
} else {
- // TODO: Remove "OrNull".
- DCHECK(condition->AsIntConstantOrNull()->IsFalse())
- << condition->AsIntConstantOrNull()->GetValue();
+ DCHECK(condition->AsIntConstant()->IsFalse()) << condition->AsIntConstant()->GetValue();
live_successors = live_successors.SubArray(1u, 1u);
DCHECK_EQ(live_successors[0], if_instruction->IfFalseSuccessor());
}
}
} else if (last_instruction->IsPackedSwitch()) {
- // TODO: Remove "OrNull".
- HPackedSwitch* switch_instruction = last_instruction->AsPackedSwitchOrNull();
+ HPackedSwitch* switch_instruction = last_instruction->AsPackedSwitch();
HInstruction* switch_input = switch_instruction->InputAt(0);
if (switch_input->IsIntConstant()) {
- // TODO: Remove "OrNull".
- int32_t switch_value = switch_input->AsIntConstantOrNull()->GetValue();
+ int32_t switch_value = switch_input->AsIntConstant()->GetValue();
int32_t start_value = switch_instruction->GetStartValue();
// Note: Though the spec forbids packed-switch values to wrap around, we leave
// that task to the verifier and use unsigned arithmetic with it's "modulo 2^32"
@@ -142,21 +136,16 @@ static HConstant* Evaluate(HCondition* condition, HInstruction* left, HInstructi
}
if (left->IsIntConstant()) {
- // TODO: Remove "OrNull".
- return condition->Evaluate(left->AsIntConstantOrNull(), right->AsIntConstantOrNull());
+ return condition->Evaluate(left->AsIntConstant(), right->AsIntConstant());
} else if (left->IsNullConstant()) {
- // TODO: Remove "OrNull".
- return condition->Evaluate(left->AsNullConstantOrNull(), right->AsNullConstantOrNull());
+ return condition->Evaluate(left->AsNullConstant(), right->AsNullConstant());
} else if (left->IsLongConstant()) {
- // TODO: Remove "OrNull".
- return condition->Evaluate(left->AsLongConstantOrNull(), right->AsLongConstantOrNull());
+ return condition->Evaluate(left->AsLongConstant(), right->AsLongConstant());
} else if (left->IsFloatConstant()) {
- // TODO: Remove "OrNull".
- return condition->Evaluate(left->AsFloatConstantOrNull(), right->AsFloatConstantOrNull());
+ return condition->Evaluate(left->AsFloatConstant(), right->AsFloatConstant());
} else {
DCHECK(left->IsDoubleConstant());
- // TODO: Remove "OrNull".
- return condition->Evaluate(left->AsDoubleConstantOrNull(), right->AsDoubleConstantOrNull());
+ return condition->Evaluate(left->AsDoubleConstant(), right->AsDoubleConstant());
}
}
@@ -165,8 +154,7 @@ static bool RemoveNonNullControlDependences(HBasicBlock* block, HBasicBlock* thr
if (!block->EndsWithIf()) {
return false;
}
- // TODO: Remove "OrNull".
- HIf* ifs = block->GetLastInstruction()->AsIfOrNull();
+ HIf* ifs = block->GetLastInstruction()->AsIf();
// Find either:
// if obj == null
// throws
@@ -279,8 +267,7 @@ bool HDeadCodeElimination::SimplifyAlwaysThrows() {
// throw, the first one will throw and the second one will never be reached.
HInstruction* throwing_invoke = nullptr;
for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
- // TODO: Remove "OrNull".
- if (it.Current()->IsInvoke() && it.Current()->AsInvokeOrNull()->AlwaysThrows()) {
+ if (it.Current()->IsInvoke() && it.Current()->AsInvoke()->AlwaysThrows()) {
throwing_invoke = it.Current();
break;
}
@@ -375,15 +362,13 @@ bool HDeadCodeElimination::SimplifyIfs() {
bool has_only_phi_condition_and_if =
!has_only_phi_and_if &&
first->IsCondition() &&
- // TODO: Remove "OrNull".
- HasInput(first->AsConditionOrNull(), block->GetFirstPhi()) &&
+ HasInput(first->AsCondition(), block->GetFirstPhi()) &&
(first->GetNext() == last) &&
(last->InputAt(0) == first) &&
first->HasOnlyOneNonEnvironmentUse();
if (has_only_phi_and_if || has_only_phi_condition_and_if) {
- // TODO: Remove "OrNull".
- HPhi* phi = block->GetFirstPhi()->AsPhiOrNull();
+ HPhi* phi = block->GetFirstPhi()->AsPhi();
bool phi_input_is_left = (first->InputAt(0) == phi);
// Walk over all inputs of the phis and update the control flow of
@@ -399,11 +384,9 @@ bool HDeadCodeElimination::SimplifyIfs() {
} else {
DCHECK(has_only_phi_condition_and_if);
if (phi_input_is_left) {
- // TODO: Remove "OrNull".
- value_to_check = Evaluate(first->AsConditionOrNull(), input, first->InputAt(1));
+ value_to_check = Evaluate(first->AsCondition(), input, first->InputAt(1));
} else {
- // TODO: Remove "OrNull".
- value_to_check = Evaluate(first->AsConditionOrNull(), first->InputAt(0), input);
+ value_to_check = Evaluate(first->AsCondition(), first->InputAt(0), input);
}
}
if (value_to_check == nullptr) {
@@ -412,16 +395,12 @@ bool HDeadCodeElimination::SimplifyIfs() {
} else {
HBasicBlock* predecessor_to_update = block->GetPredecessors()[i];
HBasicBlock* successor_to_update = nullptr;
- // TODO: Remove "OrNull".
- if (value_to_check->AsIntConstantOrNull()->IsTrue()) {
- // TODO: Remove "OrNull".
- successor_to_update = last->AsIfOrNull()->IfTrueSuccessor();
+ if (value_to_check->AsIntConstant()->IsTrue()) {
+ successor_to_update = last->AsIf()->IfTrueSuccessor();
} else {
- // TODO: Remove "OrNull".
- DCHECK(value_to_check->AsIntConstantOrNull()->IsFalse())
- << value_to_check->AsIntConstantOrNull()->GetValue();
- // TODO: Remove "OrNull".
- successor_to_update = last->AsIfOrNull()->IfFalseSuccessor();
+ DCHECK(value_to_check->AsIntConstant()->IsFalse())
+ << value_to_check->AsIntConstant()->GetValue();
+ successor_to_update = last->AsIf()->IfFalseSuccessor();
}
predecessor_to_update->ReplaceSuccessor(block, successor_to_update);
phi->RemoveInputAt(i);
@@ -442,8 +421,7 @@ bool HDeadCodeElimination::SimplifyIfs() {
if (has_only_phi_condition_and_if) {
// Evaluate here (and not wait for a constant folding pass) to open
// more opportunities for DCE.
- // TODO: Remove "OrNull".
- HInstruction* result = first->AsConditionOrNull()->TryStaticEvaluation();
+ HInstruction* result = first->AsCondition()->TryStaticEvaluation();
if (result != nullptr) {
first->ReplaceWith(result);
block->RemoveInstruction(first);
@@ -476,8 +454,7 @@ bool HDeadCodeElimination::SimplifyIfs() {
void HDeadCodeElimination::MaybeAddPhi(HBasicBlock* block) {
DCHECK(block->GetLastInstruction()->IsIf());
- // TODO: Remove "OrNull".
- HIf* if_instruction = block->GetLastInstruction()->AsIfOrNull();
+ HIf* if_instruction = block->GetLastInstruction()->AsIf();
if (if_instruction->InputAt(0)->IsConstant()) {
// Constant values are handled in RemoveDeadBlocks.
return;
@@ -500,8 +477,7 @@ void HDeadCodeElimination::MaybeAddPhi(HBasicBlock* block) {
}
HInstruction* input = if_instruction->InputAt(0);
- // TODO: Remove "OrNull".
- HInstruction* dominator_input = dominator->GetLastInstruction()->AsIfOrNull()->InputAt(0);
+ HInstruction* dominator_input = dominator->GetLastInstruction()->AsIf()->InputAt(0);
const bool same_input = dominator_input == input;
if (!same_input) {
// Try to see if the dominator has the opposite input (e.g. if(cond) and if(!cond)). If that's
@@ -510,10 +486,8 @@ void HDeadCodeElimination::MaybeAddPhi(HBasicBlock* block) {
return;
}
- // TODO: Remove "OrNull".
- HCondition* block_cond = input->AsConditionOrNull();
- // TODO: Remove "OrNull".
- HCondition* dominator_cond = dominator_input->AsConditionOrNull();
+ HCondition* block_cond = input->AsCondition();
+ HCondition* dominator_cond = dominator_input->AsCondition();
if (block_cond->GetLeft() != dominator_cond->GetLeft() ||
block_cond->GetRight() != dominator_cond->GetRight() ||
@@ -536,12 +510,10 @@ void HDeadCodeElimination::MaybeAddPhi(HBasicBlock* block) {
for (size_t index = 0; index < pred_size; index++) {
HBasicBlock* pred = block->GetPredecessors()[index];
- // TODO: Remove "OrNull".
const bool dominated_by_true =
- dominator->GetLastInstruction()->AsIfOrNull()->IfTrueSuccessor()->Dominates(pred);
- // TODO: Remove "OrNull".
+ dominator->GetLastInstruction()->AsIf()->IfTrueSuccessor()->Dominates(pred);
const bool dominated_by_false =
- dominator->GetLastInstruction()->AsIfOrNull()->IfFalseSuccessor()->Dominates(pred);
+ dominator->GetLastInstruction()->AsIf()->IfFalseSuccessor()->Dominates(pred);
if (dominated_by_true == dominated_by_false) {
// In this case, we can't know if we are coming from the true branch, or the false branch. It
// happens in cases like:
@@ -672,14 +644,12 @@ void HDeadCodeElimination::RemoveTry(HBasicBlock* try_entry,
/* out */ bool* any_block_in_loop) {
// Update all try entries.
DCHECK(try_entry->EndsWithTryBoundary());
- // TODO: Remove "OrNull".
- DCHECK(try_entry->GetLastInstruction()->AsTryBoundaryOrNull()->IsEntry());
+ DCHECK(try_entry->GetLastInstruction()->AsTryBoundary()->IsEntry());
DisconnectHandlersAndUpdateTryBoundary(try_entry, any_block_in_loop);
for (HBasicBlock* other_try_entry : try_belonging_info.coalesced_try_entries) {
DCHECK(other_try_entry->EndsWithTryBoundary());
- // TODO: Remove "OrNull".
- DCHECK(other_try_entry->GetLastInstruction()->AsTryBoundaryOrNull()->IsEntry());
+ DCHECK(other_try_entry->GetLastInstruction()->AsTryBoundary()->IsEntry());
DisconnectHandlersAndUpdateTryBoundary(other_try_entry, any_block_in_loop);
}
@@ -693,8 +663,7 @@ void HDeadCodeElimination::RemoveTry(HBasicBlock* try_entry,
if (block->EndsWithTryBoundary()) {
// Try exits.
- // TODO: Remove "OrNull".
- DCHECK(!block->GetLastInstruction()->AsTryBoundaryOrNull()->IsEntry());
+ DCHECK(!block->GetLastInstruction()->AsTryBoundary()->IsEntry());
DisconnectHandlersAndUpdateTryBoundary(block, any_block_in_loop);
if (block->GetSingleSuccessor()->IsExitBlock()) {
@@ -743,13 +712,10 @@ bool HDeadCodeElimination::RemoveUnneededTries() {
// Deduplicate the tries which have different try entries but they are really the same try.
for (auto it = tries.begin(); it != tries.end(); it++) {
DCHECK(it->first->EndsWithTryBoundary());
- // TODO: Remove "OrNull".
- HTryBoundary* try_boundary = it->first->GetLastInstruction()->AsTryBoundaryOrNull();
+ HTryBoundary* try_boundary = it->first->GetLastInstruction()->AsTryBoundary();
for (auto other_it = next(it); other_it != tries.end(); /*other_it++ in the loop*/) {
DCHECK(other_it->first->EndsWithTryBoundary());
- // TODO: Remove "OrNull".
- HTryBoundary* other_try_boundary =
- other_it->first->GetLastInstruction()->AsTryBoundaryOrNull();
+ HTryBoundary* other_try_boundary = other_it->first->GetLastInstruction()->AsTryBoundary();
if (try_boundary->HasSameExceptionHandlersAs(*other_try_boundary)) {
// Merge the entries as they are really the same one.
// Block merging.
@@ -889,8 +855,7 @@ void HDeadCodeElimination::UpdateGraphFlags() {
has_simd = true;
} else if (instruction->IsBoundsCheck()) {
has_bounds_checks = true;
- // TODO: Remove "OrNull".
- } else if (instruction->IsInvoke() && instruction->AsInvokeOrNull()->AlwaysThrows()) {
+ } else if (instruction->IsInvoke() && instruction->AsInvoke()->AlwaysThrows()) {
has_always_throwing_invokes = true;
}
}