Another significant optimization is the detection that the call to
factorial
is tail recursion, which can be eliminated in favor of
an iteration:
$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1
;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) Symbols to be put in SSA form { D.88 } Incremental SSA update started at block: 0 Number of blocks in CFG: 5 Number of blocks to update: 4 ( 80%) factorial (signed int arg) { signed int stack$2; signed int stack$1; signed int stack$0; signed int stack[8]; signed int stack_depth; signed int x; signed int y; signed int mult_acc_1; <unnamed type> _20; signed int _21; signed int _38; signed int mul_tmp_44; signed int mult_acc_51; # arg_5 = PHI <arg_39(D)(0), _38(3)> # mult_acc_1 = PHI <1(0), mult_acc_51(3)> initial: _20 = arg_5 <= 1; _21 = (signed int) _20; if (_21 != 0) goto <bb 4> (instr9); else goto <bb 3> (instr4); instr4: /* DUP */: _38 = arg_5 + -1; mult_acc_51 = mult_acc_1 * arg_5; goto <bb 2> (initial); # stack$0_52 = PHI <arg_5(2)> instr9: /* RETURN */: stack ={v} {CLOBBER}; mul_tmp_44 = mult_acc_1 * stack$0_52; return mul_tmp_44; }