llvm
llvm copied to clipboard
irutil: add utility API for creating dwarf metadata (was: Example with inclusion of DWARF output?)
Looking at the examples, would it be feasible to add one that includes the DWARF debugging info?
For example, the current "Output example - Produce LLVM IR assembly" is useful for getting people started.
Pretty much anyone wanting to make non-trivial applications though, will need to add debugging info to help with diagnosing problems in their compiled files.
Maybe a follow up example or two? :smile:
Just checked the Users repos from the README, for potential example code that could be used:
| Repo | Includes debugging info |
|---|---|
| blessedvirginmary | No |
| decomp | No |
| geode | No |
| leaven | No |
| tre | No |
| uc | No |
No luck there. Any ideas? :smile:
Hi Justin!
Glad to see you are getting into experimenting with LLVM IR in Go :)
The first principle of this how to extends beyond the scope of the llir/llvm package: When in doubt use kr/pretty :)
The easiest way to get a feel for what the structure of the IR looks like, simply parse a sample LLVM IR assembly file containing the language constructs you'd like to produce. The step by step instructions would be roughly as follows:
- Produce the sample LLVM IR assembly file.
- (option 1) Create a C file and compile it to LLVM IR:
clang -S -emit-llvm -g foo.ll foo.c. - (option 2) Create the LLVM IR assembly file by hand:
foo.ll.
- (option 1) Create a C file and compile it to LLVM IR:
- Parse the LLVM IR assembly file using asm.ParseFile.
- refer to
foo.gobelow.
- refer to
- Extract the essential details from the pretty-printed IR and create our own using
llir/llvm/ir.- refer to
bar.goandbar.llbelow.
- refer to
Hope this helps!
Cheers, Robin
Appendices
Step 1
foo.c
Sample C file (foo.c):
int foo(int a, int b) {
int sum;
sum = a + b;
return sum;
}
int main() {
return foo(12, 30);
}
foo.ll
Corresponding LLVM IR assembly file (foo.ll), produced by running clang -S -emit-llvm -g -o foo.ll foo.c.
Contents of foo.ll:
; ModuleID = 'foo.c' source_filename = "foo.c" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu"
; Function Attrs: noinline nounwind optnone sspstrong uwtable define dso_local i32 @foo(i32, i32) #0 !dbg !9 { %3 = alloca i32, align 4 %4 = alloca i32, align 4 %5 = alloca i32, align 4 store i32 %0, i32* %3, align 4 call void @llvm.dbg.declare(metadata i32* %3, metadata !13, metadata !DIExpression()), !dbg !14 store i32 %1, i32* %4, align 4 call void @llvm.dbg.declare(metadata i32* %4, metadata !15, metadata !DIExpression()), !dbg !16 call void @llvm.dbg.declare(metadata i32* %5, metadata !17, metadata !DIExpression()), !dbg !18 %6 = load i32, i32* %3, align 4, !dbg !19 %7 = load i32, i32* %4, align 4, !dbg !20 %8 = add nsw i32 %6, %7, !dbg !21 store i32 %8, i32* %5, align 4, !dbg !22 %9 = load i32, i32* %5, align 4, !dbg !23 ret i32 %9, !dbg !24 }
; Function Attrs: nounwind readnone speculatable declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
; Function Attrs: noinline nounwind optnone sspstrong uwtable define dso_local i32 @main() #0 !dbg !25 { %1 = alloca i32, align 4 store i32 0, i32* %1, align 4 %2 = call i32 @foo(i32 12, i32 30), !dbg !28 ret i32 %2, !dbg !29 }
attributes #0 = { noinline nounwind optnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { nounwind readnone speculatable }
!llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4, !5, !6, !7} !llvm.ident = !{!8}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (tags/RELEASE_800/final)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) !1 = !DIFile(filename: "foo.c", directory: "/home/u/Desktop/foo") !2 = !{} !3 = !{i32 2, !"Dwarf Version", i32 4} !4 = !{i32 2, !"Debug Info Version", i32 3} !5 = !{i32 1, !"wchar_size", i32 4} !6 = !{i32 7, !"PIC Level", i32 2} !7 = !{i32 7, !"PIE Level", i32 2} !8 = !{!"clang version 8.0.0 (tags/RELEASE_800/final)"} !9 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) !10 = !DISubroutineType(types: !11) !11 = !{!12, !12, !12} !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) !13 = !DILocalVariable(name: "a", arg: 1, scope: !9, file: !1, line: 1, type: !12) !14 = !DILocation(line: 1, column: 13, scope: !9) !15 = !DILocalVariable(name: "b", arg: 2, scope: !9, file: !1, line: 1, type: !12) !16 = !DILocation(line: 1, column: 20, scope: !9) !17 = !DILocalVariable(name: "sum", scope: !9, file: !1, line: 2, type: !12) !18 = !DILocation(line: 2, column: 6, scope: !9) !19 = !DILocation(line: 3, column: 8, scope: !9) !20 = !DILocation(line: 3, column: 12, scope: !9) !21 = !DILocation(line: 3, column: 10, scope: !9) !22 = !DILocation(line: 3, column: 6, scope: !9) !23 = !DILocation(line: 4, column: 9, scope: !9) !24 = !DILocation(line: 4, column: 2, scope: !9) !25 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 7, type: !26, scopeLine: 7, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) !26 = !DISubroutineType(types: !27) !27 = !{!12} !28 = !DILocation(line: 8, column: 9, scope: !25) !29 = !DILocation(line: 8, column: 2, scope: !25)
Step 2
foo.go
Go source code to parse and pretty-print LLVM IR assembly (foo.go):
package main
import (
"log"
"github.com/kr/pretty"
"github.com/llir/llvm/asm"
)
func main() {
m, err := asm.ParseFile("foo.ll")
if err != nil {
log.Fatalf("%+v", err)
}
pretty.Println(m)
}
Output of foo.go
The output of running go run foo.go is a pretty-printed representation of the LLVM IR assembly. We can use this as a starting point when creating the IR on our own using llir/llvm/ir.
Output of foo.go:
&ir.Module{
TypeDefs: nil,
Globals: nil,
Funcs: {
&ir.Func{
GlobalIdent: ir.GlobalIdent{GlobalName:"foo", GlobalID:0},
Sig: &types.FuncType{
TypeName: "",
RetType: &types.IntType{TypeName:"", BitSize:0x20},
Params: {
&types.IntType{TypeName:"", BitSize:0x20},
&types.IntType{TypeName:"", BitSize:0x20},
},
Variadic: false,
},
Params: {
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.IntType{TypeName:"", BitSize:0x20},
Attrs: nil,
},
&ir.Param{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:1},
Typ: &types.IntType{TypeName:"", BitSize:0x20},
Attrs: nil,
},
},
Blocks: {
&ir.Block{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:2},
Insts: {
&ir.InstAlloca{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:3},
ElemType: &types.IntType{TypeName:"", BitSize:0x20},
NElems: nil,
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.IntType{TypeName:"", BitSize:0x20},
AddrSpace: 0x0,
},
InAlloca: false,
SwiftError: false,
Align: 0x4,
Metadata: nil,
},
&ir.InstAlloca{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:4},
ElemType: &types.IntType{TypeName:"", BitSize:0x20},
NElems: nil,
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.IntType{TypeName:"", BitSize:0x20},
AddrSpace: 0x0,
},
InAlloca: false,
SwiftError: false,
Align: 0x4,
Metadata: nil,
},
&ir.InstAlloca{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:5},
ElemType: &types.IntType{TypeName:"", BitSize:0x20},
NElems: nil,
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.IntType{TypeName:"", BitSize:0x20},
AddrSpace: 0x0,
},
InAlloca: false,
SwiftError: false,
Align: 0x4,
Metadata: nil,
},
&ir.InstStore{
Src: &ir.Param{(CYCLIC REFERENCE)},
Dst: &ir.InstAlloca{(CYCLIC REFERENCE)},
Atomic: false,
Volatile: false,
SyncScope: "",
Ordering: 0x0,
Align: 0x4,
Metadata: nil,
},
&ir.InstCall{
LocalIdent: ir.LocalIdent{},
Callee: &ir.Func{
GlobalIdent: ir.GlobalIdent{GlobalName:"llvm.dbg.declare", GlobalID:0},
Sig: &types.FuncType{
TypeName: "",
RetType: &types.VoidType{},
Params: {
&types.MetadataType{},
&types.MetadataType{},
&types.MetadataType{},
},
Variadic: false,
},
Params: {
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
},
Blocks: nil,
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.FuncType{(CYCLIC REFERENCE)},
AddrSpace: 0x0,
},
Linkage: 0x0,
Preemption: 0x0,
Visibility: 0x0,
DLLStorageClass: 0x0,
CallingConv: 0x0,
ReturnAttrs: nil,
UnnamedAddr: 0x0,
FuncAttrs: {
&ir.AttrGroupDef{
ID: 1,
FuncAttrs: {
enum.FuncAttr(0x13),
enum.FuncAttr(0x16),
enum.FuncAttr(0x1e),
},
},
},
Section: "",
Comdat: (*ir.ComdatDef)(nil),
GC: "",
Prefix: nil,
Prologue: nil,
Personality: nil,
UseListOrders: nil,
Metadata: nil,
mu: sync.Mutex{},
},
Args: {
&metadata.Value{
Value: &ir.InstAlloca{(CYCLIC REFERENCE)},
},
&metadata.Value{
Value: &metadata.DILocalVariable{
MetadataID: 13,
Distinct: false,
Name: "a",
Arg: 0x1,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &!%v(DEPTH EXCEEDED),
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &!%v(DEPTH EXCEEDED),
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &!%v(DEPTH EXCEEDED),
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
Flags: 0x0,
Align: 0x0,
},
},
&metadata.Value{
Value: &metadata.DIExpression{
MetadataID: -1,
Distinct: false,
Fields: nil,
},
},
},
Typ: &types.VoidType{},
Tail: 0x0,
FastMathFlags: nil,
CallingConv: 0x0,
ReturnAttrs: nil,
AddrSpace: 0x0,
FuncAttrs: nil,
OperandBundles: nil,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 14,
Distinct: false,
Line: 1,
Column: 13,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
&ir.InstStore{
Src: &ir.Param{(CYCLIC REFERENCE)},
Dst: &ir.InstAlloca{(CYCLIC REFERENCE)},
Atomic: false,
Volatile: false,
SyncScope: "",
Ordering: 0x0,
Align: 0x4,
Metadata: nil,
},
&ir.InstCall{
LocalIdent: ir.LocalIdent{},
Callee: &ir.Func{
GlobalIdent: ir.GlobalIdent{GlobalName:"llvm.dbg.declare", GlobalID:0},
Sig: &types.FuncType{
TypeName: "",
RetType: &types.VoidType{},
Params: {
&types.MetadataType{},
&types.MetadataType{},
&types.MetadataType{},
},
Variadic: false,
},
Params: {
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
},
Blocks: nil,
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.FuncType{(CYCLIC REFERENCE)},
AddrSpace: 0x0,
},
Linkage: 0x0,
Preemption: 0x0,
Visibility: 0x0,
DLLStorageClass: 0x0,
CallingConv: 0x0,
ReturnAttrs: nil,
UnnamedAddr: 0x0,
FuncAttrs: {
&ir.AttrGroupDef{
ID: 1,
FuncAttrs: {
enum.FuncAttr(0x13),
enum.FuncAttr(0x16),
enum.FuncAttr(0x1e),
},
},
},
Section: "",
Comdat: (*ir.ComdatDef)(nil),
GC: "",
Prefix: nil,
Prologue: nil,
Personality: nil,
UseListOrders: nil,
Metadata: nil,
mu: sync.Mutex{},
},
Args: {
&metadata.Value{
Value: &ir.InstAlloca{(CYCLIC REFERENCE)},
},
&metadata.Value{
Value: &metadata.DILocalVariable{
MetadataID: 15,
Distinct: false,
Name: "b",
Arg: 0x2,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
Flags: 0x0,
Align: 0x0,
},
},
&metadata.Value{
Value: &metadata.DIExpression{
MetadataID: -1,
Distinct: false,
Fields: nil,
},
},
},
Typ: &types.VoidType{},
Tail: 0x0,
FastMathFlags: nil,
CallingConv: 0x0,
ReturnAttrs: nil,
AddrSpace: 0x0,
FuncAttrs: nil,
OperandBundles: nil,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 16,
Distinct: false,
Line: 1,
Column: 20,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{(CYCLIC REFERENCE)},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
&ir.InstCall{
LocalIdent: ir.LocalIdent{},
Callee: &ir.Func{
GlobalIdent: ir.GlobalIdent{GlobalName:"llvm.dbg.declare", GlobalID:0},
Sig: &types.FuncType{
TypeName: "",
RetType: &types.VoidType{},
Params: {
&types.MetadataType{},
&types.MetadataType{},
&types.MetadataType{},
},
Variadic: false,
},
Params: {
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
},
Blocks: nil,
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.FuncType{(CYCLIC REFERENCE)},
AddrSpace: 0x0,
},
Linkage: 0x0,
Preemption: 0x0,
Visibility: 0x0,
DLLStorageClass: 0x0,
CallingConv: 0x0,
ReturnAttrs: nil,
UnnamedAddr: 0x0,
FuncAttrs: {
&ir.AttrGroupDef{
ID: 1,
FuncAttrs: {
enum.FuncAttr(0x13),
enum.FuncAttr(0x16),
enum.FuncAttr(0x1e),
},
},
},
Section: "",
Comdat: (*ir.ComdatDef)(nil),
GC: "",
Prefix: nil,
Prologue: nil,
Personality: nil,
UseListOrders: nil,
Metadata: nil,
mu: sync.Mutex{},
},
Args: {
&metadata.Value{
Value: &ir.InstAlloca{(CYCLIC REFERENCE)},
},
&metadata.Value{
Value: &metadata.DILocalVariable{
MetadataID: 17,
Distinct: false,
Name: "sum",
Arg: 0x0,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 2,
Type: &metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
Flags: 0x0,
Align: 0x0,
},
},
&metadata.Value{
Value: &metadata.DIExpression{
MetadataID: -1,
Distinct: false,
Fields: nil,
},
},
},
Typ: &types.VoidType{},
Tail: 0x0,
FastMathFlags: nil,
CallingConv: 0x0,
ReturnAttrs: nil,
AddrSpace: 0x0,
FuncAttrs: nil,
OperandBundles: nil,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 18,
Distinct: false,
Line: 2,
Column: 6,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{(CYCLIC REFERENCE)},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
&ir.InstLoad{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:6},
Src: &ir.InstAlloca{(CYCLIC REFERENCE)},
Typ: &types.IntType{TypeName:"", BitSize:0x20},
Atomic: false,
Volatile: false,
SyncScope: "",
Ordering: 0x0,
Align: 0x4,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 19,
Distinct: false,
Line: 3,
Column: 8,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{(CYCLIC REFERENCE)},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
&ir.InstLoad{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:7},
Src: &ir.InstAlloca{(CYCLIC REFERENCE)},
Typ: &types.IntType{TypeName:"", BitSize:0x20},
Atomic: false,
Volatile: false,
SyncScope: "",
Ordering: 0x0,
Align: 0x4,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 20,
Distinct: false,
Line: 3,
Column: 12,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{(CYCLIC REFERENCE)},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
&ir.InstAdd{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:8},
X: &ir.InstLoad{(CYCLIC REFERENCE)},
Y: &ir.InstLoad{(CYCLIC REFERENCE)},
Typ: &types.IntType{TypeName:"", BitSize:0x20},
OverflowFlags: {0x0},
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 21,
Distinct: false,
Line: 3,
Column: 10,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{(CYCLIC REFERENCE)},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
&ir.InstStore{
Src: &ir.InstAdd{(CYCLIC REFERENCE)},
Dst: &ir.InstAlloca{(CYCLIC REFERENCE)},
Atomic: false,
Volatile: false,
SyncScope: "",
Ordering: 0x0,
Align: 0x4,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 22,
Distinct: false,
Line: 3,
Column: 6,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{(CYCLIC REFERENCE)},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
&ir.InstLoad{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:9},
Src: &ir.InstAlloca{(CYCLIC REFERENCE)},
Typ: &types.IntType{TypeName:"", BitSize:0x20},
Atomic: false,
Volatile: false,
SyncScope: "",
Ordering: 0x0,
Align: 0x4,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 23,
Distinct: false,
Line: 4,
Column: 9,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{(CYCLIC REFERENCE)},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
},
Term: &ir.TermRet{
X: &ir.InstLoad{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:9},
Src: &ir.InstAlloca{(CYCLIC REFERENCE)},
Typ: &types.IntType{TypeName:"", BitSize:0x20},
Atomic: false,
Volatile: false,
SyncScope: "",
Ordering: 0x0,
Align: 0x4,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 23,
Distinct: false,
Line: 4,
Column: 9,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{(CYCLIC REFERENCE)},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 24,
Distinct: false,
Line: 4,
Column: 2,
Scope: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
&!%v(DEPTH EXCEEDED),
&!%v(DEPTH EXCEEDED),
&!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
Parent: &ir.Func{(CYCLIC REFERENCE)},
},
},
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.FuncType{(CYCLIC REFERENCE)},
AddrSpace: 0x0,
},
Linkage: 0x0,
Preemption: 0x1,
Visibility: 0x0,
DLLStorageClass: 0x0,
CallingConv: 0x0,
ReturnAttrs: nil,
UnnamedAddr: 0x0,
FuncAttrs: {
&ir.AttrGroupDef{
ID: 0,
FuncAttrs: {
enum.FuncAttr(0xe),
enum.FuncAttr(0x13),
enum.FuncAttr(0x14),
enum.FuncAttr(0x22),
enum.FuncAttr(0x24),
ir.AttrPair{Key:"correctly-rounded-divide-sqrt-fp-math", Value:"false"},
ir.AttrPair{Key:"disable-tail-calls", Value:"false"},
ir.AttrPair{Key:"less-precise-fpmad", Value:"false"},
ir.AttrPair{Key:"min-legal-vector-width", Value:"0"},
ir.AttrPair{Key:"no-frame-pointer-elim", Value:"true"},
"no-frame-pointer-elim-non-leaf",
ir.AttrPair{Key:"no-infs-fp-math", Value:"false"},
ir.AttrPair{Key:"no-jump-tables", Value:"false"},
ir.AttrPair{Key:"no-nans-fp-math", Value:"false"},
ir.AttrPair{Key:"no-signed-zeros-fp-math", Value:"false"},
ir.AttrPair{Key:"no-trapping-math", Value:"false"},
ir.AttrPair{Key:"stack-protector-buffer-size", Value:"8"},
ir.AttrPair{Key:"target-cpu", Value:"x86-64"},
ir.AttrPair{Key:"target-features", Value:"+fxsr,+mmx,+sse,+sse2,+x87"},
ir.AttrPair{Key:"unsafe-fp-math", Value:"false"},
ir.AttrPair{Key:"use-soft-float", Value:"false"},
},
},
},
Section: "",
Comdat: (*ir.ComdatDef)(nil),
GC: "",
Prefix: nil,
Prologue: nil,
Personality: nil,
UseListOrders: nil,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
},
},
mu: sync.Mutex{},
},
&ir.Func{
GlobalIdent: ir.GlobalIdent{GlobalName:"llvm.dbg.declare", GlobalID:0},
Sig: &types.FuncType{
TypeName: "",
RetType: &types.VoidType{},
Params: {
&types.MetadataType{},
&types.MetadataType{},
&types.MetadataType{},
},
Variadic: false,
},
Params: {
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
&ir.Param{
LocalIdent: ir.LocalIdent{},
Typ: &types.MetadataType{},
Attrs: nil,
},
},
Blocks: nil,
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.FuncType{(CYCLIC REFERENCE)},
AddrSpace: 0x0,
},
Linkage: 0x0,
Preemption: 0x0,
Visibility: 0x0,
DLLStorageClass: 0x0,
CallingConv: 0x0,
ReturnAttrs: nil,
UnnamedAddr: 0x0,
FuncAttrs: {
&ir.AttrGroupDef{
ID: 1,
FuncAttrs: {
enum.FuncAttr(0x13),
enum.FuncAttr(0x16),
enum.FuncAttr(0x1e),
},
},
},
Section: "",
Comdat: (*ir.ComdatDef)(nil),
GC: "",
Prefix: nil,
Prologue: nil,
Personality: nil,
UseListOrders: nil,
Metadata: nil,
mu: sync.Mutex{},
},
&ir.Func{
GlobalIdent: ir.GlobalIdent{GlobalName:"main", GlobalID:0},
Sig: &types.FuncType{
TypeName: "",
RetType: &types.IntType{TypeName:"", BitSize:0x20},
Params: nil,
Variadic: false,
},
Params: nil,
Blocks: {
&ir.Block{
LocalIdent: ir.LocalIdent{},
Insts: {
&ir.InstAlloca{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:1},
ElemType: &types.IntType{TypeName:"", BitSize:0x20},
NElems: nil,
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.IntType{TypeName:"", BitSize:0x20},
AddrSpace: 0x0,
},
InAlloca: false,
SwiftError: false,
Align: 0x4,
Metadata: nil,
},
&ir.InstStore{
Src: &constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{},
},
Dst: &ir.InstAlloca{(CYCLIC REFERENCE)},
Atomic: false,
Volatile: false,
SyncScope: "",
Ordering: 0x0,
Align: 0x4,
Metadata: nil,
},
&ir.InstCall{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:2},
Callee: &ir.Func{(CYCLIC REFERENCE)},
Args: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0xc},
},
},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x1e},
},
},
},
Typ: &types.IntType{TypeName:"", BitSize:0x20},
Tail: 0x0,
FastMathFlags: nil,
CallingConv: 0x0,
ReturnAttrs: nil,
AddrSpace: 0x0,
FuncAttrs: nil,
OperandBundles: nil,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 28,
Distinct: false,
Line: 8,
Column: 9,
Scope: &metadata.DISubprogram{
MetadataID: 25,
Distinct: true,
Scope: &metadata.DIFile{(CYCLIC REFERENCE)},
Name: "main",
LinkageName: "",
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Line: 7,
Type: &metadata.DISubroutineType{
MetadataID: 26,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 27,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 7,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x0,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{(CYCLIC REFERENCE)},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{(CYCLIC REFERENCE)},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
},
Term: &ir.TermRet{
X: &ir.InstCall{
LocalIdent: ir.LocalIdent{LocalName:"", LocalID:2},
Callee: &ir.Func{(CYCLIC REFERENCE)},
Args: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0xc},
},
},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x1e},
},
},
},
Typ: &types.IntType{TypeName:"", BitSize:0x20},
Tail: 0x0,
FastMathFlags: nil,
CallingConv: 0x0,
ReturnAttrs: nil,
AddrSpace: 0x0,
FuncAttrs: nil,
OperandBundles: nil,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 28,
Distinct: false,
Line: 8,
Column: 9,
Scope: &metadata.DISubprogram{
MetadataID: 25,
Distinct: true,
Scope: &metadata.DIFile{(CYCLIC REFERENCE)},
Name: "main",
LinkageName: "",
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Line: 7,
Type: &metadata.DISubroutineType{
MetadataID: 26,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 27,
Distinct: false,
Fields: {
!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 7,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x0,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{(CYCLIC REFERENCE)},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{(CYCLIC REFERENCE)},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DILocation{
MetadataID: 29,
Distinct: false,
Line: 8,
Column: 2,
Scope: &metadata.DISubprogram{
MetadataID: 25,
Distinct: true,
Scope: &metadata.DIFile{(CYCLIC REFERENCE)},
Name: "main",
LinkageName: "",
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Line: 7,
Type: &metadata.DISubroutineType{
MetadataID: 26,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 27,
Distinct: false,
Fields: {
&!%v(DEPTH EXCEEDED),
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 7,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x0,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{(CYCLIC REFERENCE)},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{(CYCLIC REFERENCE)},
ThrownTypes: (*metadata.Tuple)(nil),
},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
},
},
Parent: &ir.Func{(CYCLIC REFERENCE)},
},
},
Typ: &types.PointerType{
TypeName: "",
ElemType: &types.FuncType{(CYCLIC REFERENCE)},
AddrSpace: 0x0,
},
Linkage: 0x0,
Preemption: 0x1,
Visibility: 0x0,
DLLStorageClass: 0x0,
CallingConv: 0x0,
ReturnAttrs: nil,
UnnamedAddr: 0x0,
FuncAttrs: {
&ir.AttrGroupDef{
ID: 0,
FuncAttrs: {
enum.FuncAttr(0xe),
enum.FuncAttr(0x13),
enum.FuncAttr(0x14),
enum.FuncAttr(0x22),
enum.FuncAttr(0x24),
ir.AttrPair{Key:"correctly-rounded-divide-sqrt-fp-math", Value:"false"},
ir.AttrPair{Key:"disable-tail-calls", Value:"false"},
ir.AttrPair{Key:"less-precise-fpmad", Value:"false"},
ir.AttrPair{Key:"min-legal-vector-width", Value:"0"},
ir.AttrPair{Key:"no-frame-pointer-elim", Value:"true"},
"no-frame-pointer-elim-non-leaf",
ir.AttrPair{Key:"no-infs-fp-math", Value:"false"},
ir.AttrPair{Key:"no-jump-tables", Value:"false"},
ir.AttrPair{Key:"no-nans-fp-math", Value:"false"},
ir.AttrPair{Key:"no-signed-zeros-fp-math", Value:"false"},
ir.AttrPair{Key:"no-trapping-math", Value:"false"},
ir.AttrPair{Key:"stack-protector-buffer-size", Value:"8"},
ir.AttrPair{Key:"target-cpu", Value:"x86-64"},
ir.AttrPair{Key:"target-features", Value:"+fxsr,+mmx,+sse,+sse2,+x87"},
ir.AttrPair{Key:"unsafe-fp-math", Value:"false"},
ir.AttrPair{Key:"use-soft-float", Value:"false"},
},
},
},
Section: "",
Comdat: (*ir.ComdatDef)(nil),
GC: "",
Prefix: nil,
Prologue: nil,
Personality: nil,
UseListOrders: nil,
Metadata: {
&metadata.Attachment{
Name: "dbg",
Node: &metadata.DISubprogram{
MetadataID: 25,
Distinct: true,
Scope: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Name: "main",
LinkageName: "",
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Line: 7,
Type: &metadata.DISubroutineType{
MetadataID: 26,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 27,
Distinct: false,
Fields: {
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 7,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x0,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{(CYCLIC REFERENCE)},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
ThrownTypes: (*metadata.Tuple)(nil),
},
},
},
mu: sync.Mutex{},
},
},
SourceFilename: "foo.c",
DataLayout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
TargetTriple: "x86_64-pc-linux-gnu",
ModuleAsms: nil,
ComdatDefs: nil,
Aliases: nil,
IFuncs: nil,
AttrGroupDefs: {
&ir.AttrGroupDef{
ID: 0,
FuncAttrs: {
enum.FuncAttr(0xe),
enum.FuncAttr(0x13),
enum.FuncAttr(0x14),
enum.FuncAttr(0x22),
enum.FuncAttr(0x24),
ir.AttrPair{Key:"correctly-rounded-divide-sqrt-fp-math", Value:"false"},
ir.AttrPair{Key:"disable-tail-calls", Value:"false"},
ir.AttrPair{Key:"less-precise-fpmad", Value:"false"},
ir.AttrPair{Key:"min-legal-vector-width", Value:"0"},
ir.AttrPair{Key:"no-frame-pointer-elim", Value:"true"},
"no-frame-pointer-elim-non-leaf",
ir.AttrPair{Key:"no-infs-fp-math", Value:"false"},
ir.AttrPair{Key:"no-jump-tables", Value:"false"},
ir.AttrPair{Key:"no-nans-fp-math", Value:"false"},
ir.AttrPair{Key:"no-signed-zeros-fp-math", Value:"false"},
ir.AttrPair{Key:"no-trapping-math", Value:"false"},
ir.AttrPair{Key:"stack-protector-buffer-size", Value:"8"},
ir.AttrPair{Key:"target-cpu", Value:"x86-64"},
ir.AttrPair{Key:"target-features", Value:"+fxsr,+mmx,+sse,+sse2,+x87"},
ir.AttrPair{Key:"unsafe-fp-math", Value:"false"},
ir.AttrPair{Key:"use-soft-float", Value:"false"},
},
},
&ir.AttrGroupDef{
ID: 1,
FuncAttrs: {
enum.FuncAttr(0x13),
enum.FuncAttr(0x16),
enum.FuncAttr(0x1e),
},
},
},
NamedMetadataDefs: {
"llvm.dbg.cu": &metadata.NamedDef{
Name: "llvm.dbg.cu",
Nodes: {
&metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
},
},
"llvm.module.flags": &metadata.NamedDef{
Name: "llvm.module.flags",
Nodes: {
&metadata.Tuple{
MetadataID: 3,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x2},
},
},
&metadata.String{Value:"Dwarf Version"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x4},
},
},
},
},
&metadata.Tuple{
MetadataID: 4,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x2},
},
},
&metadata.String{Value:"Debug Info Version"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x3},
},
},
},
},
&metadata.Tuple{
MetadataID: 5,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x1},
},
},
&metadata.String{Value:"wchar_size"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x4},
},
},
},
},
&metadata.Tuple{
MetadataID: 6,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x7},
},
},
&metadata.String{Value:"PIC Level"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x2},
},
},
},
},
&metadata.Tuple{
MetadataID: 7,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x7},
},
},
&metadata.String{Value:"PIE Level"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x2},
},
},
},
},
},
},
"llvm.ident": &metadata.NamedDef{
Name: "llvm.ident",
Nodes: {
&metadata.Tuple{
MetadataID: 8,
Distinct: false,
Fields: {
&metadata.String{Value:"clang version 8.0.0 (tags/RELEASE_800/final)"},
},
},
},
},
},
MetadataDefs: {
&metadata.DICompileUnit{
MetadataID: 0,
Distinct: true,
Language: 12,
File: &metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
IsOptimized: false,
Flags: "",
RuntimeVersion: 0x0,
SplitDebugFilename: "",
EmissionKind: 1,
Enums: &metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
RetainedTypes: (*metadata.Tuple)(nil),
Globals: (*metadata.Tuple)(nil),
Imports: (*metadata.Tuple)(nil),
Macros: (*metadata.Tuple)(nil),
DwoID: 0x0,
SplitDebugInlining: false,
DebugInfoForProfiling: false,
NameTableKind: 0x2,
DebugBaseAddress: false,
},
&metadata.DIFile{MetadataID:1, Distinct:false, Filename:"foo.c", Directory:"/home/u/Desktop/foo", Checksumkind:0x0, Checksum:"", Source:""},
&metadata.Tuple{
MetadataID: 2,
Distinct: false,
Fields: nil,
},
&metadata.Tuple{
MetadataID: 3,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x2},
},
},
&metadata.String{Value:"Dwarf Version"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x4},
},
},
},
},
&metadata.Tuple{
MetadataID: 4,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x2},
},
},
&metadata.String{Value:"Debug Info Version"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x3},
},
},
},
},
&metadata.Tuple{
MetadataID: 5,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x1},
},
},
&metadata.String{Value:"wchar_size"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x4},
},
},
},
},
&metadata.Tuple{
MetadataID: 6,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x7},
},
},
&metadata.String{Value:"PIC Level"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x2},
},
},
},
},
&metadata.Tuple{
MetadataID: 7,
Distinct: false,
Fields: {
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x7},
},
},
&metadata.String{Value:"PIE Level"},
&constant.Int{
Typ: &types.IntType{TypeName:"", BitSize:0x20},
X: &big.Int{
neg: false,
abs: {0x2},
},
},
},
},
&metadata.Tuple{
MetadataID: 8,
Distinct: false,
Fields: {
&metadata.String{Value:"clang version 8.0.0 (tags/RELEASE_800/final)"},
},
},
&metadata.DISubprogram{
MetadataID: 9,
Distinct: true,
Scope: &metadata.DIFile{(CYCLIC REFERENCE)},
Name: "foo",
LinkageName: "",
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Line: 1,
Type: &metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 1,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x100,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{(CYCLIC REFERENCE)},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{(CYCLIC REFERENCE)},
ThrownTypes: (*metadata.Tuple)(nil),
},
&metadata.DISubroutineType{
MetadataID: 10,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
},
},
},
&metadata.Tuple{
MetadataID: 11,
Distinct: false,
Fields: {
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
},
},
&metadata.DIBasicType{MetadataID:12, Distinct:false, Tag:0, Name:"int", Size:0x20, Align:0x0, Encoding:5, Flags:0x0},
&metadata.DILocalVariable{
MetadataID: 13,
Distinct: false,
Name: "a",
Arg: 0x1,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Line: 1,
Type: &metadata.DIBasicType{(CYCLIC REFERENCE)},
Flags: 0x0,
Align: 0x0,
},
&metadata.DILocation{
MetadataID: 14,
Distinct: false,
Line: 1,
Column: 13,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DILocalVariable{
MetadataID: 15,
Distinct: false,
Name: "b",
Arg: 0x2,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Line: 1,
Type: &metadata.DIBasicType{(CYCLIC REFERENCE)},
Flags: 0x0,
Align: 0x0,
},
&metadata.DILocation{
MetadataID: 16,
Distinct: false,
Line: 1,
Column: 20,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DILocalVariable{
MetadataID: 17,
Distinct: false,
Name: "sum",
Arg: 0x0,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Line: 2,
Type: &metadata.DIBasicType{(CYCLIC REFERENCE)},
Flags: 0x0,
Align: 0x0,
},
&metadata.DILocation{
MetadataID: 18,
Distinct: false,
Line: 2,
Column: 6,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DILocation{
MetadataID: 19,
Distinct: false,
Line: 3,
Column: 8,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DILocation{
MetadataID: 20,
Distinct: false,
Line: 3,
Column: 12,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DILocation{
MetadataID: 21,
Distinct: false,
Line: 3,
Column: 10,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DILocation{
MetadataID: 22,
Distinct: false,
Line: 3,
Column: 6,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DILocation{
MetadataID: 23,
Distinct: false,
Line: 4,
Column: 9,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DILocation{
MetadataID: 24,
Distinct: false,
Line: 4,
Column: 2,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DISubprogram{
MetadataID: 25,
Distinct: true,
Scope: &metadata.DIFile{(CYCLIC REFERENCE)},
Name: "main",
LinkageName: "",
File: &metadata.DIFile{(CYCLIC REFERENCE)},
Line: 7,
Type: &metadata.DISubroutineType{
MetadataID: 26,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 27,
Distinct: false,
Fields: {
&metadata.DIBasicType{(CYCLIC REFERENCE)},
},
},
},
IsLocal: false,
IsDefinition: false,
ScopeLine: 7,
ContainingType: nil,
Virtuality: 0,
VirtualIndex: 0x0,
ThisAdjustment: 0,
Flags: 0x0,
SPFlags: 0x8,
IsOptimized: false,
Unit: &metadata.DICompileUnit{(CYCLIC REFERENCE)},
TemplateParams: (*metadata.Tuple)(nil),
Declaration: nil,
RetainedNodes: &metadata.Tuple{(CYCLIC REFERENCE)},
ThrownTypes: (*metadata.Tuple)(nil),
},
&metadata.DISubroutineType{
MetadataID: 26,
Distinct: false,
Flags: 0x0,
CC: 0,
Types: &metadata.Tuple{
MetadataID: 27,
Distinct: false,
Fields: {
&metadata.DIBasicType{(CYCLIC REFERENCE)},
},
},
},
&metadata.Tuple{
MetadataID: 27,
Distinct: false,
Fields: {
&metadata.DIBasicType{(CYCLIC REFERENCE)},
},
},
&metadata.DILocation{
MetadataID: 28,
Distinct: false,
Line: 8,
Column: 9,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
&metadata.DILocation{
MetadataID: 29,
Distinct: false,
Line: 8,
Column: 2,
Scope: &metadata.DISubprogram{(CYCLIC REFERENCE)},
InlinedAt: (*metadata.DILocation)(nil),
IsImplicitCode: false,
},
},
UseListOrders: nil,
UseListOrderBBs: nil,
}
Step 3
bar.go
The following Go source program produces IR corresponding to the sample foo.ll.
Contents of bar.go:
package main
import (
"fmt"
"github.com/llir/llvm/ir"
"github.com/llir/llvm/ir/constant"
"github.com/llir/llvm/ir/enum"
"github.com/llir/llvm/ir/metadata"
"github.com/llir/llvm/ir/types"
)
// Convenience types.
var (
i32 = types.I32
)
func main() {
// Convenience constants.
var (
twelve = constant.NewInt(i32, 12)
thirty = constant.NewInt(i32, 30)
)
// Create LLVM IR module.
m := ir.NewModule()
// Add metadata.
diLocalVarA, diLocalVarB, diLocalVarSum, diLocA, diLocB, diLocSum := addMetadata(m)
// Empty DIExpression
// !DIExpression()
emptyExpr := &metadata.DIExpression{
MetadataID: -1,
}
// Declare llvm.dbg.declare function.
// declare void @llvm.dbg.declare(metadata, metadata, metadata)
llvmDbgDeclare := m.NewFunc(
"llvm.dbg.declare",
types.Void,
ir.NewParam("", types.Metadata),
ir.NewParam("", types.Metadata),
ir.NewParam("", types.Metadata),
)
// Define foo function.
// int foo(int a, int b)
// TODO: uncomment.
//aParam := ir.NewParam("a", i32)
//bParam := ir.NewParam("b", i32)
aParam := ir.NewParam("", i32)
bParam := ir.NewParam("", i32)
fooFunc := m.NewFunc("foo", i32, aParam, bParam)
fooEntry := fooFunc.NewBlock("")
a := fooEntry.NewAlloca(i32)
b := fooEntry.NewAlloca(i32)
sum := fooEntry.NewAlloca(i32)
fooEntry.NewStore(aParam, a)
dbgDeclareA := fooEntry.NewCall(llvmDbgDeclare, &metadata.Value{Value: a}, &metadata.Value{Value: diLocalVarA}, &metadata.Value{Value: emptyExpr})
dbgDeclareA.Metadata = append(dbgDeclareA.Metadata, &metadata.Attachment{Name: "dbg", Node: diLocA})
fooEntry.NewStore(bParam, b)
dbgDeclareB := fooEntry.NewCall(llvmDbgDeclare, &metadata.Value{Value: b}, &metadata.Value{Value: diLocalVarB}, &metadata.Value{Value: emptyExpr})
dbgDeclareB.Metadata = append(dbgDeclareB.Metadata, &metadata.Attachment{Name: "dbg", Node: diLocB})
dbgDeclareSum := fooEntry.NewCall(llvmDbgDeclare, &metadata.Value{Value: sum}, &metadata.Value{Value: diLocalVarSum}, &metadata.Value{Value: emptyExpr})
dbgDeclareSum.Metadata = append(dbgDeclareSum.Metadata, &metadata.Attachment{Name: "dbg", Node: diLocSum})
aVal := fooEntry.NewLoad(a)
bVal := fooEntry.NewLoad(b)
tmp := fooEntry.NewAdd(aVal, bVal)
fooEntry.NewStore(tmp, sum)
sumVal := fooEntry.NewLoad(sum)
fooEntry.NewRet(sumVal)
// Define main function
// int main()
mainFunc := m.NewFunc("main", i32)
mainEntry := mainFunc.NewBlock("")
retVal := mainEntry.NewCall(fooFunc, twelve, thirty)
mainEntry.NewRet(retVal)
// Print LLVM IR assembly to standard output.
fmt.Println(m)
}
func addMetadata(m *ir.Module) (diLocalVarA, diLocalVarB, diLocalVarSum *metadata.DILocalVariable, diLocA, diLocB, diLocSum *metadata.DILocation) {
// Note, the reason we specify MetadataID to be -1, is so that the IR
// package may assign the metadata definition an arbitrary unique ID (and 0
// is a valid ID).
//
// I think we should try to find a cleaner way to handle this. Any
// suggestions are warmly welcome! :)
// Convenience constants.
var (
one = constant.NewInt(i32, 1)
two = constant.NewInt(i32, 2)
three = constant.NewInt(i32, 3)
four = constant.NewInt(i32, 4)
seven = constant.NewInt(i32, 7)
)
// Unnamed metadata definitions.
// DICompileUnit
// !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (tags/RELEASE_800/final)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
diCompileUnit := &metadata.DICompileUnit{
MetadataID: -1,
Distinct: true,
Language: enum.DwarfLangC99,
Producer: "clang version 8.0.0 (tags/RELEASE_800/final)",
EmissionKind: enum.EmissionKindFullDebug,
}
// DIFile
// !1 = !DIFile(filename: "foo.c", directory: "/home/u/Desktop/foo")
diFile := &metadata.DIFile{
MetadataID: -1,
Filename: "foo.c",
Directory: "/home/u/Desktop/foo",
}
diCompileUnit.File = diFile
// Empty tuple.
// !2 = !{}
emptyTuple := &metadata.Tuple{
MetadataID: -1,
}
diCompileUnit.Enums = emptyTuple
// Dwarf metadata.
// !3 = !{i32 2, !"Dwarf Version", i32 4}
dwarfVersion := &metadata.Tuple{
MetadataID: -1,
Fields: []metadata.Field{two, &metadata.String{Value: "Dwarf Version"}, four},
}
// !4 = !{i32 2, !"Debug Info Version", i32 3}
debugInfoVersion := &metadata.Tuple{
MetadataID: -1,
Fields: []metadata.Field{two, &metadata.String{Value: "Debug Info Version"}, three},
}
// !5 = !{i32 1, !"wchar_size", i32 4}
wcharSize := &metadata.Tuple{
MetadataID: -1,
Fields: []metadata.Field{one, &metadata.String{Value: "wchar_size"}, four},
}
// !6 = !{i32 7, !"PIC Level", i32 2}
picLevel := &metadata.Tuple{
MetadataID: -1,
Fields: []metadata.Field{seven, &metadata.String{Value: "PIC Level"}, two},
}
// !7 = !{i32 7, !"PIE Level", i32 2}
pieLevel := &metadata.Tuple{
MetadataID: -1,
Fields: []metadata.Field{seven, &metadata.String{Value: "PIE Level"}, two},
}
// !8 = !{!"clang version 8.0.0 (tags/RELEASE_800/final)"}
clangVersion := &metadata.Tuple{
MetadataID: -1,
Fields: []metadata.Field{&metadata.String{Value: "clang version 8.0.0 (tags/RELEASE_800/final)"}},
}
// DISubprogram
// !9 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
diSubprogramFoo := &metadata.DISubprogram{
MetadataID: -1,
Distinct: true,
Name: "foo",
Scope: diFile,
File: diFile,
Line: 1,
ScopeLine: 1,
Flags: enum.DIFlagPrototyped,
SPFlags: enum.DISPFlagDefinition,
Unit: diCompileUnit,
RetainedNodes: emptyTuple,
}
// DISubroutineType
// !10 = !DISubroutineType(types: !11)
diSubroutineType := &metadata.DISubroutineType{
MetadataID: -1,
}
diSubprogramFoo.Type = diSubroutineType
// Types tuple.
// !11 = !{!12, !12, !12}
typesTuple := &metadata.Tuple{
MetadataID: -1,
}
diSubroutineType.Types = typesTuple
// DIBasicType
// !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
diBasicTypeI32 := &metadata.DIBasicType{
MetadataID: -1,
Name: "int",
Size: 32,
Encoding: enum.DwarfAttEncodingSigned,
}
typesTuple.Fields = []metadata.Field{diBasicTypeI32, diBasicTypeI32, diBasicTypeI32}
// DILocalVariable
// !13 = !DILocalVariable(name: "a", arg: 1, scope: !9, file: !1, line: 1, type: !12)
diLocalVarA = &metadata.DILocalVariable{
MetadataID: -1,
Name: "a",
Arg: 1,
Scope: diSubprogramFoo,
File: diFile,
Line: 1,
Type: diBasicTypeI32,
}
// DILocation
// !14 = !DILocation(line: 1, column: 13, scope: !9)
diLocA = &metadata.DILocation{
MetadataID: -1,
Line: 1,
Column: 13,
Scope: diSubprogramFoo,
}
// DILocalVariable
// !15 = !DILocalVariable(name: "b", arg: 2, scope: !9, file: !1, line: 1, type: !12)
diLocalVarB = &metadata.DILocalVariable{
MetadataID: -1,
Name: "b",
Arg: 2,
Scope: diSubprogramFoo,
File: diFile,
Line: 1,
Type: diBasicTypeI32,
}
// DILocation
// !16 = !DILocation(line: 1, column: 20, scope: !9)
diLocB = &metadata.DILocation{
MetadataID: -1,
Line: 1,
Column: 20,
Scope: diSubprogramFoo,
}
// DILocalVariable
// !17 = !DILocalVariable(name: "sum", scope: !9, file: !1, line: 2, type: !12)
diLocalVarSum = &metadata.DILocalVariable{
MetadataID: -1,
Name: "sum",
Scope: diSubprogramFoo,
File: diFile,
Line: 2,
Type: diBasicTypeI32,
}
// DILocation
// !18 = !DILocation(line: 2, column: 6, scope: !9)
diLocSum = &metadata.DILocation{
MetadataID: -1,
Line: 2,
Column: 6,
Scope: diSubprogramFoo,
}
m.MetadataDefs = append(m.MetadataDefs, diCompileUnit)
m.MetadataDefs = append(m.MetadataDefs, diFile)
m.MetadataDefs = append(m.MetadataDefs, emptyTuple)
m.MetadataDefs = append(m.MetadataDefs, dwarfVersion)
m.MetadataDefs = append(m.MetadataDefs, debugInfoVersion)
m.MetadataDefs = append(m.MetadataDefs, wcharSize)
m.MetadataDefs = append(m.MetadataDefs, picLevel)
m.MetadataDefs = append(m.MetadataDefs, pieLevel)
m.MetadataDefs = append(m.MetadataDefs, clangVersion)
m.MetadataDefs = append(m.MetadataDefs, diSubprogramFoo)
m.MetadataDefs = append(m.MetadataDefs, diSubroutineType)
m.MetadataDefs = append(m.MetadataDefs, typesTuple)
m.MetadataDefs = append(m.MetadataDefs, diBasicTypeI32)
m.MetadataDefs = append(m.MetadataDefs, diLocalVarA)
m.MetadataDefs = append(m.MetadataDefs, diLocA)
m.MetadataDefs = append(m.MetadataDefs, diLocalVarB)
m.MetadataDefs = append(m.MetadataDefs, diLocB)
m.MetadataDefs = append(m.MetadataDefs, diLocalVarSum)
m.MetadataDefs = append(m.MetadataDefs, diLocSum)
// Named metadata definitions.
// !llvm.dbg.cu = !{!0}
llvmDbgCu := &metadata.NamedDef{
Name: "llvm.dbg.cu",
Nodes: []metadata.Node{diCompileUnit},
}
m.NamedMetadataDefs["llvm.dbg.cu"] = llvmDbgCu
// !llvm.module.flags = !{!3, !4, !5, !6, !7}
llvmModuleFlags := &metadata.NamedDef{
Name: "llvm.module.flags",
Nodes: []metadata.Node{dwarfVersion, debugInfoVersion, wcharSize, picLevel, pieLevel},
}
m.NamedMetadataDefs["llvm.module.flags"] = llvmModuleFlags
// !llvm.ident = !{!8}
llvmIdent := &metadata.NamedDef{
Name: "llvm.ident",
Nodes: []metadata.Node{clangVersion},
}
m.NamedMetadataDefs["llvm.ident"] = llvmIdent
return diLocalVarA, diLocalVarB, diLocalVarSum, diLocA, diLocB, diLocSum
}
Output of bar.go (bar.ll)
Running go run bar.go produces the following output LLVM IR assembly (bar.ll):
declare void @llvm.dbg.declare(metadata, metadata, metadata)
define i32 @foo(i32, i32) {
; <label>:2
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32
store i32 %0, i32* %3
call void @llvm.dbg.declare(metadata i32* %3, metadata !13, metadata !DIExpression()), !dbg !14
store i32 %1, i32* %4
call void @llvm.dbg.declare(metadata i32* %4, metadata !15, metadata !DIExpression()), !dbg !16
call void @llvm.dbg.declare(metadata i32* %5, metadata !17, metadata !DIExpression()), !dbg !18
%6 = load i32, i32* %3
%7 = load i32, i32* %4
%8 = add i32 %6, %7
store i32 %8, i32* %5
%9 = load i32, i32* %5
ret i32 %9
}
define i32 @main() {
; <label>:0
%1 = call i32 @foo(i32 12, i32 30)
ret i32 %1
}
!llvm.dbg.cu = !{!0}
!llvm.ident = !{!8}
!llvm.module.flags = !{!3, !4, !5, !6, !7}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (tags/RELEASE_800/final)", emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "foo.c", directory: "/home/u/Desktop/foo")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{i32 7, !"PIC Level", i32 2}
!7 = !{i32 7, !"PIE Level", i32 2}
!8 = !{!"clang version 8.0.0 (tags/RELEASE_800/final)"}
!9 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!10 = !DISubroutineType(types: !11)
!11 = !{!12, !12, !12}
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!13 = !DILocalVariable(name: "a", arg: 1, scope: !9, file: !1, line: 1, type: !12)
!14 = !DILocation(line: 1, column: 13, scope: !9)
!15 = !DILocalVariable(name: "b", arg: 2, scope: !9, file: !1, line: 1, type: !12)
!16 = !DILocation(line: 1, column: 20, scope: !9)
!17 = !DILocalVariable(name: "sum", scope: !9, file: !1, line: 2, type: !12)
!18 = !DILocation(line: 2, column: 6, scope: !9)
Note, I am well aware that defining DWARF debug info in this way is very verbose. Sorry :) It is what we have currently.
Most likely, users would want to write their own helper libraries for constructing metadata debug info. The IR package in its current form is mostly concerned with the in-memory representation of LLVM IR.
Over time, we should evaluate the different approaches taken by the users of llir and see if some of those IR and metadata construction utilities should be merged into the cannonical helper library llir/irutil. All that will happen in due time.
Feel free to report back if you play around with DWARF debug info construction and arrive at a clean API for the helper library! We'd be curious to see what it may look like.
Just checked the Users repos from the README, for potential example code that could be used: Repo Includes debugging info blessedvirginmary No decomp No geode No leaven No tre No uc No
No luck there. Any ideas? smile
Oh, and for what it is worth, geode does include at least partial support for generating DWARF debug info.
The following grep output highlights source files that may be worth a read:
u@x1 ~/D/l/geode> ack metadata.DI
pkg/lexer/Token.go:func (t *Token) DILocation(scope *metadata.DISubprogram) *metadata.DILocation {
pkg/lexer/Token.go: return &metadata.DILocation{
pkg/ast/Program.go: md := &metadata.DISubprogram{
pkg/ast/Scope.go: DebugInfo *metadata.DISubprogram
Oh wow! That's fantastic @mewmew. This gives plenty of info on how to get up and running with it.
Thanks heaps. :grin:
Time to experiment...
Oh wow! That's fantastic @mewmew. This gives plenty of info on how to get up and running with it.
Thanks heaps. grin
Glad to be of help :)
Time to experiment...
Happy hacking!!
Oh, and if you'd like, please report back in a week or so and tell us what worked well and what didn't so we can learn, iterate and improve.
@justinclift, once you've had more experience with this, would you be willing to create a mini-guide/howto for how to generate DWARF debug info using llir/llvm? If so, of course feel free to use any of the code samples and instructions posted in https://github.com/llir/llvm/issues/86#issuecomment-498357924. I think the instructions turned out a bit too long to have them in the main README, but perhaps you could create a guide.md document for these kind of step by step instructions/tutorials?
Cheerful regards, Robin
Yep, that sounds like a good idea. And it's my kind of thing to do as well.
Will report back, and produce suitable guide kind of thing. :grin:
As an early initial thought :wink:, being able to set a default Align would be useful, so NewAlloc(), NewLoad(), NewStore() (etc) don't need to have it manually set each time. eg:
- https://github.com/justinclift/llir3/blob/a4b6c10de23a6a5acd2c76d3e9aa8d1515b86772/main.go#L66-L67
- https://github.com/justinclift/llir3/blob/a4b6c10de23a6a5acd2c76d3e9aa8d1515b86772/main.go#L98-L99
- https://github.com/justinclift/llir3/blob/a4b6c10de23a6a5acd2c76d3e9aa8d1515b86772/main.go#L113-L114
- (etc)
Maybe something like?
// Create LLVM IR module.
m := ir.NewModule()
m.SetDefaultAlign(4)
// Align doesn't need manually setting now, unless there's a reason to override it for a specific instance
a := fooEntry.NewAlloca(i32)
aVal := fooEntry.NewLoad(a)
aVal.Metadata = append(aVal.Metadata, &metadata.Attachment{Name: "dbg", Node: dbgLoc["A2"]})
I don't (yet) have enough understanding of how things hang together to create a useful PR. In theory that should come with time. :wink:
It should be possible to string that together. However, currently, an *ir.Func does not keep track of which *ir.Module it belongs to. Neither does *ir.Block with regards to which *ir.Func it belongs to. So when you invoke func (block *Block) NewAlloca, we don't have enough context information stored in the block to get the "default settings" of the module.
That being said, I think this may be something for irutil, as if we include X we should include Y, and then the API surface of the IR package will quickly become rather larger. However, it should be rather easy to implement wrappers for these constructors in an irutil package and thus provide default settings for modules, etc.
Edit: just to clarify, I think that it would make sense to extend the core IR API by adding a Parent field to ir.Func, ir.Block and ir.InstFoo, respectively. Having such a field makes several use cases possible. Including the default Align settings mentioned in this issue (even if that specific use case would likely be implemented in irutil).
package ir
type Func struct {
Parent *Module
...
}
type Block struct {
Parent *Func
...
}
type InstFoo struct {
Parent *Block
...
}
Edit2: Turns out ir.Block already had a Parent field for its parent function. So, given that we add a Parent field to ir.Func for its parent module, then it should be possible to string together what you suggested for func (block *Block) NewAlloca.
Edit3: I think we have to decide whether to add a Parent field to each instruction or not. Also, if the ir.Instruction interface should then contain a Parent method? In which case, the same should be considered for ir.Terminator.
No worries. Not personally going to put too much thinking time into it just yet, as I've just managed to put together some .ll which gets close to generating a valid Wasm file (almost runnable in Firefox).
With some minor hammering into shape, Firefox was able to run it. So, for tomorrow I'll try and reverse that ll file for equivalent llir/llvm generation (same as the foo.c example you started me with above).
If I can get that working, that would be good... :smile:
But, sleep calls atm...
But, sleep calls atm...
Sleep tight :)
Is there a decent way to compare and display the differences between two .ll files?
Started creating a basic command line util to do it, but hopefully there's existing (better) tooling that could be used?
eg no need to spend time re-inventing wheels that already exist. :smile:
Not pretty sure since I haven't tried it but maybe https://llvm.org/docs/CommandGuide/llvm-diff.html this can help?
Thanks @dannypsnl, I'll have a go with that. :smile:
Yep, that does seem to work. It operates on .ll / .bc files too. :smile:
After manually renaming all instances of "foo" in a test .ll to "bar", then running llvm-diff on it:
$ llvm-diff target.ll foo.ll
function @bar exists only in left module
function @foo exists only in right module
in function main:
in block %0 / %0:
> %2 = call i32 @foo(i32 12, i32 30), !dbg !11
> ret i32 %2, !dbg !12
< %2 = call i32 @bar(i32 12, i32 30), !dbg !11
< ret i32 %2, !dbg !12
Looks like the right kind of thing. :smile:
Apologies for the delay in getting back to this. I'll pick it up in a few days, as I'm just trying to get an initial wasm thing done first which makes use of the knowledge gained here.
Apologies for the delay in getting back to this. I'll pick it up in a few days, as I'm just trying to get an initial wasm thing done first which makes use of the knowledge gained here.
Hi Justin. No rush. Hack on it when you are in the mood! We will be here happy to look at what you've played with :)
Marking this issue with the util milestone, as generating LLVM IR metadata using the llir/llvm/ir/metadata API is quite laborious (ref https://github.com/llir/llvm/issues/86#issuecomment-498357924). Therefore, it seems like a good idea to create utility functions for generating DWARF debug info as LLVM IR metadata. Exactly what this API may look like is not yet clear, so anyone should feel free to join the discussion and propose API designs :)
According to IBM developer document
DWARF uses a series of debugging information entries (DIEs) to define a low-level representation of a source program. Each debugging information entry consists of an identifying tag and a series of attributes. An entry or group of entries together, provides a description of a corresponding entity in the source program. The tag specifies the class to which an entry belongs and the attributes define the specific characteristics of the entry.
I don't think this is possible to handle by irutil, DI information mapping to source code. But there are tons kind of source code, irutil can be convenient but not configurable, in most cases cannot fit what a compiler needs.
But I think, on the other hand, we could make a package under metadata called metadata/di which improves how we build metadata. For example:
diFile := di.NewDIFile("foo.c", "where/am/i")
compileUnit := di.NewCompileUnit(diFile) // omit others fields
subProg := diFIle.SubProgram("foo")
subProg.Location(2, 13)
wow, err := subProg.Variable("wow")
if err != nil { // probably because undefined?
}
And MetadataID definitely needs a better way to omit it XD.
@dannypsnl, your idea for the di package is essentially what I had in mind to put in irutil. We need to figure out what to keep in the core llir/llvm repo and what to keep in the llvm/irutil repo. The key point is that everyone using llir/llvm will have to import the core package, but llvm/irutil is optional, and users may want to implement those things in different ways.
So, in general we err on the side of putting things into irutil first, until we can stabalize and experiment with the API. Then once the problem is well understood, we can move the API to the core llir/llvm repo.
Aha, now I got your idea, thank you for letting me realize it. Then that makes sense, experiment API first in irutil.
Robin Eklind [email protected]於 2020年2月18日 週二,上午2:35寫道:
@dannypsnl https://github.com/dannypsnl, your idea for the di package is essentially what I had in mind to put in irutil. We need to figure out what to keep in the core llir/llvm repo and what to keep in the llvm/irutil repo. The key point is that everyone using llir/llvm will have to import the core package, but llvm/irutil is optional, and users may want to implement those things in different ways.
So, in general we err on the side of putting things into irutil first, until we can stabalize and experiment with the API. Then once the problem is well under, we can move the API to the core llir/llvm repo.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/llir/llvm/issues/86?email_source=notifications&email_token=AFH4GH6A4HO6D4ONRSYF5UDRDLKILA5CNFSM4HSCF7QKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEL7KVCI#issuecomment-587115145, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFH4GH2B3YBKBT6F7IOUM3TRDLKILANCNFSM4HSCF7QA .
Is there a di package? I'm looking to add debug info to my language, but am not sure how. The DI API is really confusing, and I'm not sure on the best way to implement it. Being able to do something like
block.SetLine(<line>)
for every line would be nice
also doing
block.AddDebugVariable(<variable>)
would be useful. If the util API isn't ready yet, how would I do this with the current API?
While messy and low-level, https://github.com/llir/llvm/issues/86#issuecomment-498357924 details the API usage for adding DWARF debug info. Note, the easiest way to try this yourself is to simply generate LLVM IR from C using the -g flag to add debug info, and the --emit-llvm to generate LLVM IR from Clang. See the comment for details. Then try to generate similar LLVM IR using the llir/llvm/metadata API.
Of course, the llir/llvm/metadata API is way too low-level to be pleasant to use. However, it should be possible to build a utility library on top of it that has functions like the one you mentioned (block.AddDebugVariable(<variable>)). If you do get around to experimenting with designing such a utility library, keep us posted as we too would like to see it happen :)
Cheers, Robin