| //===----------------- HexagonLiveVariables.cpp ---------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // Hexagon Live Variable Analysis | |
| // This file implements the Hexagon specific LiveVariables analysis pass. | |
| // This pass recomputes physical register liveness and updates live-ins for | |
| // non-entry blocks based on use/def information. | |
| //===----------------------------------------------------------------------===// | |
| #define DEBUG_TYPE "hexagon_live_vars" | |
| #include "HexagonLiveVariables.h" | |
| #include "HexagonTargetMachine.h" | |
| #include "llvm/CodeGen/MachineDominators.h" | |
| #include "llvm/CodeGen/MachinePostDominators.h" | |
| #include "llvm/CodeGen/MachineRegisterInfo.h" | |
| #include "llvm/CodeGen/Passes.h" | |
| #include "llvm/InitializePasses.h" | |
| #include "llvm/Support/Debug.h" | |
| #include "llvm/Support/ErrorHandling.h" | |
| using namespace llvm; | |
| char HexagonLiveVariables::ID = 0; | |
| char &llvm::HexagonLiveVariablesID = HexagonLiveVariables::ID; | |
| INITIALIZE_PASS(HexagonLiveVariables, "hexagon-live-vars", | |
| "Hexagon Live Variable Analysis", false, false) | |
| // TODO: Establish a protocol to handle liveness of predicated instructions. | |
| // Liveness for predicated instruction is a little convoluted. | |
| // TODO: In PhysRegDef and PhysRegUse, use a bit vector instead of 126 elems. | |
| class HexagonLiveVariablesImpl { | |
| // Intermediate data structures | |
| friend class llvm::HexagonLiveVariables; | |
| typedef MachineBasicBlock::const_instr_iterator MICInstIterType; | |
| MachineFunction *MF; | |
| MachineRegisterInfo *MRI; | |
| const TargetRegisterInfo *TRI; | |
| const HexagonInstrInfo *QII; | |
| unsigned NumRegs; | |
| /// PhysRegInfo - Keep track of which instruction was the last def of a | |
| /// physical register (possibly after a use). This is purely local to a BB. | |
| SmallVector<MachineInstr *, 0> PhysRegDef; | |
| /// PhysRegInfo - Keep track of which instruction was the last use of a | |
| /// physical register (before any def). This is purely local property to a BB. | |
| SmallVector<MachineInstr *, 0> PhysRegUse; | |
| /// MBB -> (Uses, Defs) | |
| /// Uses - use before any def in that MBB. | |
| /// Defs - def before any uses in that MBB. | |
| MBBUseDef_t MBBUseDefs; | |
| /// MI -> (Uses, Defs) | |
| MIUseDef_t MIUseDefs; | |
| /// Live-out data for each MBB => U LiveIns (For all Successors of a MBB). | |
| DenseMap<const MachineBasicBlock *, BitVector> MBBLiveOuts; | |
| /// Each MachineBasicBlock is assigned a Distance which is | |
| /// an approximation of MBB->size()*INSTR_SIZE+Some offsets. | |
| /// This is helpful in quickly finding distance between | |
| /// a branch and its target. | |
| /// @note A pass which moves instructions should update this. | |
| /// @note The data in distance map should be used carefully because | |
| /// difference in the distances of two MI might not give relative distances | |
| /// between them. The DistanceMap is mainly useful during pullup. | |
| DenseMap<const MachineBasicBlock *, unsigned> DistanceMap; | |
| // Blocks in depth first order | |
| SmallVector<MachineBasicBlock *, 16> BlocksDepthFirst; | |
| /// @brief Constructs use-defs of \p MBB by analyzing each MachineOperand. | |
| /// Collects relevant information so that global liveness can be updated. | |
| void constructUseDef(MachineBasicBlock *MBB); | |
| /// Collects used-before-define set of registers. | |
| /// A register is considered to be completely defined if | |
| /// 1. The register | |
| /// 2. Any of its super-reg | |
| /// 3. All of its subregs | |
| /// are defined. In these cases the register is not considered as | |
| /// used-before-defined. In case of partial definition of a register | |
| /// before its use, only the remaining subregs are included in the use-set. | |
| /// @note: Assumes that a register can be completely defined, by defining | |
| /// all of its sub-regs (if any). | |
| void handlePhysRegUse(MachineOperand *MO, MachineInstr *MI, BitVector &Uses); | |
| /// Collects defined-before-use set of registers. If there is any | |
| /// use of register or its aliases then the register is not counted | |
| /// as defined-before-use | |
| /// @note: Assumes that a register can be completely defined, by defining | |
| /// all of its sub-regs (if any). | |
| void handlePhysRegDef(MachineOperand *MO, MachineInstr *MI, BitVector &Defs); | |
| /// updateGlobalLiveness - wrapper around another overload | |
| inline bool updateGlobalLiveness(MachineFunction &Fn); | |
| bool updateGlobalLiveness(MachineBasicBlock *X, MachineBasicBlock *Y); | |
| /// updateGlobalLiveness - updates liveness based on | |
| /// livein and liveout entries. | |
| bool updateGlobalLiveness(MachineBasicBlock *MBB, BitVector &Defs, | |
| BitVector &LiveIns); | |
| /// update live-ins when live-out has been calculated | |
| bool updateLiveIns(MachineBasicBlock *MBB, BitVector &LiveIns, | |
| const BitVector &LiveOuts); | |
| bool updateLiveOuts(MachineBasicBlock *MBB, BitVector &LiveOuts); | |
| /// updateLocalLiveness - update only kill flags of operands. | |
| inline bool updateLocalLiveness(MachineFunction &Fn); | |
| /// updateLocalLiveness - update only kill flags of operands. | |
| bool updateLocalLiveness(MachineBasicBlock *MBB, bool UpdateBundle); | |
| /// incrementalUpdate - update the liveness when \p MIDelta is moved from | |
| /// \p From to \p To. | |
| /// @note: This is extremely fragile now. It 'assumes' that the other | |
| /// successor(s) of \p To do not use Defs of MIDelta. | |
| /// It deletes the live-in of the \p From MBB. | |
| bool incrementalUpdate(MICInstIterType MIDelta, MachineBasicBlock *From, | |
| MachineBasicBlock *To); | |
| /// addNewMBB - inform the LiveVariable Analysis that new MBB has been added. | |
| /// update the liveness of this new MBB. | |
| /// @note MBB should be empty. If we want to add an MI, add it after calling | |
| /// this function. | |
| void addNewMBB(MachineBasicBlock *MBB); | |
| void addNewMI(MachineInstr *MI, MachineBasicBlock *MBB); | |
| unsigned getNumRegs() const { return NumRegs; } | |
| // Useful for clearing out after passes which move instructions around. | |
| // e.g. GlobalScheduler. | |
| void clearDistanceMap() { DistanceMap.clear(); } | |
| /// Computes \p DistanceMap. | |
| void generateDistanceMap(const MachineFunction &Fn); | |
| public: | |
| bool runOnMachineFunction(MachineFunction &Fn, MachineDominatorTree &MDT, | |
| MachinePostDominatorTree &MPDT); | |
| }; | |
| //===----------------------------------------------------------------------===// | |
| // HexagonLiveVariables Functions | |
| //===----------------------------------------------------------------------===// | |
| HexagonLiveVariables::HexagonLiveVariables() | |
| : MachineFunctionPass(ID), HLVComplete(false), | |
| HLV(std::make_unique<HexagonLiveVariablesImpl>()) { | |
| initializeHexagonLiveVariablesPass(*PassRegistry::getPassRegistry()); | |
| } | |
| void HexagonLiveVariables::getAnalysisUsage(AnalysisUsage &AU) const { | |
| AU.setPreservesCFG(); | |
| AU.addRequired<MachineDominatorTreeWrapperPass>(); | |
| AU.addRequired<MachinePostDominatorTreeWrapperPass>(); | |
| AU.addPreserved("packets"); | |
| MachineFunctionPass::getAnalysisUsage(AU); | |
| } | |
| void HexagonLiveVariables::recalculate(MachineFunction &MF) { | |
| if (HLVComplete) | |
| return; | |
| auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); | |
| auto &MPDT = | |
| getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree(); | |
| HLV->runOnMachineFunction(MF, MDT, MPDT); | |
| } | |
| bool HexagonLiveVariables::updateLocalLiveness(MachineFunction &Fn) { | |
| return HLV->updateLocalLiveness(Fn); | |
| } | |
| bool HexagonLiveVariables::updateLocalLiveness(MachineBasicBlock *MBB, | |
| bool updateBundle) { | |
| HLV->constructUseDef(MBB); // XXX: This destroys MBBLiveOuts! | |
| return HLV->updateLocalLiveness(MBB, updateBundle); | |
| } | |
| bool HexagonLiveVariables::incrementalUpdate(MICInstIterType MIDelta, | |
| MachineBasicBlock *From, | |
| MachineBasicBlock *To) { | |
| assert(MIDelta->getParent() == To); | |
| assert(From != To); | |
| return HLV->incrementalUpdate(MIDelta, From, To); | |
| } | |
| void HexagonLiveVariables::addNewMBB(MachineBasicBlock *MBB) { | |
| assert(MBB->empty()); | |
| HLV->addNewMBB(MBB); | |
| } | |
| void HexagonLiveVariables::addNewMI(MachineInstr *MI, MachineBasicBlock *MBB) { | |
| HLV->addNewMI(MI, MBB); | |
| } | |
| void HexagonLiveVariables::constructUseDef(MachineBasicBlock *MBB) { | |
| HLV->constructUseDef(MBB); | |
| } | |
| bool HexagonLiveVariables::runOnMachineFunction(MachineFunction &Fn) { | |
| auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); | |
| auto &MPDT = | |
| getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree(); | |
| HLVComplete = !HLV->runOnMachineFunction(Fn, MDT, MPDT); | |
| return HLVComplete; | |
| } | |
| bool HexagonLiveVariables::isLiveOut(const MachineBasicBlock *MBB, | |
| unsigned Reg) const { | |
| assert(HLVComplete && "Liveness Analysis not available"); | |
| auto It = HLV->MBBLiveOuts.find(MBB); | |
| if (It == HLV->MBBLiveOuts.end()) | |
| llvm_unreachable("MBB not found in liveness map"); | |
| if (Reg >= It->second.size()) | |
| llvm_unreachable("Register index out of bounds"); | |
| return It->second[Reg]; | |
| } | |
| const BitVector & | |
| HexagonLiveVariables::getLiveOuts(const MachineBasicBlock *MBB) const { | |
| assert(HLVComplete && "Liveness Analysis not available"); | |
| auto It = HLV->MBBLiveOuts.find(MBB); | |
| if (It == HLV->MBBLiveOuts.end()) | |
| llvm_unreachable("MBB not found in liveness map"); | |
| return It->second; | |
| } | |
| // Returns true when \p Reg is used within [MIBegin, MIEnd) | |
| // @note: MIBegin and MIEnd should be from same MBB | |
| // @note: It returns just the first use found in the range. | |
| // The Use is closest to MIEnd. | |
| // Takes care of aliases and predicated defs as well. | |
| bool HexagonLiveVariables::isUsedWithin( | |
| MICInstIterType MIBegin, MICInstIterType MIEnd, unsigned Reg, | |
| MICInstIterType &Use, | |
| SmallPtrSet<MachineInstr *, 2> *ExceptionsList) const { | |
| assert(HLVComplete && "Liveness Analysis not available"); | |
| Use = MIEnd; | |
| if (MIBegin == MIEnd) // NULL Range. | |
| return false; | |
| MICInstIterType MII = MIEnd; | |
| do { | |
| --MII; | |
| if (MII->isBundle() || MII->isDebugInstr()) | |
| continue; | |
| if (ExceptionsList && ExceptionsList->contains(&*MII)) | |
| continue; | |
| auto It = HLV->MIUseDefs.find(&*MII); | |
| assert(It != HLV->MIUseDefs.end()); | |
| for (MCRegAliasIterator AI(Reg, HLV->TRI, true); AI.isValid(); ++AI) | |
| if (It->second.first[*AI]) { | |
| Use = MII; | |
| return true; | |
| } | |
| } while (MII != MIBegin); | |
| return false; | |
| } | |
| // Returns true when \p Reg id defined within [MIBegin, MIEnd) | |
| // @note: MIBegin and MIEnd should be from same MBB | |
| // The Def is closest to MIEnd. | |
| // Takes care of aliases and predicated defs as well. | |
| bool HexagonLiveVariables::isDefinedWithin(MICInstIterType MIBegin, | |
| MICInstIterType MIEnd, unsigned Reg, | |
| MICInstIterType &Def) const { | |
| assert(HLVComplete && "Liveness Analysis not available"); | |
| Def = MIEnd; | |
| if (MIBegin == MIEnd) // NULL Range. | |
| return false; | |
| MICInstIterType MII = MIEnd; | |
| do { | |
| --MII; | |
| if (MII->isBundle() || MII->isDebugInstr()) | |
| continue; | |
| auto It = HLV->MIUseDefs.find(&*MII); | |
| assert(It != HLV->MIUseDefs.end()); | |
| for (MCRegAliasIterator AI(Reg, HLV->TRI, true); AI.isValid(); ++AI) | |
| if (It->second.second[*AI]) { | |
| Def = MII; | |
| return true; | |
| } | |
| } while (MII != MIBegin); | |
| return false; | |
| } | |
| // Returns true if any of the defs of MII is live-in in the MBB. | |
| bool HexagonLiveVariables::isDefLiveIn(const MachineInstr *MI, | |
| const MachineBasicBlock *MBB) const { | |
| assert(HLVComplete && "Liveness Analysis not available"); | |
| assert(MI && "Invalid machine instruction"); | |
| assert(MBB && "Invalid machine basic block"); | |
| auto It = HLV->MIUseDefs.find(MI); | |
| assert(It != HLV->MIUseDefs.end() && "Missing MI use/def information"); | |
| BitVector MBBLiveIns(HLV->NumRegs); | |
| for (MachineBasicBlock::livein_iterator lit = MBB->livein_begin(); | |
| lit != MBB->livein_end(); ++lit) { | |
| // Include all the aliases of reg *lit. | |
| for (MCRegAliasIterator AI((*lit).PhysReg, HLV->TRI, true); AI.isValid(); | |
| ++AI) | |
| MBBLiveIns.set(*AI); | |
| } | |
| // Intersect. | |
| return MBBLiveIns.anyCommon(It->second.second); | |
| } | |
| MBBUseDef_t &HexagonLiveVariables::getMBBUseDefs() { return HLV->MBBUseDefs; } | |
| MIUseDef_t &HexagonLiveVariables::getMIUseDefs() { return HLV->MIUseDefs; } | |
| unsigned HexagonLiveVariables::getDistanceBetween(const MachineBasicBlock *From, | |
| const MachineBasicBlock *To, | |
| unsigned BufferPerMBB) const { | |
| assert(HLV->DistanceMap.find(From) != HLV->DistanceMap.end()); | |
| assert(HLV->DistanceMap.find(To) != HLV->DistanceMap.end()); | |
| unsigned FromSize = HLV->DistanceMap[From]; | |
| if (From == To) | |
| return FromSize; | |
| const MachineFunction *MF = From->getParent(); | |
| MachineFunction::const_iterator MBBI = MF->begin(); | |
| unsigned S = BufferPerMBB; | |
| bool ToFirst = false; | |
| while (MBBI != MF->end()) { | |
| const MachineBasicBlock *MBB = &*MBBI; | |
| if (MBB == From) | |
| break; | |
| else if (MBB == To) { | |
| ToFirst = true; | |
| break; | |
| } | |
| ++MBBI; | |
| } | |
| const MachineBasicBlock *ToFind = To; | |
| if (ToFirst) | |
| ToFind = From; | |
| while (MBBI != MF->end()) { | |
| const MachineBasicBlock *MBB = &*MBBI; | |
| if (MBB == ToFind) | |
| break; | |
| S += HLV->DistanceMap[MBB] + BufferPerMBB; | |
| ++MBBI; | |
| } | |
| if (ToFirst) // Jump in the opposite direction. | |
| S += FromSize + HLV->DistanceMap[To] + 2 * BufferPerMBB; | |
| return S; | |
| } | |
| void HexagonLiveVariables::regenerateDistanceMap(const MachineFunction &Fn) { | |
| HLV->clearDistanceMap(); | |
| HLV->generateDistanceMap(Fn); | |
| } | |
| //===----------------------------------------------------------------------===// | |
| // HexagonLiveVariablesImpl Functions | |
| //===----------------------------------------------------------------------===// | |
| bool HexagonLiveVariablesImpl::runOnMachineFunction( | |
| MachineFunction &Fn, MachineDominatorTree &MDT, | |
| MachinePostDominatorTree &MPDT) { | |
| LLVM_DEBUG(dbgs() << "\nHexagon Live Variables";); | |
| Fn.RenumberBlocks(); | |
| MF = &Fn; | |
| MRI = &Fn.getRegInfo(); | |
| auto &ST = Fn.getSubtarget<HexagonSubtarget>(); | |
| TRI = ST.getRegisterInfo(); | |
| QII = ST.getInstrInfo(); | |
| NumRegs = TRI->getNumRegs(); | |
| MBBUseDefs.clear(); | |
| MIUseDefs.clear(); | |
| MBBLiveOuts.clear(); | |
| LLVM_DEBUG(dbgs() << "\nNumber of registers in Hexagon is:" << NumRegs); | |
| PhysRegDef.resize(NumRegs); | |
| PhysRegUse.resize(NumRegs); | |
| for (MachineFunction::iterator MBBI = Fn.begin(), E = Fn.end(); MBBI != E; | |
| ++MBBI) { | |
| constructUseDef(&*MBBI); | |
| } | |
| updateGlobalLiveness(Fn); | |
| return false; | |
| } | |
| void HexagonLiveVariablesImpl::constructUseDef(MachineBasicBlock *MBB) { | |
| std::fill(PhysRegDef.begin(), PhysRegDef.end(), (MachineInstr *)0); | |
| std::fill(PhysRegUse.begin(), PhysRegUse.end(), (MachineInstr *)0); | |
| // Loop over all of the instructions, processing them. | |
| std::pair<BitVector, BitVector> &UseDef = MBBUseDefs[MBB]; | |
| // Use before any def in a BB. | |
| BitVector &Uses = UseDef.first; | |
| // Defs before any use in a BB. | |
| BitVector &Defs = UseDef.second; | |
| // Initializing the LiveOut bit vector. | |
| BitVector &LiveOuts = MBBLiveOuts[MBB]; | |
| Uses.resize(NumRegs, false); | |
| Defs.resize(NumRegs, false); | |
| LiveOuts.resize(NumRegs, false); | |
| // BitVector might contain set bits out of previous liveness updates. | |
| Uses.reset(); | |
| Defs.reset(); | |
| LiveOuts.reset(); | |
| LLVM_DEBUG(dbgs() << "\nBB#" << MBB->getNumber();); | |
| // MBB Number in the MSB 32 bits. | |
| unsigned MBBInsSize = 0; | |
| for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(), | |
| E = MBB->instr_end(); | |
| MII != E; ++MII) { | |
| MachineInstr *MI = &*MII; | |
| MBBInsSize += QII->getSize(*MI); | |
| // TODO: Handle isDebugInstr | |
| if (MI->isBundle() || MI->isDebugInstr()) | |
| continue; | |
| LLVM_DEBUG(dbgs() << "\n\n" << *MI;); | |
| // Clear kill and dead markers. LV will recompute them. | |
| UseDef_t &MIUseDef = MIUseDefs[MI]; | |
| MIUseDef.first.resize(NumRegs); // Uses | |
| MIUseDef.second.resize(NumRegs); // Defs | |
| MIUseDef.first.reset(); // Uses | |
| MIUseDef.second.reset(); // Defs | |
| SmallVector<MachineOperand *, 4> UseRegs; | |
| SmallVector<MachineOperand *, 4> DefRegs; | |
| SmallVector<unsigned, 1> RegMasks; | |
| // Process all of the operands of the instruction... | |
| unsigned NumOperandsToProcess = MI->getNumOperands(); | |
| for (unsigned i = 0; i != NumOperandsToProcess; ++i) { | |
| MachineOperand &MO = MI->getOperand(i); | |
| if (MO.isRegMask()) { | |
| // Assuming that predicated defs are not defs, for now. | |
| if (!QII->isPredicated(*MI)) | |
| DefRegs.push_back(&MO); | |
| continue; | |
| } | |
| if (!MO.isReg() || MO.getReg() == 0) | |
| continue; | |
| unsigned Reg = MO.getReg(); | |
| if (MO.isUse()) { | |
| // Assuming that the kill-flags on call-instructions are correct. | |
| MO.setIsKill(false); | |
| UseRegs.push_back(&MO); | |
| MIUseDef.first.set(Reg); | |
| } else /*MO.isDef()*/ { | |
| assert(MO.isDef()); | |
| if (!QII->isPredicated(*MI) && !MI->isKill()) { | |
| // Assuming that predicated defs are not defs, for now. | |
| // KILL instructions are no-ops | |
| MO.setIsDead(false); | |
| DefRegs.push_back(&MO); | |
| } | |
| MIUseDef.second.set(Reg); // Set all defs (including predicated). | |
| } | |
| } | |
| // Process all uses. | |
| for (unsigned i = 0, e = UseRegs.size(); i != e; ++i) | |
| handlePhysRegUse(UseRegs[i], MI, Uses); | |
| // Process all defs. | |
| for (unsigned i = 0, e = DefRegs.size(); i != e; ++i) | |
| handlePhysRegDef(DefRegs[i], MI, Defs); | |
| } | |
| DistanceMap[MBB] = MBBInsSize; | |
| } | |
| void HexagonLiveVariablesImpl::handlePhysRegUse(MachineOperand *MO, | |
| MachineInstr *MI, | |
| BitVector &Uses) { | |
| unsigned Reg = MO->getReg(); | |
| LLVM_DEBUG(dbgs() << "\nLooking at:";); | |
| // If the reg/super-reg is already defined in this MBB => return. | |
| for (MCSuperRegIterator SupI(Reg, TRI, true); SupI.isValid(); ++SupI) { | |
| LLVM_DEBUG(dbgs() << printReg(*SupI, TRI);); | |
| if (PhysRegDef[*SupI]) | |
| return; | |
| } | |
| // Handle if sub-regs are defined. | |
| SmallVector<unsigned, 2> undefSubRegs; | |
| bool subRegDefined = false; | |
| for (MCSubRegIterator SubI(Reg, TRI); SubI.isValid(); ++SubI) { | |
| LLVM_DEBUG(dbgs() << printReg(*SubI, TRI);); | |
| if (PhysRegDef[*SubI]) | |
| subRegDefined = true; | |
| else | |
| undefSubRegs.push_back(*SubI); | |
| } | |
| LLVM_DEBUG(dbgs() << "\nUses:"); | |
| if (undefSubRegs.empty()) { | |
| if (!subRegDefined) { // None of the subregs are defined. | |
| // Include all subregs (including self) to the uses. | |
| for (MCSubRegIterator SubI(Reg, TRI, true); SubI.isValid(); ++SubI) { | |
| LLVM_DEBUG(dbgs() << printReg(*SubI, TRI)); | |
| PhysRegUse[*SubI] = MI; | |
| Uses.set(*SubI); | |
| } | |
| } // All subregs defined. | |
| return; | |
| } | |
| // Some subregs are defined. | |
| for (unsigned i = 0; i < undefSubRegs.size(); ++i) { | |
| LLVM_DEBUG(dbgs() << printReg(undefSubRegs[i], TRI)); | |
| PhysRegUse[undefSubRegs[i]] = MI; | |
| Uses.set(undefSubRegs[i]); | |
| } | |
| } | |
| // Assumes that an MI cannot have a reg and its super/sub reg as uses. | |
| void HexagonLiveVariablesImpl::handlePhysRegDef(MachineOperand *MO, | |
| MachineInstr *MI, | |
| BitVector &Defs) { | |
| auto SetRegDef = [&](unsigned Reg) -> void { | |
| PhysRegDef[Reg] = MI; | |
| for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { | |
| if (PhysRegUse[*AI]) { | |
| LLVM_DEBUG(dbgs() << "\nUsed in current BB:" << printReg(*AI, TRI)); | |
| return; | |
| } | |
| } | |
| LLVM_DEBUG(dbgs() << "\nDefs:" << printReg(Reg, TRI)); | |
| Defs.set(Reg); | |
| }; | |
| if (MO->isReg()) { | |
| SetRegDef(MO->getReg()); | |
| } else if (MO->isRegMask()) { | |
| for (unsigned R = 1, NR = TRI->getNumRegs(); R != NR; ++R) | |
| if (MO->clobbersPhysReg(R)) | |
| SetRegDef(R); | |
| } | |
| } | |
| namespace { | |
| struct BlockState { | |
| bool SuccQueued : 1; | |
| bool Done : 1; | |
| BlockState() : SuccQueued(false), Done(false) {} | |
| }; | |
| } // namespace | |
| // Populates 'Blocks' with basic blocks of 'Fn' in depth-first order | |
| static void gatherBlocksDF(MachineFunction &Fn, | |
| SmallVectorImpl<MachineBasicBlock *> *Blocks) { | |
| Blocks->clear(); | |
| Blocks->reserve(Fn.size()); | |
| SmallVector<BlockState, 16> State(Fn.size()); | |
| SmallVector<MachineBasicBlock *, 16> WorkStack; | |
| WorkStack.push_back(&Fn.front()); | |
| while (!WorkStack.empty()) { | |
| MachineBasicBlock *W = WorkStack.back(); | |
| BlockState &WState = State[W->getNumber()]; | |
| if (WState.Done) { | |
| WorkStack.pop_back(); | |
| continue; | |
| } | |
| if (W->succ_empty() || WState.SuccQueued) { | |
| WorkStack.pop_back(); | |
| Blocks->push_back(W); | |
| WState.SuccQueued = true; | |
| WState.Done = true; | |
| continue; | |
| } | |
| WState.SuccQueued = true; | |
| for (MachineBasicBlock::succ_iterator I = W->succ_begin(), | |
| E = W->succ_end(); | |
| I != E; ++I) { | |
| MachineBasicBlock *S = *I; | |
| if (State[S->getNumber()].SuccQueued) | |
| continue; | |
| WorkStack.push_back(S); | |
| } | |
| } | |
| LLVM_DEBUG( | |
| dbgs() << "gatherBlocksDF: {"; | |
| for (SmallVectorImpl<MachineBasicBlock *>::iterator B = Blocks->begin(), | |
| BE = Blocks->end(); | |
| B != BE; ++B) { dbgs() << " BB#" << (*B)->getNumber(); } dbgs() | |
| << " }\n";); | |
| } | |
| bool HexagonLiveVariablesImpl::updateGlobalLiveness(MachineFunction &Fn) { | |
| bool Changed = false; | |
| // Removing live-ins and recomputing. | |
| MachineFunction::iterator I = Fn.begin(), E = Fn.end(); | |
| // Not touching the live-ins of entry basic block. | |
| for (++I; I != E; ++I) { | |
| std::vector<MachineBasicBlock::RegisterMaskPair> OldLiveIn( | |
| I->livein_begin(), I->livein_end()); | |
| for (unsigned i = 0; i < OldLiveIn.size(); ++i) | |
| I->removeLiveIn(OldLiveIn[i].PhysReg); | |
| } | |
| gatherBlocksDF(Fn, &BlocksDepthFirst); | |
| BitVector Defs; | |
| BitVector LiveIns; | |
| bool Repeat; | |
| do { | |
| Repeat = false; | |
| for (SmallVectorImpl<MachineBasicBlock *>::iterator | |
| B = BlocksDepthFirst.begin(), | |
| BE = BlocksDepthFirst.end(); | |
| B != BE; ++B) { | |
| Repeat |= updateGlobalLiveness(*B, Defs, LiveIns); | |
| } | |
| Changed |= Repeat; | |
| } while (Repeat); | |
| Changed |= updateLocalLiveness(Fn); | |
| return Changed; | |
| } | |
| bool HexagonLiveVariablesImpl::updateGlobalLiveness(MachineBasicBlock *X, | |
| MachineBasicBlock *Y) { | |
| assert(X && "Invalid start block"); | |
| assert(Y && "Invalid end block"); | |
| bool Changed = false; | |
| BitVector Defs; | |
| BitVector LiveIns; | |
| const SmallVectorImpl<MachineBasicBlock *>::iterator BE = | |
| BlocksDepthFirst.end(); | |
| SmallVectorImpl<MachineBasicBlock *>::iterator B; | |
| for (B = BlocksDepthFirst.begin(); (B != BE); ++B) { | |
| if (*B == X) | |
| break; | |
| if (*B == Y) | |
| break; | |
| } | |
| bool Repeat; | |
| do { | |
| Repeat = false; | |
| for (; B != BE; ++B) | |
| Repeat |= updateGlobalLiveness(*B, Defs, LiveIns); | |
| Changed |= Repeat; | |
| B = BlocksDepthFirst.begin(); | |
| } while (Repeat); | |
| return Changed; | |
| } | |
| // Defs and LiveIns could be local variables within updateGlobalLiveness, but | |
| // have been pulled out to (hopefully) improve performance. | |
| bool HexagonLiveVariablesImpl::updateGlobalLiveness(MachineBasicBlock *MBB, | |
| BitVector &Defs, | |
| BitVector &LiveIns) { | |
| LLVM_DEBUG(dbgs() << "\nTrying to Update Liveness MBB#" << MBB->getNumber()); | |
| bool Changed = false; | |
| LLVM_DEBUG(dbgs() << "\nUpdating Liveness MBB#" << MBB->getNumber()); | |
| // Update live-outs | |
| auto LiveOutIt = MBBLiveOuts.find(MBB); | |
| if (LiveOutIt == MBBLiveOuts.end()) | |
| LiveOutIt = MBBLiveOuts.insert({MBB, BitVector(NumRegs)}).first; | |
| BitVector &LiveOuts = LiveOutIt->second; | |
| for (MachineBasicBlock::succ_iterator MBBSucc = MBB->succ_begin(); | |
| MBBSucc != MBB->succ_end(); ++MBBSucc) { | |
| MachineBasicBlock *Succ = *MBBSucc; | |
| LLVM_DEBUG(dbgs() << "\n\t\tAdding LiveOut:";); | |
| for (MachineBasicBlock::livein_iterator LI = Succ->livein_begin(), | |
| LE = Succ->livein_end(); | |
| LI != LE; ++LI) { | |
| if (!LiveOuts[(*LI).PhysReg]) { | |
| LLVM_DEBUG(dbgs() << " " << printReg((*LI).PhysReg, TRI);); | |
| LiveOuts.set((*LI).PhysReg); | |
| Changed = true; | |
| } | |
| } | |
| } | |
| LLVM_DEBUG(dbgs() << "\nUpdated Successors of MBB#" << MBB->getNumber()); | |
| // Update live-ins | |
| Changed |= updateLiveIns(MBB, LiveIns, LiveOuts); | |
| return Changed; | |
| } | |
| // update live-ins when live-out has been calculated | |
| bool HexagonLiveVariablesImpl::updateLiveIns(MachineBasicBlock *MBB, | |
| BitVector &LiveIns, | |
| const BitVector &LiveOuts) { | |
| LLVM_DEBUG(dbgs() << "\n[updateLiveIns] MBB#" << MBB->getNumber()); | |
| bool Changed = false; | |
| const std::pair<BitVector, BitVector> &UseDefs = MBBUseDefs[MBB]; | |
| LiveIns = LiveOuts; | |
| // LiveIns = (LiveOuts - Defs) | Uses | |
| // Equivalent to: LiveIns = (LiveOuts & ~Defs) | Uses | |
| LiveIns.reset(UseDefs.second); | |
| LiveIns |= UseDefs.first; | |
| LLVM_DEBUG(dbgs() << "\n\t\tAdded LiveIn:";); | |
| for (int i = LiveIns.find_first(); i >= 0; i = LiveIns.find_next(i)) { | |
| // TODO: remove costly check of MBB->isLiveIn when fully functional. | |
| if (!MBB->isLiveIn(i) && MRI->isAllocatable(i)) { | |
| LLVM_DEBUG(dbgs() << " " << printReg(i, TRI)); | |
| MBB->addLiveIn(i); | |
| Changed = true; | |
| } | |
| } | |
| return Changed; | |
| } | |
| bool HexagonLiveVariablesImpl::updateLiveOuts(MachineBasicBlock *MBB, | |
| BitVector &LiveOuts) { | |
| bool Changed = false; | |
| for (auto SI = MBB->succ_begin(), SE = MBB->succ_end(); SI != SE; ++SI) { | |
| MachineBasicBlock *SB = *SI; | |
| for (auto I = SB->livein_begin(), E = SB->livein_end(); I != E; ++I) { | |
| unsigned R = (*I).PhysReg; | |
| if (LiveOuts[R]) | |
| continue; | |
| LiveOuts.set(R); | |
| Changed = true; | |
| } | |
| } | |
| return Changed; | |
| } | |
| bool HexagonLiveVariablesImpl::updateLocalLiveness(MachineFunction &Fn) { | |
| LLVM_DEBUG(dbgs() << "\n[updateLocalLiveness]"); | |
| for (MachineFunction::iterator B = Fn.begin(), E = Fn.end(); B != E; ++B) | |
| updateLocalLiveness(&*B, false); | |
| return true; | |
| } | |
| bool HexagonLiveVariablesImpl::updateLocalLiveness(MachineBasicBlock *MBB, | |
| bool UpdateBundle) { | |
| assert(MBB && "Invalid basic block"); | |
| LLVM_DEBUG(dbgs() << "\n[updateLocalLiveness] MBB#" << MBB->getNumber()); | |
| BitVector &LiveOut = MBBLiveOuts[MBB]; | |
| updateLiveOuts(MBB, LiveOut); | |
| BitVector Used = LiveOut; | |
| SmallVector<MachineInstr *, 2> BundleHeads; | |
| // Bottom up traversal of MBB. | |
| for (MachineBasicBlock::reverse_instr_iterator MII = MBB->instr_rbegin(), | |
| MIREnd = MBB->instr_rend(); | |
| MII != MIREnd; ++MII) { | |
| MachineInstr *MI = &*MII; | |
| // The bundle liveness is updated differently. | |
| if (MI->isBundle()) { | |
| if (UpdateBundle) | |
| BundleHeads.push_back(MI); | |
| continue; | |
| } | |
| if (MI->isDebugInstr()) // DBG_VALUE may have invalid reg. | |
| continue; | |
| SmallVector<MachineOperand *, 4> UseRegs; | |
| SmallVector<MachineOperand *, 2> DefRegs; | |
| for (unsigned i = 0; i < MI->getNumOperands(); ++i) { | |
| MachineOperand &MO = MI->getOperand(i); | |
| if (MO.isReg()) { // DBG_VALUE may have invalid reg. | |
| if (MO.isUse()) | |
| UseRegs.push_back(&MO); | |
| else { // Def | |
| if (!QII->isPredicated(*MI) && !MI->isKill()) { | |
| // Assuming that predicated defs are not defs, for now. | |
| // KILL instructions are no-ops | |
| DefRegs.push_back(&MO); | |
| } | |
| } | |
| } else if (MO.isRegMask()) { | |
| if (!QII->isPredicated(*MI)) | |
| DefRegs.push_back(&MO); | |
| } | |
| } | |
| // In case of a def. remove Reg and its sub-regs from Used list | |
| // such that uses in the same MI can be marked as kill. | |
| auto RemoveDef = [&](unsigned Reg, bool Implicit) -> void { | |
| for (MCSubRegIterator SI(Reg, TRI, true); SI.isValid(); ++SI) { | |
| Used.reset(*SI); | |
| if (Implicit) { | |
| // For implicit defs, check if there is an implicit use of an | |
| // aliased register. If so, mark the aliased reg as used. | |
| for (auto *UseOp : UseRegs) | |
| if (UseOp->isImplicit() && TRI->regsOverlap(*SI, UseOp->getReg())) | |
| Used.set(UseOp->getReg()); | |
| } | |
| } | |
| }; | |
| for (unsigned i = 0; i < DefRegs.size(); ++i) { | |
| MachineOperand &MO = *DefRegs[i]; | |
| if (MO.isReg()) { | |
| RemoveDef(MO.getReg(), MO.isImplicit()); | |
| } else if (MO.isRegMask()) { | |
| for (unsigned R = 1, NR = TRI->getNumRegs(); R != NR; ++R) | |
| if (MO.clobbersPhysReg(R)) | |
| RemoveDef(R, true); | |
| } | |
| } | |
| // The order is important as we are looking from right to left. | |
| for (unsigned i = UseRegs.size(); i > 0;) { | |
| --i; | |
| unsigned UseReg = UseRegs[i]->getReg(); | |
| bool Killed = true; | |
| for (MCRegAliasIterator AI(UseReg, TRI, true); AI.isValid(); ++AI) { | |
| if (Used[*AI]) | |
| Killed = false; | |
| } | |
| Used.set(UseReg); | |
| if (Killed && !UseRegs[i]->isDebug()) | |
| UseRegs[i]->setIsKill(true); | |
| } | |
| } | |
| // Recreates bundle for updating liveness. | |
| for (SmallVectorImpl<MachineInstr *>::iterator MII = BundleHeads.begin(); | |
| MII != BundleHeads.end(); ++MII) { | |
| MachineInstr *MI = *MII; | |
| assert(MI && "Invalid bundle head"); | |
| assert(MI->isBundle() && "Expected a bundle head instruction"); | |
| assert(MI->getParent() == MBB && "Bundle head not in expected block"); | |
| MachineBasicBlock::instr_iterator BS = MI->getIterator(); | |
| MachineBasicBlock::instr_iterator BE = getBundleEnd(BS); | |
| for (++BS; BS != BE; ++BS) | |
| // Remove from bundle so that BUNDLE head can be erased. | |
| BS->unbundleFromPred(); | |
| BS = MI->getIterator(); | |
| ++BS; | |
| bool memShufDisabled = QII->getBundleNoShuf(*MI); | |
| MI->eraseFromParent(); | |
| finalizeBundle(*MBB, BS, BE); | |
| MachineBasicBlock::instr_iterator BundleMII = std::prev(BS); | |
| if (memShufDisabled) | |
| QII->setBundleNoShuf(BundleMII); | |
| } | |
| return true; | |
| } | |
| // It deletes the live-in of the \p From MBB. | |
| bool HexagonLiveVariablesImpl::incrementalUpdate(MICInstIterType MIDelta, | |
| MachineBasicBlock *From, | |
| MachineBasicBlock *To) { | |
| while (!From->livein_empty()) | |
| From->removeLiveIn((*From->livein_begin()).PhysReg); | |
| // Handle MI use-def of From. | |
| constructUseDef(From); | |
| // Handle MI use-def of To. | |
| constructUseDef(To); | |
| // Calculate live-in of From and To | |
| // Reuse this by setting all MBBs except From and To as visited. | |
| updateGlobalLiveness(From, To); | |
| // Update local liveness of To. | |
| updateLocalLiveness(From, true); | |
| updateLocalLiveness(To, true); | |
| // Do this after the liveness update because MIDelta might not be in the | |
| // MIUseDefs before liveness update (since MIDelta might be newly inserted). | |
| MIUseDef_t::const_iterator MIUseDef = MIUseDefs.find(&*MIDelta); | |
| if (MIUseDef == MIUseDefs.end()) | |
| llvm_unreachable("MIDelta not found in MIUseDefs after liveness update"); | |
| const BitVector &Defs = MIUseDef->second.second; | |
| int Reg = Defs.find_first(); | |
| // Adding all the defs as live-ins. This is conservative approach but we | |
| // need to add them so as to avoid dealing with callee saved registers and | |
| // any unwanted errors in liveness that might arise. | |
| while (Reg >= 0) { | |
| From->addLiveIn(Reg); | |
| Reg = Defs.find_next(Reg); | |
| } | |
| return true; | |
| } | |
| void HexagonLiveVariablesImpl::addNewMBB(MachineBasicBlock *MBB) { | |
| // Resize and init. | |
| constructUseDef(MBB); // This is to set up some containers for MBB. | |
| gatherBlocksDF(*MBB->getParent(), &BlocksDepthFirst); | |
| updateGlobalLiveness(MBB, MBB); | |
| } | |
| // TODO: This is a slow implementation because constructUseDef destroys | |
| // the MBBLiveOuts which is generated again by updateGlobalLiveness. | |
| void HexagonLiveVariablesImpl::addNewMI(MachineInstr *MI, | |
| MachineBasicBlock *MBB) { | |
| constructUseDef(MBB); // This is to set up some containers for MBB. | |
| updateGlobalLiveness(MBB, MBB); | |
| } | |
| void HexagonLiveVariablesImpl::generateDistanceMap(const MachineFunction &Fn) { | |
| assert(DistanceMap.empty() && "DistanceMap not empty, first clear!"); | |
| for (MachineFunction::const_iterator MBBI = Fn.begin(), E = Fn.end(); | |
| MBBI != E; ++MBBI) { | |
| const MachineBasicBlock *MBB = &*MBBI; | |
| unsigned MBBInsSize = 0; | |
| for (MachineBasicBlock::const_instr_iterator MII = MBB->instr_begin(), | |
| E = MBB->instr_end(); | |
| MII != E; ++MII) { | |
| const MachineInstr *MI = &*MII; | |
| MBBInsSize += QII->getSize(*MI); | |
| } | |
| DistanceMap[MBB] = MBBInsSize; | |
| } | |
| } |