Skip to content

Commit

Permalink
[LLVM16] [LITS] Adjustment of getInstructionCost, so its calculation…
Browse files Browse the repository at this point in the history
…s are consistent with getUserCost

Porting IGC code to LLVM16

Refactor and adjustment of getUserCost (LLVM 14) and getInstructionCost (LLVM16),
so their calculations use the same algorithm.

This fixes SimplifyCFG passes for expensive_math_intrinsics LITs
Because without those adjustments the instruction cost of

"declare float @llvm.sqrt.f32(float) #0"

was 1 instead of 4.

This caused `if (Cost > Budget ...)` check in `dominatesMergePoint` method
to behave differently, thus different transformations were applied.

This commit originally introduced the "extra cost" for cos/sin/sqrt instructions.
a7bc5c8

Fixes:
SimplifyCFG/expensive_math_intrinsics-typed-pointers.ll
SimplifyCFG/expensive_math_intrinsics.ll
  • Loading branch information
bokrzesi authored and igcbot committed Jan 31, 2025
1 parent 9a5fda5 commit 1e48dc5
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 77 deletions.
120 changes: 43 additions & 77 deletions IGC/Compiler/GenTTI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ namespace llvm {

void GenIntrinsicsTTIImpl::getUnrollingPreferences(Loop* L,
ScalarEvolution& SE,
TTI::UnrollingPreferences& UP,
TTI::UnrollingPreferences& UP,
OptimizationRemarkEmitter* ORE
)
{
Expand Down Expand Up @@ -608,90 +608,56 @@ namespace llvm {
return BaseT::isProfitableToHoist(I);
}

#if LLVM_VERSION_MAJOR <= 10
unsigned GenIntrinsicsTTIImpl::getCallCost(const Function* F,
ArrayRef<const Value*> Arguments, const User* U)
// TODO: Upon the complete removal of pre-LLVM 14 conditions, move to 'getInstructionCost' per LLVM 16 API
llvm::InstructionCost GenIntrinsicsTTIImpl::getUserCost(const User* U, ArrayRef<const Value*> Operands, TTI::TargetCostKind CostKind)
{
// The extra cost of speculative execution for math intrinsics
if (auto *II = dyn_cast_or_null<IntrinsicInst>(U)) {
if (Intrinsic::ID IID = II->getIntrinsicID()) {
switch (IID) {
case Intrinsic::cos:
case Intrinsic::sin:
case Intrinsic::sqrt:
return TTI::TCC_Expensive;
default:
break;
}
}
}

IGC::CodeGenContext* CGC = this->ctx;
if (!CGC->enableFunctionCall() && !GenISAIntrinsic::isIntrinsic(F) &&
!F->isIntrinsic()) {
// If subroutine call is not enabled but we have function call. They
// are not inlined. e.g. due to two-phase inlining. Return function
// size instead of to avoid under-estimating the cost of function call.
//
// FIXME: We need to collect the cost following calling graph. However,
// as LLVM's ininer only support bottom-up inlining currently. That's
// not a big issue so far.
//
// FIXME: We also need to consider the case where sub-routine call is
// enabled.
unsigned FuncSize = countTotalInstructions(F, false);
return TargetTransformInfo::TCC_Basic * FuncSize;
}
return BaseT::getCallCost(F, Arguments, U);
return GenIntrinsicsTTIImpl::internalCalculateCost(U, Operands, CostKind);
}
#else
// [LLVM-UPGRADE] moved from getCallCost to getUserCost
// https://github.com/llvm/llvm-project/commit/2641a19981e71c887bece92074e00d1af3e716c9#diff-dd4bd65dc55d754674d9a945a0d22911

#if LLVM_VERSION_MAJOR <= 12
int GenIntrinsicsTTIImpl::getUserCost(const User* U, ArrayRef<const Value*> Operands, TTI::TargetCostKind CostKind)
#else
// TODO: Upon the complete removal of pre-LLVM 14 conditions, move to 'getInstructionCost' per LLVM 16 API
llvm::InstructionCost GenIntrinsicsTTIImpl::getUserCost(const User* U, ArrayRef<const Value*> Operands, TTI::TargetCostKind CostKind)
#if LLVM_VERSION_MAJOR >= 16
llvm::InstructionCost GenIntrinsicsTTIImpl::getInstructionCost(const User* U, ArrayRef<const Value*> Operands, TTI::TargetCostKind CostKind)
{
return GenIntrinsicsTTIImpl::internalCalculateCost(U, Operands, CostKind);
}
#endif

llvm::InstructionCost GenIntrinsicsTTIImpl::internalCalculateCost(const User* U, ArrayRef<const Value*> Operands, TTI::TargetCostKind CostKind)
{
// The extra cost of speculative execution for math intrinsics
if (auto *II = dyn_cast_or_null<IntrinsicInst>(U)) {
if (Intrinsic::ID IID = II->getIntrinsicID()) {
switch (IID) {
case Intrinsic::cos:
case Intrinsic::sin:
case Intrinsic::sqrt:
return TTI::TCC_Expensive;
default:
break;
}
}
// The extra cost of speculative execution for math intrinsics
if (auto* II = dyn_cast_or_null<IntrinsicInst>(U)) {
if (Intrinsic::ID IID = II->getIntrinsicID()) {
switch (IID) {
case Intrinsic::cos:
case Intrinsic::sin:
case Intrinsic::sqrt:
return TTI::TCC_Expensive;
default:
break;
}
}
}

const Function* F = dyn_cast<Function>(U);
if (F != nullptr)
{
IGC::CodeGenContext* CGC = this->ctx;
if (!CGC->enableFunctionCall() && !GenISAIntrinsic::isIntrinsic(F) &&
!F->isIntrinsic()) {
// If subroutine call is not enabled but we have function call. They
// are not inlined. e.g. due to two-phase inlining. Return function
// size instead of to avoid under-estimating the cost of function call.
//
// FIXME: We need to collect the cost following calling graph. However,
// as LLVM's ininer only support bottom-up inlining currently. That's
// not a big issue so far.
//
// FIXME: We also need to consider the case where sub-routine call is
// enabled.
unsigned FuncSize = countTotalInstructions(F, false);
return TargetTransformInfo::TCC_Basic * FuncSize;
}
const Function* F = dyn_cast<Function>(U);
if (F != nullptr)
{
IGC::CodeGenContext* CGC = this->ctx;
if (!CGC->enableFunctionCall() && !GenISAIntrinsic::isIntrinsic(F) &&
!F->isIntrinsic()) {
// If subroutine call is not enabled but we have function call. They
// are not inlined. e.g. due to two-phase inlining. Return function
// size instead of to avoid under-estimating the cost of function call.
//
// FIXME: We need to collect the cost following calling graph. However,
// as LLVM's ininer only support bottom-up inlining currently. That's
// not a big issue so far.
//
// FIXME: We also need to consider the case where sub-routine call is
// enabled.
unsigned FuncSize = countTotalInstructions(F, false);
return TargetTransformInfo::TCC_Basic * FuncSize;
}
}

return BaseT::getInstructionCost(U, Operands, CostKind);
return BaseT::getInstructionCost(U, Operands, CostKind);
}
#endif

} // namespace llvm
7 changes: 7 additions & 0 deletions IGC/Compiler/GenTTI.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ namespace llvm
llvm::InstructionCost getUserCost(const User* U, ArrayRef<const Value*> Operands,
TTI::TargetCostKind CostKind);

llvm::InstructionCost getInstructionCost(const User* U, ArrayRef<const Value*> Operands,
TTI::TargetCostKind CostKind);

private:
llvm::InstructionCost internalCalculateCost(const User* U, ArrayRef<const Value*> Operands,
TTI::TargetCostKind CostKind);

};

}

0 comments on commit 1e48dc5

Please sign in to comment.