aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/IPA
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-08-08 08:22:39 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-08-08 08:22:39 +0000
commit35d21021337fc3dba82155c7232c2c5277b73883 (patch)
treeb82d095572bc06d6ad3d1c12b1814e88b2e26043 /lib/Analysis/IPA
parent76ef79f410853a431c820cb5d0ee11cd66d4c90d (diff)
downloadexternal_llvm-35d21021337fc3dba82155c7232c2c5277b73883.zip
external_llvm-35d21021337fc3dba82155c7232c2c5277b73883.tar.gz
external_llvm-35d21021337fc3dba82155c7232c2c5277b73883.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187967 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/IPA')
-rw-r--r--lib/Analysis/IPA/InlineCost.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/Analysis/IPA/InlineCost.cpp b/lib/Analysis/IPA/InlineCost.cpp
index 37d73a8..89dcd81 100644
--- a/lib/Analysis/IPA/InlineCost.cpp
+++ b/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()