[llvm] [TableGen][GlobalISel] Add rule-wide type inference (PR #66377)
Pierre van Houtryve via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 7 02:39:44 PST 2023
================
@@ -1639,6 +1695,471 @@ class PrettyStackTraceEmit : public PrettyStackTraceEntry {
}
};
+//===- CombineRuleOperandTypeChecker --------------------------------------===//
+
+/// This is a wrapper around OperandTypeChecker specialized for Combiner Rules.
+/// On top of doing the same things as OperandTypeChecker, this also attempts to
+/// infer as many types as possible for temporary register defs & immediates in
+/// apply patterns.
+///
+/// The inference is trivial and leverages the MCOI OperandTypes encoded in
+/// CodeGenInstructions to infer types across patterns in a CombineRule. It's
+/// thus very limited and only supports CodeGenInstructions (but that's the main
+/// use case so it's fine).
+///
+/// We only try to infer untyped operands in apply patterns when they're temp
+/// reg defs, or immediates. Inference always outputs a `TypeOf<$x>` where $x is
+/// a named operand from a match pattern.
+class CombineRuleOperandTypeChecker : private OperandTypeChecker {
+public:
+ CombineRuleOperandTypeChecker(const Record &RuleDef,
+ const OperandTable &MatchOpTable)
+ : OperandTypeChecker(RuleDef.getLoc()), RuleDef(RuleDef),
+ MatchOpTable(MatchOpTable) {}
+
+ /// Records and checks a 'match' pattern.
+ bool processMatchPattern(InstructionPattern &P);
+
+ /// Records and checks an 'apply' pattern.
+ bool processApplyPattern(InstructionPattern &P);
+
+ /// Propagates types, then perform type inference and do a second round of
+ /// propagation in the apply patterns only if any types were inferred.
+ void propagateAndInferTypes();
+
+private:
+ /// TypeEquivalenceClasses are groups of operands of an instruction that share
+ /// a common type.
+ ///
+ /// e.g. [[a, b], [c, d]] means a and b have the same type, and c and
+ /// d have the same type too. b/c and a/d don't have to have the same type,
+ /// though.
+ ///
+ /// NOTE: We use a SetVector, not a Set. This is to guarantee a stable
+ /// iteration order which is important because:
+ /// - During inference, we iterate that set and pick the first suitable
+ /// candidate. Using a normal set could make inference inconsistent across
+ /// runs if the Set uses the StringRef ptr to cache values.
+ /// - We print this set if DebugInfer is set, and we don't want our tests to
+ /// fail randomly due to the Set's iteration order changing.
+ using TypeEquivalenceClasses = std::vector<SetVector<StringRef>>;
----------------
Pierre-vh wrote:
I didn't know if it was a good fit at first so I just hand-wrote the logic, but indeed EquivalenceClasses is just perfect for this (and gets rid of the set operations)
https://github.com/llvm/llvm-project/pull/66377
More information about the llvm-commits
mailing list