1 
2 // This examples creates and runs the equivalent of this C function:
3 
4 //  int loop_test (int n)
5 //  {
6 //      int i = 0;
7 //      int sum = 0;
8 //      while (i < n)
9 //      {
10 //          sum += i * i;
11 //          i++;
12 //      }
13 //      return sum;
14 //  }
15 
16 module gccjitd.examples.sum_squares;
17 
18 import gccjit.d;
19 
20 JITResult create_fn()
21 {
22     // Create a compilation context
23     JITContext ctxt = new JITContext();
24 
25     // Turn these on to get various kinds of debugging
26     version(none)
27     {
28         ctxt.setOption(JITBoolOption.DUMP_INITIAL_TREE, true);
29         ctxt.setOption(JITBoolOption.DUMP_INITIAL_GIMPLE, true);
30         ctxt.setOption(JITBoolOption.DUMP_GENERATED_CODE, true);
31     }
32 
33     // Adjust this to control optimization level of the generated code
34     version(none)
35         ctxt.setOption(JITIntOption.OPTIMIZATION_LEVEL, 3);
36 
37     // Build function
38     JITParam param_n = ctxt.newParam(JITTypeKind.INT, "n");
39     JITFunction fn = ctxt.newFunction(JITFunctionKind.EXPORTED,
40                                       JITTypeKind.INT,
41                                       "loop_test", false, param_n);
42 
43     // Build locals
44     JITLValue local_i = fn.newLocal(ctxt.getType(JITTypeKind.INT), "i");
45     JITLValue local_sum = fn.newLocal(ctxt.getType(JITTypeKind.INT), "sum");
46 
47     // This is what you get back from local_i.toString()
48     assert(local_i.toString() == "i");
49 
50     // Build blocks
51     JITBlock entry_block = fn.newBlock("entry");
52     JITBlock cond_block = fn.newBlock("cond");
53     JITBlock loop_block = fn.newBlock("loop");
54     JITBlock after_loop_block = fn.newBlock("after_loop");
55 
56     // sum = 0
57     entry_block.addAssignment(local_sum, ctxt.zero(JITTypeKind.INT));
58 
59     // i = 0
60     entry_block.addAssignment(local_i, ctxt.zero(JITTypeKind.INT));
61 
62     entry_block.endWithJump(cond_block);
63 
64     // while (i < n)
65     cond_block.endWithConditional(ctxt.newComparison(JITComparison.LT, local_i, param_n),
66                                   loop_block, after_loop_block);
67 
68     // sum += i * i
69     loop_block.addAssignmentOp(local_sum, JITBinaryOp.PLUS,
70                                ctxt.newBinaryOp(JITBinaryOp.MULT,
71                                                 ctxt.getType(JITTypeKind.INT),
72                                                 local_i, local_i));
73 
74     // i++
75     loop_block.addAssignmentOp(local_i, JITBinaryOp.PLUS, ctxt.one(JITTypeKind.INT));
76 
77     // goto cond_block
78     loop_block.endWithJump(cond_block);
79 
80     // return sum
81     after_loop_block.endWithReturn(local_sum);
82 
83     JITResult result = ctxt.compile();
84     return result;
85 }
86 
87 int loop_test(int n)
88 {
89     JITResult result = create_fn();
90     auto code = cast(int function(int))(result.getCode("loop_test"));
91     return code(n);
92 }
93 
94 void main()
95 {
96     import std.stdio : writeln;
97     writeln(loop_test(10));
98 }