[llvm-branch-commits] [llvm] [AMDGPU] Add `.amdgpu.info` section for per-function metadata (PR #192384)

Shilei Tian via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Apr 16 06:37:08 PDT 2026


================
@@ -6741,6 +6746,115 @@ bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
   return false;
 }
 
+bool AMDGPUAsmParser::ParseDirectiveAMDGPUInfo() {
+  if (getParser().checkForValidSection())
+    return true;
+
+  StringRef FuncName;
+  if (getParser().parseIdentifier(FuncName))
+    return TokError("expected symbol name after .amdgpu_info");
+
+  MCSymbol *FuncSym = getContext().getOrCreateSymbol(FuncName);
+  AMDGPU::FuncInfo FI;
+  FI.Sym = FuncSym;
+  bool HasScalarAttrs = false;
+
+  while (true) {
+    while (trySkipToken(AsmToken::EndOfStatement))
+      ;
+
+    StringRef ID;
+    SMLoc IDLoc = getLoc();
+    if (!parseId(ID, "expected directive or .end_amdgpu_info"))
+      return true;
+
+    if (ID == ".end_amdgpu_info")
+      break;
+
+    if (ID == ".amdgpu_flags") {
+      int64_t Val;
+      if (getParser().parseAbsoluteExpression(Val))
+        return true;
+      uint32_t Flags = static_cast<uint32_t>(Val);
+      FI.IsKernel = (Flags & AMDGPU::FUNC_IS_KERNEL) != 0;
+      FI.UsesVCC = (Flags & AMDGPU::FUNC_USES_VCC) != 0;
+      FI.UsesFlatScratch = (Flags & AMDGPU::FUNC_USES_FLAT_SCRATCH) != 0;
+      FI.HasDynStack = (Flags & AMDGPU::FUNC_HAS_DYN_STACK) != 0;
+      HasScalarAttrs = true;
+    } else if (ID == ".amdgpu_num_vgpr") {
+      int64_t Val;
+      if (getParser().parseAbsoluteExpression(Val))
+        return true;
+      FI.NumArchVGPR = static_cast<uint32_t>(Val);
+      HasScalarAttrs = true;
+    } else if (ID == ".amdgpu_num_agpr") {
+      int64_t Val;
+      if (getParser().parseAbsoluteExpression(Val))
+        return true;
+      FI.NumAccVGPR = static_cast<uint32_t>(Val);
+      HasScalarAttrs = true;
+    } else if (ID == ".amdgpu_num_sgpr") {
+      int64_t Val;
+      if (getParser().parseAbsoluteExpression(Val))
+        return true;
+      FI.NumSGPR = static_cast<uint32_t>(Val);
+      HasScalarAttrs = true;
+    } else if (ID == ".amdgpu_num_named_barrier") {
+      int64_t Val;
+      if (getParser().parseAbsoluteExpression(Val))
+        return true;
+      FI.NumNamedBarrier = static_cast<uint32_t>(Val);
+      HasScalarAttrs = true;
+    } else if (ID == ".amdgpu_private_segment_size") {
+      int64_t Val;
+      if (getParser().parseAbsoluteExpression(Val))
+        return true;
+      FI.PrivateSegmentSize = static_cast<uint32_t>(Val);
+      HasScalarAttrs = true;
+    } else if (ID == ".amdgpu_occupancy_lds_limit") {
+      int64_t Val;
+      if (getParser().parseAbsoluteExpression(Val))
+        return true;
+      FI.OccupancyLDSLimit = static_cast<uint32_t>(Val);
+      HasScalarAttrs = true;
+    } else if (ID == ".amdgpu_use") {
+      StringRef ResName;
+      if (getParser().parseIdentifier(ResName))
+        return TokError("expected resource symbol for .amdgpu_use");
+      InfoData.Uses.push_back(
+          {FuncSym, getContext().getOrCreateSymbol(ResName)});
+    } else if (ID == ".amdgpu_call") {
+      StringRef DstName;
+      if (getParser().parseIdentifier(DstName))
+        return TokError("expected callee symbol for .amdgpu_call");
+      InfoData.Calls.push_back(
+          {FuncSym, getContext().getOrCreateSymbol(DstName)});
+    } else if (ID == ".amdgpu_indirect_call") {
+      std::string TypeId;
+      if (getParser().parseEscapedString(TypeId))
+        return TokError("expected type ID string for .amdgpu_indirect_call");
+      InfoData.IndirectCalls.push_back({FuncSym, std::move(TypeId)});
+    } else if (ID == ".amdgpu_signature") {
+      std::string TypeId;
+      if (getParser().parseEscapedString(TypeId))
+        return TokError("expected type ID string for .amdgpu_signature");
+      InfoData.Signatures.push_back({FuncSym, std::move(TypeId)});
+    } else {
+      return Error(IDLoc, "unknown .amdgpu_info directive '" + ID + "'");
+    }
+  }
+
----------------
shiltian wrote:

Yes, that's the design, but it is fine to have something like below in the future:

```
.amdgpu_info foo
...
.amdgpu_new_feature_x Y
.end_amdgpu_info
```

I'm not sure how beneficial to have the information emitted into different scopes, since that will need more REL symbols, each of which is 8 byte.

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


More information about the llvm-branch-commits mailing list