From 79dc217688a774fc532584f6551a0aec8b45bc4a Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Wed, 5 Apr 2023 10:33:07 +0000 Subject: Optimizing: Rename `As##type` to `As##type##OrNull`. The null type check in the current implementation of `HInstruction::As##type()` often cannot be optimized away by clang++. It is therefore beneficial to have two functions HInstruction::As##type() HInstruction::As##type##OrNull() where the first function never returns null but the second one can return null. The additional text "OrNull" shall also flag the possibility of yielding null to the developer which may help avoid bugs similar to what we have seen previously. This requires renaming the existing function that can return null and introducing new function that cannot. However, defining the new function `HInstruction::As##type()` in the same change as renaming the old one would risk introducing bugs by missing a rename. Therefore we simply rename the old function here and the new function shall be introduced in a separate change with all behavioral changes being explicit. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: buildbot-build.sh --target Bug: 181943478 Change-Id: I4defd85038e28fe3506903ba3f33f723682b3298 --- compiler/optimizing/code_sinking.cc | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'compiler/optimizing/code_sinking.cc') diff --git a/compiler/optimizing/code_sinking.cc b/compiler/optimizing/code_sinking.cc index d759a16f48..8a3066521f 100644 --- a/compiler/optimizing/code_sinking.cc +++ b/compiler/optimizing/code_sinking.cc @@ -53,7 +53,8 @@ void CodeSinking::UncommonBranchSinking() { // actual last instruction. if (last->IsTryBoundary()) { // We have an exit try boundary. Fetch the previous instruction. - DCHECK(!last->AsTryBoundary()->IsEntry()); + // TODO: Remove "OrNull". + DCHECK(!last->AsTryBoundaryOrNull()->IsEntry()); if (last->GetPrevious() == nullptr) { DCHECK(exit_predecessor->IsSingleTryBoundary()); exit_predecessor = exit_predecessor->GetSinglePredecessor(); @@ -80,7 +81,8 @@ static bool IsInterestingInstruction(HInstruction* instruction) { // Volatile stores cannot be moved. if (instruction->IsInstanceFieldSet()) { - if (instruction->AsInstanceFieldSet()->IsVolatile()) { + // TODO: Remove "OrNull". + if (instruction->AsInstanceFieldSetOrNull()->IsVolatile()) { return false; } } @@ -93,7 +95,8 @@ static bool IsInterestingInstruction(HInstruction* instruction) { // Check it is safe to move ConstructorFence. // (Safe to move ConstructorFence for only protecting the new-instance but not for finals.) if (instruction->IsConstructorFence()) { - HConstructorFence* ctor_fence = instruction->AsConstructorFence(); + // TODO: Remove "OrNull". + HConstructorFence* ctor_fence = instruction->AsConstructorFenceOrNull(); // A fence with "0" inputs is dead and should've been removed in a prior pass. DCHECK_NE(0u, ctor_fence->InputCount()); @@ -215,7 +218,8 @@ static HInstruction* FindIdealPosition(HInstruction* instruction, if (user->IsPhi()) { // Special case phis by taking the incoming block for regular ones, // or the dominator for catch phis. - block = user->AsPhi()->IsCatchPhi() + // TODO: Remove "OrNull". + block = user->AsPhiOrNull()->IsCatchPhi() ? block->GetDominator() : block->GetPredecessors()[use.GetIndex()]; } @@ -314,7 +318,8 @@ static HInstruction* FindIdealPosition(HInstruction* instruction, DCHECK(insert_pos->IsControlFlow()); // Avoid splitting HCondition from HIf to prevent unnecessary materialization. if (insert_pos->IsIf()) { - HInstruction* if_input = insert_pos->AsIf()->InputAt(0); + // TODO: Remove "OrNull". + HInstruction* if_input = insert_pos->AsIfOrNull()->InputAt(0); if (if_input == insert_pos->GetPrevious()) { insert_pos = if_input; } @@ -381,7 +386,9 @@ void CodeSinking::SinkCodeToUncommonBranch(HBasicBlock* end_block) { // If we sink to these basic blocks we would be sinking inside of the try so we would like // to check the catch block for post dominance. const bool ends_with_try_boundary_entry = - block->EndsWithTryBoundary() && block->GetLastInstruction()->AsTryBoundary()->IsEntry(); + block->EndsWithTryBoundary() && + // TODO: Remove "OrNull". + block->GetLastInstruction()->AsTryBoundaryOrNull()->IsEntry(); ArrayRef successors = ends_with_try_boundary_entry ? block->GetNormalSuccessors() : ArrayRef(block->GetSuccessors()); @@ -571,7 +578,8 @@ void CodeSinking::ReturnSinking() { continue; } - HReturn* ret = pred->GetLastInstruction()->AsReturn(); + // TODO: Remove "OrNull". + HReturn* ret = pred->GetLastInstruction()->AsReturnOrNull(); if (new_phi == nullptr) { // Create the new_phi, if we haven't done so yet. We do it here since we need to know the // type to assign to it. @@ -596,7 +604,8 @@ void CodeSinking::ReturnSinking() { continue; } - HReturnVoid* ret = pred->GetLastInstruction()->AsReturnVoid(); + // TODO: Remove "OrNull". + HReturnVoid* ret = pred->GetLastInstruction()->AsReturnVoidOrNull(); pred->ReplaceAndRemoveInstructionWith(ret, new (graph_->GetAllocator()) HGoto(ret->GetDexPc())); pred->ReplaceSuccessor(exit, new_block); -- cgit v1.2.3-59-g8ed1b