- Notifications
You must be signed in to change notification settings - Fork 15.3k
[RISCV] Support target attribute for function #65948
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This patch implements target attribute for RISC-V.
| @llvm/pr-subscribers-clang ChangesThe spec of RISC-V target feature is riscv-non-isa/riscv-c-api-doc#35. This patch implements target attribute for RISC-V.Full diff: https://github.com/llvm/llvm-project/pull/65948.diff 3 Files Affected:
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index d55ab76395c8271..e132e3bfc9f5b75 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -224,6 +224,21 @@ ArrayRef RISCVTargetInfo::getTargetBuiltins() const { clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin); } +static std::vector +resolveTargetAttrOverride(const std::vector &FeaturesVec) { + if (!llvm::is_contained(FeaturesVec, "__RISCV_TargetAttrNeedOverride")) + return FeaturesVec; + + auto VecPtr = FeaturesVec.begin(); + + while (*VecPtr != "__RISCV_TargetAttrNeedOverride") + VecPtr++; + + VecPtr++; + + return std::vector(VecPtr, FeaturesVec.end()); +} + bool RISCVTargetInfo::initFeatureMap( llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector &FeaturesVec) const { @@ -237,7 +252,10 @@ bool RISCVTargetInfo::initFeatureMap( Features["32bit"] = true; } - auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec); + std::vector NewFeaturesVec = + resolveTargetAttrOverride(FeaturesVec); + + auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, NewFeaturesVec); if (!ParseResult) { std::string Buffer; llvm::raw_string_ostream OutputErrMsg(Buffer); @@ -251,7 +269,7 @@ bool RISCVTargetInfo::initFeatureMap( // RISCVISAInfo makes implications for ISA features std::vector ImpliedFeatures = (*ParseResult)->toFeatureVector(); // Add non-ISA features like `relax` and `save-restore` back - for (const std::string &Feature : FeaturesVec) + for (const std::string &Feature : NewFeaturesVec) if (!llvm::is_contained(ImpliedFeatures, Feature)) ImpliedFeatures.push_back(Feature); @@ -346,3 +364,78 @@ void RISCVTargetInfo::fillValidTuneCPUList( bool Is64Bit = getTriple().isArch64Bit(); llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit); } + +static void handleFullArchString(StringRef FullArchStr, + std::vector &Features) { + Features.push_back("__RISCV_TargetAttrNeedOverride"); + auto RII = llvm::RISCVISAInfo::parseArchString( + FullArchStr, /* EnableExperimentalExtension */ true); + if (!RII) { + consumeError(RII.takeError()); + // Forward the invalid FullArchStr. + Features.push_back("+" + FullArchStr.str()); + } else { + std::vector FeatStrings = (*RII)->toFeatureVector(); + for (auto FeatString : FeatStrings) + Features.push_back(FeatString); + } +} + +ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const { + ParsedTargetAttr Ret; + if (Features == "default") + return Ret; + SmallVector AttrFeatures; + Features.split(AttrFeatures, ";"); + bool FoundArch = false; + + for (auto &Feature : AttrFeatures) { + Feature = Feature.trim(); + StringRef AttrString = Feature.split("=").second.trim(); + + if (Feature.startswith("arch=")) { + // Override last features + Ret.Features.clear(); + FoundArch = true; + + if (AttrString.startswith("+")) { + // EXTENSION like arch=+v,+zbb + SmallVector Exts; + AttrString.split(Exts, ","); + for (auto Ext : Exts) { + if (Ext.empty()) + continue; + + StringRef ExtName = Ext.substr(1); + std::string TargetFeature = + llvm::RISCVISAInfo::getTargetFeatureForExtension(ExtName); + if (!TargetFeature.empty()) + Ret.Features.push_back(Ext.front() + TargetFeature); + else + Ret.Features.push_back(Ext.str()); + } + } else { + // full-arch-string like arch=rv64gcv + handleFullArchString(AttrString, Ret.Features); + } + continue; + } else if (Feature.startswith("cpu=")) { + Ret.CPU = AttrString; + + if (!FoundArch) { + // Update Features with CPU's features + StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU); + if (MarchFromCPU != "") { + Ret.Features.clear(); + handleFullArchString(MarchFromCPU, Ret.Features); + } + } + + continue; + } else if (Feature.startswith("tune=")) { + Ret.Tune = AttrString; + continue; + } + } + return Ret; +} diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index 6be0e49ca2f5525..c1892870de24c40 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -114,6 +114,8 @@ class RISCVTargetInfo : public TargetInfo { void fillValidCPUList(SmallVectorImpl &Values) const override; bool isValidTuneCPUName(StringRef Name) const override; void fillValidTuneCPUList(SmallVectorImpl &Values) const override; + bool supportsTargetAttributeTune() const override { return true; } + ParsedTargetAttr parseTargetAttr(StringRef Str) const override; }; class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { public: diff --git a/clang/test/CodeGen/RISCV/riscv-func-attr-target.c b/clang/test/CodeGen/RISCV/riscv-func-attr-target.c new file mode 100644 index 000000000000000..e75cd3d64ad91ad --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-func-attr-target.c @@ -0,0 +1,55 @@ +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +zifencei -target-feature +m -target-feature +a \ +// RUN: -emit-llvm %s -o - | FileCheck %s + +// CHECK-LABEL: define dso_local void @testDefault +// CHECK-SAME: () #0 { +void testDefault() {} +// CHECK-LABEL: define dso_local void @testMultiAttrStr +// CHECK-SAME: () #1 { +__attribute__((target("cpu=rocket-rv64;tune=generic-rv64;arch=+v"))) void +testMultiAttrStr() {} +// CHECK-LABEL: define dso_local void @testSingleExtension +// CHECK-SAME: () #2 { +__attribute__((target("arch=+zbb"))) void testSingleExtension() {} +// CHECK-LABEL: define dso_local void @testMultiExtension +// CHECK-SAME: () #3 { +__attribute__((target("arch=+zbb,+v,+zicond"))) void testMultiExtension() {} +// CHECK-LABEL: define dso_local void @testFullArch +// CHECK-SAME: () #4 { +__attribute__((target("arch=rv64gc_zbb"))) void testFullArch() {} +// CHECK-LABEL: define dso_local void @testFullArchButSmallThanCmdArch +// CHECK-SAME: () #5 { +__attribute__((target("arch=rv64im"))) void testFullArchButSmallThanCmdArch() {} +// CHECK-LABEL: define dso_local void @testAttrArchAndAttrCpu +// CHECK-SAME: () #6 { +__attribute__((target("cpu=sifive-u54;arch=+zbb"))) void +testAttrArchAndAttrCpu() {} +// CHECK-LABEL: define dso_local void @testAttrFullArchAndAttrCpu +// CHECK-SAME: () #7 { +__attribute__((target("cpu=sifive-u54;arch=rv64im"))) void +testAttrFullArchAndAttrCpu() {} +// CHECK-LABEL: define dso_local void @testAttrCpuOnly +// CHECK-SAME: () #8 { +__attribute__((target("cpu=sifive-u54"))) void testAttrCpuOnly() {} +// CHECK-LABEL: define dso_local void @testMultiArchSelectLast +// CHECK-SAME: () #4 { +__attribute__((target("arch=rv64gc;arch=rv64gc_zbb"))) void testMultiArchSelectLast() {} +// CHECK-LABEL: define dso_local void @testMultiCpuSelectLast +// CHECK-SAME: () #8 { +__attribute__((target("cpu=sifive-u74;cpu=sifive-u54"))) void testMultiCpuSelectLast() {} +// CHECK-LABEL: define dso_local void @testMultiTuneSelectLast +// CHECK-SAME: () #9 { +__attribute__((target("tune=sifive-u74;tune=sifive-u54"))) void testMultiTuneSelectLast() {} + +//. +// CHECK: attributes #0 = { {{.*}}"target-features"="+64bit,+a,+m,+zifencei" } +// CHECK: attributes #1 = { {{.*}}"target-cpu"="rocket-rv64" "target-features"="+64bit,+a,+d,+f,+m,+v,+zicsr,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" "tune-cpu"="generic-rv64" } +// CHECK: attributes #2 = { {{.*}}"target-features"="+64bit,+a,+m,+zbb,+zifencei" } +// CHECK: attributes #3 = { {{.*}}"target-features"="+64bit,+a,+d,+experimental-zicond,+f,+m,+v,+zbb,+zicsr,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" } +// CHECK: attributes #4 = { {{.*}}"target-features"="+64bit,+a,+c,+d,+f,+m,+zbb,+zicsr,+zifencei" } +// CHECK: attributes #5 = { {{.*}}"target-features"="+64bit,+m" } +// CHECK: attributes #6 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+a,+m,+zbb,+zifencei" } +// CHECK: attributes #7 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+m" } +// CHECK: attributes #8 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+a,+c,+d,+f,+m,+zicsr,+zifencei" } +// CHECK: attributes #9 = { {{.*}}"target-features"="+64bit,+a,+m,+zifencei" "tune-cpu"="sifive-u54" } |
| This pull request move from https://reviews.llvm.org/D151730. And update with lastest spec.
|
| Please do not move from Phabricator to GitHub for existing changes, it loses all the context that was built up from previous reviews. New changes should be proposed on GitHub but existing ones should stay put. |
| Sorry for disrupting the review process. I will update the change into Phabricator existing patch. |
The spec of RISC-V target feature is riscv-non-isa/riscv-c-api-doc#35.
This patch implements target attribute for RISC-V.