forked from OSchip/llvm-project
Fix stack layout error in MBlaze backend.
llvm-svn: 122631
This commit is contained in:
parent
ab14a6f174
commit
1f289afc25
|
@ -11,6 +11,8 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#define DEBUG_TYPE "mblaze-frame-info"
|
||||||
|
|
||||||
#include "MBlazeFrameInfo.h"
|
#include "MBlazeFrameInfo.h"
|
||||||
#include "MBlazeInstrInfo.h"
|
#include "MBlazeInstrInfo.h"
|
||||||
#include "MBlazeMachineFunction.h"
|
#include "MBlazeMachineFunction.h"
|
||||||
|
@ -24,6 +26,9 @@
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Target/TargetOptions.h"
|
#include "llvm/Target/TargetOptions.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
@ -66,6 +71,23 @@ static void analyzeFrameIndexes(MachineFunction &MF) {
|
||||||
|
|
||||||
int StackAdjust = 0;
|
int StackAdjust = 0;
|
||||||
int StackOffset = -28;
|
int StackOffset = -28;
|
||||||
|
|
||||||
|
// In this loop we are searching frame indexes that corrospond to incoming
|
||||||
|
// arguments that are already in the stack. We look for instruction sequences
|
||||||
|
// like the following:
|
||||||
|
//
|
||||||
|
// LWI REG, FI1, 0
|
||||||
|
// ...
|
||||||
|
// SWI REG, FI2, 0
|
||||||
|
//
|
||||||
|
// As long as there are no defs of REG in the ... part, we can eliminate
|
||||||
|
// the SWI instruction because the value has already been stored to the
|
||||||
|
// stack by the caller. All we need to do is locate FI at the correct
|
||||||
|
// stack location according to the calling convensions.
|
||||||
|
//
|
||||||
|
// Additionally, if the SWI operation kills the def of REG then we don't
|
||||||
|
// need the LWI operation so we can erase it as well.
|
||||||
|
#if 1
|
||||||
for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) {
|
for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) {
|
||||||
for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
|
for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
|
||||||
if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 ||
|
if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 ||
|
||||||
|
@ -75,60 +97,88 @@ static void analyzeFrameIndexes(MachineFunction &MF) {
|
||||||
unsigned FIReg = I->getOperand(0).getReg();
|
unsigned FIReg = I->getOperand(0).getReg();
|
||||||
MachineBasicBlock::iterator SI = I;
|
MachineBasicBlock::iterator SI = I;
|
||||||
for (SI++; SI != MIE; ++SI) {
|
for (SI++; SI != MIE; ++SI) {
|
||||||
if (!SI->getOperand(0).isReg()) continue;
|
if (!SI->getOperand(0).isReg() ||
|
||||||
if (!SI->getOperand(1).isFI()) continue;
|
!SI->getOperand(1).isFI() ||
|
||||||
if (SI->getOpcode() != MBlaze::SWI) continue;
|
SI->getOpcode() != MBlaze::SWI) continue;
|
||||||
|
|
||||||
int FI = SI->getOperand(1).getIndex();
|
int FI = SI->getOperand(1).getIndex();
|
||||||
if (SI->getOperand(0).getReg() != FIReg) continue;
|
if (SI->getOperand(0).getReg() != FIReg ||
|
||||||
if (MFI->isFixedObjectIndex(FI)) continue;
|
MFI->isFixedObjectIndex(FI) ||
|
||||||
if (MFI->getObjectSize(FI) != 4) continue;
|
MFI->getObjectSize(FI) != 4) continue;
|
||||||
|
|
||||||
if (SI->getOperand(0).isDef()) break;
|
if (SI->getOperand(0).isDef()) break;
|
||||||
|
|
||||||
if (SI->getOperand(0).isKill())
|
if (SI->getOperand(0).isKill()) {
|
||||||
|
DEBUG(dbgs() << "LWI for FI#" << I->getOperand(1).getIndex()
|
||||||
|
<< " removed\n");
|
||||||
EraseInstr.push_back(I);
|
EraseInstr.push_back(I);
|
||||||
|
}
|
||||||
|
|
||||||
EraseInstr.push_back(SI);
|
EraseInstr.push_back(SI);
|
||||||
|
DEBUG(dbgs() << "SWI for FI#" << FI << " removed\n");
|
||||||
|
|
||||||
MBlazeFI->recordLoadArgsFI(FI, StackOffset);
|
MBlazeFI->recordLoadArgsFI(FI, StackOffset);
|
||||||
|
DEBUG(dbgs() << "FI#" << FI << " relocated to " << StackOffset << "\n");
|
||||||
|
|
||||||
StackOffset -= 4;
|
StackOffset -= 4;
|
||||||
StackAdjust += 4;
|
StackAdjust += 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (MachineBasicBlock::iterator I=MBB->begin(), E=MBB->end(); I != E; ++I) {
|
// In this loop we are searching for frame indexes that corrospond to
|
||||||
if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 ||
|
// incoming arguments that are in registers. We look for instruction
|
||||||
!I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
|
// sequences like the following:
|
||||||
I->getOperand(1).getIndex() < 0) continue;
|
//
|
||||||
|
// ... SWI REG, FI, 0
|
||||||
|
//
|
||||||
|
// As long as the ... part does not define REG and if REG is an incoming
|
||||||
|
// parameter register then we know that, according to ABI convensions, the
|
||||||
|
// caller has allocated stack space for it already. Instead of allocating
|
||||||
|
// stack space on our frame, we record the correct location in the callers
|
||||||
|
// frame.
|
||||||
|
#if 1
|
||||||
|
for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) {
|
||||||
|
for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
|
||||||
|
if (I->definesRegister(LI->first))
|
||||||
|
break;
|
||||||
|
|
||||||
|
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) {
|
if (I->getOperand(0).getReg() == LI->first) {
|
||||||
FIReg = LI->first;
|
int FI = I->getOperand(1).getIndex();
|
||||||
|
MBlazeFI->recordLiveIn(FI);
|
||||||
|
|
||||||
|
int FILoc = 0;
|
||||||
|
switch (LI->first) {
|
||||||
|
default: llvm_unreachable("invalid incoming parameter!");
|
||||||
|
case MBlaze::R5: FILoc = -4; break;
|
||||||
|
case MBlaze::R6: FILoc = -8; break;
|
||||||
|
case MBlaze::R7: FILoc = -12; break;
|
||||||
|
case MBlaze::R8: FILoc = -16; break;
|
||||||
|
case MBlaze::R9: FILoc = -20; break;
|
||||||
|
case MBlaze::R10: FILoc = -24; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
StackAdjust += 4;
|
||||||
|
MBlazeFI->recordLoadArgsFI(FI, FILoc);
|
||||||
|
DEBUG(dbgs() << "FI#" << FI << " relocated to " << FILoc << "\n");
|
||||||
break;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Go ahead and erase all of the instructions that we determined were
|
||||||
|
// no longer needed.
|
||||||
for (int i = 0, e = EraseInstr.size(); i < e; ++i)
|
for (int i = 0, e = EraseInstr.size(); i < e; ++i)
|
||||||
MBB->erase(EraseInstr[i]);
|
MBB->erase(EraseInstr[i]);
|
||||||
|
|
||||||
|
DEBUG(dbgs() << "Final stack adjustment: " << StackAdjust << "\n");
|
||||||
MBlazeFI->setStackAdjust(StackAdjust);
|
MBlazeFI->setStackAdjust(StackAdjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +280,10 @@ static void determineFrameLayout(MachineFunction &MF) {
|
||||||
|
|
||||||
// Get the number of bytes to allocate from the FrameInfo
|
// Get the number of bytes to allocate from the FrameInfo
|
||||||
unsigned FrameSize = MFI->getStackSize();
|
unsigned FrameSize = MFI->getStackSize();
|
||||||
|
DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" );
|
||||||
|
|
||||||
FrameSize -= MBlazeFI->getStackAdjust();
|
FrameSize -= MBlazeFI->getStackAdjust();
|
||||||
|
DEBUG(dbgs() << "Adjusted Frame Size: " << FrameSize << "\n" );
|
||||||
|
|
||||||
// Get the alignments provided by the target, and the maximum alignment
|
// Get the alignments provided by the target, and the maximum alignment
|
||||||
// (if any) of the fixed frame objects.
|
// (if any) of the fixed frame objects.
|
||||||
|
@ -241,6 +294,7 @@ static void determineFrameLayout(MachineFunction &MF) {
|
||||||
// Make sure the frame is aligned.
|
// Make sure the frame is aligned.
|
||||||
FrameSize = (FrameSize + AlignMask) & ~AlignMask;
|
FrameSize = (FrameSize + AlignMask) & ~AlignMask;
|
||||||
MFI->setStackSize(FrameSize);
|
MFI->setStackSize(FrameSize);
|
||||||
|
DEBUG(dbgs() << "Aligned Frame Size: " << FrameSize << "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasFP - Return true if the specified function should have a dedicated frame
|
// hasFP - Return true if the specified function should have a dedicated frame
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#define DEBUG_TYPE "mblaze-reg-info"
|
#define DEBUG_TYPE "mblaze-frame-info"
|
||||||
|
|
||||||
#include "MBlaze.h"
|
#include "MBlaze.h"
|
||||||
#include "MBlazeSubtarget.h"
|
#include "MBlazeSubtarget.h"
|
||||||
|
@ -277,25 +277,32 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
|
||||||
|
|
||||||
unsigned oi = i == 2 ? 1 : 2;
|
unsigned oi = i == 2 ? 1 : 2;
|
||||||
|
|
||||||
DEBUG(errs() << "\nFunction : " << MF.getFunction()->getName() << "\n";
|
DEBUG(dbgs() << "\nFunction : " << MF.getFunction()->getName() << "\n";
|
||||||
errs() << "<--------->\n" << MI);
|
dbgs() << "<--------->\n" << MI);
|
||||||
|
|
||||||
int FrameIndex = MI.getOperand(i).getIndex();
|
int FrameIndex = MI.getOperand(i).getIndex();
|
||||||
int stackSize = MF.getFrameInfo()->getStackSize();
|
int stackSize = MF.getFrameInfo()->getStackSize();
|
||||||
int spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
|
int spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
|
||||||
|
|
||||||
DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
|
DEBUG(dbgs() << "FrameIndex : " << FrameIndex << "\n"
|
||||||
<< "spOffset : " << spOffset << "\n"
|
<< "spOffset : " << spOffset << "\n"
|
||||||
<< "stackSize : " << stackSize << "\n");
|
<< "stackSize : " << stackSize << "\n"
|
||||||
|
<< "isFixed : " << MFI->isFixedObjectIndex(FrameIndex) << "\n"
|
||||||
|
<< "isLiveIn : " << MBlazeFI->isLiveIn(FrameIndex) << "\n"
|
||||||
|
<< "isSpill : " << MFI->isSpillSlotObjectIndex(FrameIndex)
|
||||||
|
<< "\n" );
|
||||||
|
|
||||||
// as explained on LowerFormalArguments, detect negative offsets
|
// as explained on LowerFormalArguments, detect negative offsets
|
||||||
// and adjust SPOffsets considering the final stack size.
|
// and adjust SPOffsets considering the final stack size.
|
||||||
int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
|
int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
|
||||||
Offset += MI.getOperand(oi).getImm();
|
Offset += MI.getOperand(oi).getImm();
|
||||||
if (!MFI->isFixedObjectIndex(FrameIndex) && !MBlazeFI->isLiveIn(FrameIndex) && spOffset >= 0)
|
if (!MFI->isFixedObjectIndex(FrameIndex) &&
|
||||||
|
!MFI->isSpillSlotObjectIndex(FrameIndex) &&
|
||||||
|
!MBlazeFI->isLiveIn(FrameIndex) &&
|
||||||
|
spOffset >= 0)
|
||||||
Offset -= MBlazeFI->getStackAdjust();
|
Offset -= MBlazeFI->getStackAdjust();
|
||||||
|
|
||||||
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
|
DEBUG(dbgs() << "Offset : " << Offset << "\n" << "<--------->\n");
|
||||||
|
|
||||||
MI.getOperand(oi).ChangeToImmediate(Offset);
|
MI.getOperand(oi).ChangeToImmediate(Offset);
|
||||||
MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
|
MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
|
||||||
|
|
Loading…
Reference in New Issue