summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorEric Christopher <echristo@gmail.com>2015-08-27 19:59:34 +0000
committerEric Christopher <echristo@gmail.com>2015-08-27 19:59:34 +0000
commit3a98b3c1a5af22396e457d3232d74690f2ed4532 (patch)
tree2fbd78a256e66305243edf8284b29796e9d57d4a /clang/lib/CodeGen/CGCall.cpp
parent5e93e28d8b88ba30613c2bb1d55a7e5b75749626 (diff)
downloadbcm5719-llvm-3a98b3c1a5af22396e457d3232d74690f2ed4532.tar.gz
bcm5719-llvm-3a98b3c1a5af22396e457d3232d74690f2ed4532.zip
Rewrite the code generation handling for function feature and cpu attributes.
A couple of changes here: a) Do less work in the case where we don't have a target attribute on the function. We've already canonicalized the attributes for the function - no need to do more work. b) Use the newer canonicalized feature adding functions from TargetInfo to do the work when we do have a target attribute. This enables us to diagnose some warnings in the case of conflicting written attributes (only ppc does this today) and also make sure to get all of the features for a cpu that's listed rather than just change the cpu. Updated all testcases accordingly and added a new testcase to verify that we'll error out on ppc if we have some incompatible options using the existing diagnosis framework there. llvm-svn: 246195
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp132
1 files changed, 70 insertions, 62 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index f40dd086481..eff9fde8393 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1496,70 +1496,78 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
// 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;
-
- // TODO: Features gets us the features on the command line including
- // feature dependencies. For canonicalization purposes we might want to
- // avoid putting features in the target-features set if we know it'll be
- // one of the default features in the backend, e.g. corei7-avx and +avx or
- // figure out non-explicit dependencies.
- // Canonicalize the existing features in a new feature map.
- // TODO: Migrate the existing backends to keep the map around rather than
- // the vector.
- llvm::StringMap<bool> FeatureMap;
- for (auto F : getTarget().getTargetOpts().Features) {
- const char *Name = F.c_str();
- bool Enabled = Name[0] == '+';
- getTarget().setFeatureEnabled(FeatureMap, Name + 1, Enabled);
- }
-
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
- if (FD) {
- if (const auto *TD = FD->getAttr<TargetAttr>()) {
- StringRef FeaturesStr = TD->getFeatures();
- SmallVector<StringRef, 1> AttrFeatures;
- FeaturesStr.split(AttrFeatures, ",");
-
- // Grab the various features and prepend a "+" to turn on the feature to
- // the backend and add them to our existing set of features.
- for (auto &Feature : AttrFeatures) {
- // Go ahead and trim whitespace rather than either erroring or
- // accepting it weirdly.
- Feature = Feature.trim();
-
- // While we're here iterating check for a different target cpu.
- if (Feature.startswith("arch="))
- TargetCPU = Feature.split("=").second.trim();
- else if (Feature.startswith("tune="))
- // We don't support cpu tuning this way currently.
- ;
- else if (Feature.startswith("fpmath="))
- // TODO: Support the fpmath option this way. It will require checking
- // overall feature validity for the function with the rest of the
- // attributes on the function.
- ;
- else if (Feature.startswith("mno-"))
- getTarget().setFeatureEnabled(FeatureMap, Feature.split("-").second,
- false);
- else
- getTarget().setFeatureEnabled(FeatureMap, Feature, true);
- }
+ if (FD && FD->getAttr<TargetAttr>()) {
+ llvm::StringMap<bool> FeatureMap;
+ const auto *TD = FD->getAttr<TargetAttr>();
+
+ // Make a copy of the features as passed on the command line.
+ std::vector<std::string> FnFeatures(
+ getTarget().getTargetOpts().FeaturesAsWritten);
+
+ // Grab the target attribute string.
+ StringRef FeaturesStr = TD->getFeatures();
+ SmallVector<StringRef, 1> AttrFeatures;
+ FeaturesStr.split(AttrFeatures, ",");
+
+ // Grab the various features and prepend a "+" to turn on the feature to
+ // the backend and add them to our existing set of features.
+ for (auto &Feature : AttrFeatures) {
+ // Go ahead and trim whitespace rather than either erroring or
+ // accepting it weirdly.
+ Feature = Feature.trim();
+
+ // While we're here iterating check for a different target cpu.
+ if (Feature.startswith("arch="))
+ TargetCPU = Feature.split("=").second.trim();
+ else if (Feature.startswith("tune="))
+ // We don't support cpu tuning this way currently.
+ ;
+ else if (Feature.startswith("fpmath="))
+ // TODO: Support the fpmath option this way. It will require checking
+ // overall feature validity for the function with the rest of the
+ // attributes on the function.
+ ;
+ else if (Feature.startswith("mno-"))
+ FnFeatures.push_back("-" + Feature.split("-").second.str());
+ else
+ FnFeatures.push_back("+" + Feature.str());
+ }
+ // Now populate the feature map, first with the TargetCPU which is either
+ // the default or a new one from the target attribute string. Then we'll
+ // use the passed in features (FeaturesAsWritten) along with the new ones
+ // from the attribute.
+ getTarget().initDefaultFeatures(FeatureMap, TargetCPU);
+ getTarget().handleUserFeatures(FeatureMap, FnFeatures, Diags);
+
+ // Produce the canonical string for this set of features.
+ std::vector<std::string> Features;
+ for (llvm::StringMap<bool>::const_iterator it = FeatureMap.begin(),
+ ie = FeatureMap.end();
+ it != ie; ++it)
+ Features.push_back((it->second ? "+" : "-") + it->first().str());
+
+ // Now add the target-cpu and target-features to the function.
+ if (TargetCPU != "")
+ FuncAttrs.addAttribute("target-cpu", TargetCPU);
+ if (!Features.empty()) {
+ std::sort(Features.begin(), Features.end());
+ FuncAttrs.addAttribute(
+ "target-features",
+ llvm::join(Features.begin(), Features.end(), ","));
+ }
+ } else {
+ // Otherwise just add the existing target cpu and target features to the
+ // function.
+ std::vector<std::string> &Features = getTarget().getTargetOpts().Features;
+ if (TargetCPU != "")
+ FuncAttrs.addAttribute("target-cpu", TargetCPU);
+ if (!Features.empty()) {
+ std::sort(Features.begin(), Features.end());
+ FuncAttrs.addAttribute(
+ "target-features",
+ llvm::join(Features.begin(), Features.end(), ","));
}
- }
-
- // Produce the canonical string for this set of features.
- std::vector<std::string> Features;
- for (llvm::StringMap<bool>::const_iterator it = FeatureMap.begin(),
- ie = FeatureMap.end();
- it != ie; ++it)
- Features.push_back((it->second ? "+" : "-") + it->first().str());
-
- // Now add the target-cpu and target-features to the function.
- if (TargetCPU != "")
- FuncAttrs.addAttribute("target-cpu", TargetCPU);
- if (!Features.empty()) {
- std::sort(Features.begin(), Features.end());
- FuncAttrs.addAttribute("target-features",
- llvm::join(Features.begin(), Features.end(), ","));
}
}
OpenPOWER on IntegriCloud