xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===---- ScheduleDAGSDNodes.h - SDNode Scheduling --------------*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements the ScheduleDAGSDNodes class, which implements
107330f729Sjoerg // scheduling for an SDNode-based dependency graph.
117330f729Sjoerg //
127330f729Sjoerg //===----------------------------------------------------------------------===//
137330f729Sjoerg 
147330f729Sjoerg #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SCHEDULEDAGSDNODES_H
157330f729Sjoerg #define LLVM_LIB_CODEGEN_SELECTIONDAG_SCHEDULEDAGSDNODES_H
167330f729Sjoerg 
177330f729Sjoerg #include "llvm/CodeGen/ISDOpcodes.h"
187330f729Sjoerg #include "llvm/CodeGen/MachineBasicBlock.h"
197330f729Sjoerg #include "llvm/CodeGen/ScheduleDAG.h"
207330f729Sjoerg #include "llvm/CodeGen/SelectionDAGNodes.h"
217330f729Sjoerg #include "llvm/Support/Casting.h"
227330f729Sjoerg #include "llvm/Support/MachineValueType.h"
237330f729Sjoerg #include <cassert>
247330f729Sjoerg #include <string>
257330f729Sjoerg #include <vector>
267330f729Sjoerg 
277330f729Sjoerg namespace llvm {
287330f729Sjoerg 
297330f729Sjoerg class AAResults;
307330f729Sjoerg class InstrItineraryData;
317330f729Sjoerg 
327330f729Sjoerg   /// ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.
337330f729Sjoerg   ///
347330f729Sjoerg   /// Edges between SUnits are initially based on edges in the SelectionDAG,
357330f729Sjoerg   /// and additional edges can be added by the schedulers as heuristics.
367330f729Sjoerg   /// SDNodes such as Constants, Registers, and a few others that are not
377330f729Sjoerg   /// interesting to schedulers are not allocated SUnits.
387330f729Sjoerg   ///
397330f729Sjoerg   /// SDNodes with MVT::Glue operands are grouped along with the flagged
407330f729Sjoerg   /// nodes into a single SUnit so that they are scheduled together.
417330f729Sjoerg   ///
427330f729Sjoerg   /// SDNode-based scheduling graphs do not use SDep::Anti or SDep::Output
437330f729Sjoerg   /// edges.  Physical register dependence information is not carried in
447330f729Sjoerg   /// the DAG and must be handled explicitly by schedulers.
457330f729Sjoerg   ///
467330f729Sjoerg   class ScheduleDAGSDNodes : public ScheduleDAG {
477330f729Sjoerg   public:
487330f729Sjoerg     MachineBasicBlock *BB;
497330f729Sjoerg     SelectionDAG *DAG;                    // DAG of the current basic block
507330f729Sjoerg     const InstrItineraryData *InstrItins;
517330f729Sjoerg 
527330f729Sjoerg     /// The schedule. Null SUnit*'s represent noop instructions.
537330f729Sjoerg     std::vector<SUnit*> Sequence;
547330f729Sjoerg 
557330f729Sjoerg     explicit ScheduleDAGSDNodes(MachineFunction &mf);
567330f729Sjoerg 
577330f729Sjoerg     ~ScheduleDAGSDNodes() override = default;
587330f729Sjoerg 
597330f729Sjoerg     /// Run - perform scheduling.
607330f729Sjoerg     ///
617330f729Sjoerg     void Run(SelectionDAG *dag, MachineBasicBlock *bb);
627330f729Sjoerg 
637330f729Sjoerg     /// isPassiveNode - Return true if the node is a non-scheduled leaf.
647330f729Sjoerg     ///
isPassiveNode(SDNode * Node)657330f729Sjoerg     static bool isPassiveNode(SDNode *Node) {
667330f729Sjoerg       if (isa<ConstantSDNode>(Node))       return true;
677330f729Sjoerg       if (isa<ConstantFPSDNode>(Node))     return true;
687330f729Sjoerg       if (isa<RegisterSDNode>(Node))       return true;
697330f729Sjoerg       if (isa<RegisterMaskSDNode>(Node))   return true;
707330f729Sjoerg       if (isa<GlobalAddressSDNode>(Node))  return true;
717330f729Sjoerg       if (isa<BasicBlockSDNode>(Node))     return true;
727330f729Sjoerg       if (isa<FrameIndexSDNode>(Node))     return true;
737330f729Sjoerg       if (isa<ConstantPoolSDNode>(Node))   return true;
747330f729Sjoerg       if (isa<TargetIndexSDNode>(Node))    return true;
757330f729Sjoerg       if (isa<JumpTableSDNode>(Node))      return true;
767330f729Sjoerg       if (isa<ExternalSymbolSDNode>(Node)) return true;
777330f729Sjoerg       if (isa<MCSymbolSDNode>(Node))       return true;
787330f729Sjoerg       if (isa<BlockAddressSDNode>(Node))   return true;
797330f729Sjoerg       if (Node->getOpcode() == ISD::EntryToken ||
807330f729Sjoerg           isa<MDNodeSDNode>(Node)) return true;
817330f729Sjoerg       return false;
827330f729Sjoerg     }
837330f729Sjoerg 
847330f729Sjoerg     /// NewSUnit - Creates a new SUnit and return a ptr to it.
857330f729Sjoerg     ///
867330f729Sjoerg     SUnit *newSUnit(SDNode *N);
877330f729Sjoerg 
887330f729Sjoerg     /// Clone - Creates a clone of the specified SUnit. It does not copy the
897330f729Sjoerg     /// predecessors / successors info nor the temporary scheduling states.
907330f729Sjoerg     ///
917330f729Sjoerg     SUnit *Clone(SUnit *Old);
927330f729Sjoerg 
937330f729Sjoerg     /// BuildSchedGraph - Build the SUnit graph from the selection dag that we
947330f729Sjoerg     /// are input.  This SUnit graph is similar to the SelectionDAG, but
957330f729Sjoerg     /// excludes nodes that aren't interesting to scheduling, and represents
967330f729Sjoerg     /// flagged together nodes with a single SUnit.
977330f729Sjoerg     void BuildSchedGraph(AAResults *AA);
987330f729Sjoerg 
997330f729Sjoerg     /// InitNumRegDefsLeft - Determine the # of regs defined by this node.
1007330f729Sjoerg     ///
1017330f729Sjoerg     void InitNumRegDefsLeft(SUnit *SU);
1027330f729Sjoerg 
1037330f729Sjoerg     /// computeLatency - Compute node latency.
1047330f729Sjoerg     ///
1057330f729Sjoerg     virtual void computeLatency(SUnit *SU);
1067330f729Sjoerg 
1077330f729Sjoerg     virtual void computeOperandLatency(SDNode *Def, SDNode *Use,
1087330f729Sjoerg                                        unsigned OpIdx, SDep& dep) const;
1097330f729Sjoerg 
1107330f729Sjoerg     /// Schedule - Order nodes according to selected style, filling
1117330f729Sjoerg     /// in the Sequence member.
1127330f729Sjoerg     ///
1137330f729Sjoerg     virtual void Schedule() = 0;
1147330f729Sjoerg 
1157330f729Sjoerg     /// VerifyScheduledSequence - Verify that all SUnits are scheduled and
1167330f729Sjoerg     /// consistent with the Sequence of scheduled instructions.
1177330f729Sjoerg     void VerifyScheduledSequence(bool isBottomUp);
1187330f729Sjoerg 
1197330f729Sjoerg     /// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock
1207330f729Sjoerg     /// according to the order specified in Sequence.
1217330f729Sjoerg     ///
1227330f729Sjoerg     virtual MachineBasicBlock*
1237330f729Sjoerg     EmitSchedule(MachineBasicBlock::iterator &InsertPos);
1247330f729Sjoerg 
1257330f729Sjoerg     void dumpNode(const SUnit &SU) const override;
1267330f729Sjoerg     void dump() const override;
1277330f729Sjoerg     void dumpSchedule() const;
1287330f729Sjoerg 
1297330f729Sjoerg     std::string getGraphNodeLabel(const SUnit *SU) const override;
1307330f729Sjoerg 
1317330f729Sjoerg     std::string getDAGName() const override;
1327330f729Sjoerg 
1337330f729Sjoerg     virtual void getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const;
1347330f729Sjoerg 
1357330f729Sjoerg     /// RegDefIter - In place iteration over the values defined by an
1367330f729Sjoerg     /// SUnit. This does not need copies of the iterator or any other STLisms.
1377330f729Sjoerg     /// The iterator creates itself, rather than being provided by the SchedDAG.
1387330f729Sjoerg     class RegDefIter {
1397330f729Sjoerg       const ScheduleDAGSDNodes *SchedDAG;
1407330f729Sjoerg       const SDNode *Node;
1417330f729Sjoerg       unsigned DefIdx;
1427330f729Sjoerg       unsigned NodeNumDefs;
1437330f729Sjoerg       MVT ValueType;
1447330f729Sjoerg 
1457330f729Sjoerg     public:
1467330f729Sjoerg       RegDefIter(const SUnit *SU, const ScheduleDAGSDNodes *SD);
1477330f729Sjoerg 
IsValid()1487330f729Sjoerg       bool IsValid() const { return Node != nullptr; }
1497330f729Sjoerg 
GetValue()1507330f729Sjoerg       MVT GetValue() const {
1517330f729Sjoerg         assert(IsValid() && "bad iterator");
1527330f729Sjoerg         return ValueType;
1537330f729Sjoerg       }
1547330f729Sjoerg 
GetNode()1557330f729Sjoerg       const SDNode *GetNode() const {
1567330f729Sjoerg         return Node;
1577330f729Sjoerg       }
1587330f729Sjoerg 
GetIdx()1597330f729Sjoerg       unsigned GetIdx() const {
1607330f729Sjoerg         return DefIdx-1;
1617330f729Sjoerg       }
1627330f729Sjoerg 
1637330f729Sjoerg       void Advance();
1647330f729Sjoerg 
1657330f729Sjoerg     private:
1667330f729Sjoerg       void InitNodeNumDefs();
1677330f729Sjoerg     };
1687330f729Sjoerg 
1697330f729Sjoerg   protected:
1707330f729Sjoerg     /// ForceUnitLatencies - Return true if all scheduling edges should be given
1717330f729Sjoerg     /// a latency value of one.  The default is to return false; schedulers may
1727330f729Sjoerg     /// override this as needed.
forceUnitLatencies()1737330f729Sjoerg     virtual bool forceUnitLatencies() const { return false; }
1747330f729Sjoerg 
1757330f729Sjoerg   private:
1767330f729Sjoerg     /// ClusterNeighboringLoads - Cluster loads from "near" addresses into
1777330f729Sjoerg     /// combined SUnits.
1787330f729Sjoerg     void ClusterNeighboringLoads(SDNode *Node);
1797330f729Sjoerg     /// ClusterNodes - Cluster certain nodes which should be scheduled together.
1807330f729Sjoerg     ///
1817330f729Sjoerg     void ClusterNodes();
1827330f729Sjoerg 
1837330f729Sjoerg     /// BuildSchedUnits, AddSchedEdges - Helper functions for BuildSchedGraph.
1847330f729Sjoerg     void BuildSchedUnits();
1857330f729Sjoerg     void AddSchedEdges();
1867330f729Sjoerg 
187*82d56013Sjoerg     void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, Register> &VRBaseMap,
1887330f729Sjoerg                          MachineBasicBlock::iterator InsertPos);
1897330f729Sjoerg   };
1907330f729Sjoerg 
1917330f729Sjoerg } // end namespace llvm
1927330f729Sjoerg 
1937330f729Sjoerg #endif // LLVM_LIB_CODEGEN_SELECTIONDAG_SCHEDULEDAGSDNODES_H
194