Commit 31b6d14bf7

Tw <tw19881113@gmail.com>
2023-04-20 13:12:41
llvm: emit metadata for exported global variables (#15349)
* llvm: emit metadata for global variable One use case is to genearte BTF information from global variable's metadata. Signed-off-by: Tw <weii.tan>
1 parent d80e6ca
Changed files (4)
src/codegen/llvm/bindings.zig
@@ -256,6 +256,9 @@ pub const Value = opaque {
 
     pub const addByValAttr = ZigLLVMAddByValAttr;
     extern fn ZigLLVMAddByValAttr(Fn: *Value, ArgNo: c_uint, type: *Type) void;
+
+    pub const attachMetaData = ZigLLVMAttachMetaData;
+    extern fn ZigLLVMAttachMetaData(GlobalVar: *Value, DIG: *DIGlobalVariableExpression) void;
 };
 
 pub const Type = opaque {
@@ -1588,6 +1591,7 @@ pub const address_space = struct {
 pub const DIEnumerator = opaque {};
 pub const DILocalVariable = opaque {};
 pub const DILocation = opaque {};
+pub const DIGlobalExpression = opaque {};
 
 pub const DIGlobalVariable = opaque {
     pub const toNode = ZigLLVMGlobalVariableToNode;
@@ -1596,6 +1600,13 @@ pub const DIGlobalVariable = opaque {
     pub const replaceLinkageName = ZigLLVMGlobalVariableReplaceLinkageName;
     extern fn ZigLLVMGlobalVariableReplaceLinkageName(global_variable: *DIGlobalVariable, linkage_name: *MDString) void;
 };
+pub const DIGlobalVariableExpression = opaque {
+    pub const getVariable = ZigLLVMGlobalGetVariable;
+    extern fn ZigLLVMGlobalGetVariable(global_variable: *DIGlobalVariableExpression) *DIGlobalVariable;
+
+    pub const getExpression = ZigLLVMGlobalGetExpression;
+    extern fn ZigLLVMGlobalGetExpression(global_variable: *DIGlobalVariableExpression) *DIGlobalExpression;
+};
 pub const DIType = opaque {
     pub const toScope = ZigLLVMTypeToScope;
     extern fn ZigLLVMTypeToScope(ty: *DIType) *DIScope;
@@ -1803,8 +1814,8 @@ pub const DIBuilder = opaque {
         flags: c_uint,
     ) *DILocalVariable;
 
-    pub const createGlobalVariable = ZigLLVMCreateGlobalVariable;
-    extern fn ZigLLVMCreateGlobalVariable(
+    pub const createGlobalVariableExpression = ZigLLVMCreateGlobalVariableExpression;
+    extern fn ZigLLVMCreateGlobalVariableExpression(
         dib: *DIBuilder,
         scope: *DIScope,
         name: [*:0]const u8,
@@ -1813,7 +1824,7 @@ pub const DIBuilder = opaque {
         line_no: c_uint,
         di_type: *DIType,
         is_local_to_unit: bool,
-    ) *DIGlobalVariable;
+    ) *DIGlobalVariableExpression;
 
     pub const createParameterVariable = ZigLLVMCreateParameterVariable;
     extern fn ZigLLVMCreateParameterVariable(
src/codegen/llvm.zig
@@ -2549,7 +2549,7 @@ pub const DeclGen = struct {
 
                 const line_number = decl.src_line + 1;
                 const is_internal_linkage = !dg.module.decl_exports.contains(decl_index);
-                const di_global = dib.createGlobalVariable(
+                const di_global = dib.createGlobalVariableExpression(
                     di_file.toScope(),
                     decl.name,
                     global.getValueName(),
@@ -2559,7 +2559,8 @@ pub const DeclGen = struct {
                     is_internal_linkage,
                 );
 
-                try dg.object.di_map.put(dg.gpa, dg.decl, di_global.toNode());
+                try dg.object.di_map.put(dg.gpa, dg.decl, di_global.getVariable().toNode());
+                if (!is_internal_linkage) global.attachMetaData(di_global);
             }
         }
     }
src/zig_llvm.cpp
@@ -870,19 +870,18 @@ ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,
     return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
 }
 
-ZigLLVMDIGlobalVariable *ZigLLVMCreateGlobalVariable(ZigLLVMDIBuilder *dbuilder,
+ZigLLVMDIGlobalVariableExpression *ZigLLVMCreateGlobalVariableExpression(ZigLLVMDIBuilder *dbuilder,
     ZigLLVMDIScope *scope, const char *name, const char *linkage_name, ZigLLVMDIFile *file,
     unsigned line_no, ZigLLVMDIType *di_type, bool is_local_to_unit)
 {
-    DIGlobalVariableExpression *result = reinterpret_cast<DIBuilder*>(dbuilder)->createGlobalVariableExpression(
+    return reinterpret_cast<ZigLLVMDIGlobalVariableExpression*>(reinterpret_cast<DIBuilder*>(dbuilder)->createGlobalVariableExpression(
         reinterpret_cast<DIScope*>(scope),
         name,
         linkage_name,
         reinterpret_cast<DIFile*>(file),
         line_no,
         reinterpret_cast<DIType*>(di_type),
-        is_local_to_unit);
-    return reinterpret_cast<ZigLLVMDIGlobalVariable*>(result->getVariable());
+        is_local_to_unit));
 }
 
 ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilder,
@@ -1448,6 +1447,18 @@ void ZigLLVMTakeName(LLVMValueRef new_owner, LLVMValueRef victim) {
     unwrap(new_owner)->takeName(unwrap(victim));
 }
 
+ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression) {
+	return reinterpret_cast<ZigLLVMDIGlobalVariable*>(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)->getVariable());
+}
+
+ZigLLVMDIGlobalExpression* ZigLLVMGlobalGetExpression(ZigLLVMDIGlobalVariableExpression *global_variable_expression) {
+	return reinterpret_cast<ZigLLVMDIGlobalExpression*>(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)->getExpression());
+}
+
+void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression) {
+	unwrap<GlobalVariable>(Val)->addDebugInfo(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression));
+}
+
 static_assert((Triple::ArchType)ZigLLVM_UnknownArch == Triple::UnknownArch, "");
 static_assert((Triple::ArchType)ZigLLVM_arm == Triple::arm, "");
 static_assert((Triple::ArchType)ZigLLVM_armeb == Triple::armeb, "");
src/zig_llvm.h
@@ -34,7 +34,9 @@ struct ZigLLVMDILexicalBlock;
 struct ZigLLVMDISubprogram;
 struct ZigLLVMDISubroutineType;
 struct ZigLLVMDILocalVariable;
+struct ZigLLVMDIGlobalVariableExpression;
 struct ZigLLVMDIGlobalVariable;
+struct ZigLLVMDIGlobalExpression;
 struct ZigLLVMDILocation;
 struct ZigLLVMDIEnumerator;
 struct ZigLLVMInsertionPoint;
@@ -271,7 +273,7 @@ ZIG_EXTERN_C struct ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(struct Zig
         struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_no,
         struct ZigLLVMDIType *type, bool always_preserve, unsigned flags);
 
-ZIG_EXTERN_C struct ZigLLVMDIGlobalVariable *ZigLLVMCreateGlobalVariable(struct ZigLLVMDIBuilder *dbuilder,
+ZIG_EXTERN_C struct ZigLLVMDIGlobalVariableExpression *ZigLLVMCreateGlobalVariableExpression(struct ZigLLVMDIBuilder *dbuilder,
     struct ZigLLVMDIScope *scope, const char *name, const char *linkage_name, struct ZigLLVMDIFile *file,
     unsigned line_no, struct ZigLLVMDIType *di_type, bool is_local_to_unit);
 
@@ -334,6 +336,10 @@ ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
 
 ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv);
 
+ZIG_EXTERN_C ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression);
+ZIG_EXTERN_C ZigLLVMDIGlobalExpression* ZigLLVMGlobalGetExpression(ZigLLVMDIGlobalVariableExpression *global_variable_expression);
+ZIG_EXTERN_C void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression);
+
 
 // synchronize with llvm/include/ADT/Triple.h::ArchType
 // synchronize with std.Target.Cpu.Arch