[llvm] r325067 - [globalisel][legalizerinfo] Follow up on post-commit review comments after r323681

Daniel Sanders via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 13 15:02:44 PST 2018


Author: dsanders
Date: Tue Feb 13 15:02:44 2018
New Revision: 325067

URL: http://llvm.org/viewvc/llvm-project?rev=325067&view=rev
Log:
[globalisel][legalizerinfo] Follow up on post-commit review comments after r323681

* Document most API's
* Delete a useless function call
* Fix a discrepancy between the single and multi-opcode variants of
  getActionDefinitions().
  The multi-opcode variant now requires that more than one opcode is requested.
  Previously it acted much like the single-opcode form but unnecessarily
  enforced the requirements of the multi-opcode form.

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
    llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
    llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h?rev=325067&r1=325066&r2=325067&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h Tue Feb 13 15:02:44 2018
@@ -144,25 +144,46 @@ using LegalizeMutation =
     std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
 
 namespace LegalityPredicates {
+/// True iff P0 and P1 are true.
 LegalityPredicate all(LegalityPredicate P0, LegalityPredicate P1);
+/// True iff the given type index is one of the specified types.
 LegalityPredicate typeInSet(unsigned TypeIdx,
                             std::initializer_list<LLT> TypesInit);
+/// True iff the given types for the given pair of type indexes is one of the
+/// specified type pairs.
 LegalityPredicate
 typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
               std::initializer_list<std::pair<LLT, LLT>> TypesInit);
+/// True iff the specified type index is a scalar.
 LegalityPredicate isScalar(unsigned TypeIdx);
+/// True iff the specified type index is a scalar that's narrower than the given
+/// size.
 LegalityPredicate narrowerThan(unsigned TypeIdx, unsigned Size);
+/// True iff the specified type index is a scalar that's wider than the given
+/// size.
 LegalityPredicate widerThan(unsigned TypeIdx, unsigned Size);
+/// True iff the specified type index is a scalar whose size is not a power of
+/// 2.
 LegalityPredicate sizeNotPow2(unsigned TypeIdx);
+/// True iff the specified type index is a vector whose element count is not a
+/// power of 2.
 LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
 } // end namespace LegalityPredicates
 
 namespace LegalizeMutations {
+/// Select this specific type for the given type index.
 LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
+/// Widen the type for the given type index to the next power of 2.
 LegalizeMutation widenScalarToNextPow2(unsigned TypeIdx, unsigned Min = 0);
+/// Add more elements to the type for the given type index to the next power of
+/// 2.
 LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
 } // end namespace LegalizeMutations
 
+/// A single rule in a legalizer info ruleset.
+/// The specified action is chosen when the predicate is true. Where appropriate
+/// for the action (e.g. for WidenScalar) the new type is selected using the
+/// given mutator.
 class LegalizeRule {
   LegalityPredicate Predicate;
   LegalizeAction Action;
@@ -173,11 +194,14 @@ public:
                LegalizeMutation Mutation = nullptr)
       : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
 
+  /// Test whether the LegalityQuery matches.
   bool match(const LegalityQuery &Query) const {
     return Predicate(Query);
   }
 
   LegalizeAction getAction() const { return Action; }
+
+  /// Determine the change to make.
   std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
     if (Mutation)
       return Mutation(Query);
@@ -200,32 +224,48 @@ class LegalizeRuleSet {
 
   static bool always(const LegalityQuery &) { return true; }
 
+  /// Use the given action when the predicate is true.
+  /// Action should not be an action that requires mutation.
   LegalizeRuleSet &actionIf(LegalizeAction Action,
                             LegalityPredicate Predicate) {
     add({Predicate, Action});
     return *this;
   }
+  /// Use the given action when the predicate is true.
+  /// Action should not be an action that requires mutation.
   LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
                             LegalizeMutation Mutation) {
     add({Predicate, Action, Mutation});
     return *this;
   }
+  /// Use the given action when type index 0 is any type in the given list.
+  /// Action should not be an action that requires mutation.
   LegalizeRuleSet &actionFor(LegalizeAction Action,
                              std::initializer_list<LLT> Types) {
     using namespace LegalityPredicates;
     return actionIf(Action, typeInSet(0, Types));
   }
+  /// Use the given action when type indexes 0 and 1 is any type pair in the
+  /// given list.
+  /// Action should not be an action that requires mutation.
   LegalizeRuleSet &
   actionFor(LegalizeAction Action,
             std::initializer_list<std::pair<LLT, LLT>> Types) {
     using namespace LegalityPredicates;
     return actionIf(Action, typePairInSet(0, 1, Types));
   }
+  /// Use the given action when type indexes 0 and 1 are both in the given list.
+  /// That is, the type pair is in the cartesian product of the list.
+  /// Action should not be an action that requires mutation.
   LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
                                              std::initializer_list<LLT> Types) {
     using namespace LegalityPredicates;
     return actionIf(Action, all(typeInSet(0, Types), typeInSet(1, Types)));
   }
+  /// Use the given action when type indexes 0 and 1 are both their respective
+  /// lists.
+  /// That is, the type pair is in the cartesian product of the lists
+  /// Action should not be an action that requires mutation.
   LegalizeRuleSet &
   actionForCartesianProduct(LegalizeAction Action,
                             std::initializer_list<LLT> Types0,
@@ -247,24 +287,32 @@ public:
   }
   unsigned getAlias() const { return AliasOf; }
 
-  // Primitive rule definition functions
+  /// The instruction is legal if predicate is true.
   LegalizeRuleSet &legalIf(LegalityPredicate Predicate) {
     return actionIf(LegalizeAction::Legal, Predicate);
   }
+  /// The instruction is legal when type index 0 is any type in the given list.
   LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
     return actionFor(LegalizeAction::Legal, Types);
   }
+  /// The instruction is legal when type indexes 0 and 1 is any type pair in the
+  /// given list.
   LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
     return actionFor(LegalizeAction::Legal, Types);
   }
+  /// The instruction is legal when type indexes 0 and 1 are both in the given
+  /// list. That is, the type pair is in the cartesian product of the list.
   LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
     return actionForCartesianProduct(LegalizeAction::Legal, Types);
   }
+  /// The instruction is legal when type indexes 0 and 1 are both their
+  /// respective lists.
   LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
                                             std::initializer_list<LLT> Types1) {
     return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
   }
 
+  /// Like legalIf, but for the Libcall action.
   LegalizeRuleSet &libcallIf(LegalityPredicate Predicate) {
     return actionIf(LegalizeAction::Libcall, Predicate);
   }
@@ -285,24 +333,33 @@ public:
     return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
   }
 
+  /// Widen the scalar to the one selected by the mutation if the predicate is
+  /// true.
   LegalizeRuleSet &widenScalarIf(LegalityPredicate Predicate,
                                  LegalizeMutation Mutation) {
     return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
   }
+  /// Narrow the scalar to the one selected by the mutation if the predicate is
+  /// true.
   LegalizeRuleSet &narrowScalarIf(LegalityPredicate Predicate,
                                   LegalizeMutation Mutation) {
     return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
   }
 
+  /// Add more elements to reach the type selected by the mutation if the
+  /// predicate is true.
   LegalizeRuleSet &moreElementsIf(LegalityPredicate Predicate,
                                   LegalizeMutation Mutation) {
     return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
   }
+  /// Remove elements to reach the type selected by the mutation if the
+  /// predicate is true.
   LegalizeRuleSet &fewerElementsIf(LegalityPredicate Predicate,
                                    LegalizeMutation Mutation) {
     return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
   }
 
+  /// The instruction is unsupported.
   LegalizeRuleSet &unsupported() {
     return actionIf(LegalizeAction::Unsupported, always);
   }
@@ -325,7 +382,8 @@ public:
     return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
   }
 
-  // Convenience rule definition functions
+  /// Widen the scalar to the next power of two that is at least MinSize.
+  /// No effect if the type is not a scalar or is a power of two.
   LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx, unsigned MinSize = 0) {
     using namespace LegalityPredicates;
     return widenScalarIf(
@@ -338,6 +396,7 @@ public:
     return narrowScalarIf(isScalar(TypeIdx), Mutation);
   }
 
+  /// Ensure the scalar is at least as wide as Ty.
   LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) {
     using namespace LegalityPredicates;
     using namespace LegalizeMutations;
@@ -345,6 +404,7 @@ public:
                          changeTo(TypeIdx, Ty));
   }
 
+  /// Ensure the scalar is at most as wide as Ty.
   LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT &Ty) {
     using namespace LegalityPredicates;
     using namespace LegalizeMutations;
@@ -352,6 +412,9 @@ public:
                           changeTo(TypeIdx, Ty));
   }
 
+  /// Conditionally limit the maximum size of the scalar.
+  /// For example, when the maximum size of one type depends on the size of
+  /// another such as extracting N bits from an M bit container.
   LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT &Ty) {
     using namespace LegalityPredicates;
     using namespace LegalizeMutations;
@@ -363,6 +426,7 @@ public:
         changeTo(TypeIdx, Ty));
   }
 
+  /// Limit the range of scalar sizes to MinTy and MaxTy.
   LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT &MinTy, const LLT &MaxTy) {
     assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
 
@@ -370,12 +434,16 @@ public:
         .maxScalar(TypeIdx, MaxTy);
   }
 
+  /// Add more elements to the vector to reach the next power of two.
+  /// No effect if the type is not a vector or the element count is a power of
+  /// two.
   LegalizeRuleSet &moreElementsToNextPow2(unsigned TypeIdx) {
     using namespace LegalityPredicates;
     return moreElementsIf(numElementsNotPow2(TypeIdx),
                           LegalizeMutations::moreElementsToNextPow2(TypeIdx));
   }
 
+  /// Limit the number of elements in EltTy vectors to at least MinElements.
   LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT &EltTy,
                                        unsigned MinElements) {
     return moreElementsIf(
@@ -390,6 +458,7 @@ public:
               TypeIdx, LLT::vector(MinElements, VecTy.getScalarSizeInBits()));
         });
   }
+  /// Limit the number of elements in EltTy vectors to at most MaxElements.
   LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT &EltTy,
                                        unsigned MaxElements) {
     return fewerElementsIf(
@@ -404,6 +473,12 @@ public:
               TypeIdx, LLT::vector(MaxElements, VecTy.getScalarSizeInBits()));
         });
   }
+  /// Limit the number of elements for the given vectors to at least MinTy's
+  /// number of elements and at most MaxTy's number of elements.
+  ///
+  /// No effect if the type is not a vector or does not have the same element
+  /// type as the constraints.
+  /// The element type of MinTy and MaxTy must match.
   LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT &MinTy,
                                     const LLT &MaxTy) {
     assert(MinTy.getElementType() == MaxTy.getElementType() &&
@@ -414,11 +489,14 @@ public:
         .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
   }
 
+  /// Fallback on the previous implementation. This should only be used while
+  /// porting a rule.
   LegalizeRuleSet &fallback() {
     add({always, LegalizeAction::UseLegacyRules});
     return *this;
   }
 
+  /// Apply the ruleset to the given LegalityQuery.
   LegalizeActionStep apply(const LegalityQuery &Query) const;
 };
 
@@ -593,8 +671,30 @@ public:
                                               LegalizeAction DecreaseAction,
                                               LegalizeAction IncreaseAction);
 
+  /// Get the action definitions for the given opcode. Use this to run a
+  /// LegalityQuery through the definitions.
   const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
+
+  /// Get the action definition builder for the given opcode. Use this to define
+  /// the action definitions.
+  ///
+  /// It is an error to request an opcode that has already been requested by the
+  /// multiple-opcode variant.
   LegalizeRuleSet &getActionDefinitionsBuilder(unsigned Opcode);
+
+  /// Get the action definition builder for the given set of opcodes. Use this
+  /// to define the action definitions for multiple opcodes at once. The first
+  /// opcode given will be considered the representative opcode and will hold
+  /// the definitions whereas the other opcodes will be configured to refer to
+  /// the representative opcode. This lowers memory requirements and very
+  /// slightly improves performance.
+  ///
+  /// It would be very easy to introduce unexpected side-effects as a result of
+  /// this aliasing if it were permitted to request different but intersecting
+  /// sets of opcodes but that is difficult to keep track of. It is therefore an
+  /// error to request the same opcode twice using this API, to request an
+  /// opcode that already has definitions, or to use the single-opcode API on an
+  /// opcode that has already been requested by this API.
   LegalizeRuleSet &
   getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
   void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);

Modified: llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp?rev=325067&r1=325066&r2=325067&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/LegalizerInfo.cpp Tue Feb 13 15:02:44 2018
@@ -261,6 +261,10 @@ LegalizeRuleSet &LegalizerInfo::getActio
     std::initializer_list<unsigned> Opcodes) {
   unsigned Representative = *Opcodes.begin();
 
+  assert(Opcodes.begin() != Opcodes.end() &&
+         Opcodes.begin() + 1 != Opcodes.end() &&
+         "Initializer list must have at least two opcodes");
+
   for (auto I = Opcodes.begin() + 1, E = Opcodes.end(); I != E; ++I)
     aliasActionDefinitions(Representative, *I);
 

Modified: llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp?rev=325067&r1=325066&r2=325067&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp Tue Feb 13 15:02:44 2018
@@ -240,7 +240,6 @@ AArch64LegalizerInfo::AArch64LegalizerIn
     getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG)
         .legalForCartesianProduct({s8, s16, s32, s64}, {p0});
   }
-  getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG);
 
   if (ST.hasLSE()) {
     for (auto Ty : {s8, s16, s32, s64}) {




More information about the llvm-commits mailing list