BeMg updated this revision to Diff 526988.
BeMg added a comment.
update
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151730/new/
https://reviews.llvm.org/D151730
Files:
clang/include/clang/Basic/TargetInfo.h
clang/lib/Basic/Targets/RISCV.cpp
clang/lib/Basic/Targets/RISCV.h
clang/test/CodeGen/RISCV/riscv-func-attr-target.c
llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Index: llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -34,6 +34,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/RISCVISAInfo.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
@@ -44,6 +45,10 @@
STATISTIC(RISCVNumInstrsCompressed,
"Number of RISC-V Compressed instructions emitted");
+namespace llvm {
+extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
+} // namespace llvm
+
namespace {
class RISCVAsmPrinter : public AsmPrinter {
const RISCVSubtarget *STI;
@@ -82,6 +87,8 @@
void emitEndOfAsmFile(Module &M) override;
void emitFunctionEntryLabel() override;
+ void emitDirectiveOptionArch();
+ bool isSameAttribute();
private:
void emitAttributes();
@@ -232,11 +239,44 @@
return false;
}
+void RISCVAsmPrinter::emitDirectiveOptionArch() {
+ RISCVTargetStreamer &RTS =
+ static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
+ std::vector<StringRef> NeedEmitStdOption;
+ const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
+ for (auto Feature : RISCVFeatureKV) {
+ if (STI->hasFeature(Feature.Value) && !MCSTI.hasFeature(Feature.Value) &&
+ llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key))
+ NeedEmitStdOption.push_back(Feature.Key);
+ }
+
+ bool PrefixEmitted = false;
+ unsigned NeedEmitStdOptionSize = NeedEmitStdOption.size();
+ for (unsigned i = 0; i < NeedEmitStdOptionSize; i++) {
+ RTS.emitDirectiveOptionArchPlus(NeedEmitStdOption[i], PrefixEmitted,
+ i < NeedEmitStdOptionSize - 1);
+ }
+}
+
+bool RISCVAsmPrinter::isSameAttribute() {
+ const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
+ return MCSTI.getFeatureBits() == STI->getFeatureBits();
+}
+
bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
STI = &MF.getSubtarget<RISCVSubtarget>();
+ RISCVTargetStreamer &RTS =
+ static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
+ if (!isSameAttribute()) {
+ RTS.emitDirectiveOptionPush();
+ emitDirectiveOptionArch();
+ }
SetupMachineFunction(MF);
emitFunctionBody();
+
+ if (!isSameAttribute())
+ RTS.emitDirectiveOptionPop();
return false;
}
Index: clang/test/CodeGen/RISCV/riscv-func-attr-target.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/RISCV/riscv-func-attr-target.c
@@ -0,0 +1,114 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang -target riscv64 -march=rv64g -S %s -o - | FileCheck %s --check-prefix=CHECK-ASM
+// RUN: %clang -target riscv64 -march=rv64g -emit-llvm -S %s -o - | FileCheck %s --check-prefix=CHECK-IR
+
+// clang-format off
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +c, +v, +zve32f, +zve32x, +zve64d, +zve64f, +zve64x, +zvl128b, +zvl32b, +zvl64b
+// CHECK-ASM-LABEL: test1
+// CHECK-ASM: .option pop
+__attribute__((target("arch=rv64g,+c,+v"))) void test1 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +c
+// CHECK-ASM-LABEL: test2
+// CHECK-ASM: .option pop
+__attribute__((target("arch=rv64gc"))) void test2 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +c
+// CHECK-ASM-LABEL: test3
+// CHECK-ASM: .option pop
+__attribute__((target("arch=+c"))) void test3 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +v, +zve32f, +zve32x, +zve64d, +zve64f, +zve64x, +zvl128b, +zvl32b, +zvl64b
+// CHECK-ASM-LABEL: test4
+// CHECK-ASM: .option pop
+__attribute__((target("arch=+v"))) void test4 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +experimental-zihintntl
+// CHECK-ASM-LABEL: test5
+// CHECK-ASM: .option pop
+__attribute__((target("arch=+experimental-zihintntl"))) void test5 () {}
+
+// CHECK-ASM-LABEL: test7
+// CHECK-ASM-NOT: .option pop
+// CHECK-IR: void @test7() #4
+__attribute__((target("cpu=rocket-rv64"))) void test7 () {}
+
+// CHECK-ASM-LABEL: test8
+// CHECK-ASM-NOT: .option pop
+// CHECK-IR: void @test8() #5
+__attribute__((target("tune=rocket-rv64"))) void test8 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +c
+// CHECK-ASM-LABEL: test9
+// CHECK-ASM: .option pop
+// CHECK-IR: void @test9() #6
+__attribute__((target("cpu=rocket-rv64,arch=+c"))) void test9 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +c, +v, +zve32f, +zve32x, +zve64d, +zve64f, +zve64x, +zvl128b, +zvl32b, +zvl64b
+// CHECK-ASM-LABEL: test10
+// CHECK-ASM: .option pop
+// CHECK-IR: void @test10() #7
+__attribute__((target("cpu=rocket-rv64,arch=rv64gc,+v"))) void test10 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +c, +v, +zve32f, +zve32x, +zve64d, +zve64f, +zve64x, +zvl128b, +zvl32b, +zvl64b
+// CHECK-ASM-LABEL: test11
+// CHECK-ASM: .option pop
+// CHECK-IR: void @test11() #8
+__attribute__((target("tune=rocket-rv64,arch=rv64gc,+v"))) void test11 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +v, +zve32f, +zve32x, +zve64d, +zve64f, +zve64x, +zvl128b, +zvl32b, +zvl64b
+// CHECK-ASM-LABEL: test12
+// CHECK-ASM: .option pop
+// CHECK-IR: void @test12() #9
+__attribute__((target("cpu=rocket-rv64,tune=generic-rv64,arch=+v"))) void test12 () {}
+
+// CHECK-ASM-LABEL: test13
+// CHECK-ASM-NOT: .option pop
+// CHECK-IR: void @test13() #10
+__attribute__((target("cpu=rocket-rv64,tune=generic-rv64"))) void test13 () {}
+
+// CHECK-ASM-LABEL: test14
+// CHECK-ASM-NOT: .option pop
+// CHECK-IR: void @test14() #10
+__attribute__((target("tune=generic-rv64,cpu=rocket-rv64"))) void test14 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +v, +zve32f, +zve32x, +zve64d, +zve64f, +zve64x, +zvl128b, +zvl32b, +zvl64b
+// CHECK-ASM-LABEL: test15
+// CHECK-ASM: .option pop
+// CHECK-IR: void @test15() #9
+__attribute__((target("arch=+v,tune=generic-rv64,cpu=rocket-rv64"))) void test15 () {}
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +v, +zve32f, +zve32x, +zve64d, +zve64f, +zve64x, +zvl128b, +zvl32b, +zvl64b
+// CHECK-ASM-LABEL: test16
+// CHECK-ASM: .option pop
+// CHECK-IR: void @test16() #9
+__attribute__((target("tune=generic-rv64,arch=+v,cpu=rocket-rv64"))) void test16 () {}
+
+
+// CHECK-ASM: .option push
+// CHECK-ASM-NEXT: .option arch, +c
+// CHECK-ASM-LABEL: test17
+// CHECK-ASM: .option pop
+// CHECK-IR: void @test17() #11
+__attribute__((target("tune=rocket-rv64,arch=rv64gcv,-v"))) void test17 () {}
+
+// CHECK-IR: attributes #5 {{.*}} "tune-cpu"="rocket-rv64" {{.*}}
+// CHECK-IR: attributes #6 {{.*}} "target-cpu"="rocket-rv64" {{.*}}
+// CHECK-IR: attributes #7 {{.*}} "target-cpu"="rocket-rv64" {{.*}}
+// CHECK-IR: attributes #8 {{.*}} "tune-cpu"="rocket-rv64" {{.*}}
+// CHECK-IR: attributes #9 {{.*}} "target-cpu"="rocket-rv64" {{.*}} "tune-cpu"="generic-rv64" {{.*}}
+// CHECK-IR: attributes #10 {{.*}} "target-cpu"="rocket-rv64" {{.*}} "tune-cpu"="generic-rv64" {{.*}}
+// CHECK-IR: attributes #11 {{.*}} "tune-cpu"="rocket-rv64" {{.*}}
+
+// clang-format on
Index: clang/lib/Basic/Targets/RISCV.h
===================================================================
--- clang/lib/Basic/Targets/RISCV.h
+++ clang/lib/Basic/Targets/RISCV.h
@@ -109,6 +109,9 @@
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool isValidTuneCPUName(StringRef Name) const override;
void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
+ bool supportsTargetAttributeTune() const override { return true; }
+ bool validateCpuSupports(StringRef FeatureStr) const override;
+ ParsedTargetAttr parseTargetAttr(StringRef Str) const override;
};
class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
public:
Index: clang/lib/Basic/Targets/RISCV.cpp
===================================================================
--- clang/lib/Basic/Targets/RISCV.cpp
+++ clang/lib/Basic/Targets/RISCV.cpp
@@ -250,12 +250,17 @@
// RISCVISAInfo makes implications for ISA features
std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector();
+ std::vector<std::string> UpdatedFeatures;
+
// Add non-ISA features like `relax` and `save-restore` back
for (const std::string &Feature : FeaturesVec)
if (!llvm::is_contained(ImpliedFeatures, Feature))
- ImpliedFeatures.push_back(Feature);
+ UpdatedFeatures.push_back(Feature);
+
+ for (const std::string &Feature : ImpliedFeatures)
+ UpdatedFeatures.push_back(Feature);
- return TargetInfo::initFeatureMap(Features, Diags, CPU, ImpliedFeatures);
+ return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeatures);
}
std::optional<std::pair<unsigned, unsigned>>
@@ -346,3 +351,73 @@
bool Is64Bit = getTriple().isArch64Bit();
llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
}
+
+// Parse RISC-V Target attributes, which are a comma separated list of:
+// "arch=<arch>" - parsed to features as per -march=..
+// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
+// "tune=<cpu>" - TuneCPU set to <cpu>
+ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
+ ParsedTargetAttr Ret;
+ if (Features == "default")
+ return Ret;
+ SmallVector<StringRef, 1> AttrFeatures;
+ Features.split(AttrFeatures, ",");
+ bool FoundArch = false;
+
+ for (auto &Feature : AttrFeatures) {
+ Feature = Feature.trim();
+ StringRef Attrstring = Feature.split("=").second.trim();
+
+ if (Feature.startswith("arch=")) {
+ if (FoundArch)
+ Ret.Duplicate = "arch=";
+ FoundArch = true;
+
+ // EXTENSION like arch=+v
+ if (Attrstring.startswith("+") || Attrstring.startswith("-"))
+ Ret.Features.push_back(Attrstring.str());
+ else {
+ // full-arch-string like arch=rv64gcv
+ auto RII = llvm::RISCVISAInfo::parseArchString(
+ Attrstring, /* EnableExperimentalExtension */ true);
+ if (!RII) {
+ std::string Buffer;
+ llvm::raw_string_ostream OutputErrMsg(Buffer);
+ handleAllErrors(RII.takeError(), [&](llvm::StringError &ErrMsg) {
+ OutputErrMsg << "invalid arch name '" << Attrstring << "', "
+ << ErrMsg.getMessage();
+ });
+ }
+
+ std::vector<std::string> FeatStrings = (*RII)->toFeatureVector();
+ for (auto FeatString : FeatStrings)
+ Ret.Features.push_back(FeatString);
+ }
+ continue;
+ }
+
+ if (Feature.startswith("cpu=")) {
+ if (!Ret.CPU.empty())
+ Ret.Duplicate = "cpu=";
+ else
+ Ret.CPU = Attrstring;
+ continue;
+ }
+
+ if (Feature.startswith("tune=")) {
+ if (!Ret.Tune.empty())
+ Ret.Duplicate = "tune=";
+ else
+ Ret.Tune = Attrstring;
+ continue;
+ }
+
+ if (Feature.startswith("+") || Feature.startswith("-"))
+ Ret.Features.push_back(Feature.str());
+ }
+ return Ret;
+}
+
+bool RISCVTargetInfo::validateCpuSupports(StringRef FeatureStr) const {
+ return ISAInfo->isSupportedExtensionFeature(FeatureStr);
+}
Index: clang/include/clang/Basic/TargetInfo.h
===================================================================
--- clang/include/clang/Basic/TargetInfo.h
+++ clang/include/clang/Basic/TargetInfo.h
@@ -1397,7 +1397,8 @@
/// Identify whether this target supports multiversioning of functions,
/// which requires support for cpu_supports and cpu_is functionality.
bool supportsMultiVersioning() const {
- return getTriple().isX86() || getTriple().isAArch64();
+ return getTriple().isX86() || getTriple().isAArch64() ||
+ getTriple().isRISCV();
}
/// Identify whether this target supports IFuncs.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits