aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/BasicBlock.cpp
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-03-11 19:08:34 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-03-11 19:08:34 +0000
commitb51325dbdb10f0b4ab2b9c5ec4a979dffc246794 (patch)
tree5ee98ad08e88068ab4ad4151d67d74bb2ddea6ea /llvm/lib/IR/BasicBlock.cpp
parentebce18b6fc00b21826d1077399976d2447798ba7 (diff)
downloadllvm-b51325dbdb10f0b4ab2b9c5ec4a979dffc246794.zip
llvm-b51325dbdb10f0b4ab2b9c5ec4a979dffc246794.tar.gz
llvm-b51325dbdb10f0b4ab2b9c5ec4a979dffc246794.tar.bz2
Introduce @llvm.experimental.deoptimize
Summary: This intrinsic, together with deoptimization operand bundles, allow frontends to express transfer of control and frame-local state from one (typically more specialized, hence faster) version of a function into another (typically more generic, hence slower) version. In languages with a fully integrated managed runtime this intrinsic can be used to implement "uncommon trap" like functionality. In unmanaged languages like C and C++, this intrinsic can be used to represent the slow paths of specialized functions. Note: this change does not address how `@llvm.experimental_deoptimize` is lowered. That will be done in a later change. Reviewers: chandlerc, rnk, atrick, reames Subscribers: llvm-commits, kmod, mjacob, maksfb, mcrosier, JosephTremoulet Differential Revision: http://reviews.llvm.org/D17732 llvm-svn: 263281
Diffstat (limited to 'llvm/lib/IR/BasicBlock.cpp')
-rw-r--r--llvm/lib/IR/BasicBlock.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index 89a1d74..9f806fa 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -162,6 +162,21 @@ CallInst *BasicBlock::getTerminatingMustTailCall() {
return nullptr;
}
+CallInst *BasicBlock::getTerminatingDeoptimizeCall() {
+ if (InstList.empty())
+ return nullptr;
+ auto *RI = dyn_cast<ReturnInst>(&InstList.back());
+ if (!RI || RI == &InstList.front())
+ return nullptr;
+
+ if (auto *CI = dyn_cast_or_null<CallInst>(RI->getPrevNode()))
+ if (Function *F = CI->getCalledFunction())
+ if (F->getIntrinsicID() == Intrinsic::experimental_deoptimize)
+ return CI;
+
+ return nullptr;
+}
+
Instruction* BasicBlock::getFirstNonPHI() {
for (Instruction &I : *this)
if (!isa<PHINode>(I))