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  }