X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineInstrBundle.cpp;h=4619daf30141d383ab187a080b66603a022bb69f;hb=79d91e563fd0543bb7da494ebf3709c0e325099f;hp=dd46ecb17dee982b4d81b361ebb222e1a8055ba1;hpb=d04a8d4b33ff316ca4cf961e06c9e312eff8e64f;p=oota-llvm.git diff --git a/lib/CodeGen/MachineInstrBundle.cpp b/lib/CodeGen/MachineInstrBundle.cpp index dd46ecb17de..4619daf3014 100644 --- a/lib/CodeGen/MachineInstrBundle.cpp +++ b/lib/CodeGen/MachineInstrBundle.cpp @@ -16,17 +16,22 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; namespace { class UnpackMachineBundles : public MachineFunctionPass { public: static char ID; // Pass identification - UnpackMachineBundles() : MachineFunctionPass(ID) { + UnpackMachineBundles(std::function Ftor = nullptr) + : MachineFunctionPass(ID), PredicateFtor(Ftor) { initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry()); } - virtual bool runOnMachineFunction(MachineFunction &MF); + bool runOnMachineFunction(MachineFunction &MF) override; + + private: + std::function PredicateFtor; }; } // end anonymous namespace @@ -36,6 +41,9 @@ INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles", "Unpack machine instruction bundles", false, false) bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { + if (PredicateFtor && !PredicateFtor(*MF.getFunction())) + return false; + bool Changed = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock *MBB = &*I; @@ -47,8 +55,8 @@ bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { // Remove BUNDLE instruction and the InsideBundle flags from bundled // instructions. if (MI->isBundle()) { - while (++MII != MIE && MII->isInsideBundle()) { - MII->setIsInsideBundle(false); + while (++MII != MIE && MII->isBundledWithPred()) { + MII->unbundleFromPred(); for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) { MachineOperand &MO = MII->getOperand(i); if (MO.isReg() && MO.isInternalRead()) @@ -68,6 +76,10 @@ bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { return Changed; } +FunctionPass * +llvm::createUnpackMachineBundles(std::function Ftor) { + return new UnpackMachineBundles(Ftor); +} namespace { class FinalizeMachineBundles : public MachineFunctionPass { @@ -77,7 +89,7 @@ namespace { initializeFinalizeMachineBundlesPass(*PassRegistry::getPassRegistry()); } - virtual bool runOnMachineFunction(MachineFunction &MF); + bool runOnMachineFunction(MachineFunction &MF) override; }; } // end anonymous namespace @@ -101,13 +113,15 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI) { assert(FirstMI != LastMI && "Empty bundle?"); + MIBundleBuilder Bundle(MBB, FirstMI, LastMI); - const TargetMachine &TM = MBB.getParent()->getTarget(); - const TargetInstrInfo *TII = TM.getInstrInfo(); - const TargetRegisterInfo *TRI = TM.getRegisterInfo(); + MachineFunction &MF = *MBB.getParent(); + const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); + const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); - MachineInstrBuilder MIB = BuildMI(MBB, FirstMI, FirstMI->getDebugLoc(), - TII->get(TargetOpcode::BUNDLE)); + MachineInstrBuilder MIB = + BuildMI(MF, FirstMI->getDebugLoc(), TII->get(TargetOpcode::BUNDLE)); + Bundle.prepend(MIB); SmallVector LocalDefs; SmallSet LocalDefSet; @@ -138,7 +152,7 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB, // Internal def is now killed. KilledDefSet.insert(Reg); } else { - if (ExternUseSet.insert(Reg)) { + if (ExternUseSet.insert(Reg).second) { ExternUses.push_back(Reg); if (MO.isUndef()) UndefUseSet.insert(Reg); @@ -155,7 +169,7 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB, if (!Reg) continue; - if (LocalDefSet.insert(Reg)) { + if (LocalDefSet.insert(Reg).second) { LocalDefs.push_back(Reg); if (MO.isDead()) { DeadDefSet.insert(Reg); @@ -171,20 +185,19 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB, if (!MO.isDead()) { for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) { unsigned SubReg = *SubRegs; - if (LocalDefSet.insert(SubReg)) + if (LocalDefSet.insert(SubReg).second) LocalDefs.push_back(SubReg); } } } - FirstMI->setIsInsideBundle(); Defs.clear(); } SmallSet Added; for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { unsigned Reg = LocalDefs[i]; - if (Added.insert(Reg)) { + if (Added.insert(Reg).second) { // If it's not live beyond end of the bundle, mark it dead. bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg); MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) | @@ -210,7 +223,7 @@ MachineBasicBlock::instr_iterator llvm::finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI) { MachineBasicBlock::instr_iterator E = MBB.instr_end(); - MachineBasicBlock::instr_iterator LastMI = llvm::next(FirstMI); + MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI); while (LastMI != E && LastMI->isInsideBundle()) ++LastMI; finalizeBundle(MBB, FirstMI, LastMI); @@ -223,19 +236,18 @@ bool llvm::finalizeBundles(MachineFunction &MF) { bool Changed = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock &MBB = *I; - MachineBasicBlock::instr_iterator MII = MBB.instr_begin(); - assert(!MII->isInsideBundle() && - "First instr cannot be inside bundle before finalization!"); - MachineBasicBlock::instr_iterator MIE = MBB.instr_end(); if (MII == MIE) continue; + assert(!MII->isInsideBundle() && + "First instr cannot be inside bundle before finalization!"); + for (++MII; MII != MIE; ) { if (!MII->isInsideBundle()) ++MII; else { - MII = finalizeBundle(MBB, llvm::prior(MII)); + MII = finalizeBundle(MBB, std::prev(MII)); Changed = true; } } @@ -281,15 +293,17 @@ MachineOperandIteratorBase::PhysRegInfo MachineOperandIteratorBase::analyzePhysReg(unsigned Reg, const TargetRegisterInfo *TRI) { bool AllDefsDead = true; - PhysRegInfo PRI = {false, false, false, false, false, false}; + PhysRegInfo PRI = {false, false, false, false, false, false, false}; assert(TargetRegisterInfo::isPhysicalRegister(Reg) && "analyzePhysReg not given a physical register!"); for (; isValid(); ++*this) { MachineOperand &MO = deref(); - if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) - PRI.Clobbers = true; // Regmask clobbers Reg. + if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) { + PRI.Clobbered = true; + continue; + } if (!MO.isReg()) continue; @@ -298,33 +312,28 @@ MachineOperandIteratorBase::analyzePhysReg(unsigned Reg, if (!MOReg || !TargetRegisterInfo::isPhysicalRegister(MOReg)) continue; - bool IsRegOrSuperReg = MOReg == Reg || TRI->isSubRegister(MOReg, Reg); - bool IsRegOrOverlapping = MOReg == Reg || TRI->regsOverlap(MOReg, Reg); - - if (IsRegOrSuperReg && MO.readsReg()) { - // Reg or a super-reg is read, and perhaps killed also. - PRI.Reads = true; - PRI.Kills = MO.isKill(); - } - - if (IsRegOrOverlapping && MO.readsReg()) { - PRI.ReadsOverlap = true;// Reg or an overlapping register is read. - } - - if (!MO.isDef()) + if (!TRI->regsOverlap(MOReg, Reg)) continue; - if (IsRegOrSuperReg) { - PRI.Defines = true; // Reg or a super-register is defined. + bool Covered = TRI->isSuperRegisterEq(Reg, MOReg); + if (MO.readsReg()) { + PRI.Read = true; + if (Covered) { + PRI.FullyRead = true; + if (MO.isKill()) + PRI.Killed = true; + } + } else if (MO.isDef()) { + PRI.Defined = true; + if (Covered) + PRI.FullyDefined = true; if (!MO.isDead()) AllDefsDead = false; } - if (IsRegOrOverlapping) - PRI.Clobbers = true; // Reg or an overlapping reg is defined. } - if (AllDefsDead && PRI.Defines) - PRI.DefinesDead = true; // Reg or super-register was defined and was dead. + if (AllDefsDead && PRI.FullyDefined) + PRI.DeadDef = true; return PRI; }