| |
| //===----------------- 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<MachineDominatorTreeWrapperPass>(); |
| AU.addPreserved<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; |
| } |
| } |