AnyDSL / thorin

The Higher-Order Intermediate Representation
https://anydsl.github.io
GNU Lesser General Public License v3.0
151 stars 15 forks source link

C backend is amenable for the swap problem #32

Closed leissa closed 8 years ago

leissa commented 8 years ago

When translating the following program

fn main(c: bool, mut a: int, mut b: int) -> int {
    while c {
        let tmp = a;
        a = b;
        b = tmp;
    }

    a + b
}

to C:

int main_impala(bool c_29, int a_30, int b_31) {
    int tmp_55;
    int b_57;
    tmp_55 = a_30;
    b_57 = b_31;
    goto l44;
    l44: ;
        if (c_29) {
            goto l47;
        } else {
            goto l50;
        }
    l47: ;
        tmp_55 = b_57;
        b_57 = tmp_55;
        goto l44;
    l50: ;
        int _64;
        _64 = tmp_55 + b_57;
        return _64;
}

The code is incorrect. The swap is lost.

richardmembarth commented 8 years ago

As far I see, this already broken in the thorin IR:

impala -emit-thorin test.impala -Othorin
module 'test'

main_impala_27(mem mem_28, bool c_29, qs32 a_30, qs32 b_31, fn(mem, qs32) return_32) extern 
    fn(mem) _53 = @ c_29 select while_body_47, next_50
    while_head_44 mem_28, a_30, b_31

    while_head_44(mem mem_46, qs32 tmp_55, qs32 b_57)
        _53 mem_46

    while_body_47(mem mem_49)
        while_head_44 mem_49, b_57, tmp_55

    next_50(mem mem_52)
        qs32 _64 = add tmp_55, b_57
        return_32 mem_52, _64
leissa commented 8 years ago

nope. it's a problem of the C output. In Thorin the swap is in the call/args/params.

richardmembarth commented 8 years ago

I see, I'll have a look into this as discussed.

richardmembarth commented 8 years ago

07de4d711ac3c788a5be53b6eeeaa97216aaad64 should finally fix this:

int main_impala(bool c_29, int a_30, int b_31) {
    int  tmp_55;
    int ptmp_55;
    int  b_57;
    int pb_57;
    ptmp_55 = a_30;
    pb_57 = b_31;
    goto l44;
    l44: ;
        tmp_55 = ptmp_55;
        b_57 = pb_57;
        if (c_29) goto l47; else goto l50;
    l47: ;
        ptmp_55 = b_57;
        pb_57 = tmp_55;
        goto l44;
    l50: ;
        int _64;
        _64 = tmp_55 + b_57;
        return _64;
}