[llvm] e468b1b - [AMDGPU][GFX11] Refactor VOPD operands handling

Dmitry Preobrazhensky via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 16 05:29:34 PST 2022


Author: Dmitry Preobrazhensky
Date: 2022-11-16T16:29:12+03:00
New Revision: e468b1b740e522c212be24d2ead25383fe46f8f5

URL: https://github.com/llvm/llvm-project/commit/e468b1b740e522c212be24d2ead25383fe46f8f5
DIFF: https://github.com/llvm/llvm-project/commit/e468b1b740e522c212be24d2ead25383fe46f8f5.diff

LOG: [AMDGPU][GFX11] Refactor VOPD operands handling

Differential Revision: https://reviews.llvm.org/D137952

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
    llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
    llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
    llvm/test/MC/AMDGPU/gfx11_asm_vopd_err.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 07d9b7b6fc7ad..f739ccad34852 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -3590,7 +3590,7 @@ bool AMDGPUAsmParser::validateVOPDRegBankConstraints(
                : MCRegister::NoRegister;
   };
 
-  auto InstInfo = getVOPDInstInfo(Opcode, &MII);
+  const auto &InstInfo = getVOPDInstInfo(Opcode, &MII);
   auto InvalidOperandInfo = InstInfo.getInvalidOperandIndex(getVRegIdx);
   if (!InvalidOperandInfo)
     return true;
@@ -8524,11 +8524,11 @@ void AMDGPUAsmParser::cvtVOPD(MCInst &Inst, const OperandVector &Operands) {
 
   for (auto CompIdx : VOPD::COMPONENTS) {
     const auto &CInfo = InstInfo[CompIdx];
-    bool CompHasSrc2Acc = CInfo.hasSrc2Acc();
-    auto SrcOperandsNum = InstInfo[CompIdx].getSrcOperandsNum();
-    for (unsigned SrcIdx = 0; SrcIdx < SrcOperandsNum; ++SrcIdx) {
-      addOp(CInfo.getParsedSrcIndex(SrcIdx, CompHasSrc2Acc));
-    }
+    auto ParsedSrcOperandsNum = InstInfo[CompIdx].getParsedSrcOperandsNum();
+    for (unsigned SrcIdx = 0; SrcIdx < ParsedSrcOperandsNum; ++SrcIdx)
+      addOp(CInfo.getParsedSrcIndex(SrcIdx));
+    if (CInfo.hasSrc2Acc())
+      addOp(CInfo.getParsedDstIndex());
   }
 }
 

diff  --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 80e4dada6b36a..8a13567303f5e 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -499,8 +499,8 @@ unsigned ComponentInfo::getParsedOperandIndex(unsigned OprIdx) const {
     return getParsedDstIndex();
 
   auto SrcIdx = OprIdx - Component::DST_NUM;
-  if (SrcIdx < getSrcOperandsNum())
-    return getParsedSrcIndex(SrcIdx, hasSrc2Acc());
+  if (SrcIdx < getParsedSrcOperandsNum())
+    return getParsedSrcIndex(SrcIdx);
 
   // The specified operand does not exist.
   return 0;
@@ -522,25 +522,30 @@ Optional<unsigned> InstInfo::getInvalidOperandIndex(
   return {};
 }
 
+// Return an array of VGPR registers [DST,SRC0,SRC1,SRC2] used
+// by the specified component. If an operand is unused
+// or is not a VGPR, the corresponding value is 0.
+//
+// GetRegIdx(Component, OperandIdx) must return a VGPR register index
+// for the specified component and operand. The callback must return 0
+// if the operand is not a register or not a VGPR.
 InstInfo::RegIndices InstInfo::getRegIndices(
     unsigned ComponentIdx,
     std::function<unsigned(unsigned, unsigned)> GetRegIdx) const {
   assert(ComponentIdx < COMPONENTS_NUM);
 
   auto Comp = CompInfo[ComponentIdx];
+  InstInfo::RegIndices RegIndices;
 
-  unsigned DstReg = GetRegIdx(ComponentIdx, Comp.getDstIndex());
-  unsigned Src0Reg = GetRegIdx(ComponentIdx, Comp.getSrcIndex(0));
-
-  unsigned Src1Reg = 0;
-  if (Comp.hasRegularSrcOperand(1))
-    Src1Reg = GetRegIdx(ComponentIdx, Comp.getSrcIndex(1));
+  RegIndices[DST] = GetRegIdx(ComponentIdx, Comp.getDstIndex());
 
-  unsigned Src2Reg = 0;
-  if (Comp.hasRegularSrcOperand(2))
-    Src2Reg = GetRegIdx(ComponentIdx, Comp.getSrcIndex(2));
-
-  return {DstReg, Src0Reg, Src1Reg, Src2Reg};
+  for (unsigned OprIdx : {SRC0, SRC1, SRC2}) {
+    unsigned SrcIdx = OprIdx - DST_NUM;
+    RegIndices[OprIdx] = Comp.hasRegSrcOperand(SrcIdx)
+                             ? GetRegIdx(ComponentIdx, Comp.getSrcIndex(SrcIdx))
+                             : 0;
+  }
+  return RegIndices;
 }
 
 } // namespace VOPD
@@ -555,9 +560,7 @@ VOPD::InstInfo getVOPDInstInfo(unsigned VOPDOpcode,
   const auto &OpXDesc = InstrInfo->get(OpX);
   const auto &OpYDesc = InstrInfo->get(OpY);
   VOPD::ComponentInfo OpXInfo(OpXDesc, VOPD::ComponentKind::COMPONENT_X);
-  VOPD::ComponentInfo OpYInfo(
-      OpYDesc, VOPD::ComponentKind::COMPONENT_Y, OpXInfo.getSrcOperandsNum(),
-      OpXInfo.getSrcOperandsNum() - OpXInfo.hasSrc2Acc());
+  VOPD::ComponentInfo OpYInfo(OpYDesc, OpXInfo);
   return VOPD::InstInfo(OpXInfo, OpYInfo);
 }
 

diff  --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index 778987cb03e76..40b5b60212d42 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -529,6 +529,40 @@ enum ComponentIndex : unsigned { X = 0, Y = 1 };
 constexpr unsigned COMPONENTS[] = {ComponentIndex::X, ComponentIndex::Y};
 constexpr unsigned COMPONENTS_NUM = 2;
 
+// Properties of VOPD components.
+class ComponentProps {
+private:
+  unsigned SrcOperandsNum = 0;
+  Optional<unsigned> MandatoryLiteralIdx;
+  bool HasSrc2Acc = false;
+
+public:
+  ComponentProps() = default;
+  ComponentProps(const MCInstrDesc &OpDesc);
+
+  unsigned getSrcOperandsNum() const { return SrcOperandsNum; }
+  unsigned getParsedSrcOperandsNum() const {
+    return SrcOperandsNum - HasSrc2Acc;
+  }
+  bool hasMandatoryLiteral() const { return MandatoryLiteralIdx.has_value(); }
+  unsigned getMandatoryLiteralIndex() const {
+    assert(hasMandatoryLiteral());
+    return *MandatoryLiteralIdx;
+  }
+  bool hasRegSrcOperand(unsigned SrcIdx) const {
+    assert(SrcIdx < Component::MAX_SRC_NUM);
+    return SrcOperandsNum > SrcIdx && !hasMandatoryLiteralAt(SrcIdx);
+  }
+  bool hasSrc2Acc() const { return HasSrc2Acc; }
+
+private:
+  bool hasMandatoryLiteralAt(unsigned SrcIdx) const {
+    assert(SrcIdx < Component::MAX_SRC_NUM);
+    return hasMandatoryLiteral() &&
+           *MandatoryLiteralIdx == Component::DST_NUM + SrcIdx;
+  }
+};
+
 enum ComponentKind : unsigned {
   SINGLE = 0,  // A single VOP1 or VOP2 instruction which may be used in VOPD.
   COMPONENT_X, // A VOPD instruction, X component.
@@ -546,7 +580,7 @@ class ComponentLayout {
   //   dstX, dstY, src0X [, other OpX operands], src0Y [, other OpY operands]
   // Each ComponentKind has operand indices defined below.
   static constexpr unsigned MC_DST_IDX[] = {0, 0, 1};
-  static constexpr unsigned FIRST_MC_SRC_IDX[] = {1, 2, 2 /* + OpXSrcNum */};
+  static constexpr unsigned FIRST_MC_SRC_IDX[] = {1, 2, 2 /* + OpX.SrcNum */};
 
   // Parsed operands of regular instructions are ordered as follows:
   //   Mnemo dst src0 [vsrc1 ...]
@@ -555,81 +589,58 @@ class ComponentLayout {
   //   OpYMnemo dstY src0Y [vsrc1Y|imm vsrc1Y|vsrc1Y imm]
   // Each ComponentKind has operand indices defined below.
   static constexpr unsigned PARSED_DST_IDX[] = {1, 1,
-                                                4 /* + ParsedOpXSrcNum */};
+                                                4 /* + OpX.ParsedSrcNum */};
   static constexpr unsigned FIRST_PARSED_SRC_IDX[] = {
-      2, 2, 5 /* + ParsedOpXSrcNum */};
+      2, 2, 5 /* + OpX.ParsedSrcNum */};
 
 private:
-  ComponentKind Kind;
-  unsigned OpXSrcNum;
-  unsigned ParsedOpXSrcNum;
+  const ComponentKind Kind;
+  const ComponentProps PrevOp;
 
 public:
-  ComponentLayout(ComponentKind Kind = ComponentKind::SINGLE,
-                  unsigned OpXSrcNum = 0, unsigned ParsedOpXSrcNum = 0)
-      : Kind(Kind), OpXSrcNum(OpXSrcNum), ParsedOpXSrcNum(ParsedOpXSrcNum) {
-    assert(Kind <= ComponentKind::MAX);
-    assert((Kind == ComponentKind::COMPONENT_Y) == (OpXSrcNum > 0));
+  // Create layout for COMPONENT_X or SINGLE component
+  ComponentLayout(ComponentKind Kind) : Kind(Kind) {
+    assert(Kind == ComponentKind::SINGLE || Kind == ComponentKind::COMPONENT_X);
   }
 
+  // Create layout for COMPONENT_Y which depends on COMPONENT_X layout
+  ComponentLayout(const ComponentProps &OpXProps)
+      : Kind(ComponentKind::COMPONENT_Y), PrevOp(OpXProps) {}
+
 public:
   unsigned getDstIndex() const { return MC_DST_IDX[Kind]; }
   unsigned getSrcIndex(unsigned SrcIdx) const {
     assert(SrcIdx < Component::MAX_SRC_NUM);
-    return FIRST_MC_SRC_IDX[Kind] + OpXSrcNum + SrcIdx;
+    return FIRST_MC_SRC_IDX[Kind] + getPrevOpSrcNum() + SrcIdx;
   }
 
   unsigned getParsedDstIndex() const {
-    return PARSED_DST_IDX[Kind] + ParsedOpXSrcNum;
+    return PARSED_DST_IDX[Kind] + getPrevOpParsedSrcNum();
   }
-  unsigned getParsedSrcIndex(unsigned SrcIdx, bool ComponentHasSrc2Acc) const {
+  unsigned getParsedSrcIndex(unsigned SrcIdx) const {
     assert(SrcIdx < Component::MAX_SRC_NUM);
-    // FMAC and DOT2C have a src2 operand on the MCInst but
-    // not on the asm representation. src2 is tied to dst.
-    if (ComponentHasSrc2Acc && SrcIdx == (MAX_SRC_NUM - 1))
-      return getParsedDstIndex();
-    return FIRST_PARSED_SRC_IDX[Kind] + ParsedOpXSrcNum + SrcIdx;
+    return FIRST_PARSED_SRC_IDX[Kind] + getPrevOpParsedSrcNum() + SrcIdx;
   }
-};
 
-// Properties of VOPD components.
-class ComponentProps {
 private:
-  unsigned SrcOperandsNum;
-  Optional<unsigned> MandatoryLiteralIdx;
-  bool HasSrc2Acc;
-
-public:
-  ComponentProps(const MCInstrDesc &OpDesc);
-
-  unsigned getSrcOperandsNum() const { return SrcOperandsNum; }
-  bool hasMandatoryLiteral() const { return MandatoryLiteralIdx.has_value(); }
-  unsigned getMandatoryLiteralIndex() const {
-    assert(hasMandatoryLiteral());
-    return *MandatoryLiteralIdx;
-  }
-  bool hasRegularSrcOperand(unsigned SrcIdx) const {
-    assert(SrcIdx < Component::MAX_SRC_NUM);
-    return SrcOperandsNum > SrcIdx && !hasMandatoryLiteralAt(SrcIdx);
-  }
-  bool hasSrc2Acc() const { return HasSrc2Acc; }
-
-private:
-  bool hasMandatoryLiteralAt(unsigned SrcIdx) const {
-    assert(SrcIdx < Component::MAX_SRC_NUM);
-    return hasMandatoryLiteral() &&
-           *MandatoryLiteralIdx == Component::DST_NUM + SrcIdx;
+  unsigned getPrevOpSrcNum() const { return PrevOp.getSrcOperandsNum(); }
+  unsigned getPrevOpParsedSrcNum() const {
+    return PrevOp.getParsedSrcOperandsNum();
   }
 };
 
 // Layout and properties of VOPD components.
 class ComponentInfo : public ComponentLayout, public ComponentProps {
 public:
+  // Create ComponentInfo for COMPONENT_X or SINGLE component
+  ComponentInfo(const MCInstrDesc &OpDesc,
+                ComponentKind Kind = ComponentKind::SINGLE)
+      : ComponentLayout(Kind), ComponentProps(OpDesc) {}
+
+  // Create ComponentInfo for COMPONENT_Y which depends on COMPONENT_X layout
   ComponentInfo(const MCInstrDesc &OpDesc,
-                ComponentKind Kind = ComponentKind::SINGLE,
-                unsigned OpXSrcNum = 0, unsigned ParsedOpXSrcNum = 0)
-      : ComponentLayout(Kind, OpXSrcNum, ParsedOpXSrcNum),
-        ComponentProps(OpDesc) {}
+                const ComponentProps &OpXProps)
+      : ComponentLayout(OpXProps), ComponentProps(OpDesc) {}
 
   // Map MC operand index to parsed operand index.
   // Return 0 if the specified operand does not exist.

diff  --git a/llvm/test/MC/AMDGPU/gfx11_asm_vopd_err.s b/llvm/test/MC/AMDGPU/gfx11_asm_vopd_err.s
index bec22526bd124..f26fb6a4e2cda 100644
--- a/llvm/test/MC/AMDGPU/gfx11_asm_vopd_err.s
+++ b/llvm/test/MC/AMDGPU/gfx11_asm_vopd_err.s
@@ -266,7 +266,7 @@ v_dual_fmac_f32     v7, v1, v2                   :: v_dual_fmamk_f32      v6, v2
 v_dual_fmamk_f32    v6, v1, 0xaf123456, v3       :: v_dual_fmac_f32       v5, v2, v3
 // GFX11: error: src2 operands must use 
diff erent VGPR banks
 // GFX11-NEXT:{{^}}v_dual_fmamk_f32    v6, v1, 0xaf123456, v3       :: v_dual_fmac_f32       v5, v2, v3
-// GFX11-NEXT:{{^}}                                                                          ^
+// GFX11-NEXT:{{^}}                                        ^
 
 //===----------------------------------------------------------------------===//
 // Check invalid VOPD syntax.


        


More information about the llvm-commits mailing list