summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2018-12-07 20:24:04 +0000
committerVedant Kumar <vsk@apple.com>2018-12-07 20:24:04 +0000
commit03f9f15b16878e9a487429a39da6cb1934c27a15 (patch)
treed7b248a3b39a41baa22480129c5c81f9f6755e28 /llvm/lib/Transforms
parent03aaa3e2aa37b311999c6af567871325c2fa049f (diff)
downloadbcm5719-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.cpp40
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;
}
OpenPOWER on IntegriCloud