-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[TableGen] Extend direct lookup to instruction values in generic tables. #80486
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
Currently, for some tables involving a single primary key field which is integral and densely numbered, a direct lookup is generated rather than a binary search. This patch extends the direct lookup function generation to instructions, where the integral value corresponds to the instruction's enum value. While this isn't as common as for other tables, it does occur in at least one downstream backend and one in-tree backend. Added a unit test and minimally updated the documentation.
If one of @wangpc-pp , @nhaehnle , @Paul-C-Anagnostopoulos , or @TNorthover could review this small patch, it would be appreciated (chosen based on recent or past commits in this area-- other suggestions welcome). Thank you. |
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.
I think this is a great idea generally!
if (SawInstructionField && InstrEnumValueMap.empty()) { | ||
CodeGenTarget Target(Records); | ||
unsigned Num = 0; | ||
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) |
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.
I think we should add a CodeGenTarget::getInstrToIntMap
(or other names?) to get this instr->int mapping, so that we can reuse these logics and sync with other emittters (like you said, InstrInfoEmitter::emitEnums
).
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.
As you suggested, I have moved this map into CodeGenTarget::InstrToIntMap
and added a lookup method CodeGenTarget::getInstrIntValue
. The map is now populated in CodeGenTarget::computeInstrsByEnum
right after the sort that creates the order in the first place.
Overall this is cleaner and simplified the patch as well. Thanks again for the suggestions.
In a follow-up patch, as you alluded to, I could use the new query in InstrInfoEmitter::emitEnums
(and elsewhere if applicable) to reuse/sync the logic.
@@ -638,6 +662,7 @@ void SearchableTableEmitter::collectTableEntries( | |||
|
|||
Record *IntrinsicClass = Records.getClass("Intrinsic"); | |||
Record *InstructionClass = Records.getClass("Instruction"); | |||
bool SawInstructionField = false; |
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.
SawInstructionField->HasInstructionField?
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.
I have removed this variable since it is no longer necessary due to having moved the map population logic.
@@ -207,12 +213,17 @@ class SearchableTableEmitter { | |||
|
|||
// For search indices that consists of a single field whose numeric value is | |||
// known, return that numeric value. | |||
static int64_t getNumericKey(const SearchIndex &Index, Record *Rec) { | |||
static int64_t getNumericKey(const SearchIndex &Index, Record *Rec, | |||
InstrEnumMapT &InstrEnumMap) { |
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.
A style nit(just mine). What about making getNumericKey
a class function like getIntrinsic
, so that we don't need to pass InstrEnumMap
?
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.
Done. Although I removed the InstrEnumMap
parameter, it is still useful to do this since we need to invoke the new query function Target->getInstrIntValue
.
Move the instruction-to-int map into CodeGenTarget::InstrToIntMap and add CodeGenTarget::getInstrIntValue query method. Populate the map in CodeGenTarget::ComputeInstrsByEnum just below where the order is created in the first place.
Thank you for the review comments, it is appreciated. I've made changes according to your suggestions below. |
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 with nits.
@@ -663,6 +682,8 @@ void SearchableTableEmitter::run(raw_ostream &OS) { | |||
// Emit tables in a deterministic order to avoid needless rebuilds. | |||
SmallVector<std::unique_ptr<GenericTable>, 4> Tables; | |||
DenseMap<Record *, GenericTable *> TableMap; | |||
if (Records.getClass("Instruction")) |
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.
if (Records.getClass("Instruction")) | |
if (!Records.getAllDerivedDefinitions("Instruction").empty()) |
Do this only if there are Instruction
definitions instead of Instruction
class definition.
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.
Done.
I've added the derived definitions guard as suggested. I needed to leave in the original guard since the derived definitions lookup will fail with "The class 'Instruction' is not defined" for clients that do not happen to have a Instruction class at all.
If I could also trouble you (or anyone else) to merge on my behalf, I'd appreciate that.
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.
Oh sorry, I forgot it, we can use getAllDerivedDefinitionsIfDefined
here.
If I could also trouble you (or anyone else) to merge on my behalf, I'd appreciate that.
Yeah, no problem!
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.
Done (used getAllDerivedDefinitionsIfDefined
).
Add derived definitions guard.
Use getAllDerivedDefinitionsIfDefined.
// InstrInfoEmitter::emitEnums. | ||
assert(InstrToIntMap.empty()); | ||
unsigned Num = 0; | ||
for (const CodeGenInstruction *Inst : InstrsByEnum) |
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.
Sorry I'm late to this, but why not make this a field of CodeGenInstruction? We already have a map from Record* to CodeGenInstruction.
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.
Sorry I'm late to this, but why not make this a field of CodeGenInstruction? We already have a map from Record to CodeGenInstruction.
Thanks for your comments @topperc, much appreciated. I'll make your suggested change in a new PR shortly, with you as reviewer/committer if you wouldn't mind.
Looks the code assumes that This is not universally true. For example This can cause problems, because An immediate fix for that issue would be to switch the conditions around in |
CC @nvjle (not sure if notifications are sent without explicit mention) |
Thanks @piotrAMD, I'll look into this in detail sometime this week. At first glance it does seem there may be a potential problem, but there is no actual failure that I can see. All testing is good thus far, including for AMDGPU. But we surely want this to be bullet proof. |
Thanks, I'll try to come up with a reproducer. |
Hi @piotrAMD, I've revisited this and agree with your reasoning and posted this tiny patch accordingly: #83284. All tests (including the backend I'm working on which is at least as SearchableTable-heavy as AMDGPU) are good and |
Thanks! I tried, but wasn't able to come up with a reproducer. |
Currently, for some tables involving a single primary key field which is integral and densely numbered, a direct lookup is generated rather than a binary search. This patch extends the direct lookup function generation to instructions, where the integral value corresponds to the instruction's enum value.
While this isn't as common as for other tables, it does occur in at least one downstream backend and one in-tree backend.
Added a unit test and minimally updated the documentation.