[llvm] [InlineAsm] refactor InlineAsm class NFC (PR #65649)

Jessica Clarke via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 7 11:49:01 PDT 2023


================
@@ -292,101 +274,152 @@ class InlineAsm final : public Value {
     Func = 7,               // Address operand of function call
   };
 
-  static unsigned getFlagWord(Kind Kind, unsigned NumOps) {
-    assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!");
-    return static_cast<unsigned>(Kind) | (NumOps << 3);
-  }
-
-  static bool isRegDefKind(unsigned Flag) {
-    return getKind(Flag) == Kind::RegDef;
-  }
-  static bool isImmKind(unsigned Flag) { return getKind(Flag) == Kind::Imm; }
-  static bool isMemKind(unsigned Flag) { return getKind(Flag) == Kind::Mem; }
-  static bool isFuncKind(unsigned Flag) { return getKind(Flag) == Kind::Func; }
-  static bool isRegDefEarlyClobberKind(unsigned Flag) {
-    return getKind(Flag) == Kind::RegDefEarlyClobber;
-  }
-  static bool isClobberKind(unsigned Flag) {
-    return getKind(Flag) == Kind::Clobber;
-  }
-
-  /// getFlagWordForMatchingOp - Augment an existing flag word returned by
-  /// getFlagWord with information indicating that this input operand is tied
-  /// to a previous output operand.
-  static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
-                                           unsigned MatchedOperandNo) {
-    assert(MatchedOperandNo <= 0x7fff && "Too big matched operand");
-    assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
-    return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16);
-  }
-
-  /// getFlagWordForRegClass - Augment an existing flag word returned by
-  /// getFlagWord with the required register class for the following register
-  /// operands.
-  /// A tied use operand cannot have a register class, use the register class
-  /// from the def operand instead.
-  static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC) {
-    // Store RC + 1, reserve the value 0 to mean 'no register class'.
-    ++RC;
-    assert(!isImmKind(InputFlag) && "Immediates cannot have a register class");
-    assert(!isMemKind(InputFlag) && "Memory operand cannot have a register class");
-    assert(RC <= 0x7fff && "Too large register class ID");
-    assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
-    return InputFlag | (RC << 16);
-  }
+  // These are helper methods for dealing with flags in the INLINEASM SDNode
+  // in the backend.
+  //
+  // The encoding of Flag is currently:
+  //   Bits 2-0 - A Kind::* value indicating the kind of the operand.
+  //   Bits 15-3 - The number of SDNode operands associated with this inline
+  //               assembly operand.
+  //   If bit 31 is set:
+  //     Bit 30-16 - The operand number that this operand must match.
+  //                 When bits 2-0 are Kind::Mem, the Constraint_* value must be
+  //                 obtained from the flags for this operand number.
+  //   Else if bits 2-0 are Kind::Mem:
+  //     Bit 30-16 - A Constraint_* value indicating the original constraint
+  //                 code.
+  //   Else:
+  //     Bit 30-16 - The register class ID to use for the operand.
+  class Flag {
+    // union {
+    //   unsigned MatchingOpNo : 15;
+    //   unsigned OriginalConstraintCode : 15;
+    //   unsigned RegisterClassID : 15;
+    // } GrabBag;
+    Kind Kind : 3;
+    unsigned NumOperands : 13;
+    unsigned GrabBag : 15;
+    unsigned IsMatched : 1;
+
+    bool isMatched() const { return IsMatched; }
+  public:
+    explicit Flag (uint32_t F) {
+      // TODO: some kind of assertion failure if enum Kind becomes bigger than 3b?
+      static_assert(sizeof(Flag) == sizeof(F), "Expected sizeof Flag to be 4B");
+      // Look away children. May god forgive me of my sins.
+      *reinterpret_cast<uint32_t*>(this) = sys::IsBigEndianHost ? sys::getSwappedBytes(F) : F;
----------------
jrtc27 wrote:

But I *believe* this is the wrong way to do it. It will correctly swap the fields around to match the bitfield's order, but the bits within each field will be swapped when they shouldn't be. IIRC how all this works for big-endian.

https://github.com/llvm/llvm-project/pull/65649


More information about the llvm-commits mailing list