Home | History | Annotate | Download | only in CodeGen
      1 //==- ScheduleDAGInstrs.h - MachineInstr Scheduling --------------*- C++ -*-==//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the ScheduleDAGInstrs class, which implements
     11 // scheduling for a MachineInstr-based dependency graph.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
     16 #define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
     17 
     18 #include "llvm/ADT/MapVector.h"
     19 #include "llvm/ADT/SparseMultiSet.h"
     20 #include "llvm/ADT/SparseSet.h"
     21 #include "llvm/CodeGen/ScheduleDAG.h"
     22 #include "llvm/CodeGen/TargetSchedule.h"
     23 #include "llvm/Support/Compiler.h"
     24 #include "llvm/Target/TargetRegisterInfo.h"
     25 #include <list>
     26 
     27 namespace llvm {
     28   class MachineFrameInfo;
     29   class MachineLoopInfo;
     30   class MachineDominatorTree;
     31   class RegPressureTracker;
     32   class PressureDiffs;
     33 
     34   /// An individual mapping from virtual register number to SUnit.
     35   struct VReg2SUnit {
     36     unsigned VirtReg;
     37     LaneBitmask LaneMask;
     38     SUnit *SU;
     39 
     40     VReg2SUnit(unsigned VReg, LaneBitmask LaneMask, SUnit *SU)
     41       : VirtReg(VReg), LaneMask(LaneMask), SU(SU) {}
     42 
     43     unsigned getSparseSetIndex() const {
     44       return TargetRegisterInfo::virtReg2Index(VirtReg);
     45     }
     46   };
     47 
     48   /// Mapping from virtual register to SUnit including an operand index.
     49   struct VReg2SUnitOperIdx : public VReg2SUnit {
     50     unsigned OperandIndex;
     51 
     52     VReg2SUnitOperIdx(unsigned VReg, LaneBitmask LaneMask,
     53                       unsigned OperandIndex, SUnit *SU)
     54       : VReg2SUnit(VReg, LaneMask, SU), OperandIndex(OperandIndex) {}
     55   };
     56 
     57   /// Record a physical register access.
     58   /// For non-data-dependent uses, OpIdx == -1.
     59   struct PhysRegSUOper {
     60     SUnit *SU;
     61     int OpIdx;
     62     unsigned Reg;
     63 
     64     PhysRegSUOper(SUnit *su, int op, unsigned R): SU(su), OpIdx(op), Reg(R) {}
     65 
     66     unsigned getSparseSetIndex() const { return Reg; }
     67   };
     68 
     69   /// Use a SparseMultiSet to track physical registers. Storage is only
     70   /// allocated once for the pass. It can be cleared in constant time and reused
     71   /// without any frees.
     72   typedef SparseMultiSet<PhysRegSUOper, llvm::identity<unsigned>, uint16_t>
     73   Reg2SUnitsMap;
     74 
     75   /// Use SparseSet as a SparseMap by relying on the fact that it never
     76   /// compares ValueT's, only unsigned keys. This allows the set to be cleared
     77   /// between scheduling regions in constant time as long as ValueT does not
     78   /// require a destructor.
     79   typedef SparseSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMap;
     80 
     81   /// Track local uses of virtual registers. These uses are gathered by the DAG
     82   /// builder and may be consulted by the scheduler to avoid iterating an entire
     83   /// vreg use list.
     84   typedef SparseMultiSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMultiMap;
     85 
     86   typedef SparseMultiSet<VReg2SUnitOperIdx, VirtReg2IndexFunctor>
     87     VReg2SUnitOperIdxMultiMap;
     88 
     89   typedef PointerUnion<const Value *, const PseudoSourceValue *> ValueType;
     90   struct UnderlyingObject : PointerIntPair<ValueType, 1, bool> {
     91     UnderlyingObject(ValueType V, bool MayAlias)
     92         : PointerIntPair<ValueType, 1, bool>(V, MayAlias) {}
     93     ValueType getValue() const { return getPointer(); }
     94     bool mayAlias() const { return getInt(); }
     95   };
     96   typedef SmallVector<UnderlyingObject, 4> UnderlyingObjectsVector;
     97 
     98   /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
     99   /// MachineInstrs.
    100   class ScheduleDAGInstrs : public ScheduleDAG {
    101   protected:
    102     const MachineLoopInfo *MLI;
    103     const MachineFrameInfo *MFI;
    104 
    105     /// TargetSchedModel provides an interface to the machine model.
    106     TargetSchedModel SchedModel;
    107 
    108     /// True if the DAG builder should remove kill flags (in preparation for
    109     /// rescheduling).
    110     bool RemoveKillFlags;
    111 
    112     /// The standard DAG builder does not normally include terminators as DAG
    113     /// nodes because it does not create the necessary dependencies to prevent
    114     /// reordering. A specialized scheduler can override
    115     /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
    116     /// it has taken responsibility for scheduling the terminator correctly.
    117     bool CanHandleTerminators;
    118 
    119     /// Whether lane masks should get tracked.
    120     bool TrackLaneMasks;
    121 
    122     /// State specific to the current scheduling region.
    123     /// ------------------------------------------------
    124 
    125     /// The block in which to insert instructions
    126     MachineBasicBlock *BB;
    127 
    128     /// The beginning of the range to be scheduled.
    129     MachineBasicBlock::iterator RegionBegin;
    130 
    131     /// The end of the range to be scheduled.
    132     MachineBasicBlock::iterator RegionEnd;
    133 
    134     /// Instructions in this region (distance(RegionBegin, RegionEnd)).
    135     unsigned NumRegionInstrs;
    136 
    137     /// After calling BuildSchedGraph, each machine instruction in the current
    138     /// scheduling region is mapped to an SUnit.
    139     DenseMap<MachineInstr*, SUnit*> MISUnitMap;
    140 
    141     /// After calling BuildSchedGraph, each vreg used in the scheduling region
    142     /// is mapped to a set of SUnits. These include all local vreg uses, not
    143     /// just the uses for a singly defined vreg.
    144     VReg2SUnitMultiMap VRegUses;
    145 
    146     /// State internal to DAG building.
    147     /// -------------------------------
    148 
    149     /// Defs, Uses - Remember where defs and uses of each register are as we
    150     /// iterate upward through the instructions. This is allocated here instead
    151     /// of inside BuildSchedGraph to avoid the need for it to be initialized and
    152     /// destructed for each block.
    153     Reg2SUnitsMap Defs;
    154     Reg2SUnitsMap Uses;
    155 
    156     /// Tracks the last instruction(s) in this region defining each virtual
    157     /// register. There may be multiple current definitions for a register with
    158     /// disjunct lanemasks.
    159     VReg2SUnitMultiMap CurrentVRegDefs;
    160     /// Tracks the last instructions in this region using each virtual register.
    161     VReg2SUnitOperIdxMultiMap CurrentVRegUses;
    162 
    163     AliasAnalysis *AAForDep;
    164 
    165     /// Remember a generic side-effecting instruction as we proceed.
    166     /// No other SU ever gets scheduled around it (except in the special
    167     /// case of a huge region that gets reduced).
    168     SUnit *BarrierChain;
    169 
    170   public:
    171 
    172     /// A list of SUnits, used in Value2SUsMap, during DAG construction.
    173     /// Note: to gain speed it might be worth investigating an optimized
    174     /// implementation of this data structure, such as a singly linked list
    175     /// with a memory pool (SmallVector was tried but slow and SparseSet is not
    176     /// applicable).
    177     typedef std::list<SUnit *> SUList;
    178   protected:
    179     /// A map from ValueType to SUList, used during DAG construction,
    180     /// as a means of remembering which SUs depend on which memory
    181     /// locations.
    182     class Value2SUsMap;
    183 
    184     /// Remove in FIFO order some SUs from huge maps.
    185     void reduceHugeMemNodeMaps(Value2SUsMap &stores,
    186                                Value2SUsMap &loads, unsigned N);
    187 
    188     /// Add a chain edge between SUa and SUb, but only if both AliasAnalysis
    189     /// and Target fail to deny the dependency.
    190     void addChainDependency(SUnit *SUa, SUnit *SUb,
    191                             unsigned Latency = 0);
    192 
    193     /// Add dependencies as needed from all SUs in list to SU.
    194     void addChainDependencies(SUnit *SU, SUList &sus, unsigned Latency) {
    195       for (auto *su : sus)
    196         addChainDependency(SU, su, Latency);
    197     }
    198 
    199     /// Add dependencies as needed from all SUs in map, to SU.
    200     void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap);
    201 
    202     /// Add dependencies as needed to SU, from all SUs mapped to V.
    203     void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap,
    204                               ValueType V);
    205 
    206     /// Add barrier chain edges from all SUs in map, and then clear
    207     /// the map. This is equivalent to insertBarrierChain(), but
    208     /// optimized for the common case where the new BarrierChain (a
    209     /// global memory object) has a higher NodeNum than all SUs in
    210     /// map. It is assumed BarrierChain has been set before calling
    211     /// this.
    212     void addBarrierChain(Value2SUsMap &map);
    213 
    214     /// Insert a barrier chain in a huge region, far below current
    215     /// SU. Add barrier chain edges from all SUs in map with higher
    216     /// NodeNums than this new BarrierChain, and remove them from
    217     /// map. It is assumed BarrierChain has been set before calling
    218     /// this.
    219     void insertBarrierChain(Value2SUsMap &map);
    220 
    221     /// For an unanalyzable memory access, this Value is used in maps.
    222     UndefValue *UnknownValue;
    223 
    224     /// DbgValues - Remember instruction that precedes DBG_VALUE.
    225     /// These are generated by buildSchedGraph but persist so they can be
    226     /// referenced when emitting the final schedule.
    227     typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
    228       DbgValueVector;
    229     DbgValueVector DbgValues;
    230     MachineInstr *FirstDbgValue;
    231 
    232     /// Set of live physical registers for updating kill flags.
    233     BitVector LiveRegs;
    234 
    235   public:
    236     explicit ScheduleDAGInstrs(MachineFunction &mf,
    237                                const MachineLoopInfo *mli,
    238                                bool RemoveKillFlags = false);
    239 
    240     ~ScheduleDAGInstrs() override {}
    241 
    242     /// \brief Get the machine model for instruction scheduling.
    243     const TargetSchedModel *getSchedModel() const { return &SchedModel; }
    244 
    245     /// \brief Resolve and cache a resolved scheduling class for an SUnit.
    246     const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
    247       if (!SU->SchedClass && SchedModel.hasInstrSchedModel())
    248         SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
    249       return SU->SchedClass;
    250     }
    251 
    252     /// begin - Return an iterator to the top of the current scheduling region.
    253     MachineBasicBlock::iterator begin() const { return RegionBegin; }
    254 
    255     /// end - Return an iterator to the bottom of the current scheduling region.
    256     MachineBasicBlock::iterator end() const { return RegionEnd; }
    257 
    258     /// newSUnit - Creates a new SUnit and return a ptr to it.
    259     SUnit *newSUnit(MachineInstr *MI);
    260 
    261     /// getSUnit - Return an existing SUnit for this MI, or NULL.
    262     SUnit *getSUnit(MachineInstr *MI) const;
    263 
    264     /// startBlock - Prepare to perform scheduling in the given block.
    265     virtual void startBlock(MachineBasicBlock *BB);
    266 
    267     /// finishBlock - Clean up after scheduling in the given block.
    268     virtual void finishBlock();
    269 
    270     /// Initialize the scheduler state for the next scheduling region.
    271     virtual void enterRegion(MachineBasicBlock *bb,
    272                              MachineBasicBlock::iterator begin,
    273                              MachineBasicBlock::iterator end,
    274                              unsigned regioninstrs);
    275 
    276     /// Notify that the scheduler has finished scheduling the current region.
    277     virtual void exitRegion();
    278 
    279     /// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
    280     /// input.
    281     void buildSchedGraph(AliasAnalysis *AA,
    282                          RegPressureTracker *RPTracker = nullptr,
    283                          PressureDiffs *PDiffs = nullptr,
    284                          LiveIntervals *LIS = nullptr,
    285                          bool TrackLaneMasks = false);
    286 
    287     /// addSchedBarrierDeps - Add dependencies from instructions in the current
    288     /// list of instructions being scheduled to scheduling barrier. We want to
    289     /// make sure instructions which define registers that are either used by
    290     /// the terminator or are live-out are properly scheduled. This is
    291     /// especially important when the definition latency of the return value(s)
    292     /// are too high to be hidden by the branch or when the liveout registers
    293     /// used by instructions in the fallthrough block.
    294     void addSchedBarrierDeps();
    295 
    296     /// schedule - Order nodes according to selected style, filling
    297     /// in the Sequence member.
    298     ///
    299     /// Typically, a scheduling algorithm will implement schedule() without
    300     /// overriding enterRegion() or exitRegion().
    301     virtual void schedule() = 0;
    302 
    303     /// finalizeSchedule - Allow targets to perform final scheduling actions at
    304     /// the level of the whole MachineFunction. By default does nothing.
    305     virtual void finalizeSchedule() {}
    306 
    307     void dumpNode(const SUnit *SU) const override;
    308 
    309     /// Return a label for a DAG node that points to an instruction.
    310     std::string getGraphNodeLabel(const SUnit *SU) const override;
    311 
    312     /// Return a label for the region of code covered by the DAG.
    313     std::string getDAGName() const override;
    314 
    315     /// \brief Fix register kill flags that scheduling has made invalid.
    316     void fixupKills(MachineBasicBlock *MBB);
    317   protected:
    318     void initSUnits();
    319     void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
    320     void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
    321     void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
    322     void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
    323 
    324     /// \brief PostRA helper for rewriting kill flags.
    325     void startBlockForKills(MachineBasicBlock *BB);
    326 
    327     /// \brief Toggle a register operand kill flag.
    328     ///
    329     /// Other adjustments may be made to the instruction if necessary. Return
    330     /// true if the operand has been deleted, false if not.
    331     bool toggleKillFlag(MachineInstr *MI, MachineOperand &MO);
    332 
    333     /// Returns a mask for which lanes get read/written by the given (register)
    334     /// machine operand.
    335     LaneBitmask getLaneMaskForMO(const MachineOperand &MO) const;
    336 
    337     void collectVRegUses(SUnit *SU);
    338   };
    339 
    340   /// newSUnit - Creates a new SUnit and return a ptr to it.
    341   inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
    342 #ifndef NDEBUG
    343     const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0];
    344 #endif
    345     SUnits.emplace_back(MI, (unsigned)SUnits.size());
    346     assert((Addr == nullptr || Addr == &SUnits[0]) &&
    347            "SUnits std::vector reallocated on the fly!");
    348     SUnits.back().OrigNode = &SUnits.back();
    349     return &SUnits.back();
    350   }
    351 
    352   /// getSUnit - Return an existing SUnit for this MI, or NULL.
    353   inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
    354     DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI);
    355     if (I == MISUnitMap.end())
    356       return nullptr;
    357     return I->second;
    358   }
    359 } // namespace llvm
    360 
    361 #endif
    362