123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- ScheduleDFS.h - ILP metric for ScheduleDAGInstrs ---------*- C++ -*-===//
- //
- // 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
- //
- //===----------------------------------------------------------------------===//
- //
- // Definition of an ILP metric for machine level instruction scheduling.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CODEGEN_SCHEDULEDFS_H
- #define LLVM_CODEGEN_SCHEDULEDFS_H
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/CodeGen/ScheduleDAG.h"
- #include <cassert>
- #include <cstdint>
- #include <vector>
- namespace llvm {
- template <typename T> class ArrayRef;
- class raw_ostream;
- /// Represent the ILP of the subDAG rooted at a DAG node.
- ///
- /// ILPValues summarize the DAG subtree rooted at each node. ILPValues are
- /// valid for all nodes regardless of their subtree membership.
- ///
- /// When computed using bottom-up DFS, this metric assumes that the DAG is a
- /// forest of trees with roots at the bottom of the schedule branching upward.
- struct ILPValue {
- unsigned InstrCount;
- /// Length may either correspond to depth or height, depending on direction,
- /// and cycles or nodes depending on context.
- unsigned Length;
- ILPValue(unsigned count, unsigned length):
- InstrCount(count), Length(length) {}
- // Order by the ILP metric's value.
- bool operator<(ILPValue RHS) const {
- return (uint64_t)InstrCount * RHS.Length
- < (uint64_t)Length * RHS.InstrCount;
- }
- bool operator>(ILPValue RHS) const {
- return RHS < *this;
- }
- bool operator<=(ILPValue RHS) const {
- return (uint64_t)InstrCount * RHS.Length
- <= (uint64_t)Length * RHS.InstrCount;
- }
- bool operator>=(ILPValue RHS) const {
- return RHS <= *this;
- }
- void print(raw_ostream &OS) const;
- void dump() const;
- };
- /// Compute the values of each DAG node for various metrics during DFS.
- class SchedDFSResult {
- friend class SchedDFSImpl;
- static const unsigned InvalidSubtreeID = ~0u;
- /// Per-SUnit data computed during DFS for various metrics.
- ///
- /// A node's SubtreeID is set to itself when it is visited to indicate that it
- /// is the root of a subtree. Later it is set to its parent to indicate an
- /// interior node. Finally, it is set to a representative subtree ID during
- /// finalization.
- struct NodeData {
- unsigned InstrCount = 0;
- unsigned SubtreeID = InvalidSubtreeID;
- NodeData() = default;
- };
- /// Per-Subtree data computed during DFS.
- struct TreeData {
- unsigned ParentTreeID = InvalidSubtreeID;
- unsigned SubInstrCount = 0;
- TreeData() = default;
- };
- /// Record a connection between subtrees and the connection level.
- struct Connection {
- unsigned TreeID;
- unsigned Level;
- Connection(unsigned tree, unsigned level): TreeID(tree), Level(level) {}
- };
- bool IsBottomUp;
- unsigned SubtreeLimit;
- /// DFS results for each SUnit in this DAG.
- std::vector<NodeData> DFSNodeData;
- // Store per-tree data indexed on tree ID,
- SmallVector<TreeData, 16> DFSTreeData;
- // For each subtree discovered during DFS, record its connections to other
- // subtrees.
- std::vector<SmallVector<Connection, 4>> SubtreeConnections;
- /// Cache the current connection level of each subtree.
- /// This mutable array is updated during scheduling.
- std::vector<unsigned> SubtreeConnectLevels;
- public:
- SchedDFSResult(bool IsBU, unsigned lim)
- : IsBottomUp(IsBU), SubtreeLimit(lim) {}
- /// Get the node cutoff before subtrees are considered significant.
- unsigned getSubtreeLimit() const { return SubtreeLimit; }
- /// Return true if this DFSResult is uninitialized.
- ///
- /// resize() initializes DFSResult, while compute() populates it.
- bool empty() const { return DFSNodeData.empty(); }
- /// Clear the results.
- void clear() {
- DFSNodeData.clear();
- DFSTreeData.clear();
- SubtreeConnections.clear();
- SubtreeConnectLevels.clear();
- }
- /// Initialize the result data with the size of the DAG.
- void resize(unsigned NumSUnits) {
- DFSNodeData.resize(NumSUnits);
- }
- /// Compute various metrics for the DAG with given roots.
- void compute(ArrayRef<SUnit> SUnits);
- /// Get the number of instructions in the given subtree and its
- /// children.
- unsigned getNumInstrs(const SUnit *SU) const {
- return DFSNodeData[SU->NodeNum].InstrCount;
- }
- /// Get the number of instructions in the given subtree not including
- /// children.
- unsigned getNumSubInstrs(unsigned SubtreeID) const {
- return DFSTreeData[SubtreeID].SubInstrCount;
- }
- /// Get the ILP value for a DAG node.
- ///
- /// A leaf node has an ILP of 1/1.
- ILPValue getILP(const SUnit *SU) const {
- return ILPValue(DFSNodeData[SU->NodeNum].InstrCount, 1 + SU->getDepth());
- }
- /// The number of subtrees detected in this DAG.
- unsigned getNumSubtrees() const { return SubtreeConnectLevels.size(); }
- /// Get the ID of the subtree the given DAG node belongs to.
- ///
- /// For convenience, if DFSResults have not been computed yet, give everything
- /// tree ID 0.
- unsigned getSubtreeID(const SUnit *SU) const {
- if (empty())
- return 0;
- assert(SU->NodeNum < DFSNodeData.size() && "New Node");
- return DFSNodeData[SU->NodeNum].SubtreeID;
- }
- /// Get the connection level of a subtree.
- ///
- /// For bottom-up trees, the connection level is the latency depth (in cycles)
- /// of the deepest connection to another subtree.
- unsigned getSubtreeLevel(unsigned SubtreeID) const {
- return SubtreeConnectLevels[SubtreeID];
- }
- /// Scheduler callback to update SubtreeConnectLevels when a tree is
- /// initially scheduled.
- void scheduleTree(unsigned SubtreeID);
- };
- raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val);
- } // end namespace llvm
- #endif // LLVM_CODEGEN_SCHEDULEDFS_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|