github.com/llir/llvm@v0.3.6/ir/example_test.go (about) 1 package ir_test 2 3 import ( 4 "fmt" 5 6 "github.com/llir/llvm/ir" 7 "github.com/llir/llvm/ir/constant" 8 "github.com/llir/llvm/ir/types" 9 ) 10 11 func Example() { 12 // This example produces LLVM IR code equivalent to the following C code, 13 // which implements a pseudo-random number generator. 14 // 15 // int abs(int x); 16 // 17 // int seed = 0; 18 // 19 // // ref: https://en.wikipedia.org/wiki/Linear_congruential_generator 20 // // a = 0x15A4E35 21 // // c = 1 22 // int rand(void) { 23 // seed = seed*0x15A4E35 + 1; 24 // return abs(seed); 25 // } 26 27 // Create convenience types and constants. 28 i32 := types.I32 29 zero := constant.NewInt(i32, 0) 30 a := constant.NewInt(i32, 0x15A4E35) // multiplier of the PRNG. 31 c := constant.NewInt(i32, 1) // increment of the PRNG. 32 33 // Create a new LLVM IR module. 34 m := ir.NewModule() 35 36 // Create an external function declaration and append it to the module. 37 // 38 // int abs(int x); 39 abs := m.NewFunc("abs", i32, ir.NewParam("x", i32)) 40 41 // Create a global variable definition and append it to the module. 42 // 43 // int seed = 0; 44 seed := m.NewGlobalDef("seed", zero) 45 46 // Create a function definition and append it to the module. 47 // 48 // int rand(void) { ... } 49 rand := m.NewFunc("rand", i32) 50 51 // Create an unnamed entry basic block and append it to the `rand` function. 52 entry := rand.NewBlock("") 53 54 // Create instructions and append them to the entry basic block. 55 tmp1 := entry.NewLoad(types.I32, seed) 56 tmp2 := entry.NewMul(tmp1, a) 57 tmp3 := entry.NewAdd(tmp2, c) 58 entry.NewStore(tmp3, seed) 59 tmp4 := entry.NewCall(abs, tmp3) 60 entry.NewRet(tmp4) 61 62 // Print the LLVM IR assembly of the module. 63 fmt.Println(m) 64 65 // Output: 66 // 67 // @seed = global i32 0 68 // 69 // declare i32 @abs(i32 %x) 70 // 71 // define i32 @rand() { 72 // 0: 73 // %1 = load i32, i32* @seed 74 // %2 = mul i32 %1, 22695477 75 // %3 = add i32 %2, 1 76 // store i32 %3, i32* @seed 77 // %4 = call i32 @abs(i32 %3) 78 // ret i32 %4 79 // } 80 }