forked from OSchip/llvm-project
DWARF requires frame moves be specified at specific times. If you have a
prologue like this: __Z3fooi: Leh_func_begin1: LBB1_0: ## entry pushl %ebp Llabel1: movl %esp, %ebp Llabel2: pushl %esi Llabel3: subl $20, %esp call "L1$pb" "L1$pb": popl %esi The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp, %ebp" makes %ebp the new stack frame register, so that needs to be specified in DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs to be specified in DWARF. Before, all of this logic was in one method. This didn't work too well, because as you can see there are multiple FDE line entries that need to be created. This fix creates the "MachineMove" objects directly when they're needed; instead of waiting until the end, and losing information. llvm-svn: 74952
This commit is contained in:
parent
425038cc6d
commit
7a87a78c6c
|
@ -644,15 +644,16 @@ static int mergeSPUpdates(MachineBasicBlock &MBB,
|
||||||
return Offset;
|
return Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86RegisterInfo::emitFrameMoves(MachineFunction &MF,
|
void X86RegisterInfo::emitCalleeSavedFrameMoves(MachineFunction &MF,
|
||||||
unsigned FrameLabelId,
|
unsigned LabelId) const {
|
||||||
unsigned ReadyLabelId) const {
|
|
||||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
|
MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
|
||||||
if (!MMI)
|
if (!MMI) return;
|
||||||
return;
|
|
||||||
|
// Add callee saved registers to move list.
|
||||||
|
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
|
||||||
|
if (CSI.empty()) return;
|
||||||
|
|
||||||
uint64_t StackSize = MFI->getStackSize();
|
|
||||||
std::vector<MachineMove> &Moves = MMI->getFrameMoves();
|
std::vector<MachineMove> &Moves = MMI->getFrameMoves();
|
||||||
const TargetData *TD = MF.getTarget().getTargetData();
|
const TargetData *TD = MF.getTarget().getTargetData();
|
||||||
|
|
||||||
|
@ -662,62 +663,30 @@ void X86RegisterInfo::emitFrameMoves(MachineFunction &MF,
|
||||||
TargetFrameInfo::StackGrowsUp ?
|
TargetFrameInfo::StackGrowsUp ?
|
||||||
TD->getPointerSize() : -TD->getPointerSize());
|
TD->getPointerSize() : -TD->getPointerSize());
|
||||||
|
|
||||||
MachineLocation FPDst(hasFP(MF) ? FramePtr : StackPtr);
|
|
||||||
MachineLocation FPSrc(MachineLocation::VirtualFP);
|
|
||||||
Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc));
|
|
||||||
|
|
||||||
if (StackSize) {
|
|
||||||
// Show update of SP.
|
|
||||||
if (hasFP(MF)) {
|
|
||||||
// Adjust SP
|
|
||||||
MachineLocation SPDst(MachineLocation::VirtualFP);
|
|
||||||
MachineLocation SPSrc(MachineLocation::VirtualFP, 2*stackGrowth);
|
|
||||||
Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
|
|
||||||
} else {
|
|
||||||
MachineLocation SPDst(MachineLocation::VirtualFP);
|
|
||||||
MachineLocation SPSrc(MachineLocation::VirtualFP,
|
|
||||||
-StackSize+stackGrowth);
|
|
||||||
Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// FIXME: Verify & implement for FP
|
|
||||||
MachineLocation SPDst(StackPtr);
|
|
||||||
MachineLocation SPSrc(StackPtr, stackGrowth);
|
|
||||||
Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add callee saved registers to move list.
|
|
||||||
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
|
|
||||||
|
|
||||||
// FIXME: This is dirty hack. The code itself is pretty mess right now.
|
// FIXME: This is dirty hack. The code itself is pretty mess right now.
|
||||||
// It should be rewritten from scratch and generalized sometimes.
|
// It should be rewritten from scratch and generalized sometimes.
|
||||||
|
|
||||||
// Determine maximum offset (minumum due to stack growth)
|
// Determine maximum offset (minumum due to stack growth)
|
||||||
int64_t MaxOffset = 0;
|
int64_t MaxOffset = 0;
|
||||||
for (unsigned I = 0, E = CSI.size(); I!=E; ++I)
|
for (std::vector<CalleeSavedInfo>::const_iterator
|
||||||
|
I = CSI.begin(), E = CSI.end(); I != E; ++I)
|
||||||
MaxOffset = std::min(MaxOffset,
|
MaxOffset = std::min(MaxOffset,
|
||||||
MFI->getObjectOffset(CSI[I].getFrameIdx()));
|
MFI->getObjectOffset(I->getFrameIdx()));
|
||||||
|
|
||||||
// Calculate offsets
|
// Calculate offsets.
|
||||||
int64_t saveAreaOffset = (hasFP(MF) ? 3 : 2) * stackGrowth;
|
int64_t saveAreaOffset = (hasFP(MF) ? 3 : 2) * stackGrowth;
|
||||||
for (unsigned I = 0, E = CSI.size(); I!=E; ++I) {
|
for (std::vector<CalleeSavedInfo>::const_iterator
|
||||||
int64_t Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
|
I = CSI.begin(), E = CSI.end(); I != E; ++I) {
|
||||||
unsigned Reg = CSI[I].getReg();
|
int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
|
||||||
Offset = (MaxOffset-Offset+saveAreaOffset);
|
unsigned Reg = I->getReg();
|
||||||
|
Offset = MaxOffset - Offset + saveAreaOffset;
|
||||||
|
|
||||||
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
|
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
|
||||||
MachineLocation CSSrc(Reg);
|
MachineLocation CSSrc(Reg);
|
||||||
Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc));
|
Moves.push_back(MachineMove(LabelId, CSDst, CSSrc));
|
||||||
}
|
|
||||||
|
|
||||||
if (hasFP(MF)) {
|
|
||||||
// Save FP
|
|
||||||
MachineLocation FPDst(MachineLocation::VirtualFP, 2*stackGrowth);
|
|
||||||
MachineLocation FPSrc(FramePtr);
|
|
||||||
Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
|
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
|
||||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
@ -729,11 +698,9 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
bool needsFrameMoves = (MMI && MMI->hasDebugInfo()) ||
|
bool needsFrameMoves = (MMI && MMI->hasDebugInfo()) ||
|
||||||
!Fn->doesNotThrow() ||
|
!Fn->doesNotThrow() ||
|
||||||
UnwindTablesMandatory;
|
UnwindTablesMandatory;
|
||||||
|
bool HasFP = hasFP(MF);
|
||||||
DebugLoc DL;
|
DebugLoc DL;
|
||||||
|
|
||||||
// Prepare for frame info.
|
|
||||||
unsigned FrameLabelId = 0;
|
|
||||||
|
|
||||||
// Get the number of bytes to allocate from the FrameInfo.
|
// Get the number of bytes to allocate from the FrameInfo.
|
||||||
uint64_t StackSize = MFI->getStackSize();
|
uint64_t StackSize = MFI->getStackSize();
|
||||||
|
|
||||||
|
@ -757,7 +724,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
!MFI->hasCalls() && // No calls.
|
!MFI->hasCalls() && // No calls.
|
||||||
!Subtarget->isTargetWin64()) { // Win64 has no Red Zone
|
!Subtarget->isTargetWin64()) { // Win64 has no Red Zone
|
||||||
uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
|
uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
|
||||||
if (hasFP(MF)) MinSize += SlotSize;
|
if (HasFP) MinSize += SlotSize;
|
||||||
StackSize = std::max(MinSize,
|
StackSize = std::max(MinSize,
|
||||||
StackSize > 128 ? StackSize - 128 : 0);
|
StackSize > 128 ? StackSize - 128 : 0);
|
||||||
MFI->setStackSize(StackSize);
|
MFI->setStackSize(StackSize);
|
||||||
|
@ -774,8 +741,16 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
MI->getOperand(3).setIsDead();
|
MI->getOperand(3).setIsDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uint64_t StackSize = MFI->getStackSize();
|
||||||
|
std::vector<MachineMove> &Moves = MMI->getFrameMoves();
|
||||||
|
const TargetData *TD = MF.getTarget().getTargetData();
|
||||||
|
int stackGrowth =
|
||||||
|
(MF.getTarget().getFrameInfo()->getStackGrowthDirection() ==
|
||||||
|
TargetFrameInfo::StackGrowsUp ?
|
||||||
|
TD->getPointerSize() : -TD->getPointerSize());
|
||||||
|
|
||||||
uint64_t NumBytes = 0;
|
uint64_t NumBytes = 0;
|
||||||
if (hasFP(MF)) {
|
if (HasFP) {
|
||||||
// Calculate required stack adjustment
|
// Calculate required stack adjustment
|
||||||
uint64_t FrameSize = StackSize - SlotSize;
|
uint64_t FrameSize = StackSize - SlotSize;
|
||||||
if (needsStackRealignment(MF))
|
if (needsStackRealignment(MF))
|
||||||
|
@ -783,19 +758,38 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
|
|
||||||
NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize();
|
NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize();
|
||||||
|
|
||||||
// Get the offset of the stack slot for the EBP register... which is
|
// Get the offset of the stack slot for the EBP register, which is
|
||||||
// guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
|
// guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
|
||||||
// Update the frame offset adjustment.
|
// Update the frame offset adjustment.
|
||||||
MFI->setOffsetAdjustment(-NumBytes);
|
MFI->setOffsetAdjustment(-NumBytes);
|
||||||
|
|
||||||
// Save EBP into the appropriate stack slot...
|
// Save EBP/RBP into the appropriate stack slot...
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
|
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
|
||||||
.addReg(FramePtr, RegState::Kill);
|
.addReg(FramePtr, RegState::Kill);
|
||||||
|
|
||||||
if (needsFrameMoves) {
|
if (needsFrameMoves) {
|
||||||
// Mark effective beginning of when frame pointer becomes valid.
|
// Mark effective beginning of when frame pointer becomes valid.
|
||||||
FrameLabelId = MMI->NextLabelID();
|
unsigned FrameLabelId = MMI->NextLabelID();
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(FrameLabelId);
|
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(FrameLabelId);
|
||||||
|
|
||||||
|
// Define the current CFA rule to use the provided offset.
|
||||||
|
if (StackSize) {
|
||||||
|
MachineLocation SPDst(MachineLocation::VirtualFP);
|
||||||
|
MachineLocation SPSrc(MachineLocation::VirtualFP,
|
||||||
|
HasFP ? 2 * stackGrowth :
|
||||||
|
-StackSize + stackGrowth);
|
||||||
|
Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
|
||||||
|
} else {
|
||||||
|
// FIXME: Verify & implement for FP
|
||||||
|
MachineLocation SPDst(StackPtr);
|
||||||
|
MachineLocation SPSrc(StackPtr, stackGrowth);
|
||||||
|
Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the rule for the FramePtr to be an "offset" rule.
|
||||||
|
MachineLocation FPDst(MachineLocation::VirtualFP, 2 * stackGrowth);
|
||||||
|
MachineLocation FPSrc(FramePtr);
|
||||||
|
Moves.push_back(MachineMove(FrameLabelId, FPDst, FPSrc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update EBP with the new base value...
|
// Update EBP with the new base value...
|
||||||
|
@ -803,6 +797,16 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr)
|
TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr)
|
||||||
.addReg(StackPtr);
|
.addReg(StackPtr);
|
||||||
|
|
||||||
|
if (needsFrameMoves) {
|
||||||
|
unsigned FrameLabelId = MMI->NextLabelID();
|
||||||
|
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(FrameLabelId);
|
||||||
|
|
||||||
|
// Define the current CFA to use the EBP/RBP register.
|
||||||
|
MachineLocation FPDst(FramePtr);
|
||||||
|
MachineLocation FPSrc(MachineLocation::VirtualFP);
|
||||||
|
Moves.push_back(MachineMove(FrameLabelId, FPDst, FPSrc));
|
||||||
|
}
|
||||||
|
|
||||||
// Mark the FramePtr as live-in in every block except the entry.
|
// Mark the FramePtr as live-in in every block except the entry.
|
||||||
for (MachineFunction::iterator I = next(MF.begin()), E = MF.end();
|
for (MachineFunction::iterator I = next(MF.begin()), E = MF.end();
|
||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
|
@ -822,10 +826,22 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip the callee-saved push instructions.
|
// Skip the callee-saved push instructions.
|
||||||
|
bool RegsSaved = false;
|
||||||
while (MBBI != MBB.end() &&
|
while (MBBI != MBB.end() &&
|
||||||
(MBBI->getOpcode() == X86::PUSH32r ||
|
(MBBI->getOpcode() == X86::PUSH32r ||
|
||||||
MBBI->getOpcode() == X86::PUSH64r))
|
MBBI->getOpcode() == X86::PUSH64r)) {
|
||||||
|
RegsSaved = true;
|
||||||
++MBBI;
|
++MBBI;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RegsSaved && needsFrameMoves) {
|
||||||
|
// Mark end of callee-saved push instructions.
|
||||||
|
unsigned LabelId = MMI->NextLabelID();
|
||||||
|
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(LabelId);
|
||||||
|
|
||||||
|
// Emit DWARF info specifying the offsets of the callee-saved registers.
|
||||||
|
emitCalleeSavedFrameMoves(MF, LabelId);
|
||||||
|
}
|
||||||
|
|
||||||
if (MBBI != MBB.end())
|
if (MBBI != MBB.end())
|
||||||
DL = MBBI->getDebugLoc();
|
DL = MBBI->getDebugLoc();
|
||||||
|
@ -882,14 +898,6 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
if (NumBytes)
|
if (NumBytes)
|
||||||
emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII);
|
emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsFrameMoves) {
|
|
||||||
unsigned ReadyLabelId = 0;
|
|
||||||
// Mark effective beginning of when frame pointer is ready.
|
|
||||||
ReadyLabelId = MMI->NextLabelID();
|
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(ReadyLabelId);
|
|
||||||
emitFrameMoves(MF, FrameLabelId, ReadyLabelId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
|
void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||||
|
|
|
@ -136,12 +136,10 @@ public:
|
||||||
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||||
RegScavenger *RS = NULL) const;
|
RegScavenger *RS = NULL) const;
|
||||||
|
|
||||||
|
void emitCalleeSavedFrameMoves(MachineFunction &MF, unsigned LabelId) const;
|
||||||
void emitPrologue(MachineFunction &MF) const;
|
void emitPrologue(MachineFunction &MF) const;
|
||||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
|
||||||
void emitFrameMoves(MachineFunction &MF,
|
|
||||||
unsigned FrameLabelId, unsigned ReadyLabelId) const;
|
|
||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
unsigned getRARegister() const;
|
unsigned getRARegister() const;
|
||||||
unsigned getFrameRegister(MachineFunction &MF) const;
|
unsigned getFrameRegister(MachineFunction &MF) const;
|
||||||
|
|
Loading…
Reference in New Issue