Repository: llvm/llvm-project
Pull request #136214: [LLVM][TableGen] Move DecoderEmitter output to anonymous namespace
Author: login: jurahul
Labels: name: backend:AMDGPU
name: tablegen
Created: 2025-04-17T22:03:19Z | Merged: 2025-04-18T11:35:06Z

- Move the code generated by DecoderEmitter to anonymous namespace.
- Move AMDGPU's usage of this code from header file to .cpp file.

Note, we get build errors like "call to function 'decodeInstruction' that is neither visible in the template definition nor found by argument-dependent lookup" if we do not change AMDGPU.


Diff:
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 847121f251361..3fbba17159375 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -487,6 +487,46 @@ static DecodeStatus decodeVersionImm(MCInst &Inst, unsigned Imm,
 //
 //===----------------------------------------------------------------------===//
 
+template <typename InsnType>
+DecodeStatus AMDGPUDisassembler::tryDecodeInst(const uint8_t *Table, MCInst &MI,
+                                               InsnType Inst, uint64_t Address,
+                                               raw_ostream &Comments) const {
+  assert(MI.getOpcode() == 0);
+  assert(MI.getNumOperands() == 0);
+  MCInst TmpInst;
+  HasLiteral = false;
+  const auto SavedBytes = Bytes;
+
+  SmallString<64> LocalComments;
+  raw_svector_ostream LocalCommentStream(LocalComments);
+  CommentStream = &LocalCommentStream;
+
+  DecodeStatus Res =
+      decodeInstruction(Table, TmpInst, Inst, Address, this, STI);
+
+  CommentStream = nullptr;
+
+  if (Res != MCDisassembler::Fail) {
+    MI = TmpInst;
+    Comments << LocalComments;
+    return MCDisassembler::Success;
+  }
+  Bytes = SavedBytes;
+  return MCDisassembler::Fail;
+}
+
+template <typename InsnType>
+DecodeStatus
+AMDGPUDisassembler::tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
+                                  MCInst &MI, InsnType Inst, uint64_t Address,
+                                  raw_ostream &Comments) const {
+  for (const uint8_t *T : {Table1, Table2}) {
+    if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments))
+      return Res;
+  }
+  return MCDisassembler::Fail;
+}
+
 template <typename T> static inline T eatBytes(ArrayRef<uint8_t>& Bytes) {
   assert(Bytes.size() >= sizeof(T));
   const auto Res =
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
index 29452166e21a0..498ef655b7f45 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
@@ -130,41 +130,11 @@ class AMDGPUDisassembler : public MCDisassembler {
 
   template <typename InsnType>
   DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
-                             uint64_t Address, raw_ostream &Comments) const {
-    assert(MI.getOpcode() == 0);
-    assert(MI.getNumOperands() == 0);
-    MCInst TmpInst;
-    HasLiteral = false;
-    const auto SavedBytes = Bytes;
-
-    SmallString<64> LocalComments;
-    raw_svector_ostream LocalCommentStream(LocalComments);
-    CommentStream = &LocalCommentStream;
-
-    DecodeStatus Res =
-        decodeInstruction(Table, TmpInst, Inst, Address, this, STI);
-
-    CommentStream = nullptr;
-
-    if (Res != Fail) {
-      MI = TmpInst;
-      Comments << LocalComments;
-      return MCDisassembler::Success;
-    }
-    Bytes = SavedBytes;
-    return MCDisassembler::Fail;
-  }
-
+                             uint64_t Address, raw_ostream &Comments) const;
   template <typename InsnType>
   DecodeStatus tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
                              MCInst &MI, InsnType Inst, uint64_t Address,
-                             raw_ostream &Comments) const {
-    for (const uint8_t *T : {Table1, Table2}) {
-      if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments))
-        return Res;
-    }
-    return MCDisassembler::Fail;
-  }
+                             raw_ostream &Comments) const;
 
   Expected<bool> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
                                ArrayRef<uint8_t> Bytes,
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 9c6015cc24576..75c8c80aebd6d 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -2417,7 +2417,7 @@ void DecoderEmitter::run(raw_ostream &o) {
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include <assert.h>
 
-namespace llvm {
+namespace {
 )";
 
   emitFieldFromInstruction(OS);
@@ -2561,7 +2561,7 @@ namespace llvm {
   // Emit the main entry point for the decoder, decodeInstruction().
   emitDecodeInstruction(OS, IsVarLenInst);
 
-  OS << "\n} // end namespace llvm\n";
+  OS << "\n} // namespace\n";
 }
 
 void llvm::EmitDecoder(const RecordKeeper &RK, raw_ostream &OS,


Reviews:
user: login: s-barannikov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-17T23:17:10Z
user: login: jurahul
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-17T23:44:47Z
user: login: s-barannikov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-18T00:04:26Z
user: login: s-barannikov
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-18T00:04:59Z
user: login: jurahul
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-18T00:26:02Z

Review comments:
diff_hunk: @@ -128,44 +128,6 @@ class AMDGPUDisassembler : public MCDisassembler {
 
   MCOperand errOperand(unsigned V, const Twine& ErrMsg) const;
 
-  template <typename InsnType>
-  DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
path: llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
user: login: s-barannikov
body: Can you move the body to cpp and keep the declaration inside the class? So that you don't have to pass `this` to every call.

created_at: 2025-04-17T23:17:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -128,44 +128,6 @@ class AMDGPUDisassembler : public MCDisassembler {
 
   MCOperand errOperand(unsigned V, const Twine& ErrMsg) const;
 
-  template <typename InsnType>
-  DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
path: llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
user: login: jurahul
body: Done.
created_at: 2025-04-17T23:44:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2561,7 +2561,7 @@ namespace llvm {
   // Emit the main entry point for the decoder, decodeInstruction().
   emitDecodeInstruction(OS, IsVarLenInst);
 
-  OS << "\n} // end namespace llvm\n";
+  OS << "\n} // end anonymous namespace\n";
path: llvm/utils/TableGen/DecoderEmitter.cpp
user: login: s-barannikov
body: (nit) I believe this should read `// namespace` (this is what `clang-format` would insert).
`// end [[of ]name ]namespace` syntax seems to be accepted for compatibility reasons.

created_at: 2025-04-18T00:04:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2561,7 +2561,7 @@ namespace llvm {
   // Emit the main entry point for the decoder, decodeInstruction().
   emitDecodeInstruction(OS, IsVarLenInst);
 
-  OS << "\n} // end namespace llvm\n";
+  OS << "\n} // end anonymous namespace\n";
path: llvm/utils/TableGen/DecoderEmitter.cpp
user: login: jurahul
body: Done.
created_at: 2025-04-18T00:26:02Z
author_association: CONTRIBUTOR

PR comments:
user: login: llvmbot
created_at: 2025-04-17T23:46:19Z
body: 
<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-tablegen

Author: Rahul Joshi (jurahul)

<details>
<summary>Changes</summary>

- Move the code generated by DecoderEmitter to anonymous namespace.
- Move AMDGPU's usage of this code from header file to .cpp file.

Note, we get build errors like "call to function 'decodeInstruction' that is neither visible in the template definition nor found by argument-dependent lookup" if we do not change AMDGPU.

---
Full diff: https://github.com/llvm/llvm-project/pull/136214.diff


3 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+40) 
- (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h (+2-32) 
- (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+2-2) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 847121f251361..3fbba17159375 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -487,6 +487,46 @@ static DecodeStatus decodeVersionImm(MCInst &Inst, unsigned Imm,
 //
 //===----------------------------------------------------------------------===//
 
+template <typename InsnType>
+DecodeStatus AMDGPUDisassembler::tryDecodeInst(const uint8_t *Table, MCInst &MI,
+                                               InsnType Inst, uint64_t Address,
+                                               raw_ostream &Comments) const {
+  assert(MI.getOpcode() == 0);
+  assert(MI.getNumOperands() == 0);
+  MCInst TmpInst;
+  HasLiteral = false;
+  const auto SavedBytes = Bytes;
+
+  SmallString<64> LocalComments;
+  raw_svector_ostream LocalCommentStream(LocalComments);
+  CommentStream = &LocalCommentStream;
+
+  DecodeStatus Res =
+      decodeInstruction(Table, TmpInst, Inst, Address, this, STI);
+
+  CommentStream = nullptr;
+
+  if (Res != MCDisassembler::Fail) {
+    MI = TmpInst;
+    Comments << LocalComments;
+    return MCDisassembler::Success;
+  }
+  Bytes = SavedBytes;
+  return MCDisassembler::Fail;
+}
+
+template <typename InsnType>
+DecodeStatus
+AMDGPUDisassembler::tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
+                                  MCInst &MI, InsnType Inst, uint64_t Address,
+                                  raw_ostream &Comments) const {
+  for (const uint8_t *T : {Table1, Table2}) {
+    if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments))
+      return Res;
+  }
+  return MCDisassembler::Fail;
+}
+
 template <typename T> static inline T eatBytes(ArrayRef<uint8_t>& Bytes) {
   assert(Bytes.size() >= sizeof(T));
   const auto Res =
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
index 29452166e21a0..498ef655b7f45 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
@@ -130,41 +130,11 @@ class AMDGPUDisassembler : public MCDisassembler {
 
   template <typename InsnType>
   DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
-                             uint64_t Address, raw_ostream &Comments) const {
-    assert(MI.getOpcode() == 0);
-    assert(MI.getNumOperands() == 0);
-    MCInst TmpInst;
-    HasLiteral = false;
-    const auto SavedBytes = Bytes;
-
-    SmallString<64> LocalComments;
-    raw_svector_ostream LocalCommentStream(LocalComments);
-    CommentStream = &LocalCommentStream;
-
-    DecodeStatus Res =
-        decodeInstruction(Table, TmpInst, Inst, Address, this, STI);
-
-    CommentStream = nullptr;
-
-    if (Res != Fail) {
-      MI = TmpInst;
-      Comments << LocalComments;
-      return MCDisassembler::Success;
-    }
-    Bytes = SavedBytes;
-    return MCDisassembler::Fail;
-  }
-
+                             uint64_t Address, raw_ostream &Comments) const;
   template <typename InsnType>
   DecodeStatus tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
                              MCInst &MI, InsnType Inst, uint64_t Address,
-                             raw_ostream &Comments) const {
-    for (const uint8_t *T : {Table1, Table2}) {
-      if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments))
-        return Res;
-    }
-    return MCDisassembler::Fail;
-  }
+                             raw_ostream &Comments) const;
 
   Expected<bool> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
                                ArrayRef<uint8_t> Bytes,
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 9c6015cc24576..35c928fae7b2b 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -2417,7 +2417,7 @@ void DecoderEmitter::run(raw_ostream &o) {
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include <assert.h>
 
-namespace llvm {
+namespace {
 )";
 
   emitFieldFromInstruction(OS);
@@ -2561,7 +2561,7 @@ namespace llvm {
   // Emit the main entry point for the decoder, decodeInstruction().
   emitDecodeInstruction(OS, IsVarLenInst);
 
-  OS << "\n} // end namespace llvm\n";
+  OS << "\n} // end anonymous namespace\n";
 }
 
 void llvm::EmitDecoder(const RecordKeeper &RK, raw_ostream &OS,

``````````

</details>

author_association: MEMBER
user: login: llvmbot
created_at: 2025-04-17T23:46:20Z
body: 
<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Rahul Joshi (jurahul)

<details>
<summary>Changes</summary>

- Move the code generated by DecoderEmitter to anonymous namespace.
- Move AMDGPU's usage of this code from header file to .cpp file.

Note, we get build errors like "call to function 'decodeInstruction' that is neither visible in the template definition nor found by argument-dependent lookup" if we do not change AMDGPU.

---
Full diff: https://github.com/llvm/llvm-project/pull/136214.diff


3 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+40) 
- (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h (+2-32) 
- (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+2-2) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 847121f251361..3fbba17159375 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -487,6 +487,46 @@ static DecodeStatus decodeVersionImm(MCInst &Inst, unsigned Imm,
 //
 //===----------------------------------------------------------------------===//
 
+template <typename InsnType>
+DecodeStatus AMDGPUDisassembler::tryDecodeInst(const uint8_t *Table, MCInst &MI,
+                                               InsnType Inst, uint64_t Address,
+                                               raw_ostream &Comments) const {
+  assert(MI.getOpcode() == 0);
+  assert(MI.getNumOperands() == 0);
+  MCInst TmpInst;
+  HasLiteral = false;
+  const auto SavedBytes = Bytes;
+
+  SmallString<64> LocalComments;
+  raw_svector_ostream LocalCommentStream(LocalComments);
+  CommentStream = &LocalCommentStream;
+
+  DecodeStatus Res =
+      decodeInstruction(Table, TmpInst, Inst, Address, this, STI);
+
+  CommentStream = nullptr;
+
+  if (Res != MCDisassembler::Fail) {
+    MI = TmpInst;
+    Comments << LocalComments;
+    return MCDisassembler::Success;
+  }
+  Bytes = SavedBytes;
+  return MCDisassembler::Fail;
+}
+
+template <typename InsnType>
+DecodeStatus
+AMDGPUDisassembler::tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
+                                  MCInst &MI, InsnType Inst, uint64_t Address,
+                                  raw_ostream &Comments) const {
+  for (const uint8_t *T : {Table1, Table2}) {
+    if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments))
+      return Res;
+  }
+  return MCDisassembler::Fail;
+}
+
 template <typename T> static inline T eatBytes(ArrayRef<uint8_t>& Bytes) {
   assert(Bytes.size() >= sizeof(T));
   const auto Res =
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
index 29452166e21a0..498ef655b7f45 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
@@ -130,41 +130,11 @@ class AMDGPUDisassembler : public MCDisassembler {
 
   template <typename InsnType>
   DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
-                             uint64_t Address, raw_ostream &Comments) const {
-    assert(MI.getOpcode() == 0);
-    assert(MI.getNumOperands() == 0);
-    MCInst TmpInst;
-    HasLiteral = false;
-    const auto SavedBytes = Bytes;
-
-    SmallString<64> LocalComments;
-    raw_svector_ostream LocalCommentStream(LocalComments);
-    CommentStream = &LocalCommentStream;
-
-    DecodeStatus Res =
-        decodeInstruction(Table, TmpInst, Inst, Address, this, STI);
-
-    CommentStream = nullptr;
-
-    if (Res != Fail) {
-      MI = TmpInst;
-      Comments << LocalComments;
-      return MCDisassembler::Success;
-    }
-    Bytes = SavedBytes;
-    return MCDisassembler::Fail;
-  }
-
+                             uint64_t Address, raw_ostream &Comments) const;
   template <typename InsnType>
   DecodeStatus tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
                              MCInst &MI, InsnType Inst, uint64_t Address,
-                             raw_ostream &Comments) const {
-    for (const uint8_t *T : {Table1, Table2}) {
-      if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments))
-        return Res;
-    }
-    return MCDisassembler::Fail;
-  }
+                             raw_ostream &Comments) const;
 
   Expected<bool> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
                                ArrayRef<uint8_t> Bytes,
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 9c6015cc24576..35c928fae7b2b 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -2417,7 +2417,7 @@ void DecoderEmitter::run(raw_ostream &o) {
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include <assert.h>
 
-namespace llvm {
+namespace {
 )";
 
   emitFieldFromInstruction(OS);
@@ -2561,7 +2561,7 @@ namespace llvm {
   // Emit the main entry point for the decoder, decodeInstruction().
   emitDecodeInstruction(OS, IsVarLenInst);
 
-  OS << "\n} // end namespace llvm\n";
+  OS << "\n} // end anonymous namespace\n";
 }
 
 void llvm::EmitDecoder(const RecordKeeper &RK, raw_ostream &OS,

``````````

</details>

author_association: MEMBER
user: login: jurahul
created_at: 2025-04-18T00:19:51Z
body: Thanks, FYI this also unblocks my earlier PR by to adjust the decoder table `NumToSkip` per backend: https://github.com/llvm/llvm-project/pull/136019#issuecomment-2813657821
author_association: CONTRIBUTOR