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.
llvm-svn: 121639
diff --git a/llvm/lib/Target/MBlaze/MBlazeFrameInfo.cpp b/llvm/lib/Target/MBlaze/MBlazeFrameInfo.cpp
index bd968e4..cef82cc 100644
--- a/llvm/lib/Target/MBlaze/MBlazeFrameInfo.cpp
+++ b/llvm/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 @@
//
//===----------------------------------------------------------------------===//
+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 @@
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 @@
MBlazeFI->setFPStackOffset(4);
MFI->CreateFixedObject(4,4,true);
}
+
+ analyzeFrameIndexes(MF);
}