mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
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:
@@ -48,6 +48,7 @@
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Statepoint.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
@@ -5581,6 +5582,58 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
}
|
||||
case Intrinsic::instrprof_increment:
|
||||
llvm_unreachable("instrprof failed to lower an increment");
|
||||
|
||||
case Intrinsic::frameallocate: {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
const TargetInstrInfo *TII = DAG.getSubtarget().getInstrInfo();
|
||||
|
||||
// Do the allocation and map it as a normal value.
|
||||
// FIXME: Maybe we should add this to the alloca map so that we don't have
|
||||
// to register allocate it?
|
||||
uint64_t Size = cast<ConstantInt>(I.getArgOperand(0))->getZExtValue();
|
||||
int Alloc = MF.getFrameInfo()->CreateFrameAllocation(Size);
|
||||
MVT PtrVT = TLI.getPointerTy(0);
|
||||
SDValue FIVal = DAG.getFrameIndex(Alloc, PtrVT);
|
||||
setValue(&I, FIVal);
|
||||
|
||||
// Directly emit a FRAME_ALLOC machine instr. Label assignment emission is
|
||||
// the same on all targets.
|
||||
MCSymbol *FrameAllocSym =
|
||||
MF.getMMI().getContext().getOrCreateFrameAllocSymbol(MF.getName());
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, dl,
|
||||
TII->get(TargetOpcode::FRAME_ALLOC))
|
||||
.addSym(FrameAllocSym)
|
||||
.addFrameIndex(Alloc);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
case Intrinsic::recoverframeallocation: {
|
||||
// i8* @llvm.recoverframeallocation(i8* %fn, i8* %fp)
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MVT PtrVT = TLI.getPointerTy(0);
|
||||
|
||||
// Get the symbol that defines the frame offset.
|
||||
Function *Fn = cast<Function>(I.getArgOperand(0)->stripPointerCasts());
|
||||
MCSymbol *FrameAllocSym =
|
||||
MF.getMMI().getContext().getOrCreateFrameAllocSymbol(Fn->getName());
|
||||
|
||||
// Create a TargetExternalSymbol for the label to avoid any target lowering
|
||||
// that would make this PC relative.
|
||||
StringRef Name = FrameAllocSym->getName();
|
||||
assert(Name.size() == strlen(Name.data()) && "not null terminated");
|
||||
SDValue OffsetSym = DAG.getTargetExternalSymbol(Name.data(), PtrVT);
|
||||
SDValue OffsetVal =
|
||||
DAG.getNode(ISD::RECOVER_FRAME_ALLOC, sdl, PtrVT, OffsetSym);
|
||||
|
||||
// Add the offset to the FP.
|
||||
Value *FP = I.getArgOperand(1);
|
||||
SDValue FPVal = getValue(FP);
|
||||
SDValue Add = DAG.getNode(ISD::ADD, sdl, PtrVT, FPVal, OffsetVal);
|
||||
setValue(&I, Add);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user