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/instruction_builder.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/instruction_builder.cc')
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 2576b02c9f..f461be9df1 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -268,12 +268,14 @@ void HInstructionBuilder::PropagateLocalsToCatchBlocks() { if (local_value == nullptr) { // This is the first instruction throwing into `catch_block` where // `vreg` is undefined. Delete the catch phi. - catch_block->RemovePhi(handler_value->AsPhi()); + // TODO: Remove "OrNull". + catch_block->RemovePhi(handler_value->AsPhiOrNull()); (*handler_locals)[vreg] = nullptr; } else { // Vreg has been defined at all instructions throwing into `catch_block` // encountered so far. Record the local value in the catch phi. - handler_value->AsPhi()->AddInput(local_value); + // TODO: Remove "OrNull". + handler_value->AsPhiOrNull()->AddInput(local_value); } } } @@ -321,7 +323,8 @@ void HInstructionBuilder::SetLoopHeaderPhiInputs() { for (size_t i = loop_headers_.size(); i > 0; --i) { HBasicBlock* block = loop_headers_[i - 1]; for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { - HPhi* phi = it.Current()->AsPhi(); + // TODO: Remove "OrNull". + HPhi* phi = it.Current()->AsPhiOrNull(); size_t vreg = phi->GetRegNumber(); for (HBasicBlock* predecessor : block->GetPredecessors()) { HInstruction* value = ValueOfLocalAt(predecessor, vreg); @@ -1467,7 +1470,8 @@ void HInstructionBuilder::BuildConstructorFenceForAllocation(HInstruction* alloc // // Do not emit an HConstructorFence here since it can inhibit some String new-instance // optimizations (to pass checker tests that rely on those optimizations). - HNewInstance* new_inst = allocation->AsNewInstance(); + // TODO: Remove "OrNull". + HNewInstance* new_inst = allocation->AsNewInstanceOrNull(); HLoadClass* load_class = new_inst->GetLoadClass(); Thread* self = Thread::Current(); @@ -1836,15 +1840,20 @@ bool HInstructionBuilder::SetupInvokeArguments(HInstruction* invoke, if (invoke->IsInvokeStaticOrDirect() && HInvokeStaticOrDirect::NeedsCurrentMethodInput( - invoke->AsInvokeStaticOrDirect()->GetDispatchInfo())) { - DCHECK_EQ(argument_index, invoke->AsInvokeStaticOrDirect()->GetCurrentMethodIndex()); + // TODO: Remove "OrNull". + invoke->AsInvokeStaticOrDirectOrNull()->GetDispatchInfo())) { + // TODO: Remove "OrNull". + DCHECK_EQ(argument_index, invoke->AsInvokeStaticOrDirectOrNull()->GetCurrentMethodIndex()); DCHECK(invoke->InputAt(argument_index) == nullptr); invoke->SetRawInputAt(argument_index, graph_->GetCurrentMethod()); } if (invoke->IsInvokeInterface() && - (invoke->AsInvokeInterface()->GetHiddenArgumentLoadKind() == MethodLoadKind::kRecursive)) { - invoke->SetRawInputAt(invoke->AsInvokeInterface()->GetNumberOfArguments() - 1, + // TODO: Remove "OrNull". + (invoke->AsInvokeInterfaceOrNull()->GetHiddenArgumentLoadKind() == + MethodLoadKind::kRecursive)) { + // TODO: Remove "OrNull". + invoke->SetRawInputAt(invoke->AsInvokeInterfaceOrNull()->GetNumberOfArguments() - 1, graph_->GetCurrentMethod()); } @@ -1856,7 +1865,8 @@ bool HInstructionBuilder::HandleInvoke(HInvoke* invoke, const char* shorty, bool is_unresolved) { DCHECK_IMPLIES(invoke->IsInvokeStaticOrDirect(), - !invoke->AsInvokeStaticOrDirect()->IsStringInit()); + // TODO: Remove "OrNull". + !invoke->AsInvokeStaticOrDirectOrNull()->IsStringInit()); ReceiverArg receiver_arg = (invoke->GetInvokeType() == InvokeType::kStatic) ? ReceiverArg::kNone @@ -1914,7 +1924,8 @@ bool HInstructionBuilder::BuildSimpleIntrinsic(ArtMethod* method, case Intrinsics::kDoubleIsNaN: { // IsNaN(x) is the same as x != x. instruction = new (allocator_) HNotEqual(/*first=*/ nullptr, /*second=*/ nullptr, dex_pc); - instruction->AsCondition()->SetBias(ComparisonBias::kLtBias); + // TODO: Remove "OrNull". + instruction->AsConditionOrNull()->SetBias(ComparisonBias::kLtBias); break; } case Intrinsics::kStringCharAt: @@ -2061,7 +2072,8 @@ bool HInstructionBuilder::HandleStringInit(HInvoke* invoke, const InstructionOperands& operands, const char* shorty) { DCHECK(invoke->IsInvokeStaticOrDirect()); - DCHECK(invoke->AsInvokeStaticOrDirect()->IsStringInit()); + // TODO: Remove "OrNull". + DCHECK(invoke->AsInvokeStaticOrDirectOrNull()->IsStringInit()); if (!SetupInvokeArguments(invoke, operands, shorty, ReceiverArg::kIgnored)) { return false; @@ -2077,7 +2089,8 @@ bool HInstructionBuilder::HandleStringInit(HInvoke* invoke, // Replacing the NewInstance might render it redundant. Keep a list of these // to be visited once it is clear whether it has remaining uses. if (arg_this->IsNewInstance()) { - ssa_builder_->AddUninitializedString(arg_this->AsNewInstance()); + // TODO: Remove "OrNull". + ssa_builder_->AddUninitializedString(arg_this->AsNewInstanceOrNull()); } else { DCHECK(arg_this->IsPhi()); // We can get a phi as input of a String.<init> if there is a loop between the @@ -2366,8 +2379,10 @@ void HInstructionBuilder::BuildCheckedDivRem(uint16_t out_vreg, } if (!second_is_constant || - (type == DataType::Type::kInt32 && second->AsIntConstant()->GetValue() == 0) || - (type == DataType::Type::kInt64 && second->AsLongConstant()->GetValue() == 0)) { + // TODO: Remove "OrNull". + (type == DataType::Type::kInt32 && second->AsIntConstantOrNull()->GetValue() == 0) || + // TODO: Remove "OrNull". + (type == DataType::Type::kInt64 && second->AsLongConstantOrNull()->GetValue() == 0)) { second = new (allocator_) HDivZeroCheck(second, dex_pc); AppendInstruction(second); } @@ -2863,7 +2878,8 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, uint32_t reg_number = instruction.VRegB(); HInstruction* value = (*current_locals_)[reg_number]; if (value->IsIntConstant()) { - DCHECK_EQ(value->AsIntConstant()->GetValue(), 0); + // TODO: Remove "OrNull". + DCHECK_EQ(value->AsIntConstantOrNull()->GetValue(), 0); } else if (value->IsPhi()) { DCHECK(value->GetType() == DataType::Type::kInt32 || value->GetType() == DataType::Type::kReference); |