[clang] [llvm] [RISCV][FMV] Support target_clones (PR #85786)
Piyou Chen via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 20 05:56:09 PDT 2024
================
@@ -2854,10 +2854,121 @@ void CodeGenFunction::EmitMultiVersionResolver(
case llvm::Triple::aarch64:
EmitAArch64MultiVersionResolver(Resolver, Options);
return;
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ EmitRISCVMultiVersionResolver(Resolver, Options);
+ return;
default:
- assert(false && "Only implemented for x86 and AArch64 targets");
+ assert(false && "Only implemented for x86, AArch64 and RISC-V targets");
+ }
+}
+
+void CodeGenFunction::EmitRISCVMultiVersionResolver(
+ llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
+
+ if (getContext().getTargetInfo().getTriple().getOS() !=
+ llvm::Triple::OSType::Linux) {
+ CGM.getDiags().Report(diag::err_os_unsupport_riscv_target_clones);
+ return;
+ }
+
+ llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
+ Builder.SetInsertPoint(CurBlock);
+ EmitRISCVCpuInit();
+
+ bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc();
+ bool HasDefault = false;
+ unsigned DefaultIndex = 0;
+ // Check the each candidate function.
+ for (unsigned Index = 0; Index < Options.size(); Index++) {
----------------
BeMg wrote:
In other target, it sort the order base on target-defined priority score for all cpu/extension.
Take Aarch64 as example, it define a table like:
```
// `llvm/lib/Target/AArch64/AArch64FMV.td`
// The last one is score that using to sorting.
def : FMVExtension<"aes", "FEAT_AES", "+fp-armv8,+neon", 150>;
def : FMVExtension<"bf16", "FEAT_BF16", "+bf16", 280>;
def : FMVExtension<"bti", "FEAT_BTI", "+bti", 510>;
def : FMVExtension<"crc", "FEAT_CRC", "+crc", 110>;
...
```
And sort it before going to emit the resolver.
```
...
llvm::stable_sort(
Options, [&TI](const CodeGenFunction::MultiVersionResolverOption &LHS,
const CodeGenFunction::MultiVersionResolverOption &RHS) {
return TargetMVPriority(TI, LHS) > TargetMVPriority(TI, RHS);
});
...
static unsigned
TargetMVPriority(const TargetInfo &TI,
const CodeGenFunction::MultiVersionResolverOption &RO) {
unsigned Priority = 0;
unsigned NumFeatures = 0;
for (StringRef Feat : RO.Conditions.Features) {
Priority = std::max(Priority, TI.multiVersionSortPriority(Feat));
NumFeatures++;
}
if (!RO.Conditions.Architecture.empty())
Priority = std::max(
Priority, TI.multiVersionSortPriority(RO.Conditions.Architecture));
Priority += TI.multiVersionFeatureCost() * NumFeatures;
return Priority;
}
```
https://github.com/llvm/llvm-project/pull/85786
More information about the llvm-commits
mailing list