summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorEaswaran Raman <eraman@google.com>2016-08-10 00:48:04 +0000
committerEaswaran Raman <eraman@google.com>2016-08-10 00:48:04 +0000
commit1c57cc2b680a2d77bb63b554b7a7d832682e883f (patch)
tree4f2f18bcf5e3f37ca7bc4e2cc2af084076e3a33c /llvm/lib
parent21db1ec221713f0be0a1de62acab96b24ea7e8a4 (diff)
downloadbcm5719-llvm-1c57cc2b680a2d77bb63b554b7a7d832682e883f.tar.gz
bcm5719-llvm-1c57cc2b680a2d77bb63b554b7a7d832682e883f.zip
Do not directly use inline threshold cl options in cost analysis.
This adds an InlineParams struct which is populated from the command line options by getInlineParams and passed to getInlineCost for the call analyzer to use. Differential revision: https://reviews.llvm.org/D22120 llvm-svn: 278189
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/InlineCost.cpp155
-rw-r--r--llvm/lib/Transforms/IPO/InlineSimple.cpp22
2 files changed, 106 insertions, 71 deletions
diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index eba905f08e6..dd9174c0bcd 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -40,18 +40,7 @@ using namespace llvm;
STATISTIC(NumCallsAnalyzed, "Number of call sites analyzed");
-// Threshold to use when optsize is specified (and there is no
-// -inline-threshold).
-const int OptSizeThreshold = 75;
-
-// Threshold to use when -Oz is specified (and there is no -inline-threshold).
-const int OptMinSizeThreshold = 25;
-
-// Threshold to use when -O[34] is specified (and there is no
-// -inline-threshold).
-const int OptAggressiveThreshold = 275;
-
-static cl::opt<int> DefaultInlineThreshold(
+static cl::opt<int> InlineThreshold(
"inline-threshold", cl::Hidden, cl::init(225), cl::ZeroOrMore,
cl::desc("Control the amount of inlining to perform (default = 225)"));
@@ -94,6 +83,9 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
// easily cacheable. Instead, use the cover function paramHasAttr.
CallSite CandidateCS;
+ // Tunable parameters that control the analysis.
+ const InlineParams &Params;
+
int Threshold;
int Cost;
@@ -210,11 +202,11 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
public:
CallAnalyzer(const TargetTransformInfo &TTI,
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
- ProfileSummaryInfo *PSI, Function &Callee, int Threshold,
- CallSite CSArg)
+ ProfileSummaryInfo *PSI, Function &Callee, CallSite CSArg,
+ const InlineParams &Params)
: TTI(TTI), GetAssumptionCache(GetAssumptionCache), PSI(PSI), F(Callee),
- CandidateCS(CSArg), Threshold(Threshold), Cost(0),
- IsCallerRecursive(false), IsRecursiveCall(false),
+ CandidateCS(CSArg), Params(Params), Threshold(Params.DefaultThreshold),
+ Cost(0), IsCallerRecursive(false), IsRecursiveCall(false),
ExposesReturnsTwice(false), HasDynamicAlloca(false),
ContainsNoDuplicateCall(false), HasReturn(false), HasIndirectBr(false),
HasFrameEscape(false), AllocatedSize(0), NumInstructions(0),
@@ -626,18 +618,18 @@ void CallAnalyzer::updateThreshold(CallSite CS, Function &Callee) {
}
Function *Caller = CS.getCaller();
- if (DefaultInlineThreshold.getNumOccurrences() > 0) {
- // Explicitly specified -inline-threhold overrides the threshold passed to
- // CallAnalyzer's constructor.
- Threshold = DefaultInlineThreshold;
- } else {
- // If -inline-threshold is not given, listen to the optsize and minsize
- // attributes when they would decrease the threshold.
- if (Caller->optForMinSize() && OptMinSizeThreshold < Threshold)
- Threshold = OptMinSizeThreshold;
- else if (Caller->optForSize() && OptSizeThreshold < Threshold)
- Threshold = OptSizeThreshold;
- }
+
+ // return min(A, B) if B is valid.
+ auto MinIfValid = [](int A, Optional<int> B) {
+ return B ? std::min(A, B.getValue()) : A;
+ };
+
+ // Use the OptMinSizeThreshold or OptSizeThreshold knob if they are available
+ // and reduce the threshold if the caller has the necessary attribute.
+ if (Caller->optForMinSize())
+ Threshold = MinIfValid(Threshold, Params.OptMinSizeThreshold);
+ else if (Caller->optForSize())
+ Threshold = MinIfValid(Threshold, Params.OptSizeThreshold);
bool HotCallsite = false;
uint64_t TotalWeight;
@@ -651,21 +643,18 @@ void CallAnalyzer::updateThreshold(CallSite CS, Function &Callee) {
// minimize its size.
bool InlineHint = Callee.hasFnAttribute(Attribute::InlineHint) ||
PSI->isHotFunction(&Callee);
- if (InlineHint && HintThreshold > Threshold && !Caller->optForMinSize())
- Threshold = HintThreshold;
+ if (InlineHint && !Caller->optForMinSize())
+ Threshold = std::max(Threshold, Params.HintThreshold);
if (HotCallsite && HotCallSiteThreshold > Threshold &&
!Caller->optForMinSize())
- Threshold = HotCallSiteThreshold;
+ Threshold = std::max(Threshold, Params.HotCallSiteThreshold);
bool ColdCallee = PSI->isColdFunction(&Callee);
- // Command line argument for DefaultInlineThreshold will override the default
- // ColdThreshold. If we have -inline-threshold but no -inlinecold-threshold,
- // do not use the default cold threshold even if it is smaller.
- if ((DefaultInlineThreshold.getNumOccurrences() == 0 ||
- ColdThreshold.getNumOccurrences() > 0) &&
- ColdCallee && ColdThreshold < Threshold)
- Threshold = ColdThreshold;
+ // For cold callees, use the ColdThreshold knob if it is available and reduces
+ // the threshold.
+ if (ColdCallee)
+ Threshold = MinIfValid(Threshold, Params.ColdThreshold);
// Finally, take the target-specific inlining threshold multiplier into
// account.
@@ -967,8 +956,9 @@ bool CallAnalyzer::visitCallSite(CallSite CS) {
// during devirtualization and so we want to give it a hefty bonus for
// inlining, but cap that bonus in the event that inlining wouldn't pan
// out. Pretend to inline the function, with a custom threshold.
- CallAnalyzer CA(TTI, GetAssumptionCache, PSI, *F,
- InlineConstants::IndirectCallThreshold, CS);
+ auto IndirectCallParams = Params;
+ IndirectCallParams.DefaultThreshold = InlineConstants::IndirectCallThreshold;
+ CallAnalyzer CA(TTI, GetAssumptionCache, PSI, *F, CS, Params);
if (CA.analyzeCall(CS)) {
// We were able to inline the indirect call! Subtract the cost from the
// threshold to get the bonus we want to apply, but don't go below zero.
@@ -1454,28 +1444,15 @@ static bool functionsHaveCompatibleAttributes(Function *Caller,
}
InlineCost llvm::getInlineCost(
- CallSite CS, int DefaultThreshold, TargetTransformInfo &CalleeTTI,
+ CallSite CS, const InlineParams &Params, TargetTransformInfo &CalleeTTI,
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
ProfileSummaryInfo *PSI) {
- return getInlineCost(CS, CS.getCalledFunction(), DefaultThreshold, CalleeTTI,
+ return getInlineCost(CS, CS.getCalledFunction(), Params, CalleeTTI,
GetAssumptionCache, PSI);
}
-int llvm::computeThresholdFromOptLevels(unsigned OptLevel,
- unsigned SizeOptLevel) {
- if (OptLevel > 2)
- return OptAggressiveThreshold;
- if (SizeOptLevel == 1) // -Os
- return OptSizeThreshold;
- if (SizeOptLevel == 2) // -Oz
- return OptMinSizeThreshold;
- return DefaultInlineThreshold;
-}
-
-int llvm::getDefaultInlineThreshold() { return DefaultInlineThreshold; }
-
InlineCost llvm::getInlineCost(
- CallSite CS, Function *Callee, int DefaultThreshold,
+ CallSite CS, Function *Callee, const InlineParams &Params,
TargetTransformInfo &CalleeTTI,
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
ProfileSummaryInfo *PSI) {
@@ -1512,7 +1489,7 @@ InlineCost llvm::getInlineCost(
DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName()
<< "...\n");
- CallAnalyzer CA(CalleeTTI, GetAssumptionCache, PSI, *Callee, DefaultThreshold, CS);
+ CallAnalyzer CA(CalleeTTI, GetAssumptionCache, PSI, *Callee, CS, Params);
bool ShouldInline = CA.analyzeCall(CS);
DEBUG(CA.dump());
@@ -1560,3 +1537,67 @@ bool llvm::isInlineViable(Function &F) {
return true;
}
+
+// APIs to create InlineParams based on command line flags and/or other
+// parameters.
+
+InlineParams llvm::getInlineParams(int Threshold) {
+ InlineParams Params;
+
+ // This field is the threshold to use for a callee by default. This is
+ // derived from one or more of:
+ // * optimization or size-optimization levels,
+ // * a value passed to createFunctionInliningPass function, or
+ // * the -inline-threshold flag.
+ // If the -inline-threshold flag is explicitly specified, that is used
+ // irrespective of anything else.
+ if (InlineThreshold.getNumOccurrences() > 0)
+ Params.DefaultThreshold = InlineThreshold;
+ else
+ Params.DefaultThreshold = Threshold;
+
+ // Set the HintThreshold knob from the -inlinehint-threshold.
+ Params.HintThreshold = HintThreshold;
+
+ // Set the HotCallSiteThreshold knob from the -hot-callsite-threshold.
+ Params.HotCallSiteThreshold = HotCallSiteThreshold;
+
+ // Set the OptMinSizeThreshold and OptSizeThreshold params only if the
+ // Set the OptMinSizeThreshold and OptSizeThreshold params only if the
+ // -inlinehint-threshold commandline option is not explicitly given. If that
+ // option is present, then its value applies even for callees with size and
+ // minsize attributes.
+ // If the -inline-threshold is not specified, set the ColdThreshold from the
+ // -inlinecold-threshold even if it is not explicitly passed. If
+ // -inline-threshold is specified, then -inlinecold-threshold needs to be
+ // explicitly specified to set the ColdThreshold knob
+ if (InlineThreshold.getNumOccurrences() == 0) {
+ Params.OptMinSizeThreshold = InlineConstants::OptMinSizeThreshold;
+ Params.OptSizeThreshold = InlineConstants::OptSizeThreshold;
+ Params.ColdThreshold = ColdThreshold;
+ } else if (ColdThreshold.getNumOccurrences() > 0) {
+ Params.ColdThreshold = ColdThreshold;
+ }
+ return Params;
+}
+
+InlineParams llvm::getInlineParams() {
+ return getInlineParams(InlineThreshold);
+}
+
+// Compute the default threshold for inlining based on the opt level and the
+// size opt level.
+static int computeThresholdFromOptLevels(unsigned OptLevel,
+ unsigned SizeOptLevel) {
+ if (OptLevel > 2)
+ return InlineConstants::OptAggressiveThreshold;
+ if (SizeOptLevel == 1) // -Os
+ return InlineConstants::OptSizeThreshold;
+ if (SizeOptLevel == 2) // -Oz
+ return InlineConstants::OptMinSizeThreshold;
+ return InlineThreshold;
+}
+
+InlineParams llvm::getInlineParams(unsigned OptLevel, unsigned SizeOptLevel) {
+ return getInlineParams(computeThresholdFromOptLevels(OptLevel, SizeOptLevel));
+}
diff --git a/llvm/lib/Transforms/IPO/InlineSimple.cpp b/llvm/lib/Transforms/IPO/InlineSimple.cpp
index 8131683abd0..d135ccff520 100644
--- a/llvm/lib/Transforms/IPO/InlineSimple.cpp
+++ b/llvm/lib/Transforms/IPO/InlineSimple.cpp
@@ -39,20 +39,15 @@ namespace {
/// inliner pass and the always inliner pass. The two passes use different cost
/// analyses to determine when to inline.
class SimpleInliner : public Inliner {
- // This field is populated based on one of the following:
- // * optimization or size-optimization levels,
- // * the --inline-threshold flag, or
- // * a user specified value.
- int DefaultThreshold;
+
+ InlineParams Params;
public:
- SimpleInliner()
- : Inliner(ID), DefaultThreshold(llvm::getDefaultInlineThreshold()) {
+ SimpleInliner() : Inliner(ID), Params(llvm::getInlineParams()) {
initializeSimpleInlinerPass(*PassRegistry::getPassRegistry());
}
- explicit SimpleInliner(int Threshold)
- : Inliner(ID), DefaultThreshold(Threshold) {
+ explicit SimpleInliner(InlineParams Params) : Inliner(ID), Params(Params) {
initializeSimpleInlinerPass(*PassRegistry::getPassRegistry());
}
@@ -65,8 +60,7 @@ public:
[&](Function &F) -> AssumptionCache & {
return ACT->getAssumptionCache(F);
};
- return llvm::getInlineCost(CS, DefaultThreshold, TTI, GetAssumptionCache,
- PSI);
+ return llvm::getInlineCost(CS, Params, TTI, GetAssumptionCache, PSI);
}
bool runOnSCC(CallGraphSCC &SCC) override;
@@ -74,6 +68,7 @@ public:
private:
TargetTransformInfoWrapperPass *TTIWP;
+
};
} // end anonymous namespace
@@ -92,13 +87,12 @@ INITIALIZE_PASS_END(SimpleInliner, "inline", "Function Integration/Inlining",
Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
Pass *llvm::createFunctionInliningPass(int Threshold) {
- return new SimpleInliner(Threshold);
+ return new SimpleInliner(llvm::getInlineParams(Threshold));
}
Pass *llvm::createFunctionInliningPass(unsigned OptLevel,
unsigned SizeOptLevel) {
- return new SimpleInliner(
- llvm::computeThresholdFromOptLevels(OptLevel, SizeOptLevel));
+ return new SimpleInliner(llvm::getInlineParams(OptLevel, SizeOptLevel));
}
bool SimpleInliner::runOnSCC(CallGraphSCC &SCC) {
OpenPOWER on IntegriCloud