mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-19 15:13:49 -04:00
ScheduleDAGInstrs: Cleanup; NFC
Comment, doxygen and a bit of whitespace cleanup. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293322 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -7,8 +7,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the ScheduleDAGInstrs class, which implements
|
||||
// scheduling for a MachineInstr-based dependency graph.
|
||||
/// \file Implements the ScheduleDAGInstrs class, which implements scheduling
|
||||
/// for a MachineInstr-based dependency graph.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -95,8 +95,7 @@ namespace llvm {
|
||||
};
|
||||
typedef SmallVector<UnderlyingObject, 4> UnderlyingObjectsVector;
|
||||
|
||||
/// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
|
||||
/// MachineInstrs.
|
||||
/// A ScheduleDAG for scheduling lists of MachineInstr.
|
||||
class ScheduleDAGInstrs : public ScheduleDAG {
|
||||
protected:
|
||||
const MachineLoopInfo *MLI;
|
||||
@@ -119,8 +118,8 @@ namespace llvm {
|
||||
/// Whether lane masks should get tracked.
|
||||
bool TrackLaneMasks;
|
||||
|
||||
/// State specific to the current scheduling region.
|
||||
/// ------------------------------------------------
|
||||
// State specific to the current scheduling region.
|
||||
// ------------------------------------------------
|
||||
|
||||
/// The block in which to insert instructions
|
||||
MachineBasicBlock *BB;
|
||||
@@ -138,8 +137,8 @@ namespace llvm {
|
||||
/// scheduling region is mapped to an SUnit.
|
||||
DenseMap<MachineInstr*, SUnit*> MISUnitMap;
|
||||
|
||||
/// State internal to DAG building.
|
||||
/// -------------------------------
|
||||
// State internal to DAG building.
|
||||
// -------------------------------
|
||||
|
||||
/// Defs, Uses - Remember where defs and uses of each register are as we
|
||||
/// iterate upward through the instructions. This is allocated here instead
|
||||
@@ -163,64 +162,64 @@ namespace llvm {
|
||||
SUnit *BarrierChain;
|
||||
|
||||
public:
|
||||
|
||||
/// A list of SUnits, used in Value2SUsMap, during DAG construction.
|
||||
/// Note: to gain speed it might be worth investigating an optimized
|
||||
/// implementation of this data structure, such as a singly linked list
|
||||
/// with a memory pool (SmallVector was tried but slow and SparseSet is not
|
||||
/// applicable).
|
||||
typedef std::list<SUnit *> SUList;
|
||||
|
||||
protected:
|
||||
/// A map from ValueType to SUList, used during DAG construction,
|
||||
/// as a means of remembering which SUs depend on which memory
|
||||
/// locations.
|
||||
/// \brief A map from ValueType to SUList, used during DAG construction, as
|
||||
/// a means of remembering which SUs depend on which memory locations.
|
||||
class Value2SUsMap;
|
||||
|
||||
/// Remove in FIFO order some SUs from huge maps.
|
||||
/// Reduces maps in FIFO order, by N SUs. This is better than turning
|
||||
/// every Nth memory SU into BarrierChain in buildSchedGraph(), since
|
||||
/// it avoids unnecessary edges between seen SUs above the new BarrierChain,
|
||||
/// and those below it.
|
||||
void reduceHugeMemNodeMaps(Value2SUsMap &stores,
|
||||
Value2SUsMap &loads, unsigned N);
|
||||
|
||||
/// Add a chain edge between SUa and SUb, but only if both AliasAnalysis
|
||||
/// and Target fail to deny the dependency.
|
||||
/// \brief Adds a chain edge between SUa and SUb, but only if both
|
||||
/// AliasAnalysis and Target fail to deny the dependency.
|
||||
void addChainDependency(SUnit *SUa, SUnit *SUb,
|
||||
unsigned Latency = 0);
|
||||
|
||||
/// Add dependencies as needed from all SUs in list to SU.
|
||||
void addChainDependencies(SUnit *SU, SUList &sus, unsigned Latency) {
|
||||
for (auto *su : sus)
|
||||
addChainDependency(SU, su, Latency);
|
||||
/// Adds dependencies as needed from all SUs in list to SU.
|
||||
void addChainDependencies(SUnit *SU, SUList &SUs, unsigned Latency) {
|
||||
for (SUnit *Entry : SUs)
|
||||
addChainDependency(SU, Entry, Latency);
|
||||
}
|
||||
|
||||
/// Add dependencies as needed from all SUs in map, to SU.
|
||||
/// Adds dependencies as needed from all SUs in map, to SU.
|
||||
void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap);
|
||||
|
||||
/// Add dependencies as needed to SU, from all SUs mapped to V.
|
||||
/// Adds dependencies as needed to SU, from all SUs mapped to V.
|
||||
void addChainDependencies(SUnit *SU, Value2SUsMap &Val2SUsMap,
|
||||
ValueType V);
|
||||
|
||||
/// Add barrier chain edges from all SUs in map, and then clear
|
||||
/// the map. This is equivalent to insertBarrierChain(), but
|
||||
/// optimized for the common case where the new BarrierChain (a
|
||||
/// global memory object) has a higher NodeNum than all SUs in
|
||||
/// map. It is assumed BarrierChain has been set before calling
|
||||
/// this.
|
||||
/// Adds barrier chain edges from all SUs in map, and then clear the map.
|
||||
/// This is equivalent to insertBarrierChain(), but optimized for the common
|
||||
/// case where the new BarrierChain (a global memory object) has a higher
|
||||
/// NodeNum than all SUs in map. It is assumed BarrierChain has been set
|
||||
/// before calling this.
|
||||
void addBarrierChain(Value2SUsMap &map);
|
||||
|
||||
/// Insert a barrier chain in a huge region, far below current
|
||||
/// SU. Add barrier chain edges from all SUs in map with higher
|
||||
/// NodeNums than this new BarrierChain, and remove them from
|
||||
/// map. It is assumed BarrierChain has been set before calling
|
||||
/// this.
|
||||
/// Inserts a barrier chain in a huge region, far below current SU.
|
||||
/// Adds barrier chain edges from all SUs in map with higher NodeNums than
|
||||
/// this new BarrierChain, and remove them from map. It is assumed
|
||||
/// BarrierChain has been set before calling this.
|
||||
void insertBarrierChain(Value2SUsMap &map);
|
||||
|
||||
/// For an unanalyzable memory access, this Value is used in maps.
|
||||
UndefValue *UnknownValue;
|
||||
|
||||
/// DbgValues - Remember instruction that precedes DBG_VALUE.
|
||||
typedef std::vector<std::pair<MachineInstr *, MachineInstr *>>
|
||||
DbgValueVector;
|
||||
/// Remember instruction that precedes DBG_VALUE.
|
||||
/// These are generated by buildSchedGraph but persist so they can be
|
||||
/// referenced when emitting the final schedule.
|
||||
typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
|
||||
DbgValueVector;
|
||||
DbgValueVector DbgValues;
|
||||
MachineInstr *FirstDbgValue;
|
||||
|
||||
@@ -234,81 +233,86 @@ namespace llvm {
|
||||
|
||||
~ScheduleDAGInstrs() override {}
|
||||
|
||||
/// \brief Get the machine model for instruction scheduling.
|
||||
/// Gets the machine model for instruction scheduling.
|
||||
const TargetSchedModel *getSchedModel() const { return &SchedModel; }
|
||||
|
||||
/// \brief Resolve and cache a resolved scheduling class for an SUnit.
|
||||
/// Resolves and cache a resolved scheduling class for an SUnit.
|
||||
const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
|
||||
if (!SU->SchedClass && SchedModel.hasInstrSchedModel())
|
||||
SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
|
||||
return SU->SchedClass;
|
||||
}
|
||||
|
||||
/// begin - Return an iterator to the top of the current scheduling region.
|
||||
/// Returns an iterator to the top of the current scheduling region.
|
||||
MachineBasicBlock::iterator begin() const { return RegionBegin; }
|
||||
|
||||
/// end - Return an iterator to the bottom of the current scheduling region.
|
||||
/// Returns an iterator to the bottom of the current scheduling region.
|
||||
MachineBasicBlock::iterator end() const { return RegionEnd; }
|
||||
|
||||
/// newSUnit - Creates a new SUnit and return a ptr to it.
|
||||
/// Creates a new SUnit and return a ptr to it.
|
||||
SUnit *newSUnit(MachineInstr *MI);
|
||||
|
||||
/// getSUnit - Return an existing SUnit for this MI, or NULL.
|
||||
/// Returns an existing SUnit for this MI, or nullptr.
|
||||
SUnit *getSUnit(MachineInstr *MI) const;
|
||||
|
||||
/// startBlock - Prepare to perform scheduling in the given block.
|
||||
/// Prepares to perform scheduling in the given block.
|
||||
virtual void startBlock(MachineBasicBlock *BB);
|
||||
|
||||
/// finishBlock - Clean up after scheduling in the given block.
|
||||
/// Cleans up after scheduling in the given block.
|
||||
virtual void finishBlock();
|
||||
|
||||
/// Initialize the scheduler state for the next scheduling region.
|
||||
/// \brief Initialize the DAG and common scheduler state for a new
|
||||
/// scheduling region. This does not actually create the DAG, only clears
|
||||
/// it. The scheduling driver may call BuildSchedGraph multiple times per
|
||||
/// scheduling region.
|
||||
virtual void enterRegion(MachineBasicBlock *bb,
|
||||
MachineBasicBlock::iterator begin,
|
||||
MachineBasicBlock::iterator end,
|
||||
unsigned regioninstrs);
|
||||
|
||||
/// Notify that the scheduler has finished scheduling the current region.
|
||||
/// Called when the scheduler has finished scheduling the current region.
|
||||
virtual void exitRegion();
|
||||
|
||||
/// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
|
||||
/// input.
|
||||
/// Builds SUnits for the current region.
|
||||
/// If \p RPTracker is non-null, compute register pressure as a side effect.
|
||||
/// The DAG builder is an efficient place to do it because it already visits
|
||||
/// operands.
|
||||
void buildSchedGraph(AliasAnalysis *AA,
|
||||
RegPressureTracker *RPTracker = nullptr,
|
||||
PressureDiffs *PDiffs = nullptr,
|
||||
LiveIntervals *LIS = nullptr,
|
||||
bool TrackLaneMasks = false);
|
||||
|
||||
/// addSchedBarrierDeps - Add dependencies from instructions in the current
|
||||
/// list of instructions being scheduled to scheduling barrier. We want to
|
||||
/// make sure instructions which define registers that are either used by
|
||||
/// the terminator or are live-out are properly scheduled. This is
|
||||
/// especially important when the definition latency of the return value(s)
|
||||
/// are too high to be hidden by the branch or when the liveout registers
|
||||
/// used by instructions in the fallthrough block.
|
||||
/// \brief Adds dependencies from instructions in the current list of
|
||||
/// instructions being scheduled to scheduling barrier. We want to make sure
|
||||
/// instructions which define registers that are either used by the
|
||||
/// terminator or are live-out are properly scheduled. This is especially
|
||||
/// important when the definition latency of the return value(s) are too
|
||||
/// high to be hidden by the branch or when the liveout registers used by
|
||||
/// instructions in the fallthrough block.
|
||||
void addSchedBarrierDeps();
|
||||
|
||||
/// schedule - Order nodes according to selected style, filling
|
||||
/// in the Sequence member.
|
||||
/// Orders nodes according to selected style.
|
||||
///
|
||||
/// Typically, a scheduling algorithm will implement schedule() without
|
||||
/// overriding enterRegion() or exitRegion().
|
||||
virtual void schedule() = 0;
|
||||
|
||||
/// finalizeSchedule - Allow targets to perform final scheduling actions at
|
||||
/// the level of the whole MachineFunction. By default does nothing.
|
||||
/// Allow targets to perform final scheduling actions at the level of the
|
||||
/// whole MachineFunction. By default does nothing.
|
||||
virtual void finalizeSchedule() {}
|
||||
|
||||
void dumpNode(const SUnit *SU) const override;
|
||||
|
||||
/// Return a label for a DAG node that points to an instruction.
|
||||
/// Returns a label for a DAG node that points to an instruction.
|
||||
std::string getGraphNodeLabel(const SUnit *SU) const override;
|
||||
|
||||
/// Return a label for the region of code covered by the DAG.
|
||||
/// Returns a label for the region of code covered by the DAG.
|
||||
std::string getDAGName() const override;
|
||||
|
||||
/// \brief Fix register kill flags that scheduling has made invalid.
|
||||
/// Fixes register kill flags that scheduling has made invalid.
|
||||
void fixupKills(MachineBasicBlock *MBB);
|
||||
|
||||
protected:
|
||||
void initSUnits();
|
||||
void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
|
||||
@@ -316,10 +320,11 @@ namespace llvm {
|
||||
void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
|
||||
void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
|
||||
|
||||
/// \brief PostRA helper for rewriting kill flags.
|
||||
/// Initializes register live-range state for updating kills.
|
||||
/// PostRA helper for rewriting kill flags.
|
||||
void startBlockForKills(MachineBasicBlock *BB);
|
||||
|
||||
/// \brief Toggle a register operand kill flag.
|
||||
/// Toggles a register operand kill flag.
|
||||
///
|
||||
/// Other adjustments may be made to the instruction if necessary. Return
|
||||
/// true if the operand has been deleted, false if not.
|
||||
@@ -330,7 +335,7 @@ namespace llvm {
|
||||
LaneBitmask getLaneMaskForMO(const MachineOperand &MO) const;
|
||||
};
|
||||
|
||||
/// newSUnit - Creates a new SUnit and return a ptr to it.
|
||||
/// Creates a new SUnit and return a ptr to it.
|
||||
inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
|
||||
#ifndef NDEBUG
|
||||
const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0];
|
||||
@@ -341,13 +346,13 @@ namespace llvm {
|
||||
return &SUnits.back();
|
||||
}
|
||||
|
||||
/// getSUnit - Return an existing SUnit for this MI, or NULL.
|
||||
/// Returns an existing SUnit for this MI, or nullptr.
|
||||
inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
|
||||
DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI);
|
||||
if (I == MISUnitMap.end())
|
||||
return nullptr;
|
||||
return I->second;
|
||||
}
|
||||
} // namespace llvm
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This implements the ScheduleDAGInstrs class, which implements re-scheduling
|
||||
// of MachineInstrs.
|
||||
/// \file This implements the ScheduleDAGInstrs class, which implements
|
||||
/// re-scheduling of MachineInstrs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -101,8 +101,8 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
|
||||
SchedModel.init(ST.getSchedModel(), &ST, TII);
|
||||
}
|
||||
|
||||
/// getUnderlyingObjectFromInt - This is the function that does the work of
|
||||
/// looking through basic ptrtoint+arithmetic+inttoptr sequences.
|
||||
/// This is the function that does the work of looking through basic
|
||||
/// ptrtoint+arithmetic+inttoptr sequences.
|
||||
static const Value *getUnderlyingObjectFromInt(const Value *V) {
|
||||
do {
|
||||
if (const Operator *U = dyn_cast<Operator>(V)) {
|
||||
@@ -129,8 +129,8 @@ static const Value *getUnderlyingObjectFromInt(const Value *V) {
|
||||
} while (1);
|
||||
}
|
||||
|
||||
/// getUnderlyingObjects - This is a wrapper around GetUnderlyingObjects
|
||||
/// and adds support for basic ptrtoint+arithmetic+inttoptr sequences.
|
||||
/// This is a wrapper around GetUnderlyingObjects and adds support for basic
|
||||
/// ptrtoint+arithmetic+inttoptr sequences.
|
||||
static void getUnderlyingObjects(const Value *V,
|
||||
SmallVectorImpl<Value *> &Objects,
|
||||
const DataLayout &DL) {
|
||||
@@ -158,9 +158,8 @@ static void getUnderlyingObjects(const Value *V,
|
||||
} while (!Working.empty());
|
||||
}
|
||||
|
||||
/// getUnderlyingObjectsForInstr - If this machine instr has memory reference
|
||||
/// information and it can be tracked to a normal reference to a known
|
||||
/// object, return the Value for that object.
|
||||
/// If this machine instr has memory reference information and it can be tracked
|
||||
/// to a normal reference to a known object, return the Value for that object.
|
||||
static void getUnderlyingObjectsForInstr(const MachineInstr *MI,
|
||||
const MachineFrameInfo &MFI,
|
||||
UnderlyingObjectsVector &Objects,
|
||||
@@ -216,10 +215,6 @@ void ScheduleDAGInstrs::finishBlock() {
|
||||
BB = nullptr;
|
||||
}
|
||||
|
||||
/// Initialize the DAG and common scheduler state for the current scheduling
|
||||
/// region. This does not actually create the DAG, only clears it. The
|
||||
/// scheduling driver may call BuildSchedGraph multiple times per scheduling
|
||||
/// region.
|
||||
void ScheduleDAGInstrs::enterRegion(MachineBasicBlock *bb,
|
||||
MachineBasicBlock::iterator begin,
|
||||
MachineBasicBlock::iterator end,
|
||||
@@ -230,20 +225,10 @@ void ScheduleDAGInstrs::enterRegion(MachineBasicBlock *bb,
|
||||
NumRegionInstrs = regioninstrs;
|
||||
}
|
||||
|
||||
/// Close the current scheduling region. Don't clear any state in case the
|
||||
/// driver wants to refer to the previous scheduling region.
|
||||
void ScheduleDAGInstrs::exitRegion() {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/// addSchedBarrierDeps - Add dependencies from instructions in the current
|
||||
/// list of instructions being scheduled to scheduling barrier by adding
|
||||
/// the exit SU to the register defs and use list. This is because we want to
|
||||
/// make sure instructions which define registers that are either used by
|
||||
/// the terminator or are live-out are properly scheduled. This is
|
||||
/// especially important when the definition latency of the return value(s)
|
||||
/// are too high to be hidden by the branch or when the liveout registers
|
||||
/// used by instructions in the fallthrough block.
|
||||
void ScheduleDAGInstrs::addSchedBarrierDeps() {
|
||||
MachineInstr *ExitMI = RegionEnd != BB->end() ? &*RegionEnd : nullptr;
|
||||
ExitSU.setInstr(ExitMI);
|
||||
@@ -271,7 +256,7 @@ void ScheduleDAGInstrs::addSchedBarrierDeps() {
|
||||
}
|
||||
}
|
||||
|
||||
/// MO is an operand of SU's instruction that defines a physical register. Add
|
||||
/// MO is an operand of SU's instruction that defines a physical register. Adds
|
||||
/// data dependencies from SU to any uses of the physical register.
|
||||
void ScheduleDAGInstrs::addPhysRegDataDeps(SUnit *SU, unsigned OperIdx) {
|
||||
const MachineOperand &MO = SU->getInstr()->getOperand(OperIdx);
|
||||
@@ -313,9 +298,9 @@ void ScheduleDAGInstrs::addPhysRegDataDeps(SUnit *SU, unsigned OperIdx) {
|
||||
}
|
||||
}
|
||||
|
||||
/// addPhysRegDeps - Add register dependencies (data, anti, and output) from
|
||||
/// this SUnit to following instructions in the same scheduling region that
|
||||
/// depend the physical register referenced at OperIdx.
|
||||
/// \brief Adds register dependencies (data, anti, and output) from this SUnit
|
||||
/// to following instructions in the same scheduling region that depend the
|
||||
/// physical register referenced at OperIdx.
|
||||
void ScheduleDAGInstrs::addPhysRegDeps(SUnit *SU, unsigned OperIdx) {
|
||||
MachineInstr *MI = SU->getInstr();
|
||||
MachineOperand &MO = MI->getOperand(OperIdx);
|
||||
@@ -406,9 +391,9 @@ LaneBitmask ScheduleDAGInstrs::getLaneMaskForMO(const MachineOperand &MO) const
|
||||
return TRI->getSubRegIndexLaneMask(SubReg);
|
||||
}
|
||||
|
||||
/// addVRegDefDeps - Add register output and data dependencies from this SUnit
|
||||
/// to instructions that occur later in the same scheduling region if they read
|
||||
/// from or write to the virtual register defined at OperIdx.
|
||||
/// Adds register output and data dependencies from this SUnit to instructions
|
||||
/// that occur later in the same scheduling region if they read from or write to
|
||||
/// the virtual register defined at OperIdx.
|
||||
///
|
||||
/// TODO: Hoist loop induction variable increments. This has to be
|
||||
/// reevaluated. Generally, IV scheduling should be done before coalescing.
|
||||
@@ -515,10 +500,10 @@ void ScheduleDAGInstrs::addVRegDefDeps(SUnit *SU, unsigned OperIdx) {
|
||||
CurrentVRegDefs.insert(VReg2SUnit(Reg, LaneMask, SU));
|
||||
}
|
||||
|
||||
/// addVRegUseDeps - Add a register data dependency if the instruction that
|
||||
/// defines the virtual register used at OperIdx is mapped to an SUnit. Add a
|
||||
/// register antidependency from this SUnit to instructions that occur later in
|
||||
/// the same scheduling region if they write the virtual register.
|
||||
/// \brief Adds a register data dependency if the instruction that defines the
|
||||
/// virtual register used at OperIdx is mapped to an SUnit. Add a register
|
||||
/// antidependency from this SUnit to instructions that occur later in the same
|
||||
/// scheduling region if they write the virtual register.
|
||||
///
|
||||
/// TODO: Handle ExitSU "uses" properly.
|
||||
void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
|
||||
@@ -545,14 +530,14 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true if MI is an instruction we are unable to reason about
|
||||
/// Returns true if MI is an instruction we are unable to reason about
|
||||
/// (like a call or something with unmodeled side effects).
|
||||
static inline bool isGlobalMemoryObject(AliasAnalysis *AA, MachineInstr *MI) {
|
||||
return MI->isCall() || MI->hasUnmodeledSideEffects() ||
|
||||
(MI->hasOrderedMemoryRef() && !MI->isDereferenceableInvariantLoad(AA));
|
||||
}
|
||||
|
||||
/// This returns true if the two MIs need a chain edge between them.
|
||||
/// Returns true if the two MIs need a chain edge between them.
|
||||
/// This is called on normal stores and loads.
|
||||
static bool MIsNeedChainEdge(AliasAnalysis *AA, const MachineFrameInfo *MFI,
|
||||
const DataLayout &DL, MachineInstr *MIa,
|
||||
@@ -613,7 +598,6 @@ static bool MIsNeedChainEdge(AliasAnalysis *AA, const MachineFrameInfo *MFI,
|
||||
return (AAResult != NoAlias);
|
||||
}
|
||||
|
||||
/// Check whether two objects need a chain edge and add it if needed.
|
||||
void ScheduleDAGInstrs::addChainDependency (SUnit *SUa, SUnit *SUb,
|
||||
unsigned Latency) {
|
||||
if (MIsNeedChainEdge(AAForDep, &MFI, MF.getDataLayout(), SUa->getInstr(),
|
||||
@@ -624,8 +608,9 @@ void ScheduleDAGInstrs::addChainDependency (SUnit *SUa, SUnit *SUb,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an SUnit for each real instruction, numbered in top-down topological
|
||||
/// order. The instruction order A < B, implies that no edge exists from B to A.
|
||||
/// \brief Creates an SUnit for each real instruction, numbered in top-down
|
||||
/// topological order. The instruction order A < B, implies that no edge exists
|
||||
/// from B to A.
|
||||
///
|
||||
/// Map each real instruction to its SUnit.
|
||||
///
|
||||
@@ -682,14 +667,13 @@ void ScheduleDAGInstrs::initSUnits() {
|
||||
}
|
||||
|
||||
class ScheduleDAGInstrs::Value2SUsMap : public MapVector<ValueType, SUList> {
|
||||
|
||||
/// Current total number of SUs in map.
|
||||
unsigned NumNodes;
|
||||
|
||||
/// 1 for loads, 0 for stores. (see comment in SUList)
|
||||
unsigned TrueMemOrderLatency;
|
||||
public:
|
||||
|
||||
public:
|
||||
Value2SUsMap(unsigned lat = 0) : NumNodes(0), TrueMemOrderLatency(lat) {}
|
||||
|
||||
/// To keep NumNodes up to date, insert() is used instead of
|
||||
@@ -697,8 +681,8 @@ public:
|
||||
ValueType &operator[](const SUList &Key) {
|
||||
llvm_unreachable("Don't use. Use insert() instead."); };
|
||||
|
||||
/// Add SU to the SUList of V. If Map grows huge, reduce its size
|
||||
/// by calling reduce().
|
||||
/// Adds SU to the SUList of V. If Map grows huge, reduce its size by calling
|
||||
/// reduce().
|
||||
void inline insert(SUnit *SU, ValueType V) {
|
||||
MapVector::operator[](V).push_back(SU);
|
||||
NumNodes++;
|
||||
@@ -723,7 +707,7 @@ public:
|
||||
|
||||
unsigned inline size() const { return NumNodes; }
|
||||
|
||||
/// Count the number of SUs in this map after a reduction.
|
||||
/// Counts the number of SUs in this map after a reduction.
|
||||
void reComputeSize(void) {
|
||||
NumNodes = 0;
|
||||
for (auto &I : *this)
|
||||
@@ -797,9 +781,6 @@ void ScheduleDAGInstrs::insertBarrierChain(Value2SUsMap &map) {
|
||||
map.reComputeSize();
|
||||
}
|
||||
|
||||
/// If RegPressure is non-null, compute register pressure as a side effect. The
|
||||
/// DAG builder is an efficient place to do it because it already visits
|
||||
/// operands.
|
||||
void ScheduleDAGInstrs::buildSchedGraph(AliasAnalysis *AA,
|
||||
RegPressureTracker *RPTracker,
|
||||
PressureDiffs *PDiffs,
|
||||
@@ -1088,10 +1069,6 @@ void ScheduleDAGInstrs::Value2SUsMap::dump() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reduce maps in FIFO order, by N SUs. This is better than turning
|
||||
/// every Nth memory SU into BarrierChain in buildSchedGraph(), since
|
||||
/// it avoids unnecessary edges between seen SUs above the new
|
||||
/// BarrierChain, and those below it.
|
||||
void ScheduleDAGInstrs::reduceHugeMemNodeMaps(Value2SUsMap &stores,
|
||||
Value2SUsMap &loads, unsigned N) {
|
||||
DEBUG(dbgs() << "Before reduction:\nStoring SUnits:\n";
|
||||
@@ -1142,7 +1119,6 @@ void ScheduleDAGInstrs::reduceHugeMemNodeMaps(Value2SUsMap &stores,
|
||||
loads.dump());
|
||||
}
|
||||
|
||||
/// \brief Initialize register live-range state for updating kills.
|
||||
void ScheduleDAGInstrs::startBlockForKills(MachineBasicBlock *BB) {
|
||||
// Start with no live registers.
|
||||
LiveRegs.reset();
|
||||
@@ -1218,8 +1194,8 @@ bool ScheduleDAGInstrs::toggleKillFlag(MachineInstr *MI, MachineOperand &MO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Reuse the LivePhysRegs utility for this.
|
||||
void ScheduleDAGInstrs::fixupKills(MachineBasicBlock *MBB) {
|
||||
// FIXME: Reuse the LivePhysRegs utility for this.
|
||||
DEBUG(dbgs() << "Fixup kills for BB#" << MBB->getNumber() << '\n');
|
||||
|
||||
LiveRegs.resize(TRI->getNumRegs());
|
||||
@@ -1347,7 +1323,7 @@ std::string ScheduleDAGInstrs::getDAGName() const {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace llvm {
|
||||
/// \brief Internal state used to compute SchedDFSResult.
|
||||
/// Internal state used to compute SchedDFSResult.
|
||||
class SchedDFSImpl {
|
||||
SchedDFSResult &R;
|
||||
|
||||
@@ -1358,8 +1334,8 @@ class SchedDFSImpl {
|
||||
|
||||
struct RootData {
|
||||
unsigned NodeID;
|
||||
unsigned ParentNodeID; // Parent node (member of the parent subtree).
|
||||
unsigned SubInstrCount; // Instr count in this tree only, not children.
|
||||
unsigned ParentNodeID; ///< Parent node (member of the parent subtree).
|
||||
unsigned SubInstrCount; ///< Instr count in this tree only, not children.
|
||||
|
||||
RootData(unsigned id): NodeID(id),
|
||||
ParentNodeID(SchedDFSResult::InvalidSubtreeID),
|
||||
@@ -1375,7 +1351,7 @@ public:
|
||||
RootSet.setUniverse(R.DFSNodeData.size());
|
||||
}
|
||||
|
||||
/// Return true if this node been visited by the DFS traversal.
|
||||
/// Returns true if this node been visited by the DFS traversal.
|
||||
///
|
||||
/// During visitPostorderNode the Node's SubtreeID is assigned to the Node
|
||||
/// ID. Later, SubtreeID is updated but remains valid.
|
||||
@@ -1384,7 +1360,7 @@ public:
|
||||
!= SchedDFSResult::InvalidSubtreeID;
|
||||
}
|
||||
|
||||
/// Initialize this node's instruction count. We don't need to flag the node
|
||||
/// Initializes this node's instruction count. We don't need to flag the node
|
||||
/// visited until visitPostorder because the DAG cannot have cycles.
|
||||
void visitPreorder(const SUnit *SU) {
|
||||
R.DFSNodeData[SU->NodeNum].InstrCount =
|
||||
@@ -1433,8 +1409,8 @@ public:
|
||||
RootSet[SU->NodeNum] = RData;
|
||||
}
|
||||
|
||||
/// Called once for each tree edge after calling visitPostOrderNode on the
|
||||
/// predecessor. Increment the parent node's instruction count and
|
||||
/// \brief Called once for each tree edge after calling visitPostOrderNode on
|
||||
/// the predecessor. Increment the parent node's instruction count and
|
||||
/// preemptively join this subtree to its parent's if it is small enough.
|
||||
void visitPostorderEdge(const SDep &PredDep, const SUnit *Succ) {
|
||||
R.DFSNodeData[Succ->NodeNum].InstrCount
|
||||
@@ -1442,13 +1418,13 @@ public:
|
||||
joinPredSubtree(PredDep, Succ);
|
||||
}
|
||||
|
||||
/// Add a connection for cross edges.
|
||||
/// Adds a connection for cross edges.
|
||||
void visitCrossEdge(const SDep &PredDep, const SUnit *Succ) {
|
||||
ConnectionPairs.push_back(std::make_pair(PredDep.getSUnit(), Succ));
|
||||
}
|
||||
|
||||
/// Set each node's subtree ID to the representative ID and record connections
|
||||
/// between trees.
|
||||
/// Sets each node's subtree ID to the representative ID and record
|
||||
/// connections between trees.
|
||||
void finalize() {
|
||||
SubtreeClasses.compress();
|
||||
R.DFSTreeData.resize(SubtreeClasses.getNumClasses());
|
||||
@@ -1484,8 +1460,8 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Join the predecessor subtree with the successor that is its DFS
|
||||
/// parent. Apply some heuristics before joining.
|
||||
/// Joins the predecessor subtree with the successor that is its DFS parent.
|
||||
/// Applies some heuristics before joining.
|
||||
bool joinPredSubtree(const SDep &PredDep, const SUnit *Succ,
|
||||
bool CheckLimit = true) {
|
||||
assert(PredDep.getKind() == SDep::Data && "Subtrees are for data edges");
|
||||
@@ -1531,10 +1507,10 @@ protected:
|
||||
} while (FromTree != SchedDFSResult::InvalidSubtreeID);
|
||||
}
|
||||
};
|
||||
} // namespace llvm
|
||||
} // end namespace llvm
|
||||
|
||||
namespace {
|
||||
/// \brief Manage the stack used by a reverse depth-first search over the DAG.
|
||||
/// Manage the stack used by a reverse depth-first search over the DAG.
|
||||
class SchedDAGReverseDFS {
|
||||
std::vector<std::pair<const SUnit*, SUnit::const_pred_iterator> > DFSStack;
|
||||
public:
|
||||
@@ -1569,7 +1545,7 @@ static bool hasDataSucc(const SUnit *SU) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Compute an ILP metric for all nodes in the subDAG reachable via depth-first
|
||||
/// Computes an ILP metric for all nodes in the subDAG reachable via depth-first
|
||||
/// search from this root.
|
||||
void SchedDFSResult::compute(ArrayRef<SUnit> SUnits) {
|
||||
if (!IsBottomUp)
|
||||
@@ -1648,4 +1624,4 @@ raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val) {
|
||||
return OS;
|
||||
}
|
||||
|
||||
} // namespace llvm
|
||||
} // end namespace llvm
|
||||
|
||||
Reference in New Issue
Block a user