diff options
author | Vedant Kumar <vsk@apple.com> | 2018-12-07 20:24:04 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2018-12-07 20:24:04 +0000 |
commit | 03f9f15b16878e9a487429a39da6cb1934c27a15 (patch) | |
tree | d7b248a3b39a41baa22480129c5c81f9f6755e28 /llvm/lib/Transforms | |
parent | 03aaa3e2aa37b311999c6af567871325c2fa049f (diff) | |
download | bcm5719-llvm-03f9f15b16878e9a487429a39da6cb1934c27a15.tar.gz bcm5719-llvm-03f9f15b16878e9a487429a39da6cb1934c27a15.zip |
[HotColdSplitting] Refine definition of unlikelyExecuted
The splitting pass uses its 'unlikelyExecuted' predicate to statically
decide which blocks are cold.
- Do not treat noreturn calls as if they are cold unless they are actually
marked cold. This is motivated by functions like exit() and longjmp(), which
are not beneficial to outline.
- Do not treat inline asm as an outlining barrier. In practice asm("") is
frequently used to inhibit basic block merging; enabling outlining in this case
results in substantial memory savings.
- Treat invokes of cold functions as cold.
As a drive-by, remove the 'exceptionHandlingFunctions' predicate, because it's
no longer needed. The pass can identify & outline blocks dominated by EH pads,
so there's no need to special-case __cxa_begin_catch etc.
Differential Revision: https://reviews.llvm.org/D54244
llvm-svn: 348640
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/IPO/HotColdSplitting.cpp | 40 |
1 files changed, 16 insertions, 24 deletions
diff --git a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp index 93d2b7550a0..704ddbe6110 100644 --- a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp +++ b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp @@ -26,6 +26,7 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Dominators.h" @@ -98,36 +99,27 @@ bool blockEndsInUnreachable(const BasicBlock &BB) { return !(isa<ReturnInst>(I) || isa<IndirectBrInst>(I)); } -static bool exceptionHandlingFunctions(const CallInst *CI) { - auto F = CI->getCalledFunction(); - if (!F) - return false; - auto FName = F->getName(); - return FName == "__cxa_begin_catch" || - FName == "__cxa_free_exception" || - FName == "__cxa_allocate_exception" || - FName == "__cxa_begin_catch" || - FName == "__cxa_end_catch"; -} - -static bool unlikelyExecuted(const BasicBlock &BB) { - if (blockEndsInUnreachable(BB)) - return true; +bool unlikelyExecuted(BasicBlock &BB) { // Exception handling blocks are unlikely executed. if (BB.isEHPad()) return true; - for (const Instruction &I : BB) - if (const CallInst *CI = dyn_cast<CallInst>(&I)) { - // The block is cold if it calls functions tagged as cold or noreturn. - if (CI->hasFnAttr(Attribute::Cold) || - CI->hasFnAttr(Attribute::NoReturn) || - exceptionHandlingFunctions(CI)) + + // The block is cold if it calls/invokes a cold function. + for (Instruction &I : BB) + if (auto CS = CallSite(&I)) + if (CS.hasFnAttr(Attribute::Cold)) return true; - // Assume that inline assembly is hot code. - if (isa<InlineAsm>(CI->getCalledValue())) + // The block is cold if it has an unreachable terminator, unless it's + // preceded by a call to a (possibly warm) noreturn call (e.g. longjmp). + if (blockEndsInUnreachable(BB)) { + if (auto *CI = + dyn_cast_or_null<CallInst>(BB.getTerminator()->getPrevNode())) + if (CI->hasFnAttr(Attribute::NoReturn)) return false; - } + return true; + } + return false; } |