annotate lib/MCA/Instruction.cpp @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 //===--------------------- Instruction.cpp ----------------------*- C++ -*-===//
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 // This file defines abstractions used by the Pipeline to model register reads,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 // register writes and instructions.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 //
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 #include "llvm/MCA/Instruction.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 #include "llvm/Support/Debug.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 #include "llvm/Support/raw_ostream.h"
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 namespace llvm {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 namespace mca {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 void WriteState::writeStartEvent(unsigned IID, unsigned RegID,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 unsigned Cycles) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 CRD.IID = IID;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 CRD.RegID = RegID;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 CRD.Cycles = Cycles;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 DependentWriteCyclesLeft = Cycles;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 DependentWrite = nullptr;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 void ReadState::writeStartEvent(unsigned IID, unsigned RegID, unsigned Cycles) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 assert(DependentWrites);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 assert(CyclesLeft == UNKNOWN_CYCLES);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 // This read may be dependent on more than one write. This typically occurs
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 // when a definition is the result of multiple writes where at least one
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 // write does a partial register update.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 // The HW is forced to do some extra bookkeeping to track of all the
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 // dependent writes, and implement a merging scheme for the partial writes.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 --DependentWrites;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 if (TotalCycles < Cycles) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 CRD.IID = IID;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 CRD.RegID = RegID;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 CRD.Cycles = Cycles;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 TotalCycles = Cycles;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 if (!DependentWrites) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 CyclesLeft = TotalCycles;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 IsReady = !CyclesLeft;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 void WriteState::onInstructionIssued(unsigned IID) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 assert(CyclesLeft == UNKNOWN_CYCLES);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 // Update the number of cycles left based on the WriteDescriptor info.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 CyclesLeft = getLatency();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 // Now that the time left before write-back is known, notify
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 // all the users.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 for (const std::pair<ReadState *, int> &User : Users) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 ReadState *RS = User.first;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 unsigned ReadCycles = std::max(0, CyclesLeft - User.second);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 RS->writeStartEvent(IID, RegisterID, ReadCycles);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 // Notify any writes that are in a false dependency with this write.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 if (PartialWrite)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 PartialWrite->writeStartEvent(IID, RegisterID, CyclesLeft);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 void WriteState::addUser(unsigned IID, ReadState *User, int ReadAdvance) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 // If CyclesLeft is different than -1, then we don't need to
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 // update the list of users. We can just notify the user with
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 // the actual number of cycles left (which may be zero).
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 if (CyclesLeft != UNKNOWN_CYCLES) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 unsigned ReadCycles = std::max(0, CyclesLeft - ReadAdvance);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 User->writeStartEvent(IID, RegisterID, ReadCycles);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 return;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 Users.emplace_back(User, ReadAdvance);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 void WriteState::addUser(unsigned IID, WriteState *User) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 if (CyclesLeft != UNKNOWN_CYCLES) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 User->writeStartEvent(IID, RegisterID, std::max(0, CyclesLeft));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 return;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 assert(!PartialWrite && "PartialWrite already set!");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 PartialWrite = User;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 User->setDependentWrite(this);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 void WriteState::cycleEvent() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 // Note: CyclesLeft can be a negative number. It is an error to
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 // make it an unsigned quantity because users of this write may
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 // specify a negative ReadAdvance.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 if (CyclesLeft != UNKNOWN_CYCLES)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 CyclesLeft--;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 if (DependentWriteCyclesLeft)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 DependentWriteCyclesLeft--;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 void ReadState::cycleEvent() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 // Update the total number of cycles.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 if (DependentWrites && TotalCycles) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 --TotalCycles;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 return;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 // Bail out immediately if we don't know how many cycles are left.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 if (CyclesLeft == UNKNOWN_CYCLES)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 return;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 if (CyclesLeft) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 --CyclesLeft;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 IsReady = !CyclesLeft;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 #ifndef NDEBUG
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 void WriteState::dump() const {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 dbgs() << "{ OpIdx=" << WD->OpIndex << ", Lat=" << getLatency() << ", RegID "
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 << getRegisterID() << ", Cycles Left=" << getCyclesLeft() << " }";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 void WriteRef::dump() const {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 dbgs() << "IID=" << getSourceIndex() << ' ';
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 if (isValid())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 getWriteState()->dump();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 else
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 dbgs() << "(null)";
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 #endif
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 const CriticalDependency &Instruction::computeCriticalRegDep() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 if (CriticalRegDep.Cycles)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 return CriticalRegDep;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 unsigned MaxLatency = 0;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 for (const WriteState &WS : getDefs()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 const CriticalDependency &WriteCRD = WS.getCriticalRegDep();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 if (WriteCRD.Cycles > MaxLatency)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 CriticalRegDep = WriteCRD;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 for (const ReadState &RS : getUses()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 const CriticalDependency &ReadCRD = RS.getCriticalRegDep();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 if (ReadCRD.Cycles > MaxLatency)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 CriticalRegDep = ReadCRD;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 return CriticalRegDep;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
157
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 void Instruction::dispatch(unsigned RCUToken) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 assert(Stage == IS_INVALID);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 Stage = IS_DISPATCHED;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 RCUTokenID = RCUToken;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 // Check if input operands are already available.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 if (updateDispatched())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 updatePending();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
167
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 void Instruction::execute(unsigned IID) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 assert(Stage == IS_READY);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 Stage = IS_EXECUTING;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
171
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 // Set the cycles left before the write-back stage.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 CyclesLeft = getLatency();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
174
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 for (WriteState &WS : getDefs())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 WS.onInstructionIssued(IID);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 // Transition to the "executed" stage if this is a zero-latency instruction.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 if (!CyclesLeft)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 Stage = IS_EXECUTED;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
182
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 void Instruction::forceExecuted() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 assert(Stage == IS_READY && "Invalid internal state!");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 CyclesLeft = 0;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 Stage = IS_EXECUTED;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
188
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 bool Instruction::updatePending() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 assert(isPending() && "Unexpected instruction stage found!");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
191
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 if (!all_of(getUses(), [](const ReadState &Use) { return Use.isReady(); }))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 return false;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 // A partial register write cannot complete before a dependent write.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 if (!all_of(getDefs(), [](const WriteState &Def) { return Def.isReady(); }))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 return false;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
198
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 Stage = IS_READY;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 return true;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
202
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 bool Instruction::updateDispatched() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 assert(isDispatched() && "Unexpected instruction stage found!");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
205
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 if (!all_of(getUses(), [](const ReadState &Use) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 return Use.isPending() || Use.isReady();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 }))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 return false;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
210
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 // A partial register write cannot complete before a dependent write.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 if (!all_of(getDefs(),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 [](const WriteState &Def) { return !Def.getDependentWrite(); }))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 return false;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
215
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 Stage = IS_PENDING;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 return true;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
219
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 void Instruction::update() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 if (isDispatched())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 updateDispatched();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 if (isPending())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 updatePending();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 void Instruction::cycleEvent() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 if (isReady())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 return;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
230
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 if (isDispatched() || isPending()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 for (ReadState &Use : getUses())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 Use.cycleEvent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
234
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 for (WriteState &Def : getDefs())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 Def.cycleEvent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
237
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 update();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 return;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
241
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 assert(isExecuting() && "Instruction not in-flight?");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 assert(CyclesLeft && "Instruction already executed?");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 for (WriteState &Def : getDefs())
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 Def.cycleEvent();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 CyclesLeft--;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 if (!CyclesLeft)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 Stage = IS_EXECUTED;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
250
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 const unsigned WriteRef::INVALID_IID = std::numeric_limits<unsigned>::max();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 } // namespace mca
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 } // namespace llvm