diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2016-03-11 19:08:34 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2016-03-11 19:08:34 +0000 |
commit | b51325dbdb10f0b4ab2b9c5ec4a979dffc246794 (patch) | |
tree | 5ee98ad08e88068ab4ad4151d67d74bb2ddea6ea /llvm/lib/IR/BasicBlock.cpp | |
parent | ebce18b6fc00b21826d1077399976d2447798ba7 (diff) | |
download | llvm-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.cpp | 15 |
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)) |