LLVM: lib/MCA/Stages/DispatchStage.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

21

22#define DEBUG_TYPE "llvm-mca"

23

24namespace llvm {

25namespace mca {

26

31 : DispatchWidth(MaxDispatchWidth), AvailableEntries(MaxDispatchWidth),

32 CarryOver(0U), STI(Subtarget), RCU(R), PRF(F) {

33 if (!DispatchWidth)

35}

36

37void DispatchStage::notifyInstructionDispatched(const InstRef &IR,

39 unsigned UOps) const {

40 LLVM_DEBUG(dbgs() << "[E] Instruction Dispatched: #" << IR << '\n');

43}

44

45bool DispatchStage::checkPRF(const InstRef &IR) const {

47 for (const WriteState &RegDef : IR.getInstruction()->getDefs())

49

50 const unsigned RegisterMask = PRF.isAvailable(RegDefs);

51

52 if (RegisterMask) {

55 return false;

56 }

57

58 return true;

59}

60

61bool DispatchStage::checkRCU(const InstRef &IR) const {

62 const unsigned NumMicroOps = IR.getInstruction()->getNumMicroOps();

63 if (RCU.isAvailable(NumMicroOps))

64 return true;

67 return false;

68}

69

70bool DispatchStage::canDispatch(const InstRef &IR) const {

71 bool CanDispatch = checkRCU(IR);

72 CanDispatch &= checkPRF(IR);

74 return CanDispatch;

75}

76

78 assert(!CarryOver && "Cannot dispatch another instruction!");

80 const unsigned NumMicroOps = IS.getNumMicroOps();

81 if (NumMicroOps > DispatchWidth) {

82 assert(AvailableEntries == DispatchWidth);

83 AvailableEntries = 0;

84 CarryOver = NumMicroOps - DispatchWidth;

85 CarriedOver = IR;

86 } else {

87 assert(AvailableEntries >= NumMicroOps);

88 AvailableEntries -= NumMicroOps;

89 }

90

91

92 if (IS.getEndGroup())

93 AvailableEntries = 0;

94

95

96 if (IS.isOptimizableMove())

97 if (PRF.tryEliminateMoveOrSwap(IS.getDefs(), IS.getUses()))

98 IS.setEliminated();

99

100

101

102

103

104

105

106

107

108

109 if (!IS.isEliminated()) {

110 for (ReadState &RS : IS.getUses())

111 PRF.addRegisterRead(RS, STI);

112 }

113

114

115

116

117 SmallVector<unsigned, 4> RegisterFiles(PRF.getNumRegisterFiles());

118 for (WriteState &WS : IS.getDefs())

119 PRF.addRegisterWrite(WriteRef(IR.getSourceIndex(), &WS), RegisterFiles);

120

121

122 unsigned RCUTokenID = RCU.dispatch(IR);

123

124 IS.dispatch(RCUTokenID);

125

126

127

128 notifyInstructionDispatched(IR, RegisterFiles,

129 std::min(DispatchWidth, NumMicroOps));

131}

132

134

135

136 if (!CarryOver) {

137 AvailableEntries = DispatchWidth;

139 }

140

141 AvailableEntries = CarryOver >= DispatchWidth ? 0 : DispatchWidth - CarryOver;

142 unsigned DispatchedOpcodes = DispatchWidth - AvailableEntries;

143 CarryOver -= DispatchedOpcodes;

144 assert(CarriedOver && "Invalid dispatched instruction");

145

147 notifyInstructionDispatched(CarriedOver, RegisterFiles, DispatchedOpcodes);

148 if (!CarryOver)

151}

152

154

155 if (!AvailableEntries)

156 return false;

157

160 unsigned Required = std::min(NumMicroOps, DispatchWidth);

161 if (Required > AvailableEntries)

162 return false;

163

164 if (Inst.getBeginGroup() && AvailableEntries != DispatchWidth)

165 return false;

166

167

168

169

170 return canDispatch(IR);

171}

172

174 assert(canDispatch(IR) && "Cannot dispatch another instruction!");

175 return dispatch(IR);

176}

177

178#ifndef NDEBUG

180 PRF.dump();

181 RCU.dump();

182}

183#endif

184}

185}

unsigned const MachineRegisterInfo * MRI

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file models the dispatch component of an instruction pipeline.

This file defines the main interface for hardware event listeners.

Legalize the Machine IR a function s Machine IR

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Subclass of Error for the sole purpose of identifying the success path in the type system.

Lightweight error class with error context and mandatory checking.

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

Generic base class for all target subtargets.

const MCSchedModel & getSchedModel() const

Get the machine model for this subtarget's CPU.

reference emplace_back(ArgTypes &&... Args)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

Error cycleStart() override

Called once at the start of each cycle.

Definition DispatchStage.cpp:133

void dump() const

Definition DispatchStage.cpp:179

bool isAvailable(const InstRef &IR) const override

Returns true if it can execute IR during this cycle.

Definition DispatchStage.cpp:153

Error execute(InstRef &IR) override

The primary action that this stage performs on instruction IR.

Definition DispatchStage.cpp:173

DispatchStage(const MCSubtargetInfo &Subtarget, const MCRegisterInfo &MRI, unsigned MaxDispatchWidth, RetireControlUnit &R, RegisterFile &F)

Definition DispatchStage.cpp:27

An InstRef contains both a SourceMgr index and Instruction pair.

unsigned getNumMicroOps() const

bool getBeginGroup() const

An instruction propagated through the simulated instruction pipeline.

Manages hardware register files, and tracks register definitions for register renaming purposes.

unsigned isAvailable(ArrayRef< MCPhysReg > Regs) const

Error moveToTheNextStage(InstRef &IR)

Called when an instruction is ready to move the next pipeline stage.

void notifyEvent(const EventT &Event) const

Notify listeners of a particular hardware event.

bool checkNextStage(const InstRef &IR) const

friend class Instruction

Iterator for Instructions in a `BasicBlock.

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

This class tracks which instructions are in-flight (i.e., dispatched but not retired) in the OoO back...