Skip to content

Commit 517334b

Browse files
authored
[TableGen] Add maps from Write/ReadType to the parent WriteRes/ReadAdvance. NFC (#123876)
Use this to improve performance of SubtargetEmitter::findWriteResources and SubtargetEmitter::findReadAdvance. Now we can do a map lookup instead of a linear search through all WriteRes/ReadAdvance records. This reduces the build time of RISCVGenSubtargetInfo.inc on my machine from 43 seconds to 10 seconds.
1 parent 8fb4230 commit 517334b

File tree

3 files changed

+53
-32
lines changed

3 files changed

+53
-32
lines changed

llvm/utils/TableGen/Common/CodeGenSchedule.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,6 +2112,14 @@ void CodeGenSchedModels::addWriteRes(const Record *ProcWriteResDef,
21122112
return;
21132113
WRDefs.push_back(ProcWriteResDef);
21142114

2115+
if (ProcWriteResDef->isSubClassOf("WriteRes")) {
2116+
auto &WRMap = ProcModels[PIdx].WriteResMap;
2117+
const Record *WRDef = ProcWriteResDef->getValueAsDef("WriteType");
2118+
if (!WRMap.try_emplace(WRDef, ProcWriteResDef).second)
2119+
PrintFatalError(ProcWriteResDef->getLoc(),
2120+
"WriteType already used in another WriteRes");
2121+
}
2122+
21152123
// Visit ProcResourceKinds referenced by the newly discovered WriteRes.
21162124
for (const Record *ProcResDef :
21172125
ProcWriteResDef->getValueAsListOfDefs("ProcResources")) {
@@ -2135,6 +2143,14 @@ void CodeGenSchedModels::addReadAdvance(const Record *ProcReadAdvanceDef,
21352143
if (is_contained(RADefs, ProcReadAdvanceDef))
21362144
return;
21372145
RADefs.push_back(ProcReadAdvanceDef);
2146+
2147+
if (ProcReadAdvanceDef->isSubClassOf("ReadAdvance")) {
2148+
auto &RAMap = ProcModels[PIdx].ReadAdvanceMap;
2149+
const Record *RADef = ProcReadAdvanceDef->getValueAsDef("ReadType");
2150+
if (!RAMap.try_emplace(RADef, ProcReadAdvanceDef).second)
2151+
PrintFatalError(ProcReadAdvanceDef->getLoc(),
2152+
"ReadType already used in another ReadAdvance");
2153+
}
21382154
}
21392155

21402156
unsigned CodeGenProcModel::getProcResourceIdx(const Record *PRDef) const {

llvm/utils/TableGen/Common/CodeGenSchedule.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,12 @@ struct CodeGenProcModel {
244244
ConstRecVec WriteResDefs;
245245
ConstRecVec ReadAdvanceDefs;
246246

247+
// Map from the WriteType field to the parent WriteRes record.
248+
DenseMap<const Record *, const Record *> WriteResMap;
249+
250+
// Map from the ReadType field to the parent ReadAdvance record.
251+
DenseMap<const Record *, const Record *> ReadAdvanceMap;
252+
247253
// Per-operand machine model resources associated with this processor.
248254
ConstRecVec ProcResourceDefs;
249255

llvm/utils/TableGen/SubtargetEmitter.cpp

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -943,24 +943,23 @@ SubtargetEmitter::findWriteResources(const CodeGenSchedRW &SchedWrite,
943943

944944
// Check this processor's list of write resources.
945945
const Record *ResDef = nullptr;
946-
for (const Record *WR : ProcModel.WriteResDefs) {
947-
if (!WR->isSubClassOf("WriteRes"))
948-
continue;
949-
const Record *WRDef = WR->getValueAsDef("WriteType");
950-
if (AliasDef == WRDef || SchedWrite.TheDef == WRDef) {
951-
if (ResDef) {
952-
PrintFatalError(WR->getLoc(), "Resources are defined for both "
953-
"SchedWrite and its alias on processor " +
954-
ProcModel.ModelName);
955-
}
956-
ResDef = WR;
957-
// If there is no AliasDef and we find a match, we can early exit since
958-
// there is no need to verify whether there are resources defined for both
959-
// SchedWrite and its alias.
960-
if (!AliasDef)
961-
break;
946+
947+
auto I = ProcModel.WriteResMap.find(SchedWrite.TheDef);
948+
if (I != ProcModel.WriteResMap.end())
949+
ResDef = I->second;
950+
951+
if (AliasDef) {
952+
I = ProcModel.WriteResMap.find(AliasDef);
953+
if (I != ProcModel.WriteResMap.end()) {
954+
if (ResDef)
955+
PrintFatalError(I->second->getLoc(),
956+
"Resources are defined for both SchedWrite and its "
957+
"alias on processor " +
958+
ProcModel.ModelName);
959+
ResDef = I->second;
962960
}
963961
}
962+
964963
// TODO: If ProcModel has a base model (previous generation processor),
965964
// then call FindWriteResources recursively with that model here.
966965
if (!ResDef) {
@@ -1003,24 +1002,24 @@ SubtargetEmitter::findReadAdvance(const CodeGenSchedRW &SchedRead,
10031002

10041003
// Check this processor's ReadAdvanceList.
10051004
const Record *ResDef = nullptr;
1006-
for (const Record *RA : ProcModel.ReadAdvanceDefs) {
1007-
if (!RA->isSubClassOf("ReadAdvance"))
1008-
continue;
1009-
const Record *RADef = RA->getValueAsDef("ReadType");
1010-
if (AliasDef == RADef || SchedRead.TheDef == RADef) {
1011-
if (ResDef) {
1012-
PrintFatalError(RA->getLoc(), "Resources are defined for both "
1013-
"SchedRead and its alias on processor " +
1014-
ProcModel.ModelName);
1015-
}
1016-
ResDef = RA;
1017-
// If there is no AliasDef and we find a match, we can early exit since
1018-
// there is no need to verify whether there are resources defined for both
1019-
// SchedRead and its alias.
1020-
if (!AliasDef)
1021-
break;
1005+
1006+
auto I = ProcModel.ReadAdvanceMap.find(SchedRead.TheDef);
1007+
if (I != ProcModel.ReadAdvanceMap.end())
1008+
ResDef = I->second;
1009+
1010+
if (AliasDef) {
1011+
I = ProcModel.ReadAdvanceMap.find(AliasDef);
1012+
if (I != ProcModel.ReadAdvanceMap.end()) {
1013+
if (ResDef)
1014+
PrintFatalError(
1015+
I->second->getLoc(),
1016+
"Resources are defined for both SchedRead and its alias on "
1017+
"processor " +
1018+
ProcModel.ModelName);
1019+
ResDef = I->second;
10221020
}
10231021
}
1022+
10241023
// TODO: If ProcModel has a base model (previous generation processor),
10251024
// then call FindReadAdvance recursively with that model here.
10261025
if (!ResDef && SchedRead.TheDef->getName() != "ReadDefault") {

0 commit comments

Comments
 (0)