diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 26 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 4 |
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, |