14ba319b5SDimitry Andric //===---- ReachingDefAnalysis.cpp - Reaching Def Analysis ---*- C++ -*-----===//
24ba319b5SDimitry Andric //
34ba319b5SDimitry Andric // The LLVM Compiler Infrastructure
44ba319b5SDimitry Andric //
54ba319b5SDimitry Andric // This file is distributed under the University of Illinois Open Source
64ba319b5SDimitry Andric // License. See LICENSE.TXT for details.
74ba319b5SDimitry Andric //
84ba319b5SDimitry Andric //===----------------------------------------------------------------------===//
94ba319b5SDimitry Andric
104ba319b5SDimitry Andric #include "llvm/CodeGen/ReachingDefAnalysis.h"
114ba319b5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
124ba319b5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
134ba319b5SDimitry Andric
144ba319b5SDimitry Andric using namespace llvm;
154ba319b5SDimitry Andric
164ba319b5SDimitry Andric #define DEBUG_TYPE "reaching-deps-analysis"
174ba319b5SDimitry Andric
184ba319b5SDimitry Andric char ReachingDefAnalysis::ID = 0;
194ba319b5SDimitry Andric INITIALIZE_PASS(ReachingDefAnalysis, DEBUG_TYPE, "ReachingDefAnalysis", false,
204ba319b5SDimitry Andric true)
214ba319b5SDimitry Andric
enterBasicBlock(const LoopTraversal::TraversedMBBInfo & TraversedMBB)224ba319b5SDimitry Andric void ReachingDefAnalysis::enterBasicBlock(
234ba319b5SDimitry Andric const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
244ba319b5SDimitry Andric
254ba319b5SDimitry Andric MachineBasicBlock *MBB = TraversedMBB.MBB;
264ba319b5SDimitry Andric unsigned MBBNumber = MBB->getNumber();
274ba319b5SDimitry Andric assert(MBBNumber < MBBReachingDefs.size() &&
284ba319b5SDimitry Andric "Unexpected basic block number.");
294ba319b5SDimitry Andric MBBReachingDefs[MBBNumber].resize(NumRegUnits);
304ba319b5SDimitry Andric
314ba319b5SDimitry Andric // Reset instruction counter in each basic block.
324ba319b5SDimitry Andric CurInstr = 0;
334ba319b5SDimitry Andric
344ba319b5SDimitry Andric // Set up LiveRegs to represent registers entering MBB.
354ba319b5SDimitry Andric // Default values are 'nothing happened a long time ago'.
364ba319b5SDimitry Andric if (LiveRegs.empty())
374ba319b5SDimitry Andric LiveRegs.assign(NumRegUnits, ReachingDefDefaultVal);
384ba319b5SDimitry Andric
394ba319b5SDimitry Andric // This is the entry block.
404ba319b5SDimitry Andric if (MBB->pred_empty()) {
414ba319b5SDimitry Andric for (const auto &LI : MBB->liveins()) {
424ba319b5SDimitry Andric for (MCRegUnitIterator Unit(LI.PhysReg, TRI); Unit.isValid(); ++Unit) {
434ba319b5SDimitry Andric // Treat function live-ins as if they were defined just before the first
444ba319b5SDimitry Andric // instruction. Usually, function arguments are set up immediately
454ba319b5SDimitry Andric // before the call.
464ba319b5SDimitry Andric LiveRegs[*Unit] = -1;
474ba319b5SDimitry Andric MBBReachingDefs[MBBNumber][*Unit].push_back(LiveRegs[*Unit]);
484ba319b5SDimitry Andric }
494ba319b5SDimitry Andric }
504ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << ": entry\n");
514ba319b5SDimitry Andric return;
524ba319b5SDimitry Andric }
534ba319b5SDimitry Andric
544ba319b5SDimitry Andric // Try to coalesce live-out registers from predecessors.
554ba319b5SDimitry Andric for (MachineBasicBlock *pred : MBB->predecessors()) {
564ba319b5SDimitry Andric assert(unsigned(pred->getNumber()) < MBBOutRegsInfos.size() &&
574ba319b5SDimitry Andric "Should have pre-allocated MBBInfos for all MBBs");
584ba319b5SDimitry Andric const LiveRegsDefInfo &Incoming = MBBOutRegsInfos[pred->getNumber()];
594ba319b5SDimitry Andric // Incoming is null if this is a backedge from a BB
604ba319b5SDimitry Andric // we haven't processed yet
614ba319b5SDimitry Andric if (Incoming.empty())
624ba319b5SDimitry Andric continue;
634ba319b5SDimitry Andric
644ba319b5SDimitry Andric for (unsigned Unit = 0; Unit != NumRegUnits; ++Unit) {
654ba319b5SDimitry Andric // Use the most recent predecessor def for each register.
664ba319b5SDimitry Andric LiveRegs[Unit] = std::max(LiveRegs[Unit], Incoming[Unit]);
674ba319b5SDimitry Andric if ((LiveRegs[Unit] != ReachingDefDefaultVal))
684ba319b5SDimitry Andric MBBReachingDefs[MBBNumber][Unit].push_back(LiveRegs[Unit]);
694ba319b5SDimitry Andric }
704ba319b5SDimitry Andric }
714ba319b5SDimitry Andric
724ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << printMBBReference(*MBB)
734ba319b5SDimitry Andric << (!TraversedMBB.IsDone ? ": incomplete\n"
744ba319b5SDimitry Andric : ": all preds known\n"));
754ba319b5SDimitry Andric }
764ba319b5SDimitry Andric
leaveBasicBlock(const LoopTraversal::TraversedMBBInfo & TraversedMBB)774ba319b5SDimitry Andric void ReachingDefAnalysis::leaveBasicBlock(
784ba319b5SDimitry Andric const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
794ba319b5SDimitry Andric assert(!LiveRegs.empty() && "Must enter basic block first.");
804ba319b5SDimitry Andric unsigned MBBNumber = TraversedMBB.MBB->getNumber();
814ba319b5SDimitry Andric assert(MBBNumber < MBBOutRegsInfos.size() &&
824ba319b5SDimitry Andric "Unexpected basic block number.");
834ba319b5SDimitry Andric // Save register clearances at end of MBB - used by enterBasicBlock().
844ba319b5SDimitry Andric MBBOutRegsInfos[MBBNumber] = LiveRegs;
854ba319b5SDimitry Andric
864ba319b5SDimitry Andric // While processing the basic block, we kept `Def` relative to the start
874ba319b5SDimitry Andric // of the basic block for convenience. However, future use of this information
884ba319b5SDimitry Andric // only cares about the clearance from the end of the block, so adjust
894ba319b5SDimitry Andric // everything to be relative to the end of the basic block.
904ba319b5SDimitry Andric for (int &OutLiveReg : MBBOutRegsInfos[MBBNumber])
914ba319b5SDimitry Andric OutLiveReg -= CurInstr;
924ba319b5SDimitry Andric LiveRegs.clear();
934ba319b5SDimitry Andric }
944ba319b5SDimitry Andric
processDefs(MachineInstr * MI)954ba319b5SDimitry Andric void ReachingDefAnalysis::processDefs(MachineInstr *MI) {
964ba319b5SDimitry Andric assert(!MI->isDebugInstr() && "Won't process debug instructions");
974ba319b5SDimitry Andric
984ba319b5SDimitry Andric unsigned MBBNumber = MI->getParent()->getNumber();
994ba319b5SDimitry Andric assert(MBBNumber < MBBReachingDefs.size() &&
1004ba319b5SDimitry Andric "Unexpected basic block number.");
1014ba319b5SDimitry Andric const MCInstrDesc &MCID = MI->getDesc();
1024ba319b5SDimitry Andric for (unsigned i = 0,
1034ba319b5SDimitry Andric e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs();
1044ba319b5SDimitry Andric i != e; ++i) {
1054ba319b5SDimitry Andric MachineOperand &MO = MI->getOperand(i);
1064ba319b5SDimitry Andric if (!MO.isReg() || !MO.getReg())
1074ba319b5SDimitry Andric continue;
1084ba319b5SDimitry Andric if (MO.isUse())
1094ba319b5SDimitry Andric continue;
1104ba319b5SDimitry Andric for (MCRegUnitIterator Unit(MO.getReg(), TRI); Unit.isValid(); ++Unit) {
1114ba319b5SDimitry Andric // This instruction explicitly defines the current reg unit.
1124ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << printReg(MO.getReg(), TRI) << ":\t" << CurInstr
1134ba319b5SDimitry Andric << '\t' << *MI);
1144ba319b5SDimitry Andric
1154ba319b5SDimitry Andric // How many instructions since this reg unit was last written?
1164ba319b5SDimitry Andric LiveRegs[*Unit] = CurInstr;
1174ba319b5SDimitry Andric MBBReachingDefs[MBBNumber][*Unit].push_back(CurInstr);
1184ba319b5SDimitry Andric }
1194ba319b5SDimitry Andric }
1204ba319b5SDimitry Andric InstIds[MI] = CurInstr;
1214ba319b5SDimitry Andric ++CurInstr;
1224ba319b5SDimitry Andric }
1234ba319b5SDimitry Andric
processBasicBlock(const LoopTraversal::TraversedMBBInfo & TraversedMBB)1244ba319b5SDimitry Andric void ReachingDefAnalysis::processBasicBlock(
1254ba319b5SDimitry Andric const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
1264ba319b5SDimitry Andric enterBasicBlock(TraversedMBB);
1274ba319b5SDimitry Andric for (MachineInstr &MI : *TraversedMBB.MBB) {
1284ba319b5SDimitry Andric if (!MI.isDebugInstr())
1294ba319b5SDimitry Andric processDefs(&MI);
1304ba319b5SDimitry Andric }
1314ba319b5SDimitry Andric leaveBasicBlock(TraversedMBB);
1324ba319b5SDimitry Andric }
1334ba319b5SDimitry Andric
runOnMachineFunction(MachineFunction & mf)1344ba319b5SDimitry Andric bool ReachingDefAnalysis::runOnMachineFunction(MachineFunction &mf) {
1354ba319b5SDimitry Andric if (skipFunction(mf.getFunction()))
1364ba319b5SDimitry Andric return false;
1374ba319b5SDimitry Andric MF = &mf;
1384ba319b5SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo();
1394ba319b5SDimitry Andric
1404ba319b5SDimitry Andric LiveRegs.clear();
1414ba319b5SDimitry Andric NumRegUnits = TRI->getNumRegUnits();
1424ba319b5SDimitry Andric
1434ba319b5SDimitry Andric MBBReachingDefs.resize(mf.getNumBlockIDs());
1444ba319b5SDimitry Andric
1454ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "********** REACHING DEFINITION ANALYSIS **********\n");
1464ba319b5SDimitry Andric
1474ba319b5SDimitry Andric // Initialize the MBBOutRegsInfos
1484ba319b5SDimitry Andric MBBOutRegsInfos.resize(mf.getNumBlockIDs());
1494ba319b5SDimitry Andric
1504ba319b5SDimitry Andric // Traverse the basic blocks.
1514ba319b5SDimitry Andric LoopTraversal Traversal;
1524ba319b5SDimitry Andric LoopTraversal::TraversalOrder TraversedMBBOrder = Traversal.traverse(mf);
1534ba319b5SDimitry Andric for (LoopTraversal::TraversedMBBInfo TraversedMBB : TraversedMBBOrder) {
1544ba319b5SDimitry Andric processBasicBlock(TraversedMBB);
1554ba319b5SDimitry Andric }
1564ba319b5SDimitry Andric
1574ba319b5SDimitry Andric // Sorting all reaching defs found for a ceartin reg unit in a given BB.
1584ba319b5SDimitry Andric for (MBBDefsInfo &MBBDefs : MBBReachingDefs) {
1594ba319b5SDimitry Andric for (MBBRegUnitDefs &RegUnitDefs : MBBDefs)
160*b5893f02SDimitry Andric llvm::sort(RegUnitDefs);
1614ba319b5SDimitry Andric }
1624ba319b5SDimitry Andric
1634ba319b5SDimitry Andric return false;
1644ba319b5SDimitry Andric }
1654ba319b5SDimitry Andric
releaseMemory()1664ba319b5SDimitry Andric void ReachingDefAnalysis::releaseMemory() {
1674ba319b5SDimitry Andric // Clear the internal vectors.
1684ba319b5SDimitry Andric MBBOutRegsInfos.clear();
1694ba319b5SDimitry Andric MBBReachingDefs.clear();
1704ba319b5SDimitry Andric InstIds.clear();
1714ba319b5SDimitry Andric }
1724ba319b5SDimitry Andric
getReachingDef(MachineInstr * MI,int PhysReg)1734ba319b5SDimitry Andric int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, int PhysReg) {
1744ba319b5SDimitry Andric assert(InstIds.count(MI) && "Unexpected machine instuction.");
1754ba319b5SDimitry Andric int InstId = InstIds[MI];
1764ba319b5SDimitry Andric int DefRes = ReachingDefDefaultVal;
1774ba319b5SDimitry Andric unsigned MBBNumber = MI->getParent()->getNumber();
1784ba319b5SDimitry Andric assert(MBBNumber < MBBReachingDefs.size() &&
1794ba319b5SDimitry Andric "Unexpected basic block number.");
1804ba319b5SDimitry Andric int LatestDef = ReachingDefDefaultVal;
1814ba319b5SDimitry Andric for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) {
1824ba319b5SDimitry Andric for (int Def : MBBReachingDefs[MBBNumber][*Unit]) {
1834ba319b5SDimitry Andric if (Def >= InstId)
1844ba319b5SDimitry Andric break;
1854ba319b5SDimitry Andric DefRes = Def;
1864ba319b5SDimitry Andric }
1874ba319b5SDimitry Andric LatestDef = std::max(LatestDef, DefRes);
1884ba319b5SDimitry Andric }
1894ba319b5SDimitry Andric return LatestDef;
1904ba319b5SDimitry Andric }
1914ba319b5SDimitry Andric
getClearance(MachineInstr * MI,MCPhysReg PhysReg)1924ba319b5SDimitry Andric int ReachingDefAnalysis::getClearance(MachineInstr *MI, MCPhysReg PhysReg) {
1934ba319b5SDimitry Andric assert(InstIds.count(MI) && "Unexpected machine instuction.");
1944ba319b5SDimitry Andric return InstIds[MI] - getReachingDef(MI, PhysReg);
1954ba319b5SDimitry Andric }
196