summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r--lib/CodeGen/CGCall.cpp73
1 files changed, 56 insertions, 17 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index e77539c..58ef171 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1465,6 +1465,8 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf");
}
+ FuncAttrs.addAttribute("disable-tail-calls",
+ llvm::toStringRef(CodeGenOpts.DisableTailCalls));
FuncAttrs.addAttribute("less-precise-fpmad",
llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
FuncAttrs.addAttribute("no-infs-fp-math",
@@ -1481,24 +1483,62 @@ 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 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-"))
+ Features.push_back("-" + Feature.split("-").second.str());
+ 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));
}
}
@@ -2231,11 +2271,10 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
if (Intrinsic->getIntrinsicID() == llvm::Intrinsic::lifetime_end) {
const llvm::Value *CastAddr = Intrinsic->getArgOperand(1);
++II;
- if (isa<llvm::BitCastInst>(&*II)) {
- if (CastAddr == &*II) {
- continue;
- }
- }
+ if (II == IE)
+ break;
+ if (isa<llvm::BitCastInst>(&*II) && (CastAddr == &*II))
+ continue;
}
}
I = &*II;
@@ -2571,7 +2610,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,
LValue srcLV;
// Make an optimistic effort to emit the address as an l-value.
- // This can fail if the the argument expression is more complicated.
+ // This can fail if the argument expression is more complicated.
if (const Expr *lvExpr = maybeGetUnaryAddrOfOperand(CRE->getSubExpr())) {
srcLV = CGF.EmitLValue(lvExpr);
OpenPOWER on IntegriCloud