mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +00:00
Expand DYNAMIC_STACKALLOC nodes rather than doing custom-lowering.
The frame object which points to the dynamically allocated area will not be needed after changes are made to cease reserving call frames. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161076 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f99efdf329
commit
1d165f1c25
@ -157,7 +157,6 @@ MipsTargetLowering(MipsTargetMachine &TM)
|
||||
setOperationAction(ISD::SETCC, MVT::f32, Custom);
|
||||
setOperationAction(ISD::SETCC, MVT::f64, Custom);
|
||||
setOperationAction(ISD::BRCOND, MVT::Other, Custom);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
|
||||
setOperationAction(ISD::VASTART, MVT::Other, Custom);
|
||||
setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
|
||||
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
|
||||
@ -178,7 +177,6 @@ MipsTargetLowering(MipsTargetMachine &TM)
|
||||
setOperationAction(ISD::JumpTable, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
|
||||
setOperationAction(ISD::SELECT, MVT::i64, Custom);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
|
||||
setOperationAction(ISD::LOAD, MVT::i64, Custom);
|
||||
setOperationAction(ISD::STORE, MVT::i64, Custom);
|
||||
}
|
||||
@ -217,6 +215,8 @@ MipsTargetLowering(MipsTargetMachine &TM)
|
||||
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Expand);
|
||||
setOperationAction(ISD::ROTL, MVT::i32, Expand);
|
||||
setOperationAction(ISD::ROTL, MVT::i64, Expand);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
|
||||
|
||||
if (!Subtarget->hasMips32r2())
|
||||
setOperationAction(ISD::ROTR, MVT::i32, Expand);
|
||||
@ -792,7 +792,6 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
|
||||
{
|
||||
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
|
||||
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
|
||||
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
|
||||
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
|
||||
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
|
||||
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
|
||||
@ -1501,42 +1500,6 @@ MipsTargetLowering::EmitAtomicCmpSwapPartword(MachineInstr *MI,
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Misc Lower Operation implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
SDValue MipsTargetLowering::
|
||||
LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
|
||||
{
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
|
||||
unsigned SP = IsN64 ? Mips::SP_64 : Mips::SP;
|
||||
|
||||
assert(getTargetMachine().getFrameLowering()->getStackAlignment() >=
|
||||
cast<ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue() &&
|
||||
"Cannot lower if the alignment of the allocated space is larger than \
|
||||
that of the stack.");
|
||||
|
||||
SDValue Chain = Op.getOperand(0);
|
||||
SDValue Size = Op.getOperand(1);
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
|
||||
// Get a reference from Mips stack pointer
|
||||
SDValue StackPointer = DAG.getCopyFromReg(Chain, dl, SP, getPointerTy());
|
||||
|
||||
// Subtract the dynamic size from the actual stack size to
|
||||
// obtain the new stack size.
|
||||
SDValue Sub = DAG.getNode(ISD::SUB, dl, getPointerTy(), StackPointer, Size);
|
||||
|
||||
// The Sub result contains the new stack start address, so it
|
||||
// must be placed in the stack pointer register.
|
||||
Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, SP, Sub, SDValue());
|
||||
|
||||
// This node always has two return values: a new stack pointer
|
||||
// value and a chain
|
||||
SDVTList VTLs = DAG.getVTList(getPointerTy(), MVT::Other);
|
||||
SDValue Ptr = DAG.getFrameIndex(MipsFI->getDynAllocFI(), getPointerTy());
|
||||
SDValue Ops[] = { Chain, Ptr, Chain.getValue(1) };
|
||||
|
||||
return DAG.getNode(MipsISD::DynAlloc, dl, VTLs, Ops, 3);
|
||||
}
|
||||
|
||||
SDValue MipsTargetLowering::
|
||||
LowerBRCOND(SDValue Op, SelectionDAG &DAG) const
|
||||
{
|
||||
@ -2691,19 +2654,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
IsN64 ? Mips::SP_64 : Mips::SP,
|
||||
getPointerTy());
|
||||
|
||||
// Get the frame index of the stack frame object that points to the location
|
||||
// of dynamically allocated area on the stack.
|
||||
int DynAllocFI = MipsFI->getDynAllocFI();
|
||||
|
||||
if (MipsFI->getMaxCallFrameSize() < NextStackOffset) {
|
||||
if (MipsFI->getMaxCallFrameSize() < NextStackOffset)
|
||||
MipsFI->setMaxCallFrameSize(NextStackOffset);
|
||||
|
||||
// Set the offsets relative to $sp of the $gp restore slot and dynamically
|
||||
// allocated stack space. These offsets must be aligned to a boundary
|
||||
// determined by the stack alignment of the ABI.
|
||||
MFI->setObjectOffset(DynAllocFI, NextStackOffset);
|
||||
}
|
||||
|
||||
// With EABI is it possible to have 16 args on registers.
|
||||
SmallVector<std::pair<unsigned, SDValue>, 16> RegsToPass;
|
||||
SmallVector<SDValue, 8> MemOpChains;
|
||||
|
@ -132,7 +132,6 @@ namespace llvm {
|
||||
// Lower Operand specifics
|
||||
SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
@ -48,7 +48,6 @@ class MipsFunctionInfo : public MachineFunctionInfo {
|
||||
// OutArgFIRange: Range of indices of all frame objects created during call to
|
||||
// LowerCall except for the frame object for restoring $gp.
|
||||
std::pair<int, int> InArgFIRange, OutArgFIRange;
|
||||
mutable int DynAllocFI; // Frame index of dynamically allocated stack area.
|
||||
unsigned MaxCallFrameSize;
|
||||
|
||||
bool EmitNOAT;
|
||||
@ -57,8 +56,7 @@ public:
|
||||
MipsFunctionInfo(MachineFunction& MF)
|
||||
: MF(MF), SRetReturnReg(0), GlobalBaseReg(0),
|
||||
VarArgsFrameIndex(0), InArgFIRange(std::make_pair(-1, 0)),
|
||||
OutArgFIRange(std::make_pair(-1, 0)), DynAllocFI(0),
|
||||
MaxCallFrameSize(0), EmitNOAT(false)
|
||||
OutArgFIRange(std::make_pair(-1, 0)), MaxCallFrameSize(0), EmitNOAT(false)
|
||||
{}
|
||||
|
||||
bool isInArgFI(int FI) const {
|
||||
@ -76,16 +74,6 @@ public:
|
||||
OutArgFIRange.second = LastFI;
|
||||
}
|
||||
|
||||
// The first call to this function creates a frame object for dynamically
|
||||
// allocated stack area.
|
||||
int getDynAllocFI() const {
|
||||
if (!DynAllocFI)
|
||||
DynAllocFI = MF.getFrameInfo()->CreateFixedObject(4, 0, true);
|
||||
|
||||
return DynAllocFI;
|
||||
}
|
||||
bool isDynAllocFI(int FI) const { return DynAllocFI && DynAllocFI == FI; }
|
||||
|
||||
unsigned getSRetReturnReg() const { return SRetReturnReg; }
|
||||
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
|
||||
|
||||
|
@ -199,7 +199,7 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
|
||||
// getFrameRegister() returns.
|
||||
unsigned FrameReg;
|
||||
|
||||
if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isDynAllocFI(FrameIndex) ||
|
||||
if (MipsFI->isOutArgFI(FrameIndex) ||
|
||||
(FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI))
|
||||
FrameReg = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP;
|
||||
else
|
||||
@ -214,7 +214,7 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
|
||||
// incoming argument, callee-saved register location or local variable.
|
||||
int64_t Offset;
|
||||
|
||||
if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isDynAllocFI(FrameIndex))
|
||||
if (MipsFI->isOutArgFI(FrameIndex))
|
||||
Offset = spOffset;
|
||||
else
|
||||
Offset = spOffset + (int64_t)stackSize;
|
||||
|
@ -4,14 +4,10 @@ define i32 @twoalloca(i32 %size) nounwind {
|
||||
entry:
|
||||
; CHECK: subu $[[T0:[0-9]+]], $sp, $[[SZ:[0-9]+]]
|
||||
; CHECK: addu $sp, $zero, $[[T0]]
|
||||
; CHECK: addiu $[[T1:[0-9]+]], $sp, [[OFF:[0-9]+]]
|
||||
; CHECK: subu $[[T2:[0-9]+]], $sp, $[[SZ]]
|
||||
; CHECK: addu $sp, $zero, $[[T2]]
|
||||
; CHECK: addiu $[[T3:[0-9]+]], $sp, [[OFF]]
|
||||
; CHECK: lw $[[T4:[0-9]+]], %call16(foo)
|
||||
; CHECK: addu $25, $zero, $[[T4]]
|
||||
; CHECK: addu $4, $zero, $[[T1]]
|
||||
; CHECK: jalr $25
|
||||
; CHECK: addu $4, $zero, $[[T0]]
|
||||
; CHECK: addu $4, $zero, $[[T2]]
|
||||
%tmp1 = alloca i8, i32 %size, align 4
|
||||
%add.ptr = getelementptr inbounds i8* %tmp1, i32 5
|
||||
store i8 97, i8* %add.ptr, align 1
|
||||
@ -34,7 +30,6 @@ entry:
|
||||
; CHECK: alloca2
|
||||
; CHECK: subu $[[T0:[0-9]+]], $sp
|
||||
; CHECK: addu $sp, $zero, $[[T0]]
|
||||
; CHECK: addiu $[[T1:[0-9]+]], $sp
|
||||
|
||||
%tmp1 = alloca i8, i32 %size, align 4
|
||||
%0 = bitcast i8* %tmp1 to i32*
|
||||
@ -42,7 +37,7 @@ entry:
|
||||
br i1 %cmp, label %if.then, label %if.else
|
||||
|
||||
if.then: ; preds = %entry
|
||||
; CHECK: addiu $4, $[[T1]], 40
|
||||
; CHECK: addiu $4, $[[T0]], 40
|
||||
|
||||
%add.ptr = getelementptr inbounds i8* %tmp1, i32 40
|
||||
%1 = bitcast i8* %add.ptr to i32*
|
||||
@ -52,7 +47,7 @@ if.then: ; preds = %entry
|
||||
br label %if.end
|
||||
|
||||
if.else: ; preds = %entry
|
||||
; CHECK: addiu $4, $[[T1]], 12
|
||||
; CHECK: addiu $4, $[[T0]], 12
|
||||
|
||||
%add.ptr5 = getelementptr inbounds i8* %tmp1, i32 12
|
||||
%2 = bitcast i8* %add.ptr5 to i32*
|
||||
@ -60,7 +55,7 @@ if.else: ; preds = %entry
|
||||
br label %if.end
|
||||
|
||||
if.end: ; preds = %if.else, %if.then
|
||||
; CHECK: lw $5, 0($[[T1]])
|
||||
; CHECK: lw $5, 0($[[T0]])
|
||||
; CHECK: lw $25, %call16(printf)
|
||||
|
||||
%.pre-phi = phi i32* [ %2, %if.else ], [ %.pre, %if.then ]
|
||||
|
Loading…
x
Reference in New Issue
Block a user