diff options
author | Eric Christopher <echristo@gmail.com> | 2015-06-12 01:35:52 +0000 |
---|---|---|
committer | Eric Christopher <echristo@gmail.com> | 2015-06-12 01:35:52 +0000 |
commit | 11acf739f8f7737137a0641e49a48e2f30b5f759 (patch) | |
tree | 5ab019c94c013627c21f79f38171bc7cf0a16528 /clang/lib/CodeGen | |
parent | a1431077de66aebf75e1da83f56314a78cb8ebb2 (diff) | |
download | bcm5719-llvm-11acf739f8f7737137a0641e49a48e2f30b5f759.tar.gz bcm5719-llvm-11acf739f8f7737137a0641e49a48e2f30b5f759.zip |
Add support for the the target attribute.
Modeled after the gcc attribute of the same name, this feature
allows source level annotations to correspond to backend code
generation. In llvm particular parlance, this allows the adding
of subtarget features and changing the cpu for a particular function
based on source level hints.
This has been added into the existing support for function level
attributes without particular verification for any target outside
of whether or not the backend will support the features/cpu given
(similar to section, etc).
llvm-svn: 239579
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index c2e1e57463a..894391c2ab5 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1483,24 +1483,52 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, if (!CodeGenOpts.StackRealignment) FuncAttrs.addAttribute("no-realign-stack"); - // Add target-cpu and target-features work if they differ from the defaults. - std::string &CPU = getTarget().getTargetOpts().CPU; - if (CPU != "") - FuncAttrs.addAttribute("target-cpu", CPU); + // 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; // 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. - std::vector<std::string> &Features = getTarget().getTargetOpts().Features; + // 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. + std::vector<std::string> Features(getTarget().getTargetOpts().Features); + + // TODO: The target attribute complicates this further by allowing multiple + // additional features to be tacked on to the feature string for a + // particular function. For now we simply append to the set of features and + // let backend resolution fix them up. + const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl); + if (FD) { + if (const TargetAttr *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) { + // While we're here iterating check for a different target cpu. + if (Feature.startswith("arch=")) + TargetCPU = Feature.split("=").second; + else + Features.push_back("+" + Feature.str()); + } + } + } + + // Now add the target-cpu and target-features to the function. + if (TargetCPU != "") + FuncAttrs.addAttribute("target-cpu", TargetCPU); if (!Features.empty()) { - std::stringstream S; + std::stringstream TargetFeatures; std::copy(Features.begin(), Features.end(), - std::ostream_iterator<std::string>(S, ",")); + std::ostream_iterator<std::string>(TargetFeatures, ",")); + // The drop_back gets rid of the trailing space. FuncAttrs.addAttribute("target-features", - StringRef(S.str()).drop_back(1)); + StringRef(TargetFeatures.str()).drop_back(1)); } } |