mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-03 13:31:05 +00:00
Handle IMPLICIT_DEF with isUndef operand marker, part 2. This patch moves the code to annotate machineoperands to LiveIntervalAnalysis. It also add markers for implicit_def that define physical registers. The rest, is just a lot of details.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74580 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5bcc8bd0c6
commit
2578ba26e7
@ -390,6 +390,10 @@ namespace llvm {
|
||||
unsigned getNumConflictsWithPhysReg(const LiveInterval &li,
|
||||
unsigned PhysReg) const;
|
||||
|
||||
/// processImplicitDefs - Process IMPLICIT_DEF instructions. Add isUndef
|
||||
/// marker to implicit_def defs and their uses.
|
||||
void processImplicitDefs();
|
||||
|
||||
/// computeNumbering - Compute the index numbering.
|
||||
void computeNumbering();
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "llvm/CodeGen/LiveVariables.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineLoopInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
@ -33,6 +34,8 @@
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <algorithm>
|
||||
@ -98,6 +101,93 @@ void LiveIntervals::releaseMemory() {
|
||||
}
|
||||
}
|
||||
|
||||
/// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure
|
||||
/// there is one implicit_def for each use. Add isUndef marker to
|
||||
/// implicit_def defs and their uses.
|
||||
void LiveIntervals::processImplicitDefs() {
|
||||
SmallSet<unsigned, 8> ImpDefRegs;
|
||||
SmallVector<MachineInstr*, 8> ImpDefMIs;
|
||||
MachineBasicBlock *Entry = mf_->begin();
|
||||
SmallPtrSet<MachineBasicBlock*,16> Visited;
|
||||
for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> >
|
||||
DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
|
||||
DFI != E; ++DFI) {
|
||||
MachineBasicBlock *MBB = *DFI;
|
||||
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
|
||||
I != E; ) {
|
||||
MachineInstr *MI = &*I;
|
||||
++I;
|
||||
if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
|
||||
unsigned Reg = MI->getOperand(0).getReg();
|
||||
MI->getOperand(0).setIsUndef();
|
||||
ImpDefRegs.insert(Reg);
|
||||
ImpDefMIs.push_back(MI);
|
||||
continue;
|
||||
}
|
||||
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
|
||||
MachineOperand& MO = MI->getOperand(i);
|
||||
if (!MO.isReg() || !MO.isUse())
|
||||
continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (!Reg)
|
||||
continue;
|
||||
if (!ImpDefRegs.count(Reg))
|
||||
continue;
|
||||
MO.setIsUndef();
|
||||
if (MO.isKill() || MI->isRegTiedToDefOperand(i))
|
||||
ImpDefRegs.erase(Reg);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
|
||||
MachineOperand& MO = MI->getOperand(i);
|
||||
if (!MO.isReg() || !MO.isDef())
|
||||
continue;
|
||||
ImpDefRegs.erase(MO.getReg());
|
||||
}
|
||||
}
|
||||
|
||||
// Any outstanding liveout implicit_def's?
|
||||
for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) {
|
||||
MachineInstr *MI = ImpDefMIs[i];
|
||||
unsigned Reg = MI->getOperand(0).getReg();
|
||||
if (TargetRegisterInfo::isPhysicalRegister(Reg))
|
||||
// Physical registers are not liveout (yet).
|
||||
continue;
|
||||
if (!ImpDefRegs.count(Reg))
|
||||
continue;
|
||||
bool HasLocalUse = false;
|
||||
for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(Reg),
|
||||
RE = mri_->reg_end(); RI != RE; ) {
|
||||
MachineOperand &RMO = RI.getOperand();
|
||||
MachineInstr *RMI = &*RI;
|
||||
++RI;
|
||||
if (RMO.isDef()) {
|
||||
// Don't expect another def of the same register.
|
||||
assert(RMI == MI &&
|
||||
"Register with multiple defs including an implicit_def?");
|
||||
continue;
|
||||
}
|
||||
MachineBasicBlock *RMBB = RMI->getParent();
|
||||
if (RMBB == MBB) {
|
||||
HasLocalUse = true;
|
||||
continue;
|
||||
}
|
||||
const TargetRegisterClass* RC = mri_->getRegClass(Reg);
|
||||
unsigned NewVReg = mri_->createVirtualRegister(RC);
|
||||
BuildMI(*RMBB, RMI, RMI->getDebugLoc(),
|
||||
tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg);
|
||||
RMO.setReg(NewVReg);
|
||||
RMO.setIsUndef();
|
||||
RMO.setIsKill();
|
||||
}
|
||||
if (!HasLocalUse)
|
||||
MI->eraseFromParent();
|
||||
}
|
||||
ImpDefRegs.clear();
|
||||
ImpDefMIs.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void LiveIntervals::computeNumbering() {
|
||||
Index2MiMap OldI2MI = i2miMap_;
|
||||
std::vector<IdxMBBPair> OldI2MBB = Idx2MBBMap;
|
||||
@ -299,6 +389,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
||||
lv_ = &getAnalysis<LiveVariables>();
|
||||
allocatableRegs_ = tri_->getAllocatableSet(fn);
|
||||
|
||||
processImplicitDefs();
|
||||
computeNumbering();
|
||||
computeIntervals();
|
||||
|
||||
@ -1785,8 +1876,6 @@ LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
|
||||
if (MO.isReg() && MO.getReg() == li.reg) {
|
||||
MO.setReg(NewVReg);
|
||||
MO.setIsUndef();
|
||||
if (MO.isKill())
|
||||
MO.setIsKill(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -545,26 +545,6 @@ void RALinScan::linearScan()
|
||||
if (!isPhys && vrm_->getPreSplitReg(cur.reg))
|
||||
continue;
|
||||
|
||||
// A register defined by an implicit_def can be liveout the def BB and livein
|
||||
// to a use BB. Add it to the livein set of the use BB's.
|
||||
if (!isPhys && cur.empty()) {
|
||||
if (MachineInstr *DefMI = mri_->getVRegDef(cur.reg)) {
|
||||
assert(DefMI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF);
|
||||
MachineBasicBlock *DefMBB = DefMI->getParent();
|
||||
SmallPtrSet<MachineBasicBlock*, 4> Seen;
|
||||
Seen.insert(DefMBB);
|
||||
for (MachineRegisterInfo::reg_iterator ri = mri_->reg_begin(cur.reg),
|
||||
re = mri_->reg_end(); ri != re; ++ri) {
|
||||
MachineInstr *UseMI = &*ri;
|
||||
MachineBasicBlock *UseMBB = UseMI->getParent();
|
||||
if (Seen.insert(UseMBB)) {
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
|
||||
"Adding a virtual register to livein set?");
|
||||
UseMBB->addLiveIn(Reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (LiveInterval::Ranges::const_iterator I = cur.begin(), E = cur.end();
|
||||
I != E; ++I) {
|
||||
const LiveRange &LR = *I;
|
||||
@ -905,17 +885,6 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
|
||||
DOUT << tri_->getName(physReg) << '\n';
|
||||
// Note the register is not really in use.
|
||||
vrm_->assignVirt2Phys(cur->reg, physReg);
|
||||
// Since the register allocator is allowed to assign this virtual register
|
||||
// physical register that overlaps other live intervals. Mark these
|
||||
// operands as "Undef" which means later passes, e.g. register scavenger
|
||||
// can ignore them.
|
||||
for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(cur->reg),
|
||||
RE = mri_->reg_end(); RI != RE; ++RI) {
|
||||
MachineOperand &MO = RI.getOperand();
|
||||
MO.setIsUndef();
|
||||
if (MO.isKill())
|
||||
MO.setIsKill(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -254,6 +254,8 @@ void RegScavenger::forward() {
|
||||
unsigned Idx = (i < NumECs)
|
||||
? EarlyClobberMOs[i].second : DefMOs[i-NumECs].second;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (MO.isUndef())
|
||||
continue;
|
||||
|
||||
// If it's dead upon def, then it is now free.
|
||||
if (MO.isDead()) {
|
||||
@ -262,7 +264,9 @@ void RegScavenger::forward() {
|
||||
}
|
||||
|
||||
// Skip two-address destination operand.
|
||||
if (MI->isRegTiedToUseOperand(Idx)) {
|
||||
unsigned UseIdx;
|
||||
if (MI->isRegTiedToUseOperand(Idx, &UseIdx) &&
|
||||
!MI->getOperand(UseIdx).isUndef()) {
|
||||
assert(isUsed(Reg) && "Using an undefined register!");
|
||||
continue;
|
||||
}
|
||||
@ -316,6 +320,8 @@ void RegScavenger::backward() {
|
||||
? *DefMOs[i].first : *EarlyClobberMOs[i-NumDefs].first;
|
||||
unsigned Idx = (i < NumECs)
|
||||
? DefMOs[i].second : EarlyClobberMOs[i-NumDefs].second;
|
||||
if (MO.isUndef())
|
||||
continue;
|
||||
|
||||
// Skip two-address destination operand.
|
||||
if (MI->isRegTiedToUseOperand(Idx))
|
||||
|
@ -2029,8 +2029,12 @@ private:
|
||||
if (!TargetRegisterInfo::isVirtualRegister(VirtReg)) {
|
||||
// Check to see if this is a noop copy. If so, eliminate the
|
||||
// instruction before considering the dest reg to be changed.
|
||||
// Also check if it's copying from an "undef", if so, we can't
|
||||
// eliminate this or else the undef marker is lost and it will
|
||||
// confuses the scavenger. This is extremely rare.
|
||||
unsigned Src, Dst, SrcSR, DstSR;
|
||||
if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
|
||||
if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst &&
|
||||
!MI.findRegisterUseOperand(Src)->isUndef()) {
|
||||
++NumDCE;
|
||||
DOUT << "Removing now-noop copy: " << MI;
|
||||
SmallVector<unsigned, 2> KillRegs;
|
||||
@ -2049,7 +2053,7 @@ private:
|
||||
Spills.disallowClobberPhysReg(VirtReg);
|
||||
goto ProcessNextInst;
|
||||
}
|
||||
|
||||
|
||||
// If it's not a no-op copy, it clobbers the value in the destreg.
|
||||
Spills.ClobberPhysReg(VirtReg);
|
||||
ReusedOperands.markClobbered(VirtReg);
|
||||
|
@ -619,14 +619,19 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned SrcReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
|
||||
.addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
|
||||
} else { // move -> load
|
||||
unsigned DstReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR))
|
||||
.addReg(DstReg, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(DstReg,
|
||||
RegState::Define |
|
||||
getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef))
|
||||
.addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
|
||||
}
|
||||
break;
|
||||
@ -636,14 +641,22 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
|
||||
unsigned PredReg = MI->getOperand(3).getReg();
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned SrcReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS))
|
||||
.addReg(SrcReg).addFrameIndex(FI)
|
||||
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0).addImm(Pred).addReg(PredReg);
|
||||
} else { // move -> load
|
||||
unsigned DstReg = MI->getOperand(0).getReg();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS), DstReg)
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0).addImm(Pred).addReg(PredReg);
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS))
|
||||
.addReg(DstReg,
|
||||
RegState::Define |
|
||||
getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef))
|
||||
.addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -653,14 +666,19 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned SrcReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
|
||||
.addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
|
||||
} else { // move -> load
|
||||
unsigned DstReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDD))
|
||||
.addReg(DstReg, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(DstReg,
|
||||
RegState::Define |
|
||||
getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef))
|
||||
.addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
|
||||
}
|
||||
break;
|
||||
|
@ -289,19 +289,22 @@ MachineInstr *AlphaInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
|
||||
if (Ops[0] == 0) { // move -> store
|
||||
unsigned InReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
Opc = (Opc == Alpha::BISr) ? Alpha::STQ :
|
||||
((Opc == Alpha::CPYSS) ? Alpha::STS : Alpha::STT);
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addReg(InReg, getKillRegState(isKill))
|
||||
.addReg(InReg, getKillRegState(isKill) | getUndefRegState(isUndef))
|
||||
.addFrameIndex(FrameIndex)
|
||||
.addReg(Alpha::F31);
|
||||
} else { // load -> move
|
||||
unsigned OutReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
Opc = (Opc == Alpha::BISr) ? Alpha::LDQ :
|
||||
((Opc == Alpha::CPYSS) ? Alpha::LDS : Alpha::LDT);
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(Opc))
|
||||
.addReg(OutReg, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(OutReg, RegState::Define | getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef))
|
||||
.addFrameIndex(FrameIndex)
|
||||
.addReg(Alpha::F31);
|
||||
}
|
||||
|
@ -491,19 +491,22 @@ SPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned InReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
if (FrameIndex < SPUFrameInfo::maxFrameOffset()) {
|
||||
MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(),
|
||||
get(SPU::STQDr32));
|
||||
|
||||
MIB.addReg(InReg, getKillRegState(isKill));
|
||||
MIB.addReg(InReg, getKillRegState(isKill) | getUndefRegState(isUndef));
|
||||
NewMI = addFrameReference(MIB, FrameIndex);
|
||||
}
|
||||
} else { // move -> load
|
||||
unsigned OutReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(Opc));
|
||||
|
||||
MIB.addReg(OutReg, RegState::Define | getDeadRegState(isDead));
|
||||
MIB.addReg(OutReg, RegState::Define | getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef));
|
||||
Opc = (FrameIndex < SPUFrameInfo::maxFrameOffset())
|
||||
? SPU::STQDr32 : SPU::STQXr32;
|
||||
NewMI = addFrameReference(MIB, FrameIndex);
|
||||
|
@ -291,14 +291,17 @@ foldMemoryOperandImpl(MachineFunction &MF,
|
||||
if (Ops[0] == 0) { // COPY -> STORE
|
||||
unsigned SrcReg = MI->getOperand(2).getReg();
|
||||
bool isKill = MI->getOperand(2).isKill();
|
||||
bool isUndef = MI->getOperand(2).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::SW))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
|
||||
.addImm(0).addFrameIndex(FI);
|
||||
} else { // COPY -> LOAD
|
||||
unsigned DstReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::LW))
|
||||
.addReg(DstReg, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(DstReg, RegState::Define | getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef))
|
||||
.addImm(0).addFrameIndex(FI);
|
||||
}
|
||||
}
|
||||
@ -321,14 +324,17 @@ foldMemoryOperandImpl(MachineFunction &MF,
|
||||
if (Ops[0] == 0) { // COPY -> STORE
|
||||
unsigned SrcReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(2).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(StoreOpc))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
|
||||
.addImm(0).addFrameIndex(FI) ;
|
||||
} else { // COPY -> LOAD
|
||||
unsigned DstReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(), get(LoadOpc))
|
||||
.addReg(DstReg, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(DstReg, RegState::Define | getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef))
|
||||
.addImm(0).addFrameIndex(FI);
|
||||
}
|
||||
}
|
||||
|
@ -691,16 +691,21 @@ MachineInstr *PPCInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned InReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STW))
|
||||
.addReg(InReg, getKillRegState(isKill)),
|
||||
.addReg(InReg,
|
||||
getKillRegState(isKill) |
|
||||
getUndefRegState(isUndef)),
|
||||
FrameIndex);
|
||||
} else { // move -> load
|
||||
unsigned OutReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LWZ))
|
||||
.addReg(OutReg,
|
||||
RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef)),
|
||||
FrameIndex);
|
||||
}
|
||||
} else if ((Opc == PPC::OR8 &&
|
||||
@ -708,48 +713,63 @@ MachineInstr *PPCInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned InReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STD))
|
||||
.addReg(InReg, getKillRegState(isKill)),
|
||||
.addReg(InReg,
|
||||
getKillRegState(isKill) |
|
||||
getUndefRegState(isUndef)),
|
||||
FrameIndex);
|
||||
} else { // move -> load
|
||||
unsigned OutReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LD))
|
||||
.addReg(OutReg,
|
||||
RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef)),
|
||||
FrameIndex);
|
||||
}
|
||||
} else if (Opc == PPC::FMRD) {
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned InReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFD))
|
||||
.addReg(InReg, getKillRegState(isKill)),
|
||||
.addReg(InReg,
|
||||
getKillRegState(isKill) |
|
||||
getUndefRegState(isUndef)),
|
||||
FrameIndex);
|
||||
} else { // move -> load
|
||||
unsigned OutReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFD))
|
||||
.addReg(OutReg,
|
||||
RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef)),
|
||||
FrameIndex);
|
||||
}
|
||||
} else if (Opc == PPC::FMRS) {
|
||||
if (OpNum == 0) { // move -> store
|
||||
unsigned InReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFS))
|
||||
.addReg(InReg, getKillRegState(isKill)),
|
||||
.addReg(InReg,
|
||||
getKillRegState(isKill) |
|
||||
getUndefRegState(isUndef)),
|
||||
FrameIndex);
|
||||
} else { // move -> load
|
||||
unsigned OutReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFS))
|
||||
.addReg(OutReg,
|
||||
RegState::Define |
|
||||
getDeadRegState(isDead)),
|
||||
getDeadRegState(isDead) |
|
||||
getUndefRegState(isUndef)),
|
||||
FrameIndex);
|
||||
}
|
||||
}
|
||||
|
@ -256,17 +256,20 @@ MachineInstr *SparcInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
|
||||
if (OpNum == 0) { // COPY -> STORE
|
||||
unsigned SrcReg = MI->getOperand(1).getReg();
|
||||
bool isKill = MI->getOperand(1).isKill();
|
||||
bool isUndef = MI->getOperand(1).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(),
|
||||
get(isFloat ? SP::STFri : SP::STDFri))
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0)
|
||||
.addReg(SrcReg, getKillRegState(isKill));
|
||||
.addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef));
|
||||
} else { // COPY -> LOAD
|
||||
unsigned DstReg = MI->getOperand(0).getReg();
|
||||
bool isDead = MI->getOperand(0).isDead();
|
||||
bool isUndef = MI->getOperand(0).isUndef();
|
||||
NewMI = BuildMI(MF, MI->getDebugLoc(),
|
||||
get(isFloat ? SP::LDFri : SP::LDDFri))
|
||||
.addReg(DstReg, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(DstReg, RegState::Define |
|
||||
getDeadRegState(isDead) | getUndefRegState(isUndef))
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0);
|
||||
}
|
||||
|
128
test/CodeGen/ARM/2009-06-30-RegScavengerAssert3.ll
Normal file
128
test/CodeGen/ARM/2009-06-30-RegScavengerAssert3.ll
Normal file
@ -0,0 +1,128 @@
|
||||
; RUN: llvm-as < %s | llc -march=arm -mtriple=armv6-apple-darwin9
|
||||
|
||||
@JJ = external global i32* ; <i32**> [#uses=1]
|
||||
|
||||
define arm_apcscc void @SIM(i8* %A, i8* %B, i32 %M, i32 %N, i32 %K, [256 x i32]* %V, i32 %Q, i32 %R, i32 %nseq) nounwind {
|
||||
entry:
|
||||
br i1 undef, label %bb5, label %bb
|
||||
|
||||
bb: ; preds = %bb, %entry
|
||||
br label %bb
|
||||
|
||||
bb5: ; preds = %entry
|
||||
br i1 undef, label %bb6, label %bb8
|
||||
|
||||
bb6: ; preds = %bb6, %bb5
|
||||
br i1 undef, label %bb8, label %bb6
|
||||
|
||||
bb8: ; preds = %bb6, %bb5
|
||||
br label %bb15
|
||||
|
||||
bb9: ; preds = %bb15
|
||||
br i1 undef, label %bb10, label %bb11
|
||||
|
||||
bb10: ; preds = %bb9
|
||||
unreachable
|
||||
|
||||
bb11: ; preds = %bb9
|
||||
br i1 undef, label %bb15, label %bb12
|
||||
|
||||
bb12: ; preds = %bb11
|
||||
%0 = load i32** @JJ, align 4 ; <i32*> [#uses=1]
|
||||
br label %bb228.i
|
||||
|
||||
bb74.i: ; preds = %bb228.i
|
||||
br i1 undef, label %bb138.i, label %bb145.i
|
||||
|
||||
bb138.i: ; preds = %bb74.i
|
||||
br label %bb145.i
|
||||
|
||||
bb145.i: ; preds = %bb228.i, %bb138.i, %bb74.i
|
||||
%cflag.0.i = phi i16 [ 0, %bb228.i ], [ 0, %bb74.i ], [ 1, %bb138.i ] ; <i16> [#uses=1]
|
||||
br i1 undef, label %bb146.i, label %bb151.i
|
||||
|
||||
bb146.i: ; preds = %bb145.i
|
||||
br i1 undef, label %bb228.i, label %bb151.i
|
||||
|
||||
bb151.i: ; preds = %bb146.i, %bb145.i
|
||||
%.not297 = icmp ne i16 %cflag.0.i, 0 ; <i1> [#uses=1]
|
||||
%or.cond298 = and i1 undef, %.not297 ; <i1> [#uses=1]
|
||||
br i1 %or.cond298, label %bb153.i, label %bb228.i
|
||||
|
||||
bb153.i: ; preds = %bb151.i
|
||||
br i1 undef, label %bb220.i, label %bb.nph.i98
|
||||
|
||||
bb.nph.i98: ; preds = %bb153.i
|
||||
br label %bb158.i
|
||||
|
||||
bb158.i: ; preds = %bb218.i, %bb.nph.i98
|
||||
%c.1020.i = phi i32 [ 0, %bb.nph.i98 ], [ %c.14.i, %bb218.i ] ; <i32> [#uses=1]
|
||||
%cflag.418.i = phi i16 [ 0, %bb.nph.i98 ], [ %cflag.3.i, %bb218.i ] ; <i16> [#uses=1]
|
||||
%pj.317.i = phi i32 [ undef, %bb.nph.i98 ], [ %8, %bb218.i ] ; <i32> [#uses=1]
|
||||
%pi.316.i = phi i32 [ undef, %bb.nph.i98 ], [ %7, %bb218.i ] ; <i32> [#uses=1]
|
||||
%fj.515.i = phi i32 [ undef, %bb.nph.i98 ], [ %fj.4.i, %bb218.i ] ; <i32> [#uses=3]
|
||||
%ci.910.i = phi i32 [ undef, %bb.nph.i98 ], [ %ci.12.i, %bb218.i ] ; <i32> [#uses=2]
|
||||
%i.121.i = sub i32 undef, undef ; <i32> [#uses=3]
|
||||
%tmp105.i = sub i32 undef, undef ; <i32> [#uses=1]
|
||||
%1 = sub i32 %c.1020.i, undef ; <i32> [#uses=0]
|
||||
br i1 undef, label %bb168.i, label %bb160.i
|
||||
|
||||
bb160.i: ; preds = %bb158.i
|
||||
br i1 undef, label %bb161.i, label %bb168.i
|
||||
|
||||
bb161.i: ; preds = %bb160.i
|
||||
br i1 undef, label %bb168.i, label %bb163.i
|
||||
|
||||
bb163.i: ; preds = %bb161.i
|
||||
%2 = icmp slt i32 %fj.515.i, undef ; <i1> [#uses=1]
|
||||
%3 = and i1 %2, undef ; <i1> [#uses=1]
|
||||
br i1 %3, label %bb167.i, label %bb168.i
|
||||
|
||||
bb167.i: ; preds = %bb163.i
|
||||
br label %bb168.i
|
||||
|
||||
bb168.i: ; preds = %bb167.i, %bb163.i, %bb161.i, %bb160.i, %bb158.i
|
||||
%fi.5.i = phi i32 [ undef, %bb167.i ], [ %ci.910.i, %bb158.i ], [ undef, %bb160.i ], [ %ci.910.i, %bb161.i ], [ undef, %bb163.i ] ; <i32> [#uses=1]
|
||||
%fj.4.i = phi i32 [ undef, %bb167.i ], [ undef, %bb158.i ], [ %fj.515.i, %bb160.i ], [ undef, %bb161.i ], [ %fj.515.i, %bb163.i ] ; <i32> [#uses=2]
|
||||
%scevgep88.i = getelementptr i32* null, i32 %i.121.i ; <i32*> [#uses=3]
|
||||
%4 = load i32* %scevgep88.i, align 4 ; <i32> [#uses=2]
|
||||
%scevgep89.i = getelementptr i32* %0, i32 %i.121.i ; <i32*> [#uses=3]
|
||||
%5 = load i32* %scevgep89.i, align 4 ; <i32> [#uses=1]
|
||||
%ci.10.i = select i1 undef, i32 %pi.316.i, i32 %i.121.i ; <i32> [#uses=0]
|
||||
%cj.9.i = select i1 undef, i32 %pj.317.i, i32 undef ; <i32> [#uses=0]
|
||||
%6 = icmp slt i32 undef, 0 ; <i1> [#uses=3]
|
||||
%ci.12.i = select i1 %6, i32 %fi.5.i, i32 %4 ; <i32> [#uses=2]
|
||||
%cj.11.i100 = select i1 %6, i32 %fj.4.i, i32 %5 ; <i32> [#uses=1]
|
||||
%c.14.i = select i1 %6, i32 0, i32 undef ; <i32> [#uses=2]
|
||||
store i32 %c.14.i, i32* undef, align 4
|
||||
%7 = load i32* %scevgep88.i, align 4 ; <i32> [#uses=1]
|
||||
%8 = load i32* %scevgep89.i, align 4 ; <i32> [#uses=1]
|
||||
store i32 %ci.12.i, i32* %scevgep88.i, align 4
|
||||
store i32 %cj.11.i100, i32* %scevgep89.i, align 4
|
||||
store i32 %4, i32* undef, align 4
|
||||
br i1 undef, label %bb211.i, label %bb218.i
|
||||
|
||||
bb211.i: ; preds = %bb168.i
|
||||
br label %bb218.i
|
||||
|
||||
bb218.i: ; preds = %bb211.i, %bb168.i
|
||||
%cflag.3.i = phi i16 [ %cflag.418.i, %bb168.i ], [ 1, %bb211.i ] ; <i16> [#uses=2]
|
||||
%9 = icmp slt i32 %tmp105.i, undef ; <i1> [#uses=1]
|
||||
br i1 %9, label %bb220.i, label %bb158.i
|
||||
|
||||
bb220.i: ; preds = %bb218.i, %bb153.i
|
||||
%cflag.4.lcssa.i = phi i16 [ 0, %bb153.i ], [ %cflag.3.i, %bb218.i ] ; <i16> [#uses=0]
|
||||
br i1 undef, label %bb221.i, label %bb228.i
|
||||
|
||||
bb221.i: ; preds = %bb220.i
|
||||
br label %bb228.i
|
||||
|
||||
bb228.i: ; preds = %bb221.i, %bb220.i, %bb151.i, %bb146.i, %bb12
|
||||
br i1 undef, label %bb74.i, label %bb145.i
|
||||
|
||||
bb15: ; preds = %bb11, %bb8
|
||||
br i1 undef, label %return, label %bb9
|
||||
|
||||
return: ; preds = %bb15
|
||||
ret void
|
||||
}
|
128
test/CodeGen/ARM/2009-06-30-RegScavengerAssert4.ll
Normal file
128
test/CodeGen/ARM/2009-06-30-RegScavengerAssert4.ll
Normal file
@ -0,0 +1,128 @@
|
||||
; RUN: llvm-as < %s | llc -march=arm -mtriple=armv6-apple-darwin9
|
||||
|
||||
@r = external global i32 ; <i32*> [#uses=1]
|
||||
@qr = external global i32 ; <i32*> [#uses=1]
|
||||
@II = external global i32* ; <i32**> [#uses=1]
|
||||
@no_mis = external global i32 ; <i32*> [#uses=1]
|
||||
@name1 = external global i8* ; <i8**> [#uses=1]
|
||||
|
||||
declare arm_apcscc void @diff(i8*, i8*, i32, i32, i32, i32) nounwind
|
||||
|
||||
define arm_apcscc void @SIM(i8* %A, i8* %B, i32 %M, i32 %N, i32 %K, [256 x i32]* %V, i32 %Q, i32 %R, i32 %nseq) nounwind {
|
||||
entry:
|
||||
br i1 undef, label %bb5, label %bb
|
||||
|
||||
bb: ; preds = %bb, %entry
|
||||
br label %bb
|
||||
|
||||
bb5: ; preds = %entry
|
||||
br i1 undef, label %bb6, label %bb8
|
||||
|
||||
bb6: ; preds = %bb6, %bb5
|
||||
br i1 undef, label %bb8, label %bb6
|
||||
|
||||
bb8: ; preds = %bb6, %bb5
|
||||
%0 = load i8** @name1, align 4 ; <i8*> [#uses=0]
|
||||
br label %bb15
|
||||
|
||||
bb9: ; preds = %bb15
|
||||
br i1 undef, label %bb10, label %bb11
|
||||
|
||||
bb10: ; preds = %bb9
|
||||
unreachable
|
||||
|
||||
bb11: ; preds = %bb9
|
||||
store i32 0, i32* @no_mis, align 4
|
||||
%1 = getelementptr i8* %A, i32 0 ; <i8*> [#uses=1]
|
||||
%2 = getelementptr i8* %B, i32 0 ; <i8*> [#uses=1]
|
||||
tail call arm_apcscc void @diff(i8* %1, i8* %2, i32 undef, i32 undef, i32 undef, i32 undef) nounwind
|
||||
br i1 undef, label %bb15, label %bb12
|
||||
|
||||
bb12: ; preds = %bb11
|
||||
%3 = load i32** @II, align 4 ; <i32*> [#uses=1]
|
||||
%4 = load i32* @r, align 4 ; <i32> [#uses=1]
|
||||
%5 = load i32* @qr, align 4 ; <i32> [#uses=1]
|
||||
br label %bb228.i
|
||||
|
||||
bb74.i: ; preds = %bb228.i
|
||||
br i1 undef, label %bb138.i, label %bb145.i
|
||||
|
||||
bb138.i: ; preds = %bb74.i
|
||||
br label %bb145.i
|
||||
|
||||
bb145.i: ; preds = %bb228.i, %bb138.i, %bb74.i
|
||||
br i1 undef, label %bb146.i, label %bb151.i
|
||||
|
||||
bb146.i: ; preds = %bb145.i
|
||||
br i1 undef, label %bb228.i, label %bb151.i
|
||||
|
||||
bb151.i: ; preds = %bb146.i, %bb145.i
|
||||
br i1 undef, label %bb153.i, label %bb228.i
|
||||
|
||||
bb153.i: ; preds = %bb151.i
|
||||
%6 = add i32 undef, -1 ; <i32> [#uses=3]
|
||||
br i1 undef, label %bb220.i, label %bb.nph.i98
|
||||
|
||||
bb.nph.i98: ; preds = %bb153.i
|
||||
br label %bb158.i
|
||||
|
||||
bb158.i: ; preds = %bb218.i, %bb.nph.i98
|
||||
%c.1020.i = phi i32 [ 0, %bb.nph.i98 ], [ %c.14.i, %bb218.i ] ; <i32> [#uses=1]
|
||||
%f.419.i = phi i32 [ undef, %bb.nph.i98 ], [ %f.5.i, %bb218.i ] ; <i32> [#uses=1]
|
||||
%pi.316.i = phi i32 [ undef, %bb.nph.i98 ], [ %10, %bb218.i ] ; <i32> [#uses=1]
|
||||
%fj.515.i = phi i32 [ %6, %bb.nph.i98 ], [ %fj.4.i, %bb218.i ] ; <i32> [#uses=2]
|
||||
%fi.614.i = phi i32 [ undef, %bb.nph.i98 ], [ %fi.5.i, %bb218.i ] ; <i32> [#uses=3]
|
||||
%cj.811.i = phi i32 [ %6, %bb.nph.i98 ], [ %cj.11.i100, %bb218.i ] ; <i32> [#uses=3]
|
||||
%ci.910.i = phi i32 [ undef, %bb.nph.i98 ], [ %ci.12.i, %bb218.i ] ; <i32> [#uses=2]
|
||||
%7 = sub i32 %f.419.i, %4 ; <i32> [#uses=5]
|
||||
%8 = sub i32 %c.1020.i, %5 ; <i32> [#uses=2]
|
||||
%9 = icmp slt i32 %7, %8 ; <i1> [#uses=1]
|
||||
br i1 %9, label %bb168.i, label %bb160.i
|
||||
|
||||
bb160.i: ; preds = %bb158.i
|
||||
br i1 undef, label %bb161.i, label %bb168.i
|
||||
|
||||
bb161.i: ; preds = %bb160.i
|
||||
br i1 undef, label %bb168.i, label %bb163.i
|
||||
|
||||
bb163.i: ; preds = %bb161.i
|
||||
br i1 undef, label %bb167.i, label %bb168.i
|
||||
|
||||
bb167.i: ; preds = %bb163.i
|
||||
br label %bb168.i
|
||||
|
||||
bb168.i: ; preds = %bb167.i, %bb163.i, %bb161.i, %bb160.i, %bb158.i
|
||||
%fi.5.i = phi i32 [ %fi.614.i, %bb167.i ], [ %ci.910.i, %bb158.i ], [ %fi.614.i, %bb160.i ], [ %ci.910.i, %bb161.i ], [ %fi.614.i, %bb163.i ] ; <i32> [#uses=2]
|
||||
%fj.4.i = phi i32 [ %cj.811.i, %bb167.i ], [ %cj.811.i, %bb158.i ], [ %fj.515.i, %bb160.i ], [ %cj.811.i, %bb161.i ], [ %fj.515.i, %bb163.i ] ; <i32> [#uses=2]
|
||||
%f.5.i = phi i32 [ %7, %bb167.i ], [ %8, %bb158.i ], [ %7, %bb160.i ], [ %7, %bb161.i ], [ %7, %bb163.i ] ; <i32> [#uses=2]
|
||||
%scevgep88.i = getelementptr i32* %3, i32 undef ; <i32*> [#uses=1]
|
||||
%ci.10.i = select i1 undef, i32 %pi.316.i, i32 undef ; <i32> [#uses=0]
|
||||
%ci.12.i = select i1 undef, i32 %fi.5.i, i32 undef ; <i32> [#uses=1]
|
||||
%cj.11.i100 = select i1 undef, i32 %fj.4.i, i32 undef ; <i32> [#uses=1]
|
||||
%c.14.i = select i1 undef, i32 %f.5.i, i32 undef ; <i32> [#uses=1]
|
||||
%10 = load i32* %scevgep88.i, align 4 ; <i32> [#uses=1]
|
||||
br i1 undef, label %bb211.i, label %bb218.i
|
||||
|
||||
bb211.i: ; preds = %bb168.i
|
||||
br label %bb218.i
|
||||
|
||||
bb218.i: ; preds = %bb211.i, %bb168.i
|
||||
br i1 undef, label %bb220.i, label %bb158.i
|
||||
|
||||
bb220.i: ; preds = %bb218.i, %bb153.i
|
||||
%11 = getelementptr i32* null, i32 %6 ; <i32*> [#uses=1]
|
||||
store i32 undef, i32* %11, align 4
|
||||
br i1 undef, label %bb221.i, label %bb228.i
|
||||
|
||||
bb221.i: ; preds = %bb220.i
|
||||
br label %bb228.i
|
||||
|
||||
bb228.i: ; preds = %bb221.i, %bb220.i, %bb151.i, %bb146.i, %bb12
|
||||
br i1 undef, label %bb74.i, label %bb145.i
|
||||
|
||||
bb15: ; preds = %bb11, %bb8
|
||||
br i1 undef, label %return, label %bb9
|
||||
|
||||
return: ; preds = %bb15
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user