123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- //===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/CodeGen/MachineInstrBundle.h"
- #include "llvm/ADT/SmallSet.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/CodeGen/MachineFunctionPass.h"
- #include "llvm/CodeGen/MachineInstrBuilder.h"
- #include "llvm/CodeGen/Passes.h"
- #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(std::function<bool(const Function &)> Ftor = nullptr)
- : MachineFunctionPass(ID), PredicateFtor(Ftor) {
- initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());
- }
- bool runOnMachineFunction(MachineFunction &MF) override;
- private:
- std::function<bool(const Function &)> PredicateFtor;
- };
- } // end anonymous namespace
- char UnpackMachineBundles::ID = 0;
- char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID;
- 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;
- for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(),
- MIE = MBB->instr_end(); MII != MIE; ) {
- MachineInstr *MI = &*MII;
- // Remove BUNDLE instruction and the InsideBundle flags from bundled
- // instructions.
- if (MI->isBundle()) {
- 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())
- MO.setIsInternalRead(false);
- }
- }
- MI->eraseFromParent();
- Changed = true;
- continue;
- }
- ++MII;
- }
- }
- return Changed;
- }
- FunctionPass *
- llvm::createUnpackMachineBundles(std::function<bool(const Function &)> Ftor) {
- return new UnpackMachineBundles(Ftor);
- }
- namespace {
- class FinalizeMachineBundles : public MachineFunctionPass {
- public:
- static char ID; // Pass identification
- FinalizeMachineBundles() : MachineFunctionPass(ID) {
- initializeFinalizeMachineBundlesPass(*PassRegistry::getPassRegistry());
- }
- bool runOnMachineFunction(MachineFunction &MF) override;
- };
- } // end anonymous namespace
- char FinalizeMachineBundles::ID = 0;
- char &llvm::FinalizeMachineBundlesID = FinalizeMachineBundles::ID;
- INITIALIZE_PASS(FinalizeMachineBundles, "finalize-mi-bundles",
- "Finalize machine instruction bundles", false, false)
- bool FinalizeMachineBundles::runOnMachineFunction(MachineFunction &MF) {
- return llvm::finalizeBundles(MF);
- }
- /// finalizeBundle - Finalize a machine instruction bundle which includes
- /// a sequence of instructions starting from FirstMI to LastMI (exclusive).
- /// This routine adds a BUNDLE instruction to represent the bundle, it adds
- /// IsInternalRead markers to MachineOperands which are defined inside the
- /// bundle, and it copies externally visible defs and uses to the BUNDLE
- /// instruction.
- void llvm::finalizeBundle(MachineBasicBlock &MBB,
- MachineBasicBlock::instr_iterator FirstMI,
- MachineBasicBlock::instr_iterator LastMI) {
- assert(FirstMI != LastMI && "Empty bundle?");
- MIBundleBuilder Bundle(MBB, FirstMI, LastMI);
- MachineFunction &MF = *MBB.getParent();
- const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
- const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
- MachineInstrBuilder MIB =
- BuildMI(MF, FirstMI->getDebugLoc(), TII->get(TargetOpcode::BUNDLE));
- Bundle.prepend(MIB);
- SmallVector<unsigned, 32> LocalDefs;
- SmallSet<unsigned, 32> LocalDefSet;
- SmallSet<unsigned, 8> DeadDefSet;
- SmallSet<unsigned, 16> KilledDefSet;
- SmallVector<unsigned, 8> ExternUses;
- SmallSet<unsigned, 8> ExternUseSet;
- SmallSet<unsigned, 8> KilledUseSet;
- SmallSet<unsigned, 8> UndefUseSet;
- SmallVector<MachineOperand*, 4> Defs;
- for (; FirstMI != LastMI; ++FirstMI) {
- for (unsigned i = 0, e = FirstMI->getNumOperands(); i != e; ++i) {
- MachineOperand &MO = FirstMI->getOperand(i);
- if (!MO.isReg())
- continue;
- if (MO.isDef()) {
- Defs.push_back(&MO);
- continue;
- }
- unsigned Reg = MO.getReg();
- if (!Reg)
- continue;
- assert(TargetRegisterInfo::isPhysicalRegister(Reg));
- if (LocalDefSet.count(Reg)) {
- MO.setIsInternalRead();
- if (MO.isKill())
- // Internal def is now killed.
- KilledDefSet.insert(Reg);
- } else {
- if (ExternUseSet.insert(Reg).second) {
- ExternUses.push_back(Reg);
- if (MO.isUndef())
- UndefUseSet.insert(Reg);
- }
- if (MO.isKill())
- // External def is now killed.
- KilledUseSet.insert(Reg);
- }
- }
- for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
- MachineOperand &MO = *Defs[i];
- unsigned Reg = MO.getReg();
- if (!Reg)
- continue;
- if (LocalDefSet.insert(Reg).second) {
- LocalDefs.push_back(Reg);
- if (MO.isDead()) {
- DeadDefSet.insert(Reg);
- }
- } else {
- // Re-defined inside the bundle, it's no longer killed.
- KilledDefSet.erase(Reg);
- if (!MO.isDead())
- // Previously defined but dead.
- DeadDefSet.erase(Reg);
- }
- if (!MO.isDead()) {
- for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
- unsigned SubReg = *SubRegs;
- if (LocalDefSet.insert(SubReg).second)
- LocalDefs.push_back(SubReg);
- }
- }
- }
- Defs.clear();
- }
- SmallSet<unsigned, 32> Added;
- for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
- unsigned Reg = LocalDefs[i];
- 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) |
- getImplRegState(true));
- }
- }
- for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) {
- unsigned Reg = ExternUses[i];
- bool isKill = KilledUseSet.count(Reg);
- bool isUndef = UndefUseSet.count(Reg);
- MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |
- getImplRegState(true));
- }
- }
- /// finalizeBundle - Same functionality as the previous finalizeBundle except
- /// the last instruction in the bundle is not provided as an input. This is
- /// used in cases where bundles are pre-determined by marking instructions
- /// with 'InsideBundle' marker. It returns the MBB instruction iterator that
- /// points to the end of the bundle.
- MachineBasicBlock::instr_iterator
- llvm::finalizeBundle(MachineBasicBlock &MBB,
- MachineBasicBlock::instr_iterator FirstMI) {
- MachineBasicBlock::instr_iterator E = MBB.instr_end();
- MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI);
- while (LastMI != E && LastMI->isInsideBundle())
- ++LastMI;
- finalizeBundle(MBB, FirstMI, LastMI);
- return LastMI;
- }
- /// finalizeBundles - Finalize instruction bundles in the specified
- /// MachineFunction. Return true if any bundles are finalized.
- 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();
- 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, std::prev(MII));
- Changed = true;
- }
- }
- }
- return Changed;
- }
- //===----------------------------------------------------------------------===//
- // MachineOperand iterator
- //===----------------------------------------------------------------------===//
- MachineOperandIteratorBase::VirtRegInfo
- MachineOperandIteratorBase::analyzeVirtReg(unsigned Reg,
- SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops) {
- VirtRegInfo RI = { false, false, false };
- for(; isValid(); ++*this) {
- MachineOperand &MO = deref();
- if (!MO.isReg() || MO.getReg() != Reg)
- continue;
- // Remember each (MI, OpNo) that refers to Reg.
- if (Ops)
- Ops->push_back(std::make_pair(MO.getParent(), getOperandNo()));
- // Both defs and uses can read virtual registers.
- if (MO.readsReg()) {
- RI.Reads = true;
- if (MO.isDef())
- RI.Tied = true;
- }
- // Only defs can write.
- if (MO.isDef())
- RI.Writes = true;
- else if (!RI.Tied && MO.getParent()->isRegTiedToDefOperand(getOperandNo()))
- RI.Tied = true;
- }
- return RI;
- }
- MachineOperandIteratorBase::PhysRegInfo
- MachineOperandIteratorBase::analyzePhysReg(unsigned Reg,
- const TargetRegisterInfo *TRI) {
- bool AllDefsDead = true;
- PhysRegInfo PRI = {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.isReg())
- continue;
- unsigned MOReg = MO.getReg();
- 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())
- continue;
- if (IsRegOrSuperReg) {
- PRI.Defines = true; // Reg or a super-register is defined.
- 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.
- return PRI;
- }
|