Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

irutil: add utility API for creating dwarf metadata (was: Example with inclusion of DWARF output?) #86

Open
justinclift opened this issue Jun 2, 2019 · 23 comments

Comments

@justinclift
Copy link
Contributor

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? 😄

@justinclift
Copy link
Contributor Author

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? 😄

@mewmew
Copy link
Member

mewmew commented Jun 3, 2019

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:

  1. 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.
  2. Parse the LLVM IR assembly file using asm.ParseFile.
    • refer to foo.go below.
  3. Extract the essential details from the pretty-printed IR and create our own using llir/llvm/ir.
    • refer to bar.go and bar.ll below.

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)

@mewmew
Copy link
Member

mewmew commented Jun 3, 2019

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.

@mewmew
Copy link
Member

mewmew commented Jun 3, 2019

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

@justinclift
Copy link
Contributor Author

Oh wow! That's fantastic @mewmew. This gives plenty of info on how to get up and running with it.

Thanks heaps. 😁

Time to experiment...

@mewmew
Copy link
Member

mewmew commented Jun 4, 2019

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 #86 (comment). 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

@justinclift
Copy link
Contributor Author

justinclift commented Jun 4, 2019

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. 😁

justinclift added a commit to justinclift/llir3 that referenced this issue Jun 4, 2019
From:

  llir/llvm#86 (comment)

The .ll was generated using:

  $ go run main.go > foo.ll

The .ll can be compiled to a Linux binary with:

  $ clang --target=x86_64-pc-linux-gnu -g -Wno-override-module -o foo foo.ll
@justinclift
Copy link
Contributor Author

justinclift commented Jun 5, 2019

As an early initial thought 😉, 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:

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. 😉

@mewmew
Copy link
Member

mewmew commented Jun 5, 2019

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.

@justinclift
Copy link
Contributor Author

justinclift commented Jun 5, 2019

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... 😄

But, sleep calls atm...

@mewmew
Copy link
Member

mewmew commented Jun 5, 2019

But, sleep calls atm...

Sleep tight :)

justinclift added a commit to justinclift/llircomp that referenced this issue Jun 6, 2019
@justinclift
Copy link
Contributor Author

justinclift commented Jun 6, 2019

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. 😄

@dannypsnl
Copy link
Member

Not pretty sure since I haven't tried it but maybe https://llvm.org/docs/CommandGuide/llvm-diff.html this can help?

@justinclift
Copy link
Contributor Author

Thanks @dannypsnl, I'll have a go with that. 😄

@justinclift
Copy link
Contributor Author

Yep, that does seem to work. It operates on .ll / .bc files too. 😄

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. 😄

@justinclift
Copy link
Contributor Author

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.

@mewmew
Copy link
Member

mewmew commented Jun 18, 2019

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 :)

@mewmew mewmew added the howto label Jun 30, 2019
@mewmew mewmew added this to the util milestone Jun 30, 2019
@mewmew
Copy link
Member

mewmew commented Jun 30, 2019

Marking this issue with the util milestone, as generating LLVM IR metadata using the llir/llvm/ir/metadata API is quite laborious (ref #86 (comment)). 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 :)

@dannypsnl
Copy link
Member

dannypsnl commented Feb 17, 2020

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.

@mewmew
Copy link
Member

mewmew commented Feb 17, 2020

@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.

@dannypsnl

This comment has been minimized.

@mewmew mewmew changed the title Example with inclusion of DWARF output? irutil: add utility API for creating dwarf metadata (was: Example with inclusion of DWARF output?) May 16, 2021
@Nv7-GitHub
Copy link
Contributor

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?

@mewmew
Copy link
Member

mewmew commented Sep 30, 2021

While messy and low-level, #86 (comment) 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants