llvm.org GIT mirror llvm / d510dbf
[llvm-mca] Remove namespace prefixes made redundant by r345612. NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@345730 91177308-0d34-0410-b5e6-96231b3b80d8 Andrea Di Biagio 10 months ago
18 changed file(s) with 130 addition(s) and 150 deletion(s). Raw diff Collapse all Expand all
4242 };
4343
4444 class Context {
45 llvm::SmallVector, 4> Hardware;
46 const llvm::MCRegisterInfo &MRI;
47 const llvm::MCSubtargetInfo &STI;
45 SmallVector, 4> Hardware;
46 const MCRegisterInfo &MRI;
47 const MCSubtargetInfo &STI;
4848
4949 public:
50 Context(const llvm::MCRegisterInfo &R, const llvm::MCSubtargetInfo &S)
51 : MRI(R), STI(S) {}
50 Context(const MCRegisterInfo &R, const MCSubtargetInfo &S) : MRI(R), STI(S) {}
5251 Context(const Context &C) = delete;
5352 Context &operator=(const Context &C) = delete;
5453
6161 class HWInstructionIssuedEvent : public HWInstructionEvent {
6262 public:
6363 using ResourceRef = std::pair;
64 HWInstructionIssuedEvent(
65 const InstRef &IR,
66 llvm::ArrayRef> UR)
64 HWInstructionIssuedEvent(const InstRef &IR,
65 ArrayRef> UR)
6766 : HWInstructionEvent(HWInstructionEvent::Issued, IR), UsedResources(UR) {}
6867
69 llvm::ArrayRef> UsedResources;
68 ArrayRef> UsedResources;
7069 };
7170
7271 class HWInstructionDispatchedEvent : public HWInstructionEvent {
7372 public:
74 HWInstructionDispatchedEvent(const InstRef &IR, llvm::ArrayRef Regs,
73 HWInstructionDispatchedEvent(const InstRef &IR, ArrayRef Regs,
7574 unsigned UOps)
7675 : HWInstructionEvent(HWInstructionEvent::Dispatched, IR),
7776 UsedPhysRegs(Regs), MicroOpcodes(UOps) {}
7877 // Number of physical register allocated for this instruction. There is one
7978 // entry per register file.
80 llvm::ArrayRef UsedPhysRegs;
79 ArrayRef UsedPhysRegs;
8180 // Number of micro opcodes dispatched.
8281 // This field is often set to the total number of micro-opcodes specified by
8382 // the instruction descriptor of IR.
9291
9392 class HWInstructionRetiredEvent : public HWInstructionEvent {
9493 public:
95 HWInstructionRetiredEvent(const InstRef &IR, llvm::ArrayRef Regs)
94 HWInstructionRetiredEvent(const InstRef &IR, ArrayRef Regs)
9695 : HWInstructionEvent(HWInstructionEvent::Retired, IR),
9796 FreedPhysRegs(Regs) {}
9897 // Number of register writes that have been architecturally committed. There
9998 // is one entry per register file.
100 llvm::ArrayRef FreedPhysRegs;
99 ArrayRef FreedPhysRegs;
101100 };
102101
103102 // A HWStallEvent represents a pipeline stall caused by the lack of hardware
141140 // Events generated by the Scheduler when buffered resources are
142141 // consumed/freed for an instruction.
143142 virtual void onReservedBuffers(const InstRef &Inst,
144 llvm::ArrayRef Buffers) {}
143 ArrayRef Buffers) {}
145144 virtual void onReleasedBuffers(const InstRef &Inst,
146 llvm::ArrayRef Buffers) {}
145 ArrayRef Buffers) {}
147146
148147 virtual ~HWEventListener() {}
149148
128128 void dump() const;
129129 #endif
130130
131 enum Status {
132 LSU_AVAILABLE = 0,
133 LSU_LQUEUE_FULL,
134 LSU_SQUEUE_FULL
135 };
131 enum Status { LSU_AVAILABLE = 0, LSU_LQUEUE_FULL, LSU_SQUEUE_FULL };
136132
137133 // Returns LSU_AVAILABLE if there are enough load/store queue entries to serve
138134 // IR. It also returns LSU_AVAILABLE if IR is not a memory operation.
3333 /// Manages hardware register files, and tracks register definitions for
3434 /// register renaming purposes.
3535 class RegisterFile : public HardwareUnit {
36 const llvm::MCRegisterInfo &MRI;
36 const MCRegisterInfo &MRI;
3737
3838 // class RegisterMappingTracker is a physical register file (PRF) descriptor.
3939 // There is one RegisterMappingTracker for every PRF definition in the
8484 //
8585 // Users can limit the number of physical registers that are available in
8686 // regsiter file #0 specifying command line flag `-register-file-size=`.
87 llvm::SmallVector RegisterFiles;
87 SmallVector RegisterFiles;
8888
8989 // This type is used to propagate information about the owner of a register,
9090 // and the cost of allocating it in the PRF. Register cost is defined as the
100100 //
101101 // There is a RegisterRenamingInfo object for every logical register defined
102102 // by the target. RegisteRenamingInfo objects are stored into vector
103 // `RegisterMappings`, and llvm::MCPhysReg IDs can be used to reference
103 // `RegisterMappings`, and MCPhysReg IDs can be used to reference
104104 // elements in that vector.
105105 //
106106 // Each RegisterRenamingInfo is owned by a PRF, and field `IndexPlusCost`
116116 // register definition.
117117 struct RegisterRenamingInfo {
118118 IndexPlusCostPairTy IndexPlusCost;
119 llvm::MCPhysReg RenameAs;
120 llvm::MCPhysReg AliasRegID;
119 MCPhysReg RenameAs;
120 MCPhysReg AliasRegID;
121121 bool AllowMoveElimination;
122122 RegisterRenamingInfo()
123123 : IndexPlusCost(std::make_pair(0U, 1U)), RenameAs(0U), AliasRegID(0U),
143143
144144 // Used to track zero registers. There is one bit for each register defined by
145145 // the target. Bits are set for registers that are known to be zero.
146 llvm::APInt ZeroRegisters;
146 APInt ZeroRegisters;
147147
148148 // This method creates a new register file descriptor.
149149 // The new register file owns all of the registers declared by register
159159 // Here FPRegisterFile contains all the registers defined by register class
160160 // VR128RegClass and VR256RegClass. FPRegisterFile implements 60
161161 // registers which can be used for register renaming purpose.
162 void addRegisterFile(const llvm::MCRegisterFileDesc &RF,
163 llvm::ArrayRef Entries);
162 void addRegisterFile(const MCRegisterFileDesc &RF,
163 ArrayRef Entries);
164164
165165 // Consumes physical registers in each register file specified by the
166166 // `IndexPlusCostPairTy`. This method is called from `addRegisterMapping()`.
167167 void allocatePhysRegs(const RegisterRenamingInfo &Entry,
168 llvm::MutableArrayRef UsedPhysRegs);
168 MutableArrayRef UsedPhysRegs);
169169
170170 // Releases previously allocated physical registers from the register file(s).
171171 // This method is called from `invalidateRegisterMapping()`.
172172 void freePhysRegs(const RegisterRenamingInfo &Entry,
173 llvm::MutableArrayRef FreedPhysRegs);
173 MutableArrayRef FreedPhysRegs);
174174
175175 // Create an instance of RegisterMappingTracker for every register file
176176 // specified by the processor model.
177177 // If no register file is specified, then this method creates a default
178178 // register file with an unbounded number of physical registers.
179 void initialize(const llvm::MCSchedModel &SM, unsigned NumRegs);
179 void initialize(const MCSchedModel &SM, unsigned NumRegs);
180180
181181 public:
182 RegisterFile(const llvm::MCSchedModel &SM, const llvm::MCRegisterInfo &mri,
182 RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri,
183183 unsigned NumRegs = 0);
184184
185185 // This method updates the register mappings inserting a new register
186186 // definition. This method is also responsible for updating the number of
187187 // allocated physical registers in each register file modified by the write.
188188 // No physical regiser is allocated if this write is from a zero-idiom.
189 void addRegisterWrite(WriteRef Write,
190 llvm::MutableArrayRef UsedPhysRegs);
189 void addRegisterWrite(WriteRef Write, MutableArrayRef UsedPhysRegs);
191190
192191 // Removes write \param WS from the register mappings.
193192 // Physical registers may be released to reflect this update.
194193 // No registers are released if this write is from a zero-idiom.
195194 void removeRegisterWrite(const WriteState &WS,
196 llvm::MutableArrayRef FreedPhysRegs);
195 MutableArrayRef FreedPhysRegs);
197196
198197 // Returns true if a move from RS to WS can be eliminated.
199198 // On success, it updates WriteState by setting flag `WS.isEliminated`.
211210 //
212211 // Current implementation can simulate up to 32 register files (including the
213212 // special register file at index #0).
214 unsigned isAvailable(llvm::ArrayRef Regs) const;
215 void collectWrites(llvm::SmallVectorImpl &Writes,
216 unsigned RegID) const;
213 unsigned isAvailable(ArrayRef Regs) const;
214 void collectWrites(SmallVectorImpl &Writes, unsigned RegID) const;
217215 unsigned getNumRegisterFiles() const { return RegisterFiles.size(); }
218216
219217 // Notify each PRF that a new cycle just started.
188188 }
189189
190190 public:
191 ResourceState(const llvm::MCProcResourceDesc &Desc, unsigned Index,
192 uint64_t Mask);
191 ResourceState(const MCProcResourceDesc &Desc, unsigned Index, uint64_t Mask);
193192
194193 unsigned getProcResourceID() const { return ProcResourceDescIndex; }
195194 uint64_t getResourceMask() const { return ResourceMask; }
210209 /// `NumUnits` available units.
211210 bool isReady(unsigned NumUnits = 1) const;
212211
213 bool isAResourceGroup() const {
214 return llvm::countPopulation(ResourceMask) > 1;
215 }
212 bool isAResourceGroup() const { return countPopulation(ResourceMask) > 1; }
216213
217214 bool containsResource(uint64_t ID) const { return ResourceMask & ID; }
218215
227224 }
228225
229226 unsigned getNumUnits() const {
230 return isAResourceGroup() ? 1U : llvm::countPopulation(ResourceSizeMask);
227 return isAResourceGroup() ? 1U : countPopulation(ResourceSizeMask);
231228 }
232229
233230 /// Checks if there is an available slot in the resource buffer.
285282
286283 // Keeps track of which resources are busy, and how many cycles are left
287284 // before those become usable again.
288 llvm::SmallDenseMap BusyResources;
285 SmallDenseMap BusyResources;
289286
290287 // A table to map processor resource IDs to processor resource masks.
291 llvm::SmallVector ProcResID2Mask;
288 SmallVector ProcResID2Mask;
292289
293290 // Returns the actual resource unit that will be used.
294291 ResourceRef selectPipe(uint64_t ResourceID);
304301 uint64_t ResourceMask);
305302
306303 public:
307 ResourceManager(const llvm::MCSchedModel &SM);
304 ResourceManager(const MCSchedModel &SM);
308305 virtual ~ResourceManager() = default;
309306
310307 // Overrides the selection strategy for the resource at index ResourceID in
318315
319316 // Returns RS_BUFFER_AVAILABLE if buffered resources are not reserved, and if
320317 // there are enough available slots in the buffers.
321 ResourceStateEvent canBeDispatched(llvm::ArrayRef Buffers) const;
318 ResourceStateEvent canBeDispatched(ArrayRef Buffers) const;
322319
323320 // Return the processor resource identifier associated to this Mask.
324321 unsigned resolveResourceMask(uint64_t Mask) const;
325322
326323 // Consume a slot in every buffered resource from array 'Buffers'. Resource
327324 // units that are dispatch hazards (i.e. BufferSize=0) are marked as reserved.
328 void reserveBuffers(llvm::ArrayRef Buffers);
325 void reserveBuffers(ArrayRef Buffers);
329326
330327 // Release buffer entries previously allocated by method reserveBuffers.
331 void releaseBuffers(llvm::ArrayRef Buffers);
328 void releaseBuffers(ArrayRef Buffers);
332329
333330 // Reserve a processor resource. A reserved resource is not available for
334331 // instruction issue until it is released.
345342
346343 void issueInstruction(
347344 const InstrDesc &Desc,
348 llvm::SmallVectorImpl> &Pipes);
349
350 void cycleEvent(llvm::SmallVectorImpl &ResourcesFreed);
345 SmallVectorImpl> &Pipes);
346
347 void cycleEvent(SmallVectorImpl &ResourcesFreed);
351348
352349 #ifndef NDEBUG
353350 void dump() const {
6262 std::vector Queue;
6363
6464 public:
65 RetireControlUnit(const llvm::MCSchedModel &SM);
65 RetireControlUnit(const MCSchedModel &SM);
6666
6767 bool isEmpty() const { return AvailableSlots == Queue.size(); }
6868 bool isAvailable(unsigned Quantity = 1) const {
104104 /// Issue an instruction without updating the ready queue.
105105 void issueInstructionImpl(
106106 InstRef &IR,
107 llvm::SmallVectorImpl> &Pipes);
107 SmallVectorImpl> &Pipes);
108108
109109 // Identify instructions that have finished executing, and remove them from
110110 // the IssuedSet. References to executed instructions are added to input
111111 // vector 'Executed'.
112 void updateIssuedSet(llvm::SmallVectorImpl &Executed);
112 void updateIssuedSet(SmallVectorImpl &Executed);
113113
114114 // Try to promote instructions from WaitSet to ReadySet.
115115 // Add promoted instructions to the 'Ready' vector in input.
116 void promoteToReadySet(llvm::SmallVectorImpl &Ready);
116 void promoteToReadySet(SmallVectorImpl &Ready);
117117
118118 public:
119 Scheduler(const llvm::MCSchedModel &Model, LSUnit *Lsu)
120 : LSU(Lsu), Resources(llvm::make_unique(Model)) {
119 Scheduler(const MCSchedModel &Model, LSUnit *Lsu)
120 : LSU(Lsu), Resources(make_unique(Model)) {
121121 initializeStrategy(nullptr);
122122 }
123 Scheduler(const llvm::MCSchedModel &Model, LSUnit *Lsu,
123 Scheduler(const MCSchedModel &Model, LSUnit *Lsu,
124124 std::unique_ptr SelectStrategy)
125 : LSU(Lsu), Resources(llvm::make_unique(Model)) {
125 : LSU(Lsu), Resources(make_unique(Model)) {
126126 initializeStrategy(std::move(SelectStrategy));
127127 }
128128 Scheduler(std::unique_ptr RM, LSUnit *Lsu,
167167 /// result of this event.
168168 void issueInstruction(
169169 InstRef &IR,
170 llvm::SmallVectorImpl> &Used,
171 llvm::SmallVectorImpl &Ready);
170 SmallVectorImpl> &Used,
171 SmallVectorImpl &Ready);
172172
173173 /// Returns true if IR has to be issued immediately, or if IR is a zero
174174 /// latency instruction.
181181 /// have changed in state, and that are now available to new instructions.
182182 /// Instructions executed are added to vector Executed, while vector Ready is
183183 /// populated with instructions that have become ready in this new cycle.
184 void cycleEvent(llvm::SmallVectorImpl &Freed,
185 llvm::SmallVectorImpl &Ready,
186 llvm::SmallVectorImpl &Executed);
184 void cycleEvent(SmallVectorImpl &Freed,
185 SmallVectorImpl &Ready,
186 SmallVectorImpl &Executed);
187187
188188 /// Convert a resource mask into a valid llvm processor resource identifier.
189189 unsigned getResourceID(uint64_t Mask) const {
202202 // This routine performs a sanity check. This routine should only be called
203203 // when we know that 'IR' is not in the scheduler's instruction queues.
204204 void sanityCheck(const InstRef &IR) const {
205 assert(llvm::find(WaitSet, IR) == WaitSet.end());
206 assert(llvm::find(ReadySet, IR) == ReadySet.end());
207 assert(llvm::find(IssuedSet, IR) == IssuedSet.end());
205 assert(find(WaitSet, IR) == WaitSet.end() && "Already in the wait set!");
206 assert(find(ReadySet, IR) == ReadySet.end() && "Already in the ready set!");
207 assert(find(IssuedSet, IR) == IssuedSet.end() && "Already executing!");
208208 }
209209 #endif // !NDEBUG
210210 };
3636 /// Information from the machine scheduling model is used to identify processor
3737 /// resources that are consumed by an instruction.
3838 class InstrBuilder {
39 const llvm::MCSubtargetInfo &STI;
40 const llvm::MCInstrInfo &MCII;
41 const llvm::MCRegisterInfo &MRI;
42 const llvm::MCInstrAnalysis &MCIA;
43 llvm::SmallVector ProcResourceMasks;
39 const MCSubtargetInfo &STI;
40 const MCInstrInfo &MCII;
41 const MCRegisterInfo &MRI;
42 const MCInstrAnalysis &MCIA;
43 SmallVector ProcResourceMasks;
4444
45 llvm::DenseMap> Descriptors;
46 llvm::DenseMap>
47 VariantDescriptors;
45 DenseMap> Descriptors;
46 DenseMap> VariantDescriptors;
4847
49 llvm::Expected
50 createInstrDescImpl(const llvm::MCInst &MCI);
51 llvm::Expected
52 getOrCreateInstrDesc(const llvm::MCInst &MCI);
48 Expected createInstrDescImpl(const MCInst &MCI);
49 Expected getOrCreateInstrDesc(const MCInst &MCI);
5350
5451 InstrBuilder(const InstrBuilder &) = delete;
5552 InstrBuilder &operator=(const InstrBuilder &) = delete;
5653
57 llvm::Error populateWrites(InstrDesc &ID, const llvm::MCInst &MCI,
58 unsigned SchedClassID);
59 llvm::Error populateReads(InstrDesc &ID, const llvm::MCInst &MCI,
60 unsigned SchedClassID);
61 llvm::Error verifyInstrDesc(const InstrDesc &ID,
62 const llvm::MCInst &MCI) const;
54 Error populateWrites(InstrDesc &ID, const MCInst &MCI, unsigned SchedClassID);
55 Error populateReads(InstrDesc &ID, const MCInst &MCI, unsigned SchedClassID);
56 Error verifyInstrDesc(const InstrDesc &ID, const MCInst &MCI) const;
6357
6458 public:
65 InstrBuilder(const llvm::MCSubtargetInfo &STI, const llvm::MCInstrInfo &MCII,
66 const llvm::MCRegisterInfo &RI, const llvm::MCInstrAnalysis &IA);
59 InstrBuilder(const MCSubtargetInfo &STI, const MCInstrInfo &MCII,
60 const MCRegisterInfo &RI, const MCInstrAnalysis &IA);
6761
6862 void clear() { VariantDescriptors.shrink_and_clear(); }
6963
70 llvm::Expected>
71 createInstruction(const llvm::MCInst &MCI);
64 Expected> createInstruction(const MCInst &MCI);
7265 };
7366 } // namespace mca
7467 } // namespace llvm
328328
329329 // Output dependencies.
330330 // One entry per each implicit and explicit register definition.
331 llvm::SmallVector Defs;
331 SmallVector Defs;
332332
333333 // Input dependencies.
334334 // One entry per each implicit and explicit register use.
335 llvm::SmallVector Uses;
335 SmallVector Uses;
336336
337337 public:
338338 InstructionBase(const InstrDesc &D) : Desc(D), IsOptimizableMove(false) {}
339339
340 llvm::SmallVectorImpl &getDefs() { return Defs; }
341 const llvm::ArrayRef getDefs() const { return Defs; }
342 llvm::SmallVectorImpl &getUses() { return Uses; }
343 const llvm::ArrayRef getUses() const { return Uses; }
340 SmallVectorImpl &getDefs() { return Defs; }
341 const ArrayRef getDefs() const { return Defs; }
342 SmallVectorImpl &getUses() { return Uses; }
343 const ArrayRef getUses() const { return Uses; }
344344 const InstrDesc &getDesc() const { return Desc; }
345345
346346 unsigned getLatency() const { return Desc.MaxLatency; }
347347
348348 bool hasDependentUsers() const {
349 return llvm::any_of(
350 Defs, [](const WriteState &Def) { return Def.getNumUsers() > 0; });
349 return any_of(Defs,
350 [](const WriteState &Def) { return Def.getNumUsers() > 0; });
351351 }
352352
353353 unsigned getNumUsers() const {
419419
420420 bool isEliminated() const {
421421 return isReady() && getDefs().size() &&
422 llvm::all_of(getDefs(),
423 [](const WriteState &W) { return W.isEliminated(); });
422 all_of(getDefs(),
423 [](const WriteState &W) { return W.isEliminated(); });
424424 }
425425
426426 // Forces a transition from state IS_AVAILABLE to state IS_EXECUTED.
457457 void invalidate() { Data.second = nullptr; }
458458
459459 #ifndef NDEBUG
460 void print(llvm::raw_ostream &OS) const { OS << getSourceIndex(); }
460 void print(raw_ostream &OS) const { OS << getSourceIndex(); }
461461 #endif
462462 };
463463
464464 #ifndef NDEBUG
465 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InstRef &IR) {
465 inline raw_ostream &operator<<(raw_ostream &OS, const InstRef &IR) {
466466 IR.print(OS);
467467 return OS;
468468 }
5454 Pipeline &operator=(const Pipeline &P) = delete;
5555
5656 /// An ordered list of stages that define this instruction pipeline.
57 llvm::SmallVector, 8> Stages;
57 SmallVector, 8> Stages;
5858 std::set Listeners;
5959 unsigned Cycles;
6060
61 llvm::Error runCycle();
61 Error runCycle();
6262 bool hasWorkToProcess();
6363 void notifyCycleBegin();
6464 void notifyCycleEnd();
6666 public:
6767 Pipeline() : Cycles(0) {}
6868 void appendStage(std::unique_ptr S);
69 llvm::Error run();
69 Error run();
7070 void addEventListener(HWEventListener *Listener);
7171 };
7272 } // namespace mca
2626
2727 class SourceMgr {
2828 using UniqueInst = std::unique_ptr;
29 llvm::ArrayRef Sequence;
29 ArrayRef Sequence;
3030 unsigned Current;
3131 const unsigned Iterations;
3232 static const unsigned DefaultIterations = 100;
3333
3434 public:
35 SourceMgr(llvm::ArrayRef S, unsigned Iter)
35 SourceMgr(ArrayRef S, unsigned Iter)
3636 : Sequence(S), Current(0), Iterations(Iter ? Iter : DefaultIterations) {}
3737
3838 unsigned getNumIterations() const { return Iterations; }
4545 return SourceRef(Current, *Sequence[Current % Sequence.size()]);
4646 }
4747
48 using const_iterator = llvm::ArrayRef::const_iterator;
48 using const_iterator = ArrayRef::const_iterator;
4949 const_iterator begin() const { return Sequence.begin(); }
5050 const_iterator end() const { return Sequence.end(); }
5151 };
5252 unsigned AvailableEntries;
5353 unsigned CarryOver;
5454 InstRef CarriedOver;
55 const llvm::MCSubtargetInfo &STI;
55 const MCSubtargetInfo &STI;
5656 RetireControlUnit &RCU;
5757 RegisterFile &PRF;
5858
5959 bool checkRCU(const InstRef &IR) const;
6060 bool checkPRF(const InstRef &IR) const;
6161 bool canDispatch(const InstRef &IR) const;
62 llvm::Error dispatch(InstRef IR);
62 Error dispatch(InstRef IR);
6363
64 void updateRAWDependencies(ReadState &RS, const llvm::MCSubtargetInfo &STI);
64 void updateRAWDependencies(ReadState &RS, const MCSubtargetInfo &STI);
6565
6666 void notifyInstructionDispatched(const InstRef &IR,
67 llvm::ArrayRef UsedPhysRegs,
67 ArrayRef UsedPhysRegs,
6868 unsigned uOps) const;
6969
70 void collectWrites(llvm::SmallVectorImpl &Vec,
71 unsigned RegID) const {
70 void collectWrites(SmallVectorImpl &Vec, unsigned RegID) const {
7271 return PRF.collectWrites(Vec, RegID);
7372 }
7473
7574 public:
76 DispatchStage(const llvm::MCSubtargetInfo &Subtarget,
77 const llvm::MCRegisterInfo &MRI, unsigned MaxDispatchWidth,
78 RetireControlUnit &R, RegisterFile &F)
75 DispatchStage(const MCSubtargetInfo &Subtarget, const MCRegisterInfo &MRI,
76 unsigned MaxDispatchWidth, RetireControlUnit &R,
77 RegisterFile &F)
7978 : DispatchWidth(MaxDispatchWidth), AvailableEntries(MaxDispatchWidth),
8079 CarryOver(0U), CarriedOver(), STI(Subtarget), RCU(R), PRF(F) {}
8180
8483 // The dispatch logic internally doesn't buffer instructions. So there is
8584 // never work to do at the beginning of every cycle.
8685 bool hasWorkToComplete() const override { return false; }
87 llvm::Error cycleStart() override;
88 llvm::Error execute(InstRef &IR) override;
86 Error cycleStart() override;
87 Error execute(InstRef &IR) override;
8988
9089 #ifndef NDEBUG
9190 void dump() const;
2828 class ExecuteStage final : public Stage {
2929 Scheduler &HWS;
3030
31 llvm::Error issueInstruction(InstRef &IR);
31 Error issueInstruction(InstRef &IR);
3232
3333 // Called at the beginning of each cycle to issue already dispatched
3434 // instructions to the underlying pipelines.
35 llvm::Error issueReadyInstructions();
35 Error issueReadyInstructions();
3636
3737 // Used to notify instructions eliminated at register renaming stage.
38 llvm::Error handleInstructionEliminated(InstRef &IR);
38 Error handleInstructionEliminated(InstRef &IR);
3939
4040 ExecuteStage(const ExecuteStage &Other) = delete;
4141 ExecuteStage &operator=(const ExecuteStage &Other) = delete;
5959 // state changes, and processor resources freed by the scheduler.
6060 // Instructions that transitioned to the 'Executed' state are automatically
6161 // moved to the next stage (i.e. RetireStage).
62 llvm::Error cycleStart() override;
63 llvm::Error execute(InstRef &IR) override;
62 Error cycleStart() override;
63 Error execute(InstRef &IR) override;
6464
6565 void notifyInstructionIssued(
6666 const InstRef &IR,
67 llvm::ArrayRef> Used) const;
67 ArrayRef> Used) const;
6868 void notifyInstructionExecuted(const InstRef &IR) const;
6969 void notifyInstructionReady(const InstRef &IR) const;
7070 void notifyResourceAvailable(const ResourceRef &RR) const;
3939
4040 bool isAvailable(const InstRef &IR) const override;
4141 bool hasWorkToComplete() const override;
42 llvm::Error execute(InstRef &IR) override;
43 llvm::Error cycleStart() override;
44 llvm::Error cycleEnd() override;
42 Error execute(InstRef &IR) override;
43 Error cycleStart() override;
44 Error cycleEnd() override;
4545 };
4646
4747 } // namespace mca
2626 namespace mca {
2727
2828 class InstructionTables final : public Stage {
29 const llvm::MCSchedModel &SM;
30 llvm::SmallVector, 4> UsedResources;
31 llvm::SmallVector Masks;
29 const MCSchedModel &SM;
30 SmallVector, 4> UsedResources;
31 SmallVector Masks;
3232
3333 public:
34 InstructionTables(const llvm::MCSchedModel &Model) : Stage(), SM(Model) {
34 InstructionTables(const MCSchedModel &Model) : Stage(), SM(Model) {
3535 computeProcResourceMasks(Model, Masks);
3636 }
3737
3838 bool hasWorkToComplete() const override { return false; }
39 llvm::Error execute(InstRef &IR) override;
39 Error execute(InstRef &IR) override;
4040 };
4141 } // namespace mca
4242 } // namespace llvm
3636 : Stage(), RCU(R), PRF(F) {}
3737
3838 bool hasWorkToComplete() const override { return !RCU.isEmpty(); }
39 llvm::Error cycleStart() override;
40 llvm::Error execute(InstRef &IR) override;
39 Error cycleStart() override;
40 Error execute(InstRef &IR) override;
4141 void notifyInstructionRetired(const InstRef &IR) const;
4242 };
4343
4646
4747 /// Called once at the start of each cycle. This can be used as a setup
4848 /// phase to prepare for the executions during the cycle.
49 virtual llvm::Error cycleStart() { return llvm::ErrorSuccess(); }
49 virtual Error cycleStart() { return ErrorSuccess(); }
5050
5151 /// Called once at the end of each cycle.
52 virtual llvm::Error cycleEnd() { return llvm::ErrorSuccess(); }
52 virtual Error cycleEnd() { return ErrorSuccess(); }
5353
5454 /// The primary action that this stage performs on instruction IR.
55 virtual llvm::Error execute(InstRef &IR) = 0;
55 virtual Error execute(InstRef &IR) = 0;
5656
5757 void setNextInSequence(Stage *NextStage) {
5858 assert(!NextInSequence && "This stage already has a NextInSequence!");
6767 ///
6868 /// Stages are responsible for moving instructions to their immediate
6969 /// successor stages.
70 llvm::Error moveToTheNextStage(InstRef &IR) {
70 Error moveToTheNextStage(InstRef &IR) {
7171 assert(checkNextStage(IR) && "Next stage is not ready!");
7272 return NextInSequence->execute(IR);
7373 }
2323 namespace mca {
2424
2525 template
26 class InstructionError : public llvm::ErrorInfo> {
26 class InstructionError : public ErrorInfo> {
2727 public:
2828 static char ID;
2929 std::string Message;
3232 InstructionError(std::string M, const T &MCI)
3333 : Message(std::move(M)), Inst(MCI) {}
3434
35 void log(llvm::raw_ostream &OS) const override { OS << Message; }
35 void log(raw_ostream &OS) const override { OS << Message; }
3636
3737 std::error_code convertToErrorCode() const override {
38 return llvm::inconvertibleErrorCode();
38 return inconvertibleErrorCode();
3939 }
4040 };
4141
6969 else {
7070 // Create a common denominator for LHS and RHS by calculating the least
7171 // common multiple from the GCD.
72 unsigned GCD =
73 llvm::GreatestCommonDivisor64(Denominator, RHS.Denominator);
72 unsigned GCD = GreatestCommonDivisor64(Denominator, RHS.Denominator);
7473 unsigned LCM = (Denominator * RHS.Denominator) / GCD;
7574 unsigned LHSNumerator = Numerator * (LCM / Denominator);
7675 unsigned RHSNumerator = RHS.Numerator * (LCM / RHS.Denominator);
103102 ///
104103 /// Resource masks are used by the ResourceManager to solve set membership
105104 /// problems with simple bit manipulation operations.
106 void computeProcResourceMasks(const llvm::MCSchedModel &SM,
107 llvm::SmallVectorImpl &Masks);
105 void computeProcResourceMasks(const MCSchedModel &SM,
106 SmallVectorImpl &Masks);
108107
109108 /// Compute the reciprocal block throughput from a set of processor resource
110109 /// cycles. The reciprocal block throughput is computed as the MAX between:
111110 /// - NumMicroOps / DispatchWidth
112111 /// - ProcResourceCycles / #ProcResourceUnits (for every consumed resource).
113 double computeBlockRThroughput(const llvm::MCSchedModel &SM,
114 unsigned DispatchWidth, unsigned NumMicroOps,
115 llvm::ArrayRef ProcResourceUsage);
112 double computeBlockRThroughput(const MCSchedModel &SM, unsigned DispatchWidth,
113 unsigned NumMicroOps,
114 ArrayRef ProcResourceUsage);
116115 } // namespace mca
117116 } // namespace llvm
118117