aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWesley Peck <peckw@wesleypeck.com>2010-12-12 20:52:31 +0000
committerWesley Peck <peckw@wesleypeck.com>2010-12-12 20:52:31 +0000
commiteb1338233399dec17c4a7b88f5ec2866606d4bb0 (patch)
tree3772699753da166480d1dc94826c0336e40c7466
parenta30b7d2c707b5720691f7aea0652e37bd333d3af (diff)
downloadexternal_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.cpp127
-rw-r--r--lib/Target/MBlaze/MBlazeISelLowering.cpp1
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.td2
-rw-r--r--lib/Target/MBlaze/MBlazeMachineFunction.h27
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.cpp13
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);
}