diff options
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 29c294f7212..4959b80faec 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1667,7 +1667,7 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, bool AddedAttr = false; if (TD || SD) { llvm::StringMap<bool> FeatureMap; - getContext().getFunctionFeatureMap(FeatureMap, GD); + getFunctionFeatureMap(FeatureMap, GD); // Produce the canonical string for this set of features. for (const llvm::StringMap<bool>::value_type &Entry : FeatureMap) @@ -5858,6 +5858,58 @@ 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, + GlobalDecl GD) { + StringRef TargetCPU = Target.getTargetOpts().CPU; + const FunctionDecl *FD = GD.getDecl()->getAsFunction(); + if (const auto *TD = FD->getAttr<TargetAttr>()) { + 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. + ParsedAttr.Features.insert(ParsedAttr.Features.begin(), + Target.getTargetOpts().FeaturesAsWritten.begin(), + Target.getTargetOpts().FeaturesAsWritten.end()); + + if (ParsedAttr.Architecture != "" && + Target.isValidCPUName(ParsedAttr.Architecture)) + TargetCPU = ParsedAttr.Architecture; + + // 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. + Target.initFeatureMap(FeatureMap, getDiags(), TargetCPU, + ParsedAttr.Features); + } else if (const auto *SD = FD->getAttr<CPUSpecificAttr>()) { + llvm::SmallVector<StringRef, 32> FeaturesTmp; + Target.getCPUSpecificCPUDispatchFeatures( + SD->getCPUName(GD.getMultiVersionIndex())->getName(), FeaturesTmp); + std::vector<std::string> Features(FeaturesTmp.begin(), FeaturesTmp.end()); + Target.initFeatureMap(FeatureMap, getDiags(), TargetCPU, Features); + } else { + Target.initFeatureMap(FeatureMap, getDiags(), TargetCPU, + Target.getTargetOpts().Features); + } +} + llvm::SanitizerStatReport &CodeGenModule::getSanStats() { if (!SanStats) SanStats = std::make_unique<llvm::SanitizerStatReport>(&getModule()); |