@@ -37,8 +37,16 @@ ResourcePressureView::ResourcePressureView(const llvm::MCSubtargetInfo &sti,
37
37
}
38
38
39
39
NumResourceUnits = R2VIndex;
40
- ResourceUsage.resize (NumResourceUnits * (getSource ().size () + 1 ));
41
- std::fill (ResourceUsage.begin (), ResourceUsage.end (), 0.0 );
40
+ ResourceUsage.resize (getSource ().size ());
41
+
42
+ ResourceReleaseAtCycles InitValue{0 , 0 };
43
+ auto Generator = [&InitValue]() {
44
+ ResourceReleaseAtCycles Old = InitValue;
45
+ ++InitValue.ResourceIdx ;
46
+ return Old;
47
+ };
48
+ std::generate_n (std::back_inserter (CommonResourceUsage), NumResourceUnits,
49
+ Generator);
42
50
}
43
51
44
52
void ResourcePressureView::onEvent (const HWInstructionEvent &Event) {
@@ -60,8 +68,19 @@ void ResourcePressureView::onEvent(const HWInstructionEvent &Event) {
60
68
assert (Resource2VecIndex.contains (RR.first ));
61
69
unsigned R2VIndex = Resource2VecIndex[RR.first ];
62
70
R2VIndex += llvm::countr_zero (RR.second );
63
- ResourceUsage[R2VIndex + NumResourceUnits * SourceIdx] += Use.second ;
64
- ResourceUsage[R2VIndex + NumResourceUnits * Source.size ()] += Use.second ;
71
+
72
+ InstResourceUsage &RU = ResourceUsage[SourceIdx];
73
+ ResourceReleaseAtCycles NewUsage{R2VIndex, Use.second };
74
+ auto ResCyclesIt =
75
+ lower_bound (RU, NewUsage, [](const auto &L, const auto &R) {
76
+ return L.ResourceIdx < R.ResourceIdx ;
77
+ });
78
+ if (ResCyclesIt != RU.end () && ResCyclesIt->ResourceIdx == R2VIndex)
79
+ ResCyclesIt->Cycles += NewUsage.Cycles ;
80
+ else
81
+ RU.insert (ResCyclesIt, std::move (NewUsage));
82
+
83
+ CommonResourceUsage[R2VIndex].Cycles += NewUsage.Cycles ;
65
84
}
66
85
}
67
86
@@ -135,10 +154,17 @@ void ResourcePressureView::printResourcePressurePerIter(raw_ostream &OS) const {
135
154
136
155
ArrayRef<llvm::MCInst> Source = getSource ();
137
156
const unsigned Executions = LastInstructionIdx / Source.size () + 1 ;
157
+ auto UsageEntryEnd = CommonResourceUsage.end ();
158
+ auto UsageEntryIt = CommonResourceUsage.begin ();
138
159
for (unsigned I = 0 , E = NumResourceUnits; I < E; ++I) {
139
- double Usage = ResourceUsage[I + Source.size () * E];
140
- printResourcePressure (FOS, Usage / Executions, (I + 1 ) * 7 );
160
+ double Pressure = 0.0 ;
161
+ if (UsageEntryIt != UsageEntryEnd && UsageEntryIt->ResourceIdx == I) {
162
+ Pressure = UsageEntryIt->Cycles / Executions;
163
+ ++UsageEntryIt;
164
+ }
165
+ printResourcePressure (FOS, Pressure, (I + 1 ) * 7 );
141
166
}
167
+ assert (UsageEntryIt == UsageEntryEnd);
142
168
143
169
FOS.flush ();
144
170
OS << Buffer;
@@ -157,11 +183,17 @@ void ResourcePressureView::printResourcePressurePerInst(raw_ostream &OS) const {
157
183
ArrayRef<llvm::MCInst> Source = getSource ();
158
184
const unsigned Executions = LastInstructionIdx / Source.size () + 1 ;
159
185
for (const MCInst &MCI : Source) {
160
- unsigned BaseEltIdx = InstrIndex * NumResourceUnits;
186
+ auto UsageEntryEnd = ResourceUsage[InstrIndex].end ();
187
+ auto UsageEntryIt = ResourceUsage[InstrIndex].begin ();
161
188
for (unsigned J = 0 ; J < NumResourceUnits; ++J) {
162
- double Usage = ResourceUsage[J + BaseEltIdx];
163
- printResourcePressure (FOS, Usage / Executions, (J + 1 ) * 7 );
189
+ double Pressure = 0.0 ;
190
+ if (UsageEntryIt != UsageEntryEnd && UsageEntryIt->ResourceIdx == J) {
191
+ Pressure = UsageEntryIt->Cycles / Executions;
192
+ ++UsageEntryIt;
193
+ }
194
+ printResourcePressure (FOS, Pressure, (J + 1 ) * 7 );
164
195
}
196
+ assert (UsageEntryIt == UsageEntryEnd);
165
197
166
198
FOS << printInstructionString (MCI) << ' \n ' ;
167
199
FOS.flush ();
@@ -180,17 +212,22 @@ json::Value ResourcePressureView::toJSON() const {
180
212
// non-zero values.
181
213
ArrayRef<llvm::MCInst> Source = getSource ();
182
214
const unsigned Executions = LastInstructionIdx / Source.size () + 1 ;
183
- for (const auto &R : enumerate(ResourceUsage)) {
184
- const ReleaseAtCycles &RU = R.value ();
185
- if (RU.getNumerator () == 0 )
186
- continue ;
187
- unsigned InstructionIndex = R.index () / NumResourceUnits;
188
- unsigned ResourceIndex = R.index () % NumResourceUnits;
189
- double Usage = RU / Executions;
215
+
216
+ auto AddToJSON = [&ResourcePressureInfo, Executions](
217
+ const ResourceReleaseAtCycles &RU, unsigned InstIndex) {
218
+ assert (RU.Cycles .getNumerator () != 0 );
219
+ double Usage = RU.Cycles / Executions;
190
220
ResourcePressureInfo.push_back (
191
- json::Object ({{" InstructionIndex" , InstructionIndex },
192
- {" ResourceIndex" , ResourceIndex },
221
+ json::Object ({{" InstructionIndex" , InstIndex },
222
+ {" ResourceIndex" , RU. ResourceIdx },
193
223
{" ResourceUsage" , Usage}}));
224
+ };
225
+ for (const auto &[InstIndex, Usages] : enumerate(ResourceUsage))
226
+ for (const auto &RU : Usages)
227
+ AddToJSON (RU, InstIndex);
228
+ for (const auto &RU : CommonResourceUsage) {
229
+ if (RU.Cycles .getNumerator () != 0 )
230
+ AddToJSON (RU, Source.size ());
194
231
}
195
232
196
233
json::Object JO ({{" ResourcePressureInfo" , std::move (ResourcePressureInfo)}});
0 commit comments