diff options
author | Wesley Peck <peckw@wesleypeck.com> | 2010-12-12 20:52:31 +0000 |
---|---|---|
committer | Wesley Peck <peckw@wesleypeck.com> | 2010-12-12 20:52:31 +0000 |
commit | eb1338233399dec17c4a7b88f5ec2866606d4bb0 (patch) | |
tree | 3772699753da166480d1dc94826c0336e40c7466 | |
parent | a30b7d2c707b5720691f7aea0652e37bd333d3af (diff) | |
download | external_llvm-eb1338233399dec17c4a7b88f5ec2866606d4bb0.zip external_llvm-eb1338233399dec17c4a7b88f5ec2866606d4bb0.tar.gz external_llvm-eb1338233399dec17c4a7b88f5ec2866606d4bb0.tar.bz2 |
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
-rw-r--r-- | lib/Target/MBlaze/MBlazeFrameInfo.cpp | 127 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeISelLowering.cpp | 1 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeInstrInfo.td | 2 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeMachineFunction.h | 27 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeRegisterInfo.cpp | 13 |
5 files changed, 158 insertions, 12 deletions
diff --git a/lib/Target/MBlaze/MBlazeFrameInfo.cpp b/lib/Target/MBlaze/MBlazeFrameInfo.cpp index bd968e4..cef82cc 100644 --- a/lib/Target/MBlaze/MBlazeFrameInfo.cpp +++ b/lib/Target/MBlaze/MBlazeFrameInfo.cpp @@ -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); } diff --git a/lib/Target/MBlaze/MBlazeISelLowering.cpp b/lib/Target/MBlaze/MBlazeISelLowering.cpp index c4c3e24..fb6fb54 100644 --- a/lib/Target/MBlaze/MBlazeISelLowering.cpp +++ b/lib/Target/MBlaze/MBlazeISelLowering.cpp @@ -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()); diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td index d5abe5a..9bda006 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.td +++ b/lib/Target/MBlaze/MBlazeInstrInfo.td @@ -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)>; diff --git a/lib/Target/MBlaze/MBlazeMachineFunction.h b/lib/Target/MBlaze/MBlazeMachineFunction.h index 09b916e..d1468db 100644 --- a/lib/Target/MBlaze/MBlazeMachineFunction.h +++ b/lib/Target/MBlaze/MBlazeMachineFunction.h @@ -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)); diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp index 58aa151..891e189 100644 --- a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp +++ b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp @@ -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(); + + DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); - MI.getOperand(oi).ChangeToImmediate(spOffset); + MI.getOperand(oi).ChangeToImmediate(Offset); MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false); } |