1*9880d681SAndroid Build Coastguard Worker //=- llvm/CodeGen/AggressiveAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-=// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file implements the AggressiveAntiDepBreaker class, which 11*9880d681SAndroid Build Coastguard Worker // implements register anti-dependence breaking during post-RA 12*9880d681SAndroid Build Coastguard Worker // scheduling. It attempts to break all anti-dependencies within a 13*9880d681SAndroid Build Coastguard Worker // block. 14*9880d681SAndroid Build Coastguard Worker // 15*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H 18*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker #include "AntiDepBreaker.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallSet.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h" 24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h" 25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h" 26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h" 27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ScheduleDAG.h" 28*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h" 29*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h" 30*9880d681SAndroid Build Coastguard Worker #include <map> 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker namespace llvm { 33*9880d681SAndroid Build Coastguard Worker class RegisterClassInfo; 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker /// Contains all the state necessary for anti-dep breaking. 36*9880d681SAndroid Build Coastguard Worker class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepState { 37*9880d681SAndroid Build Coastguard Worker public: 38*9880d681SAndroid Build Coastguard Worker /// Information about a register reference within a liverange 39*9880d681SAndroid Build Coastguard Worker typedef struct { 40*9880d681SAndroid Build Coastguard Worker /// The registers operand 41*9880d681SAndroid Build Coastguard Worker MachineOperand *Operand; 42*9880d681SAndroid Build Coastguard Worker /// The register class 43*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC; 44*9880d681SAndroid Build Coastguard Worker } RegisterReference; 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker private: 47*9880d681SAndroid Build Coastguard Worker /// Number of non-virtual target registers (i.e. TRI->getNumRegs()). 48*9880d681SAndroid Build Coastguard Worker const unsigned NumTargetRegs; 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker /// Implements a disjoint-union data structure to 51*9880d681SAndroid Build Coastguard Worker /// form register groups. A node is represented by an index into 52*9880d681SAndroid Build Coastguard Worker /// the vector. A node can "point to" itself to indicate that it 53*9880d681SAndroid Build Coastguard Worker /// is the parent of a group, or point to another node to indicate 54*9880d681SAndroid Build Coastguard Worker /// that it is a member of the same group as that node. 55*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> GroupNodes; 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker /// For each register, the index of the GroupNode 58*9880d681SAndroid Build Coastguard Worker /// currently representing the group that the register belongs to. 59*9880d681SAndroid Build Coastguard Worker /// Register 0 is always represented by the 0 group, a group 60*9880d681SAndroid Build Coastguard Worker /// composed of registers that are not eligible for anti-aliasing. 61*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> GroupNodeIndices; 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker /// Map registers to all their references within a live range. 64*9880d681SAndroid Build Coastguard Worker std::multimap<unsigned, RegisterReference> RegRefs; 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker /// The index of the most recent kill (proceeding bottom-up), 67*9880d681SAndroid Build Coastguard Worker /// or ~0u if the register is not live. 68*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> KillIndices; 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker /// The index of the most recent complete def (proceeding bottom 71*9880d681SAndroid Build Coastguard Worker /// up), or ~0u if the register is live. 72*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> DefIndices; 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker public: 75*9880d681SAndroid Build Coastguard Worker AggressiveAntiDepState(const unsigned TargetRegs, MachineBasicBlock *BB); 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker /// Return the kill indices. GetKillIndices()78*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> &GetKillIndices() { return KillIndices; } 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker /// Return the define indices. GetDefIndices()81*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> &GetDefIndices() { return DefIndices; } 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Worker /// Return the RegRefs map. GetRegRefs()84*9880d681SAndroid Build Coastguard Worker std::multimap<unsigned, RegisterReference>& GetRegRefs() { return RegRefs; } 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Worker // Get the group for a register. The returned value is 87*9880d681SAndroid Build Coastguard Worker // the index of the GroupNode representing the group. 88*9880d681SAndroid Build Coastguard Worker unsigned GetGroup(unsigned Reg); 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker // Return a vector of the registers belonging to a group. 91*9880d681SAndroid Build Coastguard Worker // If RegRefs is non-NULL then only included referenced registers. 92*9880d681SAndroid Build Coastguard Worker void GetGroupRegs( 93*9880d681SAndroid Build Coastguard Worker unsigned Group, 94*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> &Regs, 95*9880d681SAndroid Build Coastguard Worker std::multimap<unsigned, 96*9880d681SAndroid Build Coastguard Worker AggressiveAntiDepState::RegisterReference> *RegRefs); 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker // Union Reg1's and Reg2's groups to form a new group. 99*9880d681SAndroid Build Coastguard Worker // Return the index of the GroupNode representing the group. 100*9880d681SAndroid Build Coastguard Worker unsigned UnionGroups(unsigned Reg1, unsigned Reg2); 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker // Remove a register from its current group and place 103*9880d681SAndroid Build Coastguard Worker // it alone in its own group. Return the index of the GroupNode 104*9880d681SAndroid Build Coastguard Worker // representing the registers new group. 105*9880d681SAndroid Build Coastguard Worker unsigned LeaveGroup(unsigned Reg); 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker /// Return true if Reg is live. 108*9880d681SAndroid Build Coastguard Worker bool IsLive(unsigned Reg); 109*9880d681SAndroid Build Coastguard Worker }; 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepBreaker 112*9880d681SAndroid Build Coastguard Worker : public AntiDepBreaker { 113*9880d681SAndroid Build Coastguard Worker MachineFunction& MF; 114*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &MRI; 115*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII; 116*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI; 117*9880d681SAndroid Build Coastguard Worker const RegisterClassInfo &RegClassInfo; 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker /// The set of registers that should only be 120*9880d681SAndroid Build Coastguard Worker /// renamed if they are on the critical path. 121*9880d681SAndroid Build Coastguard Worker BitVector CriticalPathSet; 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker /// The state used to identify and rename anti-dependence registers. 124*9880d681SAndroid Build Coastguard Worker AggressiveAntiDepState *State; 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker public: 127*9880d681SAndroid Build Coastguard Worker AggressiveAntiDepBreaker(MachineFunction& MFi, 128*9880d681SAndroid Build Coastguard Worker const RegisterClassInfo &RCI, 129*9880d681SAndroid Build Coastguard Worker TargetSubtargetInfo::RegClassVector& CriticalPathRCs); 130*9880d681SAndroid Build Coastguard Worker ~AggressiveAntiDepBreaker() override; 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker /// Initialize anti-dep breaking for a new basic block. 133*9880d681SAndroid Build Coastguard Worker void StartBlock(MachineBasicBlock *BB) override; 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker /// Identifiy anti-dependencies along the critical path 136*9880d681SAndroid Build Coastguard Worker /// of the ScheduleDAG and break them by renaming registers. 137*9880d681SAndroid Build Coastguard Worker /// 138*9880d681SAndroid Build Coastguard Worker unsigned BreakAntiDependencies(const std::vector<SUnit>& SUnits, 139*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Begin, 140*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator End, 141*9880d681SAndroid Build Coastguard Worker unsigned InsertPosIndex, 142*9880d681SAndroid Build Coastguard Worker DbgValueVector &DbgValues) override; 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker /// Update liveness information to account for the current 145*9880d681SAndroid Build Coastguard Worker /// instruction, which will not be scheduled. 146*9880d681SAndroid Build Coastguard Worker /// 147*9880d681SAndroid Build Coastguard Worker void Observe(MachineInstr &MI, unsigned Count, 148*9880d681SAndroid Build Coastguard Worker unsigned InsertPosIndex) override; 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker /// Finish anti-dep breaking for a basic block. 151*9880d681SAndroid Build Coastguard Worker void FinishBlock() override; 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker private: 154*9880d681SAndroid Build Coastguard Worker /// Keep track of a position in the allocation order for each regclass. 155*9880d681SAndroid Build Coastguard Worker typedef std::map<const TargetRegisterClass *, unsigned> RenameOrderType; 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker /// Return true if MO represents a register 158*9880d681SAndroid Build Coastguard Worker /// that is both implicitly used and defined in MI 159*9880d681SAndroid Build Coastguard Worker bool IsImplicitDefUse(MachineInstr &MI, MachineOperand &MO); 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Worker /// If MI implicitly def/uses a register, then 162*9880d681SAndroid Build Coastguard Worker /// return that register and all subregisters. 163*9880d681SAndroid Build Coastguard Worker void GetPassthruRegs(MachineInstr &MI, std::set<unsigned> &PassthruRegs); 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Worker void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag, 166*9880d681SAndroid Build Coastguard Worker const char *header = nullptr, 167*9880d681SAndroid Build Coastguard Worker const char *footer = nullptr); 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Worker void PrescanInstruction(MachineInstr &MI, unsigned Count, 170*9880d681SAndroid Build Coastguard Worker std::set<unsigned> &PassthruRegs); 171*9880d681SAndroid Build Coastguard Worker void ScanInstruction(MachineInstr &MI, unsigned Count); 172*9880d681SAndroid Build Coastguard Worker BitVector GetRenameRegisters(unsigned Reg); 173*9880d681SAndroid Build Coastguard Worker bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex, 174*9880d681SAndroid Build Coastguard Worker RenameOrderType& RenameOrder, 175*9880d681SAndroid Build Coastguard Worker std::map<unsigned, unsigned> &RenameMap); 176*9880d681SAndroid Build Coastguard Worker }; 177*9880d681SAndroid Build Coastguard Worker } 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker #endif 180