-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[TableGen] Add support for per-write cycle tunables #125870
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This patch adds support for describing per-write resource cycle counts for ReadAdvance records via a new optional field called `tunables'. This makes it possible to declare ReadAdvance records such as: def : ReadAdvance<Read_C, 1, [Write_A, Write_B], [2]>; The above will effectivelly declare two entries in the ReadAdvance table for Read_C, one for Write_A with a cycle count of 1+2, and one for Write_B with a cycle count of 1+0 (omitted values are assumed 0). The field `tunables' provides a list of deltas relative to the base `cycle' count of the ReadAdvance. Since the field is optional and defaults to a list of 0's, this change doesn't affect current targets.
@llvm/pr-subscribers-tablegen Author: Ricardo Jesus (rj-jesus) ChangesThis patch adds support for describing per-write resource cycle counts This makes it possible to declare ReadAdvance records such as:
The above will effectively declare two entries in the ReadAdvance The field Full diff: https://github.com/llvm/llvm-project/pull/125870.diff 3 Files Affected:
diff --git a/llvm/include/llvm/Target/TargetSchedule.td b/llvm/include/llvm/Target/TargetSchedule.td
index 2562ed0901303fe..4b82c1e2410fc8c 100644
--- a/llvm/include/llvm/Target/TargetSchedule.td
+++ b/llvm/include/llvm/Target/TargetSchedule.td
@@ -321,9 +321,11 @@ class SchedWriteRes<list<ProcResourceKind> resources> : SchedWrite,
// Define values common to ReadAdvance and SchedReadAdvance.
//
// SchedModel ties these resources to a processor.
-class ProcReadAdvance<int cycles, list<SchedWrite> writes = []> {
+class ProcReadAdvance<int cycles, list<SchedWrite> writes = [],
+ list<int> tunables = []> {
int Cycles = cycles;
list<SchedWrite> ValidWrites = writes;
+ list<int> CycleTunables = tunables;
// Allow a processor to mark some scheduling classes as unsupported
// for stronger verification.
bit Unsupported = false;
@@ -340,15 +342,17 @@ class ProcReadAdvance<int cycles, list<SchedWrite> writes = []> {
// indicate operands that are always read this number of Cycles later
// than a normal register read, allowing the read's parent instruction
// to issue earlier relative to the writer.
-class ReadAdvance<SchedRead read, int cycles, list<SchedWrite> writes = []>
- : ProcReadAdvance<cycles, writes> {
+class ReadAdvance<SchedRead read, int cycles, list<SchedWrite> writes = [],
+ list<int> tunables = []>
+ : ProcReadAdvance<cycles, writes, tunables> {
SchedRead ReadType = read;
}
// Directly associate a new SchedRead type with a delay and optional
// pipeline bypass. For use with InstRW or ItinRW.
-class SchedReadAdvance<int cycles, list<SchedWrite> writes = []> : SchedRead,
- ProcReadAdvance<cycles, writes>;
+class SchedReadAdvance<int cycles, list<SchedWrite> writes = [],
+ list<int> tunables = []>
+ : SchedRead, ProcReadAdvance<cycles, writes, tunables>;
// Define SchedRead defaults. Reads seldom need special treatment.
def ReadDefault : SchedRead;
diff --git a/llvm/test/TableGen/PreWriteCycleCount.td b/llvm/test/TableGen/PreWriteCycleCount.td
new file mode 100644
index 000000000000000..40260a9bacef449
--- /dev/null
+++ b/llvm/test/TableGen/PreWriteCycleCount.td
@@ -0,0 +1,41 @@
+// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s 2>&1 | FileCheck %s
+
+// Make sure that ReadAdvance entries with multiple writes are correctly
+// handled.
+
+include "llvm/Target/Target.td"
+
+def MyTarget : Target;
+
+let OutOperandList = (outs), InOperandList = (ins) in {
+ def Inst_A : Instruction;
+ def Inst_B : Instruction;
+ def Inst_C : Instruction;
+}
+
+let CompleteModel = 0 in {
+ def SchedModel_A: SchedMachineModel;
+}
+
+def Read_D : SchedRead;
+
+// CHECK: extern const llvm::MCReadAdvanceEntry MyTargetReadAdvanceTable[] = {
+// CHECK-NEXT: {0, 0, 0}, // Invalid
+// CHECK-NEXT: {0, 1, 1}, // #1
+// CHECK-NEXT: {0, 2, 3}, // #2
+// CHECK-NEXT: {0, 3, 2} // #3
+// CHECK-NEXT: }; // MyTargetReadAdvanceTable
+
+let SchedModel = SchedModel_A in {
+ def Write_A : SchedWriteRes<[]>;
+ def Write_B : SchedWriteRes<[]>;
+ def Write_C : SchedWriteRes<[]>;
+
+ def : InstRW<[Write_A], (instrs Inst_A)>;
+ def : InstRW<[Write_B], (instrs Inst_B)>;
+ def : InstRW<[Write_C, Read_D], (instrs Inst_C)>;
+
+ def : ReadAdvance<Read_D, 2, [Write_A, Write_B, Write_C], [-1, 1]>;
+}
+
+def ProcessorA: ProcessorModel<"ProcessorA", SchedModel_A, []>;
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 49362ff5ef65563..ec0990292738230 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -1308,23 +1308,30 @@ void SubtargetEmitter::genSchedClassTables(const CodeGenProcModel &ProcModel,
}
ConstRecVec ValidWrites =
ReadAdvance->getValueAsListOfDefs("ValidWrites");
- IdxVec WriteIDs;
+ std::vector<int64_t> CycleTunables =
+ ReadAdvance->getValueAsListOfInts("CycleTunables");
+ std::vector<std::pair<unsigned, int>> WriteIDs;
+ if (!CycleTunables.empty() && CycleTunables.size() > ValidWrites.size())
+ PrintFatalError(ReadAdvance->getLoc(),
+ "If specified, CycleTunables must have at most the "
+ "same number of elements of ValidWrites.\n");
+ CycleTunables.resize(ValidWrites.size(), 0);
if (ValidWrites.empty())
- WriteIDs.push_back(0);
+ WriteIDs.push_back(std::make_pair(0, 0));
else {
- for (const Record *VW : ValidWrites) {
+ for (const auto [VW, CT] : zip_equal(ValidWrites, CycleTunables)) {
unsigned WriteID = SchedModels.getSchedRWIdx(VW, /*IsRead=*/false);
assert(WriteID != 0 &&
"Expected a valid SchedRW in the list of ValidWrites");
- WriteIDs.push_back(WriteID);
+ WriteIDs.push_back(std::make_pair(WriteID, CT));
}
}
llvm::sort(WriteIDs);
- for (unsigned W : WriteIDs) {
+ for (const auto &[W, T] : WriteIDs) {
MCReadAdvanceEntry RAEntry;
RAEntry.UseIdx = UseIdx;
RAEntry.WriteResourceID = W;
- RAEntry.Cycles = ReadAdvance->getValueAsInt("Cycles");
+ RAEntry.Cycles = ReadAdvance->getValueAsInt("Cycles") + T;
ReadAdvanceEntries.push_back(RAEntry);
}
}
|
Ping. :) |
Also, once that is done, I think you need to re-request the review by clicking the small circle arrow button next to the reviewers, otherwise I am suspecting it won't get back on their radar. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but please wait for @topperc 's (or someone else's) approval as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks very much for the comments! |
This patch adds support for describing per-write resource cycle counts for ReadAdvance records via a new optional field called `tunables`. This makes it possible to declare ReadAdvance records such as: def : ReadAdvance<Read_C, 1, [Write_A, Write_B], [2]>; The above will effectively declare two entries in the ReadAdvance table for Read_C, one for Write_A with a cycle count of 1+2, and one for Write_B with a cycle count of 1+0 (omitted values are assumed 0). The field `tunables` provides a list of deltas relative to the base `cycle` count of the ReadAdvance. Since the field is optional and defaults to a list of 0's, this change doesn't affect current targets.
This patch adds support for describing per-write resource cycle counts
for ReadAdvance records via a new optional field called
tunables
.This makes it possible to declare ReadAdvance records such as:
The above will effectively declare two entries in the ReadAdvance
table for Read_C, one for Write_A with a cycle count of 1+2, and one for
Write_B with a cycle count of 1+0 (omitted values are assumed 0).
The field
tunables
provides a list of deltas relative to the basecycle
count of the ReadAdvance. Since the field is optional anddefaults to a list of 0's, this change doesn't affect current targets.