[clang] [llvm] [RISCV][FMV] Support target_clones (PR #85786)

Piyou Chen via cfe-commits cfe-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 cfe-commits mailing list