diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-08-08 08:22:39 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-08-08 08:22:39 +0000 |
| commit | 2ad3698b70745826f73e7270fc173e056e879619 (patch) | |
| tree | 1b44562fab0c488f5f5779289ef549c40870139e /llvm/lib/Analysis/IPA/InlineCost.cpp | |
| parent | 056b647d1f229ef4cd6c739bbede52e4c7a87cf7 (diff) | |
| download | bcm5719-llvm-2ad3698b70745826f73e7270fc173e056e879619.tar.gz bcm5719-llvm-2ad3698b70745826f73e7270fc173e056e879619.zip | |
Disable inlining between sanitized and non-sanitized functions.
Inlining between functions with different values of sanitize_* attributes
leads to over- or under-sanitizing, which is always bad.
llvm-svn: 187967
Diffstat (limited to 'llvm/lib/Analysis/IPA/InlineCost.cpp')
| -rw-r--r-- | llvm/lib/Analysis/IPA/InlineCost.cpp | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/IPA/InlineCost.cpp b/llvm/lib/Analysis/IPA/InlineCost.cpp index 37d73a80f7a..89dcd819ee2 100644 --- a/llvm/lib/Analysis/IPA/InlineCost.cpp +++ b/llvm/lib/Analysis/IPA/InlineCost.cpp @@ -1171,6 +1171,22 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, int Threshold) { return getInlineCost(CS, CS.getCalledFunction(), Threshold); } +/// \brief Test that two functions either have or have not the given attribute +/// at the same time. +static bool attributeMatches(Function *F1, Function *F2, + Attribute::AttrKind Attr) { + return F1->hasFnAttribute(Attr) == F2->hasFnAttribute(Attr); +} + +/// \brief Test that there are no attribute conflicts between Caller and Callee +/// that prevent inlining. +static bool functionsHaveCompatibleAttributes(Function *Caller, + Function *Callee) { + return attributeMatches(Caller, Callee, Attribute::SanitizeAddress) && + attributeMatches(Caller, Callee, Attribute::SanitizeMemory) && + attributeMatches(Caller, Callee, Attribute::SanitizeThread); +} + InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee, int Threshold) { // Cannot inline indirect calls. @@ -1179,20 +1195,22 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee, // Calls to functions with always-inline attributes should be inlined // whenever possible. - if (Callee->getAttributes().hasAttribute(AttributeSet::FunctionIndex, - Attribute::AlwaysInline)) { + if (Callee->hasFnAttribute(Attribute::AlwaysInline)) { if (isInlineViable(*Callee)) return llvm::InlineCost::getAlways(); return llvm::InlineCost::getNever(); } + // Never inline functions with conflicting attributes (unless callee has + // always-inline attribute). + if (!functionsHaveCompatibleAttributes(CS.getCaller(), Callee)) + return llvm::InlineCost::getNever(); + // Don't inline functions which can be redefined at link-time to mean // something else. Don't inline functions marked noinline or call sites // marked noinline. if (Callee->mayBeOverridden() || - Callee->getAttributes().hasAttribute(AttributeSet::FunctionIndex, - Attribute::NoInline) || - CS.isNoInline()) + Callee->hasFnAttribute(Attribute::NoInline) || CS.isNoInline()) return llvm::InlineCost::getNever(); DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName() |

