New way of building C++ code from MSIL

Coordinator
Dec 8, 2015 at 11:06 AM
Edited Dec 8, 2015 at 11:10 AM
I am writing new methods to generate stack base code in C which allows to generate more Assembler style code instead of C code. I have found that stack base code is better optimized by compiler than the equivalent code.

Example: Fibonacci code
using System;

public class Fib {

    public static int fib (int n) {
        if (n < 2)
            return 1;
        return fib(n-2)+fib(n-1);
    }
    public static int Main (string[] args) {
        int repeat = 10;
        
        Console.WriteLine ("Repeat = " + repeat);

            DateTime start, end;
            start = DateTime.Now;

        for (int i = 0; i < (repeat * 50); i++)
            if (fib (32) != 3524578)
                return 1;
        
        end = DateTime.Now;
        var n2 = (end-start).TotalMilliseconds;
        Console.WriteLine("{0} milliseconds.", (int)n2);

        return 0;
    }
}
Current IL2C generates the corresponding code for the method fib
Int32 Int32_Fib_fibFInt32N(Int32 n) {
    if (n >= 2) goto a6;
    return 1;
a6:
    Int32 __expr9;
    __expr9 = Int32_Fib_fibFInt32N((n - 2));
    Int32 __expr17;
    __expr17 = Int32_Fib_fibFInt32N((n - 1));
    return (__expr9 + __expr17);
}
and if we run it the time taken to calculate fib(32) 10 times will be 2850 milliseconds.

Whereas new IL2C (not available yet) generates the code
Int32 Int32_Fib_fibFInt32N(Int32 n) {
    // removed header
    _push(n);
    _push_i(2);
    if (_pop_M1 >= _pop_1) goto a6;
    _push_i(1);
    return _pop;
a6:
    _push(n);
    _push_i(2);
    _push((_pop_M1 - _pop_1));
    _push(Int32_Fib_fibFInt32N(_pop));
    _push(n);
    _push_i(1);
    _push((_pop_M1 - _pop_1));
    _push(Int32_Fib_fibFInt32N(_pop));
    _push((_pop_M1 + _pop_1));
    return _pop;
}
and time taken to calculate fib(32) 10 times takes 480 milliseconds which is 5 times faster

PS. Both codes compiled with the same settings (-Ofast -march=native)