1. Change MBlaze indirect branches to use absolute branch BRALD instead of pc relative branch BRLD.

2. Make sure that the MBlaze stack is aligned to 4-byte boundaries.
3. Determine frame indexes that should be placed in the callers stack frame, as per the MBlaze ABI, and place them in the correct locations.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121639 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Wesley Peck 2010-12-12 20:52:31 +00:00
parent a30b7d2c70
commit eb13382333
5 changed files with 158 additions and 12 deletions

View File

@ -14,6 +14,7 @@
#include "MBlazeFrameInfo.h"
#include "MBlazeInstrInfo.h"
#include "MBlazeMachineFunction.h"
#include "InstPrinter/MBlazeInstPrinter.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@ -26,6 +27,14 @@
using namespace llvm;
namespace llvm {
cl::opt<bool> DisableStackAdjust(
"disable-mblaze-stack-adjust",
cl::init(false),
cl::desc("Disable MBlaze stack layout adjustment."),
cl::Hidden);
}
//===----------------------------------------------------------------------===//
//
// Stack Frame Processing methods
@ -39,6 +48,115 @@ using namespace llvm;
//
//===----------------------------------------------------------------------===//
static void analyzeFrameIndexes(MachineFunction &MF) {
if (DisableStackAdjust) return;
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
const MachineRegisterInfo &MRI = MF.getRegInfo();
MachineRegisterInfo::livein_iterator LII = MRI.livein_begin();
MachineRegisterInfo::livein_iterator LIE = MRI.livein_end();
const SmallVector<int, 16> &LiveInFI = MBlazeFI->getLiveIn();
SmallVector<MachineInstr*, 16> EraseInstr;
MachineBasicBlock *MBB = MF.getBlockNumbered(0);
MachineBasicBlock::iterator MIB = MBB->begin();
MachineBasicBlock::iterator MIE = MBB->end();
int StackAdjust = 0;
int StackOffset = -28;
for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) {
for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 ||
!I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
I->getOperand(1).getIndex() != LiveInFI[i]) continue;
unsigned FIReg = I->getOperand(0).getReg();
MachineBasicBlock::iterator SI = I;
for (SI++; SI != MIE; ++SI) {
if (!SI->getOperand(0).isReg()) continue;
if (!SI->getOperand(1).isFI()) continue;
if (SI->getOpcode() != MBlaze::SWI) continue;
int FI = SI->getOperand(1).getIndex();
if (SI->getOperand(0).getReg() != FIReg) continue;
if (MFI->isFixedObjectIndex(FI)) continue;
if (MFI->getObjectSize(FI) != 4) continue;
if (SI->getOperand(0).isDef()) break;
if (SI->getOperand(0).isKill())
EraseInstr.push_back(I);
EraseInstr.push_back(SI);
MBlazeFI->recordLoadArgsFI(FI, StackOffset);
StackOffset -= 4;
StackAdjust += 4;
break;
}
}
}
for (MachineBasicBlock::iterator I=MBB->begin(), E=MBB->end(); I != E; ++I) {
if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 ||
!I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
I->getOperand(1).getIndex() < 0) continue;
unsigned FIReg = 0;
for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) {
if (I->getOperand(0).getReg() == LI->first) {
FIReg = LI->first;
break;
}
}
if (FIReg) {
int FI = I->getOperand(1).getIndex();
MBlazeFI->recordLiveIn(FI);
StackAdjust += 4;
switch (FIReg) {
default: llvm_unreachable("invalid incoming parameter!");
case MBlaze::R5: MBlazeFI->recordLoadArgsFI(FI, -4); break;
case MBlaze::R6: MBlazeFI->recordLoadArgsFI(FI, -8); break;
case MBlaze::R7: MBlazeFI->recordLoadArgsFI(FI, -12); break;
case MBlaze::R8: MBlazeFI->recordLoadArgsFI(FI, -16); break;
case MBlaze::R9: MBlazeFI->recordLoadArgsFI(FI, -20); break;
case MBlaze::R10: MBlazeFI->recordLoadArgsFI(FI, -24); break;
}
}
}
for (int i = 0, e = EraseInstr.size(); i < e; ++i)
MBB->erase(EraseInstr[i]);
MBlazeFI->setStackAdjust(StackAdjust);
}
static void determineFrameLayout(MachineFunction &MF) {
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
// Replace the dummy '0' SPOffset by the negative offsets, as explained on
// LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
// the approach done by calculateFrameObjectOffsets to the stack frame.
MBlazeFI->adjustLoadArgsFI(MFI);
MBlazeFI->adjustStoreVarArgsFI(MFI);
// Get the number of bytes to allocate from the FrameInfo
unsigned FrameSize = MFI->getStackSize();
FrameSize -= MBlazeFI->getStackAdjust();
// Get the alignments provided by the target, and the maximum alignment
// (if any) of the fixed frame objects.
// unsigned MaxAlign = MFI->getMaxAlignment();
unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
unsigned AlignMask = TargetAlign - 1;
// Make sure the frame is aligned.
FrameSize = (FrameSize + AlignMask) & ~AlignMask;
MFI->setStackSize(FrameSize);
}
// hasFP - Return true if the specified function should have a dedicated frame
// pointer register. This is true if the function has variable sized allocas or
// if frame pointer elimination is disabled.
@ -56,11 +174,8 @@ void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Replace the dummy '0' SPOffset by the negative offsets, as explained on
// LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
// the approach done by calculateFrameObjectOffsets to the stack frame.
MBlazeFI->adjustLoadArgsFI(MFI);
MBlazeFI->adjustStoreVarArgsFI(MFI);
// Determine the correct frame layout
determineFrameLayout(MF);
// Get the number of bytes to allocate from the FrameInfo.
unsigned StackSize = MFI->getStackSize();
@ -146,4 +261,6 @@ void MBlazeFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
MBlazeFI->setFPStackOffset(4);
MFI->CreateFixedObject(4,4,true);
}
analyzeFrameIndexes(MF);
}

View File

@ -766,6 +766,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
unsigned StackLoc = VA.getLocMemOffset() + 4;
int FI = MFI->CreateFixedObject(ArgSize, 0, true);
MBlazeFI->recordLoadArgsFI(FI, -StackLoc);
MBlazeFI->recordLiveIn(FI);
// Create load nodes to retrieve arguments from the stack
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());

View File

@ -650,7 +650,7 @@ def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),
(BRLID (i32 R15), texternalsym:$dst)>;
def : Pat<(MBlazeJmpLink GPR:$dst),
(BRLD (i32 R15), GPR:$dst)>;
(BRALD (i32 R15), GPR:$dst)>;
// Shift Instructions
def : Pat<(shl GPR:$L, GPR:$R), (ShiftL GPR:$L, GPR:$R)>;

View File

@ -34,6 +34,9 @@ private:
/// saved. This is used on Prologue and Epilogue to emit RA save/restore
int RAStackOffset;
/// Holds the stack adjustment necessary for each function.
int StackAdjust;
/// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
struct MBlazeFIHolder {
@ -76,11 +79,15 @@ private:
// VarArgsFrameIndex - FrameIndex for start of varargs area.
int VarArgsFrameIndex;
/// LiveInFI - keeps track of the frame indexes in a callers stack
/// frame that are live into a function.
SmallVector<int, 16> LiveInFI;
public:
MBlazeFunctionInfo(MachineFunction& MF)
: FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1),
: FPStackOffset(0), RAStackOffset(0), StackAdjust(0), GPHolder(-1,-1),
HasLoadArgs(false), HasStoreVarArgs(false), SRetReturnReg(0),
GlobalBaseReg(0), VarArgsFrameIndex(0)
GlobalBaseReg(0), VarArgsFrameIndex(0), LiveInFI()
{}
int getFPStackOffset() const { return FPStackOffset; }
@ -89,6 +96,9 @@ public:
int getRAStackOffset() const { return RAStackOffset; }
void setRAStackOffset(int Off) { RAStackOffset = Off; }
int getStackAdjust() const { return StackAdjust; }
void setStackAdjust(int Adj) { StackAdjust = Adj; }
int getGPStackOffset() const { return GPHolder.SPOffset; }
int getGPFI() const { return GPHolder.FI; }
void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
@ -98,6 +108,19 @@ public:
bool hasLoadArgs() const { return HasLoadArgs; }
bool hasStoreVarArgs() const { return HasStoreVarArgs; }
void recordLiveIn(int FI) {
LiveInFI.push_back(FI);
}
bool isLiveIn(int FI) {
for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i)
if (FI == LiveInFI[i]) return true;
return false;
}
const SmallVector<int, 16>& getLiveIn() const { return LiveInFI; }
void recordLoadArgsFI(int FI, int SPOffset) {
if (!HasLoadArgs) HasLoadArgs=true;
FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset));

View File

@ -210,6 +210,8 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
RegScavenger *RS) const {
MachineInstr &MI = *II;
MachineFunction &MF = *MI.getParent()->getParent();
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
unsigned i = 0;
while (!MI.getOperand(i).isFI()) {
@ -233,11 +235,14 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
// as explained on LowerFormalArguments, detect negative offsets
// and adjust SPOffsets considering the final stack size.
spOffset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
spOffset += MI.getOperand(oi).getImm();
DEBUG(errs() << "Offset : " << spOffset << "\n" << "<--------->\n");
int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
Offset += MI.getOperand(oi).getImm();
if (!MFI->isFixedObjectIndex(FrameIndex) && !MBlazeFI->isLiveIn(FrameIndex) && spOffset >= 0)
Offset -= MBlazeFI->getStackAdjust();
MI.getOperand(oi).ChangeToImmediate(spOffset);
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
MI.getOperand(oi).ChangeToImmediate(Offset);
MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
}