summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2016-12-23 23:33:35 +0000
committerChandler Carruth <chandlerc@gmail.com>2016-12-23 23:33:35 +0000
commit4eaff12ba28eba1f1b0fe174f60f12457d98b5ba (patch)
tree6e5559988df397f2a545822e131a1c2e14b4f4b9 /llvm/lib/Transforms
parentf32f63f22252f570a7b515c29cc20b14ebc8e07e (diff)
downloadbcm5719-llvm-4eaff12ba28eba1f1b0fe174f60f12457d98b5ba.tar.gz
bcm5719-llvm-4eaff12ba28eba1f1b0fe174f60f12457d98b5ba.zip
[PM] Teach the always inlining test case to be much more strict about
whether functions are removed, and fix the new PM's always inliner to actually pass this test. Without this, the new PM's always inliner leaves all the functions kicking around which won't work out very well given the semantics of always inline. Doing this really highlights how frustrating the current alwaysinline semantic contract is though -- why can we put it on *external* functions, etc? Also I've added a number of tricky and interesting test cases for removing functions with the always inliner. There is one remaining case not handled -- fully removing comdats -- and I've left a FIXME about this. llvm-svn: 290457
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/IPO/AlwaysInliner.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index 304694f9cef..1a3f8ced465 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -38,6 +38,7 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M, ModuleAnalysisManager &) {
InlineFunctionInfo IFI;
SmallSetVector<CallSite, 16> Calls;
bool Changed = false;
+ SmallVector<Function *, 16> InlinedFunctions;
for (Function &F : M)
if (!F.isDeclaration() && F.hasFnAttribute(Attribute::AlwaysInline) &&
isInlineViable(F)) {
@@ -52,8 +53,22 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M, ModuleAnalysisManager &) {
// FIXME: We really shouldn't be able to fail to inline at this point!
// We should do something to log or check the inline failures here.
Changed |= InlineFunction(CS, IFI);
+
+ // Remember to try and delete this function afterward. This both avoids
+ // re-walking the rest of the module and avoids dealing with any iterator
+ // invalidation issues while deleting functions.
+ InlinedFunctions.push_back(&F);
}
+ // Now try to delete all the functions we inlined.
+ for (Function *InlinedF : InlinedFunctions) {
+ InlinedF->removeDeadConstantUsers();
+ // FIXME: We should use some utility to handle cases where we can
+ // completely remove the comdat.
+ if (InlinedF->isDefTriviallyDead() && !InlinedF->hasComdat())
+ M.getFunctionList().erase(InlinedF);
+ }
+
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
OpenPOWER on IntegriCloud