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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225746 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Kleckner
2015-01-13 00:48:10 +00:00
parent 698be08c84
commit 221a7075cf
21 changed files with 303 additions and 4 deletions

View File

@@ -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(),