summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/IPO/AlwaysInliner.cpp4
-rw-r--r--llvm/lib/Transforms/IPO/Inliner.cpp120
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp29
3 files changed, 69 insertions, 84 deletions
diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index 07138718ce2..3b735ddd192 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -150,7 +150,7 @@ InlineCost AlwaysInlinerLegacyPass::getInlineCost(CallSite CS) {
// declarations.
if (Callee && !Callee->isDeclaration() &&
CS.hasFnAttr(Attribute::AlwaysInline) && isInlineViable(*Callee))
- return InlineCost::getAlways("always inliner");
+ return InlineCost::getAlways();
- return InlineCost::getNever("always inliner");
+ return InlineCost::getNever();
}
diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp
index fdf47b7bd62..3da0c2e83eb 100644
--- a/llvm/lib/Transforms/IPO/Inliner.cpp
+++ b/llvm/lib/Transforms/IPO/Inliner.cpp
@@ -64,7 +64,6 @@
#include <algorithm>
#include <cassert>
#include <functional>
-#include <sstream>
#include <tuple>
#include <utility>
#include <vector>
@@ -276,9 +275,8 @@ static bool InlineCallIfPossible(
// Try to inline the function. Get the list of static allocas that were
// inlined.
- InlineResult IR = InlineFunction(CS, IFI, &AAR, InsertLifetime);
- if (!IR)
- return IR;
+ if (!InlineFunction(CS, IFI, &AAR, InsertLifetime))
+ return false;
if (InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No)
ImportedFunctionsStats.recordInline(*Caller, *Callee);
@@ -288,7 +286,7 @@ static bool InlineCallIfPossible(
if (!DisableInlinedAllocaMerging)
mergeInlinedArrayAllocas(Caller, IFI, InlinedArrayAllocas, InlineHistory);
- return IR; // success
+ return true;
}
/// Return true if inlining of CS can block the caller from being
@@ -367,33 +365,6 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
return false;
}
-static std::basic_ostream<char> &operator<<(std::basic_ostream<char> &R,
- const ore::NV &Arg) {
- return R << Arg.Val;
-}
-
-template <class RemarkT>
-RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
- using namespace ore;
- if (IC.isAlways()) {
- R << "(cost=always)";
- } else if (IC.isNever()) {
- R << "(cost=never)";
- } else {
- R << "(cost=" << ore::NV("Cost", IC.getCost())
- << ", threshold=" << ore::NV("Threshold", IC.getThreshold()) << ")";
- }
- if (const char *Reason = IC.getReason())
- R << ": " << ore::NV("Reason", Reason);
- return R;
-}
-
-static std::string inlineCostStr(const InlineCost &IC) {
- std::stringstream Remark;
- Remark << IC;
- return Remark.str();
-}
-
/// Return the cost only if the inliner should attempt to inline at the given
/// CallSite. If we return the cost, we will emit an optimisation remark later
/// using that cost, so we won't do so from this function.
@@ -408,32 +379,35 @@ shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
Function *Caller = CS.getCaller();
if (IC.isAlways()) {
- LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC)
+ LLVM_DEBUG(dbgs() << " Inlining: cost=always"
<< ", Call: " << *CS.getInstruction() << "\n");
return IC;
}
if (IC.isNever()) {
- LLVM_DEBUG(dbgs() << " NOT Inlining " << inlineCostStr(IC)
+ LLVM_DEBUG(dbgs() << " NOT Inlining: cost=never"
<< ", Call: " << *CS.getInstruction() << "\n");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", Call)
<< NV("Callee", Callee) << " not inlined into "
- << NV("Caller", Caller) << " because it should never be inlined "
- << IC;
+ << NV("Caller", Caller)
+ << " because it should never be inlined (cost=never)";
});
- return IC;
+ return None;
}
if (!IC) {
- LLVM_DEBUG(dbgs() << " NOT Inlining " << inlineCostStr(IC)
+ LLVM_DEBUG(dbgs() << " NOT Inlining: cost=" << IC.getCost()
+ << ", thres=" << IC.getThreshold()
<< ", Call: " << *CS.getInstruction() << "\n");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "TooCostly", Call)
<< NV("Callee", Callee) << " not inlined into "
- << NV("Caller", Caller) << " because too costly to inline " << IC;
+ << NV("Caller", Caller) << " because too costly to inline (cost="
+ << NV("Cost", IC.getCost())
+ << ", threshold=" << NV("Threshold", IC.getThreshold()) << ")";
});
- return IC;
+ return None;
}
int TotalSecondaryCost = 0;
@@ -454,7 +428,8 @@ shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
return None;
}
- LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC)
+ LLVM_DEBUG(dbgs() << " Inlining: cost=" << IC.getCost()
+ << ", thres=" << IC.getThreshold()
<< ", Call: " << *CS.getInstruction() << '\n');
return IC;
}
@@ -486,18 +461,6 @@ bool LegacyInlinerBase::runOnSCC(CallGraphSCC &SCC) {
return inlineCalls(SCC);
}
-static void emit_inlined_into(OptimizationRemarkEmitter &ORE, DebugLoc &DLoc,
- const BasicBlock *Block, const Function &Callee,
- const Function &Caller, const InlineCost &IC) {
- ORE.emit([&]() {
- bool AlwaysInline = IC.isAlways();
- StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined";
- return OptimizationRemark(DEBUG_TYPE, RemarkName, DLoc, Block)
- << ore::NV("Callee", &Callee) << " inlined into "
- << ore::NV("Caller", &Caller) << " with " << IC;
- });
-}
-
static bool
inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
std::function<AssumptionCache &(Function &)> GetAssumptionCache,
@@ -622,9 +585,8 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
Optional<InlineCost> OIC = shouldInline(CS, GetInlineCost, ORE);
// If the policy determines that we should inline this function,
// delete the call instead.
- if (!OIC || !*OIC) {
+ if (!OIC)
continue;
- }
// If this call site is dead and it is to a readonly function, we should
// just delete the call instead of trying to inline it, regardless of
@@ -644,21 +606,34 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// Attempt to inline the function.
using namespace ore;
- InlineResult IR = InlineCallIfPossible(
- CS, InlineInfo, InlinedArrayAllocas, InlineHistoryID,
- InsertLifetime, AARGetter, ImportedFunctionsStats);
- if (!IR) {
+ if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas,
+ InlineHistoryID, InsertLifetime, AARGetter,
+ ImportedFunctionsStats)) {
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc,
Block)
<< NV("Callee", Callee) << " will not be inlined into "
- << NV("Caller", Caller) << ": " << NV("Reason", IR.message);
+ << NV("Caller", Caller);
});
continue;
}
++NumInlined;
- emit_inlined_into(ORE, DLoc, Block, *Callee, *Caller, *OIC);
+ ORE.emit([&]() {
+ bool AlwaysInline = OIC->isAlways();
+ StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined";
+ OptimizationRemark R(DEBUG_TYPE, RemarkName, DLoc, Block);
+ R << NV("Callee", Callee) << " inlined into ";
+ R << NV("Caller", Caller);
+ if (AlwaysInline)
+ R << " with cost=always";
+ else {
+ R << " with cost=" << NV("Cost", OIC->getCost());
+ R << " (threshold=" << NV("Threshold", OIC->getThreshold());
+ R << ")";
+ }
+ return R;
+ });
// If inlining this function gave us any new call sites, throw them
// onto our worklist to process. They are useful inline candidates.
@@ -996,7 +971,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
Optional<InlineCost> OIC = shouldInline(CS, GetInlineCost, ORE);
// Check whether we want to inline this callsite.
- if (!OIC || !*OIC)
+ if (!OIC)
continue;
// Setup the data structure used to plumb customization into the
@@ -1012,19 +987,32 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
using namespace ore;
- InlineResult IR = InlineFunction(CS, IFI);
- if (!IR) {
+ if (!InlineFunction(CS, IFI)) {
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
<< NV("Callee", &Callee) << " will not be inlined into "
- << NV("Caller", &F) << ": " << NV("Reason", IR.message);
+ << NV("Caller", &F);
});
continue;
}
DidInline = true;
InlinedCallees.insert(&Callee);
- emit_inlined_into(ORE, DLoc, Block, Callee, F, *OIC);
+ ORE.emit([&]() {
+ bool AlwaysInline = OIC->isAlways();
+ StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined";
+ OptimizationRemark R(DEBUG_TYPE, RemarkName, DLoc, Block);
+ R << NV("Callee", &Callee) << " inlined into ";
+ R << NV("Caller", &F);
+ if (AlwaysInline)
+ R << " with cost=always";
+ else {
+ R << " with cost=" << NV("Cost", OIC->getCost());
+ R << " (threshold=" << NV("Threshold", OIC->getThreshold());
+ R << ")";
+ }
+ return R;
+ });
// Add any new callsites to defined functions to the worklist.
if (!IFI.InlinedCallSites.empty()) {
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index f8226f529ee..ddc6e07e2f5 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -84,15 +84,13 @@ PreserveAlignmentAssumptions("preserve-alignment-assumptions-during-inlining",
cl::init(true), cl::Hidden,
cl::desc("Convert align attributes to assumptions during inlining."));
-llvm::InlineResult llvm::InlineFunction(CallInst *CI, InlineFunctionInfo &IFI,
- AAResults *CalleeAAR,
- bool InsertLifetime) {
+bool llvm::InlineFunction(CallInst *CI, InlineFunctionInfo &IFI,
+ AAResults *CalleeAAR, bool InsertLifetime) {
return InlineFunction(CallSite(CI), IFI, CalleeAAR, InsertLifetime);
}
-llvm::InlineResult llvm::InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI,
- AAResults *CalleeAAR,
- bool InsertLifetime) {
+bool llvm::InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI,
+ AAResults *CalleeAAR, bool InsertLifetime) {
return InlineFunction(CallSite(II), IFI, CalleeAAR, InsertLifetime);
}
@@ -1493,10 +1491,9 @@ static void updateCalleeCount(BlockFrequencyInfo *CallerBFI, BasicBlock *CallBB,
/// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now
/// exists in the instruction stream. Similarly this will inline a recursive
/// function by one level.
-llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
- AAResults *CalleeAAR,
- bool InsertLifetime,
- Function *ForwardVarArgsTo) {
+bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
+ AAResults *CalleeAAR, bool InsertLifetime,
+ Function *ForwardVarArgsTo) {
Instruction *TheCall = CS.getInstruction();
assert(TheCall->getParent() && TheCall->getFunction()
&& "Instruction not in function!");
@@ -1507,7 +1504,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
Function *CalledFunc = CS.getCalledFunction();
if (!CalledFunc || // Can't inline external function or indirect
CalledFunc->isDeclaration()) // call!
- return "external or indirect";
+ return false;
// The inliner does not know how to inline through calls with operand bundles
// in general ...
@@ -1521,7 +1518,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
if (Tag == LLVMContext::OB_funclet)
continue;
- return "unsupported operand bundle";
+ return false;
}
}
@@ -1540,7 +1537,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
if (!Caller->hasGC())
Caller->setGC(CalledFunc->getGC());
else if (CalledFunc->getGC() != Caller->getGC())
- return "incompatible GC";
+ return false;
}
// Get the personality function from the callee if it contains a landing pad.
@@ -1564,7 +1561,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
// TODO: This isn't 100% true. Some personality functions are proper
// supersets of others and can be used in place of the other.
else if (CalledPersonality != CallerPersonality)
- return "incompatible personality";
+ return false;
}
// We need to figure out which funclet the callsite was in so that we may
@@ -1589,7 +1586,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
// for catchpads.
for (const BasicBlock &CalledBB : *CalledFunc) {
if (isa<CatchSwitchInst>(CalledBB.getFirstNonPHI()))
- return "catch in cleanup funclet";
+ return false;
}
}
} else if (isAsynchronousEHPersonality(Personality)) {
@@ -1597,7 +1594,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
// funclet in the callee.
for (const BasicBlock &CalledBB : *CalledFunc) {
if (CalledBB.isEHPad())
- return "SEH in cleanup funclet";
+ return false;
}
}
}
OpenPOWER on IntegriCloud