github.com/llir/llvm@v0.3.6/ir/block.go (about) 1 // The basic block API of the ir package was heavily inspired by 2 // https://github.com/mrbenshef/goory. 3 4 package ir 5 6 import ( 7 "fmt" 8 "strings" 9 10 "github.com/llir/llvm/internal/enc" 11 "github.com/llir/llvm/ir/types" 12 ) 13 14 // === [ Basic blocks ] ======================================================== 15 16 // Block is an LLVM IR basic block; a sequence of non-branching instructions 17 // terminated by a control flow instruction (e.g. br or ret). 18 type Block struct { 19 // Name of local variable associated with the basic block. 20 LocalIdent 21 // Instructions of the basic block. 22 Insts []Instruction 23 // Terminator of the basic block. 24 Term Terminator 25 26 // extra. 27 28 // Parent function; field set by ir.Func.NewBlock. 29 Parent *Func `json:"-"` 30 } 31 32 // NewBlock returns a new basic block based on the given label name. An empty 33 // label name indicates an unnamed basic block. 34 func NewBlock(name string) *Block { 35 block := &Block{} 36 block.SetName(name) 37 return block 38 } 39 40 // String returns the LLVM syntax representation of the basic block as a 41 // type-value pair. 42 func (block *Block) String() string { 43 return fmt.Sprintf("%s %s", block.Type(), block.Ident()) 44 } 45 46 // Type returns the type of the basic block. 47 func (block *Block) Type() types.Type { 48 return types.Label 49 } 50 51 // LLString returns the LLVM syntax representation of the basic block 52 // definition. 53 // 54 // Name=LabelIdentopt Insts=Instruction* Term=Terminator 55 func (block *Block) LLString() string { 56 buf := &strings.Builder{} 57 if block.IsUnnamed() { 58 //fmt.Fprintf(buf, "; <label>:%d\n", block.LocalID) 59 // Explicitly print basic block label to conform with Clang 9.0, and 60 // because it's the sane thing to do. 61 fmt.Fprintf(buf, "%s\n", enc.LabelID(block.LocalID)) 62 } else { 63 fmt.Fprintf(buf, "%s\n", enc.LabelName(block.LocalName)) 64 } 65 for _, inst := range block.Insts { 66 fmt.Fprintf(buf, "\t%s\n", inst.LLString()) 67 } 68 if block.Term == nil { 69 panic(fmt.Sprintf("missing terminator in basic block %q.\ncurrent instructions:\n%s", block.Name(), buf.String())) 70 } 71 fmt.Fprintf(buf, "\t%s", block.Term.LLString()) 72 return buf.String() 73 }