summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-01-13 00:48:10 +0000
committerReid Kleckner <reid@kleckner.net>2015-01-13 00:48:10 +0000
commite9b893187333ca069b5aed697ad784865e42f79f (patch)
treee17ad1b3279b4a6383370b0739b862f1b0635790 /llvm/lib/IR/Verifier.cpp
parent845755c4bb6c55eca84700060de706331ba77a71 (diff)
downloadbcm5719-llvm-e9b893187333ca069b5aed697ad784865e42f79f.tar.gz
bcm5719-llvm-e9b893187333ca069b5aed697ad784865e42f79f.zip
Add the llvm.frameallocate and llvm.recoverframeallocation intrinsics
These intrinsics allow multiple functions to share a single stack allocation from one function's call frame. The function with the allocation may only perform one allocation, and it must be in the entry block. Functions accessing the allocation call llvm.recoverframeallocation with the function whose frame they are accessing and a frame pointer from an active call frame of that function. These intrinsics are very difficult to inline correctly, so the intention is that they be introduced rarely, or at least very late during EH preparation. Reviewers: echristo, andrew.w.kaylor Differential Revision: http://reviews.llvm.org/D6493 llvm-svn: 225746
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index ad7473b6611..4a98b546099 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -198,9 +198,14 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
/// personality function.
const Value *PersonalityFn;
+ /// \brief Whether we've seen a call to @llvm.frameallocate in this function
+ /// already.
+ bool SawFrameAllocate;
+
public:
explicit Verifier(raw_ostream &OS = dbgs())
- : VerifierSupport(OS), Context(nullptr), PersonalityFn(nullptr) {}
+ : VerifierSupport(OS), Context(nullptr), PersonalityFn(nullptr),
+ SawFrameAllocate(false) {}
bool verify(const Function &F) {
M = F.getParent();
@@ -235,6 +240,7 @@ public:
visit(const_cast<Function &>(F));
InstsInThisBlock.clear();
PersonalityFn = nullptr;
+ SawFrameAllocate = false;
return !Broken;
}
@@ -2599,7 +2605,26 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
Assert1(isa<ConstantInt>(CI.getArgOperand(1)),
"llvm.invariant.end parameter #2 must be a constant integer", &CI);
break;
-
+
+ case Intrinsic::frameallocate: {
+ BasicBlock *BB = CI.getParent();
+ Assert1(BB == &BB->getParent()->front(),
+ "llvm.frameallocate used outside of entry block", &CI);
+ Assert1(!SawFrameAllocate,
+ "multiple calls to llvm.frameallocate in one function", &CI);
+ SawFrameAllocate = true;
+ Assert1(isa<ConstantInt>(CI.getArgOperand(0)),
+ "llvm.frameallocate argument must be constant integer size", &CI);
+ break;
+ }
+ case Intrinsic::recoverframeallocation: {
+ Value *FnArg = CI.getArgOperand(0)->stripPointerCasts();
+ Function *Fn = dyn_cast<Function>(FnArg);
+ Assert1(Fn && !Fn->isDeclaration(), "llvm.recoverframeallocation first "
+ "argument must be function defined in this module", &CI);
+ break;
+ }
+
case Intrinsic::experimental_gc_statepoint: {
Assert1(!CI.doesNotAccessMemory() &&
!CI.onlyReadsMemory(),
OpenPOWER on IntegriCloud