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);
 }