void ProcessCopy(MachineInstr *MI, MachineBasicBlock *MBB,
SmallPtrSet<MachineInstr*, 8> &Processed);
+
public:
static char ID; // Pass identification, replacement for typeid
TwoAddressInstructionPass() : MachineFunctionPass(&ID) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
AU.addPreserved<LiveVariables>();
AU.addPreservedID(MachineLoopInfoID);
AU.addPreservedID(MachineDominatorsID);
MachineInstr *TwoAddressInstructionPass::FindLastUseInMBB(unsigned Reg,
MachineBasicBlock *MBB,
unsigned Dist) {
- unsigned LastUseDist = Dist;
+ unsigned LastUseDist = 0;
MachineInstr *LastUse = 0;
for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(Reg),
E = MRI->reg_end(); I != E; ++I) {
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(MI);
if (DI == DistanceMap.end())
continue;
- if (MO.isUse() && DI->second < LastUseDist) {
+ if (DI->second >= Dist)
+ continue;
+
+ if (MO.isUse() && DI->second > LastUseDist) {
LastUse = DI->first;
LastUseDist = DI->second;
}
bool MadeChange = false;
DOUT << "********** REWRITING TWO-ADDR INSTRS **********\n";
- DOUT << "********** Function: " << MF.getFunction()->getName() << '\n';
+ DEBUG(errs() << "********** Function: "
+ << MF.getFunction()->getName() << '\n');
// ReMatRegs - Keep track of the registers whose def's are remat'ed.
BitVector ReMatRegs;
if (FirstTied) {
++NumTwoAddressInstrs;
- DOUT << '\t'; DEBUG(mi->print(*cerr.stream(), &TM));
+ DOUT << '\t' << *mi;
}
FirstTied = false;
// a = a op c
unsigned regA = mi->getOperand(ti).getReg();
unsigned regB = mi->getOperand(si).getReg();
+ unsigned regASubIdx = mi->getOperand(ti).getSubReg();
assert(TargetRegisterInfo::isVirtualRegister(regB) &&
- "cannot update physical register live information");
+ "cannot make instruction into two-address form");
#ifndef NDEBUG
// First, verify that we don't have a use of a in the instruction (a =
// so, swap the B and C operands. This makes the live ranges of A
// and C joinable.
// FIXME: This code also works for A := B op C instructions.
- if (TID.isCommutable() && mi->getNumOperands() >= 3) {
- assert(mi->getOperand(3-si).isReg() &&
- "Not a proper commutative instruction!");
- unsigned regC = mi->getOperand(3-si).getReg();
+ unsigned SrcOp1, SrcOp2;
+ if (TID.isCommutable() && mi->getNumOperands() >= 3 &&
+ TII->findCommutedOpIndices(mi, SrcOp1, SrcOp2)) {
+ unsigned regC = 0;
+ if (si == SrcOp1)
+ regC = mi->getOperand(SrcOp2).getReg();
+ else if (si == SrcOp2)
+ regC = mi->getOperand(SrcOp1).getReg();
if (isKilled(*mi, regC, MRI, TII)) {
if (CommuteInstruction(mi, mbbi, regB, regC, Dist)) {
++NumCommuted;
}
// If it's profitable to commute the instruction, do so.
- if (TID.isCommutable() && mi->getNumOperands() >= 3) {
- unsigned regC = mi->getOperand(3-si).getReg();
- if (isProfitableToCommute(regB, regC, mi, mbbi, Dist))
+ unsigned SrcOp1, SrcOp2;
+ if (TID.isCommutable() && mi->getNumOperands() >= 3 &&
+ TII->findCommutedOpIndices(mi, SrcOp1, SrcOp2)) {
+ unsigned regC = 0;
+ if (si == SrcOp1)
+ regC = mi->getOperand(SrcOp2).getReg();
+ else if (si == SrcOp2)
+ regC = mi->getOperand(SrcOp1).getReg();
+
+ if (regC && isProfitableToCommute(regB, regC, mi, mbbi, Dist))
if (CommuteInstruction(mi, mbbi, regB, regC, Dist)) {
++NumAggrCommuted;
++NumCommuted;
DefMI->isSafeToReMat(TII, regB) &&
isProfitableToReMat(regB, rc, mi, DefMI, mbbi, Dist)){
DEBUG(cerr << "2addr: REMATTING : " << *DefMI << "\n");
- TII->reMaterialize(*mbbi, mi, regA, DefMI);
+ TII->reMaterialize(*mbbi, mi, regA, regASubIdx, DefMI);
ReMatRegs.set(regB);
++NumReMats;
} else {
// Update live variables for regB.
if (LV) {
- LiveVariables::VarInfo& varInfoB = LV->getVarInfo(regB);
-
- // regB is used in this BB.
- varInfoB.UsedBlocks[mbbi->getNumber()] = true;
-
if (LV->removeVirtualRegisterKilled(regB, mi))
LV->addVirtualRegisterKilled(regB, prevMI);
LV->addVirtualRegisterDead(regB, prevMI);
}
- DOUT << "\t\tprepend:\t"; DEBUG(prevMI->print(*cerr.stream(), &TM));
+ DOUT << "\t\tprepend:\t" << *prevMI;
// Replace all occurences of regB with regA.
for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) {
mi->getOperand(ti).setReg(mi->getOperand(si).getReg());
MadeChange = true;
- DOUT << "\t\trewrite to:\t"; DEBUG(mi->print(*cerr.stream(), &TM));
+ DOUT << "\t\trewrite to:\t" << *mi;
}
mi = nmi;