summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp10
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp26
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h4
3 files changed, 30 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 6c73a8cebdc..916051556a2 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2330,9 +2330,19 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
} else if (TargetDecl->hasAttr<TargetAttr>()) {
// Get the required features for the callee.
+
+ const TargetAttr *TD = TargetDecl->getAttr<TargetAttr>();
+ TargetAttr::ParsedTargetAttr ParsedAttr = CGM.filterFunctionTargetAttrs(TD);
+
SmallVector<StringRef, 1> ReqFeatures;
llvm::StringMap<bool> CalleeFeatureMap;
CGM.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
+
+ for (const auto &F : ParsedAttr.Features) {
+ if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1)))
+ ReqFeatures.push_back(StringRef(F).substr(1));
+ }
+
for (const auto &F : CalleeFeatureMap) {
// Only positive features are "required".
if (F.getValue())
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b57004f7e12..19cfffd81c4 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -5033,22 +5033,28 @@ void CodeGenModule::AddVTableTypeMetadata(llvm::GlobalVariable *VTable,
}
}
+TargetAttr::ParsedTargetAttr CodeGenModule::filterFunctionTargetAttrs(const TargetAttr *TD) {
+ assert(TD != nullptr);
+ TargetAttr::ParsedTargetAttr ParsedAttr = TD->parse();
+
+ ParsedAttr.Features.erase(
+ llvm::remove_if(ParsedAttr.Features,
+ [&](const std::string &Feat) {
+ return !Target.isValidFeatureName(
+ StringRef{Feat}.substr(1));
+ }),
+ ParsedAttr.Features.end());
+ return ParsedAttr;
+}
+
+
// Fills in the supplied string map with the set of target features for the
// passed in function.
void CodeGenModule::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
const FunctionDecl *FD) {
StringRef TargetCPU = Target.getTargetOpts().CPU;
if (const auto *TD = FD->getAttr<TargetAttr>()) {
- // If we have a TargetAttr build up the feature map based on that.
- TargetAttr::ParsedTargetAttr ParsedAttr = TD->parse();
-
- ParsedAttr.Features.erase(
- llvm::remove_if(ParsedAttr.Features,
- [&](const std::string &Feat) {
- return !Target.isValidFeatureName(
- StringRef{Feat}.substr(1));
- }),
- ParsedAttr.Features.end());
+ TargetAttr::ParsedTargetAttr ParsedAttr = filterFunctionTargetAttrs(TD);
// Make a copy of the features as passed on the command line into the
// beginning of the additional features from the function to override.
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 961bae324d3..89823982ac2 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1089,6 +1089,10 @@ public:
/// It's up to you to ensure that this is safe.
void AddDefaultFnAttrs(llvm::Function &F);
+ /// Parses the target attributes passed in, and returns only the ones that are
+ /// valid feature names.
+ TargetAttr::ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD);
+
// Fills in the supplied string map with the set of target features for the
// passed in function.
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
OpenPOWER on IntegriCloud