diff options
author | 2023-04-05 10:33:07 +0000 | |
---|---|---|
committer | 2023-04-27 10:52:39 +0000 | |
commit | 79dc217688a774fc532584f6551a0aec8b45bc4a (patch) | |
tree | 5abfe4bd90364e66b593088ab4d1b407b51dada5 /compiler/optimizing/loop_optimization.cc | |
parent | d60aff547dedefc35265ce57707d406e8ccc4dc6 (diff) |
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
Diffstat (limited to 'compiler/optimizing/loop_optimization.cc')
-rw-r--r-- | compiler/optimizing/loop_optimization.cc | 72 |
1 files changed, 48 insertions, 24 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index d5e34634c8..4c517482c8 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -732,7 +732,8 @@ void HLoopOptimization::SimplifyInduction(LoopNode* node) { // Examples: for (int i = 0; x != null; i++) { .... no i .... } // for (int i = 0; i < 10; i++, k++) { .... no k .... } return k; for (HInstructionIterator it(header->GetPhis()); !it.Done(); it.Advance()) { - HPhi* phi = it.Current()->AsPhi(); + // TODO: Remove "OrNull". + HPhi* phi = it.Current()->AsPhiOrNull(); if (TrySetPhiInduction(phi, /*restrict_uses*/ true) && TryAssignLastValue(node->loop_info, phi, preheader, /*collect_loop_uses*/ false)) { // Note that it's ok to have replaced uses after the loop with the last value, without @@ -891,8 +892,9 @@ bool HLoopOptimization::TryUnrollingForBranchPenaltyReduction(LoopAnalysisInfo* helper.DoUnrolling(); // Remove the redundant loop check after unrolling. + // TODO: Remove "OrNull". HIf* copy_hif = - helper.GetBasicBlockMap()->Get(loop_info->GetHeader())->GetLastInstruction()->AsIf(); + helper.GetBasicBlockMap()->Get(loop_info->GetHeader())->GetLastInstruction()->AsIfOrNull(); int32_t constant = loop_info->Contains(*copy_hif->IfTrueSuccessor()) ? 1 : 0; copy_hif->ReplaceInput(graph_->GetIntConstant(constant), 0u); } @@ -920,7 +922,8 @@ bool HLoopOptimization::TryPeelingForLoopInvariantExitsElimination(LoopAnalysisI for (auto entry : *hir_map) { HInstruction* copy = entry.second; if (copy->IsIf()) { - TryToEvaluateIfCondition(copy->AsIf(), graph_); + // TODO: Remove "OrNull". + TryToEvaluateIfCondition(copy->AsIfOrNull(), graph_); } } } @@ -959,7 +962,8 @@ bool HLoopOptimization::TryFullUnrolling(LoopAnalysisInfo* analysis_info, bool g // HLoopInformation* loop_info = analysis_info->GetLoopInfo(); PeelByCount(loop_info, trip_count, &induction_range_); - HIf* loop_hif = loop_info->GetHeader()->GetLastInstruction()->AsIf(); + // TODO: Remove "OrNull". + HIf* loop_hif = loop_info->GetHeader()->GetLastInstruction()->AsIfOrNull(); int32_t constant = loop_info->Contains(*loop_hif->IfTrueSuccessor()) ? 0 : 1; loop_hif->ReplaceInput(graph_->GetIntConstant(constant), 0u); } @@ -1367,7 +1371,8 @@ void HLoopOptimization::GenerateNewLoop(LoopNode* node, if (i != vector_map_->end() && !i->second->IsInBlock()) { Insert(vector_body_, i->second); if (IsInPredicatedVectorizationMode() && i->second->IsVecOperation()) { - HVecOperation* op = i->second->AsVecOperation(); + // TODO: Remove "OrNull". + HVecOperation* op = i->second->AsVecOperationOrNull(); op->SetMergingGoverningPredicate(set_pred); } // Deal with instructions that need an environment, such as the scalar intrinsics. @@ -1384,7 +1389,8 @@ void HLoopOptimization::GenerateNewLoop(LoopNode* node, for (auto i = reductions_->begin(); i != reductions_->end(); ++i) { if (!i->first->IsPhi()) { DCHECK(i->second->IsPhi()); - GenerateVecReductionPhiInputs(i->second->AsPhi(), i->first); + // TODO: Remove "OrNull". + GenerateVecReductionPhiInputs(i->second->AsPhiOrNull(), i->first); } } // Finalize phi inputs for the loop index. @@ -1407,7 +1413,8 @@ bool HLoopOptimization::VectorizeDef(LoopNode* node, return false; } if (instruction->IsArraySet()) { - DataType::Type type = instruction->AsArraySet()->GetComponentType(); + // TODO: Remove "OrNull". + DataType::Type type = instruction->AsArraySetOrNull()->GetComponentType(); HInstruction* base = instruction->InputAt(0); HInstruction* index = instruction->InputAt(1); HInstruction* value = instruction->InputAt(2); @@ -1483,7 +1490,8 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node, return true; } else if (instruction->IsArrayGet()) { // Deal with vector restrictions. - bool is_string_char_at = instruction->AsArrayGet()->IsStringCharAt(); + // TODO: Remove "OrNull". + bool is_string_char_at = instruction->AsArrayGetOrNull()->IsStringCharAt(); if (is_string_char_at && (HasVectorRestrictions(restrictions, kNoStringCharAt) || IsInPredicatedVectorizationMode())) { @@ -1518,7 +1526,8 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node, } // Accept a reduction. if (generate_code) { - GenerateVecReductionPhi(instruction->AsPhi()); + // TODO: Remove "OrNull". + GenerateVecReductionPhi(instruction->AsPhiOrNull()); } return true; } @@ -1526,7 +1535,8 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node, return false; } else if (instruction->IsTypeConversion()) { // Accept particular type conversions. - HTypeConversion* conversion = instruction->AsTypeConversion(); + // TODO: Remove "OrNull". + HTypeConversion* conversion = instruction->AsTypeConversionOrNull(); HInstruction* opa = conversion->InputAt(0); DataType::Type from = conversion->GetInputType(); DataType::Type to = conversion->GetResultType(); @@ -1862,7 +1872,8 @@ void HLoopOptimization::GenerateVecInv(HInstruction* org, DataType::Type type) { vector_length_, 0u); vector_preheader_->InsertInstructionBefore(set_pred, vector); - vector->AsVecOperation()->SetMergingGoverningPredicate(set_pred); + // TODO: Remove "OrNull". + vector->AsVecOperationOrNull()->SetMergingGoverningPredicate(set_pred); } } vector_map_->Put(org, vector); @@ -1898,7 +1909,8 @@ void HLoopOptimization::GenerateVecMem(HInstruction* org, vector = new (global_allocator_) HVecStore( global_allocator_, base, opa, opb, type, org->GetSideEffects(), vector_length_, dex_pc); } else { - is_string_char_at = org->AsArrayGet()->IsStringCharAt(); + // TODO: Remove "OrNull". + is_string_char_at = org->AsArrayGetOrNull()->IsStringCharAt(); vector = new (global_allocator_) HVecLoad(global_allocator_, base, opa, @@ -1913,22 +1925,26 @@ void HLoopOptimization::GenerateVecMem(HInstruction* org, if (vector_dynamic_peeling_candidate_->offset == offset && // TODO: diffs too? DataType::Size(vector_dynamic_peeling_candidate_->type) == DataType::Size(type) && vector_dynamic_peeling_candidate_->is_string_char_at == is_string_char_at) { - vector->AsVecMemoryOperation()->SetAlignment( // forced + // TODO: Remove "OrNull". + vector->AsVecMemoryOperationOrNull()->SetAlignment( // forced Alignment(GetVectorSizeInBytes(), 0)); } } else { - vector->AsVecMemoryOperation()->SetAlignment( // adjusted/original + // TODO: Remove "OrNull". + vector->AsVecMemoryOperationOrNull()->SetAlignment( // adjusted/original ComputeAlignment(offset, type, is_string_char_at, vector_static_peeling_factor_)); } } else { // Scalar store or load. DCHECK(vector_mode_ == kSequential); if (opb != nullptr) { - DataType::Type component_type = org->AsArraySet()->GetComponentType(); + // TODO: Remove "OrNull". + DataType::Type component_type = org->AsArraySetOrNull()->GetComponentType(); vector = new (global_allocator_) HArraySet( org->InputAt(0), opa, opb, component_type, org->GetSideEffects(), dex_pc); } else { - bool is_string_char_at = org->AsArrayGet()->IsStringCharAt(); + // TODO: Remove "OrNull". + bool is_string_char_at = org->AsArrayGetOrNull()->IsStringCharAt(); vector = new (global_allocator_) HArrayGet( org->InputAt(0), opa, org->GetType(), org->GetSideEffects(), dex_pc, is_string_char_at); } @@ -1972,7 +1988,8 @@ void HLoopOptimization::GenerateVecReductionPhiInputs(HPhi* phi, HInstruction* r if (vector_mode_ == kVector) { // Generate a [initial, 0, .., 0] vector for add or // a [initial, initial, .., initial] vector for min/max. - HVecOperation* red_vector = new_red->AsVecOperation(); + // TODO: Remove "OrNull". + HVecOperation* red_vector = new_red->AsVecOperationOrNull(); HVecReduce::ReductionKind kind = GetReductionKind(red_vector); uint32_t vector_length = red_vector->GetVectorLength(); DataType::Type type = red_vector->GetPackedType(); @@ -1999,15 +2016,18 @@ void HLoopOptimization::GenerateVecReductionPhiInputs(HPhi* phi, HInstruction* r vector_length, 0u); vector_preheader_->InsertInstructionBefore(set_pred, new_init); - new_init->AsVecOperation()->SetMergingGoverningPredicate(set_pred); + // TODO: Remove "OrNull". + new_init->AsVecOperationOrNull()->SetMergingGoverningPredicate(set_pred); } } else { new_init = ReduceAndExtractIfNeeded(new_init); } // Set the phi inputs. DCHECK(new_phi->IsPhi()); - new_phi->AsPhi()->AddInput(new_init); - new_phi->AsPhi()->AddInput(new_red); + // TODO: Remove "OrNull". + new_phi->AsPhiOrNull()->AddInput(new_init); + // TODO: Remove "OrNull". + new_phi->AsPhiOrNull()->AddInput(new_red); // New feed value for next phi (safe mutation in iteration). reductions_->find(phi)->second = new_phi; } @@ -2017,7 +2037,8 @@ HInstruction* HLoopOptimization::ReduceAndExtractIfNeeded(HInstruction* instruct HInstruction* input = instruction->InputAt(1); if (HVecOperation::ReturnsSIMDValue(input)) { DCHECK(!input->IsPhi()); - HVecOperation* input_vector = input->AsVecOperation(); + // TODO: Remove "OrNull". + HVecOperation* input_vector = input->AsVecOperationOrNull(); uint32_t vector_length = input_vector->GetVectorLength(); DataType::Type type = input_vector->GetPackedType(); HVecReduce::ReductionKind kind = GetReductionKind(input_vector); @@ -2041,7 +2062,8 @@ HInstruction* HLoopOptimization::ReduceAndExtractIfNeeded(HInstruction* instruct 0u); exit->InsertInstructionBefore(set_pred, reduce); reduce->SetMergingGoverningPredicate(set_pred); - instruction->AsVecOperation()->SetMergingGoverningPredicate(set_pred); + // TODO: Remove "OrNull". + instruction->AsVecOperationOrNull()->SetMergingGoverningPredicate(set_pred); } } } @@ -2521,11 +2543,13 @@ bool HLoopOptimization::TrySetSimpleLoopHeader(HBasicBlock* block, /*out*/ HPhi* // (2) the main induction, used in loop control. HPhi* phi = nullptr; for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { - if (TrySetPhiReduction(it.Current()->AsPhi())) { + // TODO: Remove "OrNull". + if (TrySetPhiReduction(it.Current()->AsPhiOrNull())) { continue; } else if (phi == nullptr) { // Found the first candidate for main induction. - phi = it.Current()->AsPhi(); + // TODO: Remove "OrNull". + phi = it.Current()->AsPhiOrNull(); } else { return false; } |