summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2018-02-12 17:01:41 +0000
committerErich Keane <erich.keane@intel.com>2018-02-12 17:01:41 +0000
commit93e58667ee1030f36affff0cc5c43e404be19523 (patch)
treeee537870827d464ee92e4f4e5a77f0f405068e4d /clang/lib/CodeGen/CodeGenModule.cpp
parent1022220b16123d918fa885b86fd3ca2b3b5683f1 (diff)
downloadbcm5719-llvm-93e58667ee1030f36affff0cc5c43e404be19523.tar.gz
bcm5719-llvm-93e58667ee1030f36affff0cc5c43e404be19523.zip
Make attribute-target on a Definition-after-use update the LLVM attributes
As reported here: https://bugs.llvm.org/show_bug.cgi?id=36301 The issue is that the 'use' causes the plain declaration to emit the attributes to LLVM-IR. However, if the definition added it later, these would silently disappear. This commit extracts that logic to its own function in CodeGenModule, and has the attribute-applications done during 'definition' update the attributes properly. Differential Revision: https://reviews.llvm.org/D43095 llvm-svn: 324907
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 7a93123a549..33cf0bc9571 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1248,6 +1248,52 @@ void CodeGenModule::setAliasAttributes(const Decl *D,
GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
}
+bool CodeGenModule::GetCPUAndFeaturesAttributes(const Decl *D,
+ llvm::AttrBuilder &Attrs) {
+ // Add target-cpu and target-features attributes to functions. If
+ // we have a decl for the function and it has a target attribute then
+ // parse that and add it to the feature set.
+ StringRef TargetCPU = getTarget().getTargetOpts().CPU;
+ std::vector<std::string> Features;
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
+ FD = FD ? FD->getMostRecentDecl() : FD;
+ const auto *TD = FD ? FD->getAttr<TargetAttr>() : nullptr;
+ bool AddedAttr = false;
+ if (TD) {
+ llvm::StringMap<bool> FeatureMap;
+ getFunctionFeatureMap(FeatureMap, FD);
+
+ // Produce the canonical string for this set of features.
+ for (const llvm::StringMap<bool>::value_type &Entry : FeatureMap)
+ Features.push_back((Entry.getValue() ? "+" : "-") + Entry.getKey().str());
+
+ // Now add the target-cpu and target-features to the function.
+ // While we populated the feature map above, we still need to
+ // get and parse the target attribute so we can get the cpu for
+ // the function.
+ TargetAttr::ParsedTargetAttr ParsedAttr = TD->parse();
+ if (ParsedAttr.Architecture != "" &&
+ getTarget().isValidCPUName(ParsedAttr.Architecture))
+ TargetCPU = ParsedAttr.Architecture;
+ } else {
+ // Otherwise just add the existing target cpu and target features to the
+ // function.
+ Features = getTarget().getTargetOpts().Features;
+ }
+
+ if (TargetCPU != "") {
+ Attrs.addAttribute("target-cpu", TargetCPU);
+ AddedAttr = true;
+ }
+ if (!Features.empty()) {
+ std::sort(Features.begin(), Features.end());
+ Attrs.addAttribute("target-features", llvm::join(Features, ","));
+ AddedAttr = true;
+ }
+
+ return AddedAttr;
+}
+
void CodeGenModule::setNonAliasAttributes(const Decl *D,
llvm::GlobalObject *GO) {
SetCommonAttributes(D, GO);
@@ -1266,6 +1312,16 @@ void CodeGenModule::setNonAliasAttributes(const Decl *D,
if (auto *SA = D->getAttr<PragmaClangTextSectionAttr>())
if (!D->getAttr<SectionAttr>())
F->addFnAttr("implicit-section-name", SA->getName());
+
+ llvm::AttrBuilder Attrs;
+ if (GetCPUAndFeaturesAttributes(D, Attrs)) {
+ // We know that GetCPUAndFeaturesAttributes will always have the
+ // newest set, since it has the newest possible FunctionDecl, so the
+ // new ones should replace the old.
+ F->removeFnAttr("target-cpu");
+ F->removeFnAttr("target-features");
+ F->addAttributes(llvm::AttributeList::FunctionIndex, Attrs);
+ }
}
if (const SectionAttr *SA = D->getAttr<SectionAttr>())
OpenPOWER on IntegriCloud