Implement frame unwinding information emission for Thumb1. Not finished yet because there is no way given the constpool index to examine the actual entry: the reason is clones inserted by constant island pass, which are not tracked at all! The only connection is done during asmprinting time via magic label names which is really gross and needs to be eventually fixed.

llvm-svn: 127104
This commit is contained in:
Anton Korobeynikov 2011-03-05 18:43:50 +00:00
parent 51537f1c7f
commit a8d177b2d4
8 changed files with 82 additions and 52 deletions

View File

@ -822,11 +822,15 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
unsigned Opc = MI->getOpcode(); unsigned Opc = MI->getOpcode();
unsigned SrcReg, DstReg; unsigned SrcReg, DstReg;
// Special case: tPUSH does not have src/dst regs. if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
if (Opc == ARM::tPUSH) { // Two special cases:
// 1) tPUSH does not have src/dst regs.
// 2) for Thumb1 code we sometimes materialize the constant via constpool
// load. Yes, this is pretty fragile, but for now I don't see better
// way... :(
SrcReg = DstReg = ARM::SP; SrcReg = DstReg = ARM::SP;
} else { } else {
SrcReg = MI->getOperand(1).getReg(); SrcReg = MI->getOperand(1).getReg();
DstReg = MI->getOperand(0).getReg(); DstReg = MI->getOperand(0).getReg();
} }
@ -875,6 +879,7 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
assert(0 && "Unsupported opcode for unwinding information"); assert(0 && "Unsupported opcode for unwinding information");
case ARM::MOVr: case ARM::MOVr:
case ARM::tMOVgpr2gpr: case ARM::tMOVgpr2gpr:
case ARM::tMOVgpr2tgpr:
Offset = 0; Offset = 0;
break; break;
case ARM::ADDri: case ARM::ADDri:
@ -891,6 +896,9 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
case ARM::tADDrSPi: case ARM::tADDrSPi:
Offset = -MI->getOperand(2).getImm()*4; Offset = -MI->getOperand(2).getImm()*4;
break; break;
case ARM::tLDRpci:
assert(0 && "Not implemented yet!");
break;
} }
if (DstReg == FramePtr && FramePtr != ARM::SP) if (DstReg == FramePtr && FramePtr != ARM::SP)

View File

@ -806,7 +806,7 @@ emitLoadConstPool(MachineBasicBlock &MBB,
DebugLoc dl, DebugLoc dl,
unsigned DestReg, unsigned SubIdx, int Val, unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred, ARMCC::CondCodes Pred,
unsigned PredReg) const { unsigned PredReg, unsigned MIFlags) const {
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
MachineConstantPool *ConstantPool = MF.getConstantPool(); MachineConstantPool *ConstantPool = MF.getConstantPool();
const Constant *C = const Constant *C =
@ -816,7 +816,8 @@ emitLoadConstPool(MachineBasicBlock &MBB,
BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp)) BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
.addReg(DestReg, getDefRegState(true), SubIdx) .addReg(DestReg, getDefRegState(true), SubIdx)
.addConstantPoolIndex(Idx) .addConstantPoolIndex(Idx)
.addImm(0).addImm(Pred).addReg(PredReg); .addImm(0).addImm(Pred).addReg(PredReg)
.setMIFlags(MIFlags);
} }
bool ARMBaseRegisterInfo:: bool ARMBaseRegisterInfo::

View File

@ -176,7 +176,8 @@ public:
unsigned DestReg, unsigned SubIdx, unsigned DestReg, unsigned SubIdx,
int Val, int Val,
ARMCC::CondCodes Pred = ARMCC::AL, ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0) const; unsigned PredReg = 0,
unsigned MIFlags = MachineInstr::NoFlags)const;
/// Code Generation virtual methods... /// Code Generation virtual methods...
virtual bool isReservedReg(const MachineFunction &MF, unsigned Reg) const; virtual bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;

View File

@ -34,13 +34,14 @@ bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const
return !MF.getFrameInfo()->hasVarSizedObjects(); return !MF.getFrameInfo()->hasVarSizedObjects();
} }
static void emitSPUpdate(MachineBasicBlock &MBB, static void
MachineBasicBlock::iterator &MBBI, emitSPUpdate(MachineBasicBlock &MBB,
const TargetInstrInfo &TII, DebugLoc dl, MachineBasicBlock::iterator &MBBI,
const Thumb1RegisterInfo &MRI, const TargetInstrInfo &TII, DebugLoc dl,
int NumBytes) { const Thumb1RegisterInfo &MRI,
int NumBytes, unsigned MIFlags = MachineInstr::NoFlags) {
emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII, emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII,
MRI); MRI, MIFlags);
} }
void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
@ -70,11 +71,13 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
int FramePtrSpillFI = 0; int FramePtrSpillFI = 0;
if (VARegSaveSize) if (VARegSaveSize)
emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -VARegSaveSize); emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -VARegSaveSize,
MachineInstr::FrameSetup);
if (!AFI->hasStackFrame()) { if (!AFI->hasStackFrame()) {
if (NumBytes != 0) if (NumBytes != 0)
emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes); emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
MachineInstr::FrameSetup);
return; return;
} }
@ -131,7 +134,8 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
// Adjust FP so it point to the stack slot that contains the previous FP. // Adjust FP so it point to the stack slot that contains the previous FP.
if (hasFP(MF)) { if (hasFP(MF)) {
BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr) BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
.addFrameIndex(FramePtrSpillFI).addImm(0); .addFrameIndex(FramePtrSpillFI).addImm(0)
.setMIFlags(MachineInstr::FrameSetup);
if (NumBytes > 7) if (NumBytes > 7)
// If offset is > 7 then sp cannot be adjusted in a single instruction, // If offset is > 7 then sp cannot be adjusted in a single instruction,
// try restoring from fp instead. // try restoring from fp instead.
@ -140,7 +144,8 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
if (NumBytes) if (NumBytes)
// Insert it after all the callee-save spills. // Insert it after all the callee-save spills.
emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes); emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
MachineInstr::FrameSetup);
if (STI.isTargetELF() && hasFP(MF)) if (STI.isTargetELF() && hasFP(MF))
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
@ -307,6 +312,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MIB.addReg(Reg, getKillRegState(isKill)); MIB.addReg(Reg, getKillRegState(isKill));
} }
MIB.setMIFlags(MachineInstr::FrameSetup);
return true; return true;
} }

View File

@ -50,13 +50,14 @@ Thumb1RegisterInfo::Thumb1RegisterInfo(const ARMBaseInstrInfo &tii,
/// emitLoadConstPool - Emits a load from constpool to materialize the /// emitLoadConstPool - Emits a load from constpool to materialize the
/// specified immediate. /// specified immediate.
void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, void
MachineBasicBlock::iterator &MBBI, Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
DebugLoc dl, MachineBasicBlock::iterator &MBBI,
unsigned DestReg, unsigned SubIdx, DebugLoc dl,
int Val, unsigned DestReg, unsigned SubIdx,
ARMCC::CondCodes Pred, int Val,
unsigned PredReg) const { ARMCC::CondCodes Pred, unsigned PredReg,
unsigned MIFlags) const {
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
MachineConstantPool *ConstantPool = MF.getConstantPool(); MachineConstantPool *ConstantPool = MF.getConstantPool();
const Constant *C = ConstantInt::get( const Constant *C = ConstantInt::get(
@ -65,7 +66,8 @@ void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci)) BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci))
.addReg(DestReg, getDefRegState(true), SubIdx) .addReg(DestReg, getDefRegState(true), SubIdx)
.addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg); .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg)
.setMIFlags(MIFlags)
} }
@ -76,11 +78,12 @@ void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
static static
void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, MachineBasicBlock::iterator &MBBI,
DebugLoc dl,
unsigned DestReg, unsigned BaseReg, unsigned DestReg, unsigned BaseReg,
int NumBytes, bool CanChangeCC, int NumBytes, bool CanChangeCC,
const TargetInstrInfo &TII, const TargetInstrInfo &TII,
const ARMBaseRegisterInfo& MRI, const ARMBaseRegisterInfo& MRI,
DebugLoc dl) { unsigned MIFlags = MachineInstr::NoFlags) {
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
bool isHigh = !isARMLowRegister(DestReg) || bool isHigh = !isARMLowRegister(DestReg) ||
(BaseReg != 0 && !isARMLowRegister(BaseReg)); (BaseReg != 0 && !isARMLowRegister(BaseReg));
@ -101,14 +104,15 @@ void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
if (NumBytes <= 255 && NumBytes >= 0) if (NumBytes <= 255 && NumBytes >= 0)
AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
.addImm(NumBytes); .addImm(NumBytes).setMIFlags(MIFlags);
else if (NumBytes < 0 && NumBytes >= -255) { else if (NumBytes < 0 && NumBytes >= -255) {
AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
.addImm(NumBytes); .addImm(NumBytes).setMIFlags(MIFlags);
AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)) AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
.addReg(LdReg, RegState::Kill); .addReg(LdReg, RegState::Kill).setMIFlags(MIFlags);
} else } else
MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes); MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes,
ARMCC::AL, 0, MIFlags);
// Emit add / sub. // Emit add / sub.
int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
@ -154,7 +158,8 @@ void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
DebugLoc dl, DebugLoc dl,
unsigned DestReg, unsigned BaseReg, unsigned DestReg, unsigned BaseReg,
int NumBytes, const TargetInstrInfo &TII, int NumBytes, const TargetInstrInfo &TII,
const ARMBaseRegisterInfo& MRI, unsigned) { const ARMBaseRegisterInfo& MRI,
unsigned MIFlags) {
bool isSub = NumBytes < 0; bool isSub = NumBytes < 0;
unsigned Bytes = (unsigned)NumBytes; unsigned Bytes = (unsigned)NumBytes;
if (isSub) Bytes = -NumBytes; if (isSub) Bytes = -NumBytes;
@ -211,8 +216,9 @@ void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
if (NumMIs > Threshold) { if (NumMIs > Threshold) {
// This will expand into too many instructions. Load the immediate from a // This will expand into too many instructions. Load the immediate from a
// constpool entry. // constpool entry.
emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII, emitThumbRegPlusImmInReg(MBB, MBBI, dl,
MRI, dl); DestReg, BaseReg, NumBytes, true,
TII, MRI, MIFlags);
return; return;
} }
@ -224,11 +230,12 @@ void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
Bytes -= ThisVal; Bytes -= ThisVal;
const TargetInstrDesc &TID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3); const TargetInstrDesc &TID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3);
const MachineInstrBuilder MIB = const MachineInstrBuilder MIB =
AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg)); AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg).setMIFlags(MIFlags));
AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal)); AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal));
} else { } else {
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
.addReg(BaseReg, RegState::Kill); .addReg(BaseReg, RegState::Kill)
.setMIFlags(MIFlags);
} }
BaseReg = DestReg; BaseReg = DestReg;
} }
@ -243,9 +250,10 @@ void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
if (NeedCC) if (NeedCC)
MIB = AddDefaultT1CC(MIB); MIB = AddDefaultT1CC(MIB);
MIB .addReg(DestReg).addImm(ThisVal); MIB.addReg(DestReg).addImm(ThisVal);
if (NeedPred) if (NeedPred)
MIB = AddDefaultPred(MIB); MIB = AddDefaultPred(MIB);
MIB.setMIFlags(MIFlags);
} }
else { else {
bool isKill = BaseReg != ARM::SP; bool isKill = BaseReg != ARM::SP;
@ -255,8 +263,9 @@ void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal); MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
if (NeedPred) if (NeedPred)
MIB = AddDefaultPred(MIB); MIB = AddDefaultPred(MIB);
BaseReg = DestReg; MIB.setMIFlags(MIFlags);
BaseReg = DestReg;
if (Opc == ARM::tADDrSPi) { if (Opc == ARM::tADDrSPi) {
// r4 = add sp, imm // r4 = add sp, imm
// r4 = add r4, imm // r4 = add r4, imm
@ -274,7 +283,8 @@ void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
const TargetInstrDesc &TID = TII.get(ExtraOpc); const TargetInstrDesc &TID = TII.get(ExtraOpc);
AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg)) AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg))
.addReg(DestReg, RegState::Kill) .addReg(DestReg, RegState::Kill)
.addImm(((unsigned)NumBytes) & 3)); .addImm(((unsigned)NumBytes) & 3)
.setMIFlags(MIFlags));
} }
} }
@ -645,8 +655,8 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
bool UseRR = false; bool UseRR = false;
if (Opcode == ARM::tRestore) { if (Opcode == ARM::tRestore) {
if (FrameReg == ARM::SP) if (FrameReg == ARM::SP)
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,
Offset, false, TII, *this, dl); Offset, false, TII, *this);
else { else {
emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
UseRR = true; UseRR = true;
@ -668,8 +678,8 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
if (Opcode == ARM::tSpill) { if (Opcode == ARM::tSpill) {
if (FrameReg == ARM::SP) if (FrameReg == ARM::SP)
emitThumbRegPlusImmInReg(MBB, II, VReg, FrameReg, emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,
Offset, false, TII, *this, dl); Offset, false, TII, *this);
else { else {
emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
UseRR = true; UseRR = true;

View File

@ -35,7 +35,8 @@ public:
DebugLoc dl, DebugLoc dl,
unsigned DestReg, unsigned SubIdx, int Val, unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred = ARMCC::AL, ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0) const; unsigned PredReg = 0,
unsigned MIFlags = MachineInstr::NoFlags) const;
/// Code Generation virtual methods... /// Code Generation virtual methods...
void eliminateCallFramePseudoInstr(MachineFunction &MF, void eliminateCallFramePseudoInstr(MachineFunction &MF,

View File

@ -42,13 +42,14 @@ Thumb2RegisterInfo::Thumb2RegisterInfo(const ARMBaseInstrInfo &tii,
/// emitLoadConstPool - Emits a load from constpool to materialize the /// emitLoadConstPool - Emits a load from constpool to materialize the
/// specified immediate. /// specified immediate.
void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, void
MachineBasicBlock::iterator &MBBI, Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
DebugLoc dl, MachineBasicBlock::iterator &MBBI,
unsigned DestReg, unsigned SubIdx, DebugLoc dl,
int Val, unsigned DestReg, unsigned SubIdx,
ARMCC::CondCodes Pred, int Val,
unsigned PredReg) const { ARMCC::CondCodes Pred, unsigned PredReg,
unsigned MIFlags) const {
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
MachineConstantPool *ConstantPool = MF.getConstantPool(); MachineConstantPool *ConstantPool = MF.getConstantPool();
const Constant *C = ConstantInt::get( const Constant *C = ConstantInt::get(
@ -57,5 +58,6 @@ void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci)) BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci))
.addReg(DestReg, getDefRegState(true), SubIdx) .addReg(DestReg, getDefRegState(true), SubIdx)
.addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0); .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0)
.setMIFlags(MIFlags);
} }

View File

@ -35,7 +35,8 @@ public:
DebugLoc dl, DebugLoc dl,
unsigned DestReg, unsigned SubIdx, int Val, unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred = ARMCC::AL, ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0) const; unsigned PredReg = 0,
unsigned MIFlags = MachineInstr::NoFlags) const;
}; };
} }