[clang] [RISCV] Support target attribute for function (PR #65948)

2023-09-11 Thread Jessica Clarke via cfe-commits

jrtc27 wrote:

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.

https://github.com/llvm/llvm-project/pull/65948
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Support target attribute for function (PR #65948)

2023-09-11 Thread Piyou Chen via cfe-commits

BeMg wrote:

This pull request move from https://reviews.llvm.org/D151730.

And update with lastest spec.

1. When it exist the duplicate target attribute, select the lastest one.
2. arch's features will override cpu's features


https://github.com/llvm/llvm-project/pull/65948
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Support target attribute for function (PR #65948)

2023-09-11 Thread via cfe-commits

llvmbot wrote:

@llvm/pr-subscribers-clang


Changes

The spec of RISC-V target feature is 
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/35.

---

This patch implements target attribute for RISC-V.
--
Full diff: https://github.com/llvm/llvm-project/pull/65948.diff

3 Files Affected:

- (modified) clang/lib/Basic/Targets/RISCV.cpp (+95-2) 
- (modified) clang/lib/Basic/Targets/RISCV.h (+2) 
- (added) clang/test/CodeGen/RISCV/riscv-func-attr-target.c (+55) 



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 ) {
+  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 , DiagnosticsEngine , StringRef CPU,
 const std::vector ) 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  : FeaturesVec)
+  for (const std::string  : 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.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  : 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 ) const 

[clang] [RISCV] Support target attribute for function (PR #65948)

2023-09-11 Thread via cfe-commits

https://github.com/llvmbot labeled 
https://github.com/llvm/llvm-project/pull/65948
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Support target attribute for function (PR #65948)

2023-09-11 Thread via cfe-commits

https://github.com/llvmbot labeled 
https://github.com/llvm/llvm-project/pull/65948
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Support target attribute for function (PR #65948)

2023-09-11 Thread via cfe-commits

https://github.com/llvmbot labeled 
https://github.com/llvm/llvm-project/pull/65948
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Support target attribute for function (PR #65948)

2023-09-11 Thread Piyou Chen via cfe-commits

https://github.com/BeMg review_requested 
https://github.com/llvm/llvm-project/pull/65948
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [RISCV] Support target attribute for function (PR #65948)

2023-09-11 Thread Piyou Chen via cfe-commits

https://github.com/BeMg created https://github.com/llvm/llvm-project/pull/65948:

The spec of RISC-V target feature is 
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/35.

---

This patch implements target attribute for RISC-V.

>From 4e661a7cc4775e569bd648b0a119ece51ec031f7 Mon Sep 17 00:00:00 2001
From: Piyou Chen 
Date: Mon, 14 Aug 2023 05:23:20 -0700
Subject: [PATCH] [RISCV] Support target attribute for function

This patch implements target attribute for RISC-V.
---
 clang/lib/Basic/Targets/RISCV.cpp | 97 ++-
 clang/lib/Basic/Targets/RISCV.h   |  2 +
 .../CodeGen/RISCV/riscv-func-attr-target.c| 55 +++
 3 files changed, 152 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CodeGen/RISCV/riscv-func-attr-target.c

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 ) {
+  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 , DiagnosticsEngine , StringRef CPU,
 const std::vector ) 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  : FeaturesVec)
+  for (const std::string  : 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.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  : 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