mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-07 12:56:43 +00:00
Fix some potential issues in the pseudo instruction expansion phase: copy implicit operands and memoperands. Also, expand instructions even if their defs are "dead" since they may have implicit kill operands.
llvm-svn: 103667
This commit is contained in:
parent
de7caed021
commit
aef4fc8804
@ -37,11 +37,31 @@ namespace {
|
||||
}
|
||||
|
||||
private:
|
||||
void TransferImpOps(MachineInstr &OldMI,
|
||||
MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI);
|
||||
bool ExpandMBB(MachineBasicBlock &MBB);
|
||||
};
|
||||
char ARMExpandPseudo::ID = 0;
|
||||
}
|
||||
|
||||
/// TransferImpOps - Transfer implicit operands on the pseudo instruction to
|
||||
/// the instructions created from the expansion.
|
||||
void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI,
|
||||
MachineInstrBuilder &UseMI,
|
||||
MachineInstrBuilder &DefMI) {
|
||||
const TargetInstrDesc &Desc = OldMI.getDesc();
|
||||
for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands();
|
||||
i != e; ++i) {
|
||||
const MachineOperand &MO = OldMI.getOperand(i);
|
||||
assert(MO.isReg() && MO.getReg());
|
||||
if (MO.isUse())
|
||||
UseMI.addReg(MO.getReg(), getKillRegState(MO.isKill()));
|
||||
else
|
||||
DefMI.addReg(MO.getReg(),
|
||||
getDefRegState(true) | getDeadRegState(MO.isDead()));
|
||||
}
|
||||
}
|
||||
|
||||
bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
|
||||
bool Modified = false;
|
||||
|
||||
@ -58,48 +78,54 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
|
||||
unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
|
||||
? ARM::tLDRpci : ARM::t2LDRpci;
|
||||
unsigned DstReg = MI.getOperand(0).getReg();
|
||||
if (!MI.getOperand(0).isDead()) {
|
||||
MachineInstr *NewMI =
|
||||
AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
||||
TII->get(NewLdOpc), DstReg)
|
||||
.addOperand(MI.getOperand(1)));
|
||||
NewMI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
||||
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tPICADD))
|
||||
.addReg(DstReg, getDefRegState(true))
|
||||
.addReg(DstReg)
|
||||
.addOperand(MI.getOperand(2));
|
||||
}
|
||||
bool DstIsDead = MI.getOperand(0).isDead();
|
||||
MachineInstrBuilder MIB1 =
|
||||
AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
||||
TII->get(NewLdOpc), DstReg)
|
||||
.addOperand(MI.getOperand(1)));
|
||||
(*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
||||
MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
||||
TII->get(ARM::tPICADD))
|
||||
.addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
|
||||
.addReg(DstReg)
|
||||
.addOperand(MI.getOperand(2));
|
||||
TransferImpOps(MI, MIB1, MIB2);
|
||||
MI.eraseFromParent();
|
||||
Modified = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case ARM::t2MOVi32imm: {
|
||||
unsigned PredReg = 0;
|
||||
ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
|
||||
unsigned DstReg = MI.getOperand(0).getReg();
|
||||
if (!MI.getOperand(0).isDead()) {
|
||||
const MachineOperand &MO = MI.getOperand(1);
|
||||
MachineInstrBuilder LO16, HI16;
|
||||
bool DstIsDead = MI.getOperand(0).isDead();
|
||||
const MachineOperand &MO = MI.getOperand(1);
|
||||
MachineInstrBuilder LO16, HI16;
|
||||
|
||||
LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVi16),
|
||||
DstReg);
|
||||
HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVTi16))
|
||||
.addReg(DstReg, getDefRegState(true)).addReg(DstReg);
|
||||
LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVi16),
|
||||
DstReg);
|
||||
HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVTi16))
|
||||
.addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
|
||||
.addReg(DstReg);
|
||||
|
||||
if (MO.isImm()) {
|
||||
unsigned Imm = MO.getImm();
|
||||
unsigned Lo16 = Imm & 0xffff;
|
||||
unsigned Hi16 = (Imm >> 16) & 0xffff;
|
||||
LO16 = LO16.addImm(Lo16);
|
||||
HI16 = HI16.addImm(Hi16);
|
||||
} else {
|
||||
const GlobalValue *GV = MO.getGlobal();
|
||||
unsigned TF = MO.getTargetFlags();
|
||||
LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
|
||||
HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
|
||||
// FIXME: What's about memoperands?
|
||||
}
|
||||
AddDefaultPred(LO16);
|
||||
AddDefaultPred(HI16);
|
||||
if (MO.isImm()) {
|
||||
unsigned Imm = MO.getImm();
|
||||
unsigned Lo16 = Imm & 0xffff;
|
||||
unsigned Hi16 = (Imm >> 16) & 0xffff;
|
||||
LO16 = LO16.addImm(Lo16);
|
||||
HI16 = HI16.addImm(Hi16);
|
||||
} else {
|
||||
const GlobalValue *GV = MO.getGlobal();
|
||||
unsigned TF = MO.getTargetFlags();
|
||||
LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
|
||||
HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
|
||||
}
|
||||
(*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
||||
(*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
||||
LO16.addImm(Pred).addReg(PredReg);
|
||||
HI16.addImm(Pred).addReg(PredReg);
|
||||
TransferImpOps(MI, LO16, HI16);
|
||||
MI.eraseFromParent();
|
||||
Modified = true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user