AnyDSL / thorin

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

[New PE] Divergent partial evaluation #82

Closed madmann91 closed 6 years ago

madmann91 commented 6 years ago

Compile with -emit-thorin -Othorin.

struct SmallStack {
    write: fn (int, float) -> (),
    read:  fn (int) -> float
}

fn @(true) make_small_stack(n: int) -> SmallStack {
    fn @(?begin & ?end) make_small_stack_helper(begin: int, end: int) -> SmallStack {
        if begin == end {
            SmallStack {
                write: @(true) |_, _| (),
                read:  @(true) |_| 0.0f
            }
        } else if begin + 1 == end {
            let mut val : float;
            SmallStack {
                write: @(true) |i, v| val = v,
                read:  @(true) |i| val
            }
        } else {
            let m = (begin + end) / 2;
            let left  = make_small_stack_helper(begin, m);
            let right = make_small_stack_helper(m, end);
            SmallStack {
                write: @(true) |i, v| if i < m { left.write(i, v) } else { right.write(i, v) },
                read:  @(true) |i|    if i < m { left.read(i)     } else { right.read(i)     }
            }
        }
    }

    make_small_stack_helper(0, n)
}

fn @(?a & ?b) range_step(a: int, b: int, @(true) c: int, @(true) body: fn (int) -> ()) -> () {
    if a < b {
        body(a);
        range_step(a + c, b, c, body, return)
    }
}

fn @(true) range(a: int, b: int, body: fn (int) -> ()) -> () {
    range_step(a, b, 1, body);
}

fn main(res: &mut [float]) -> () {
    for n in range(0, 8) {
        let tmp = make_small_stack(n);
        for i in range(0, n) {
            tmp.write(i, i as float * 42.0f);
        }
        let mut sum = 0.0f;
        for i in range(0, n) {
            let v = tmp.read(i);
            sum += v as float;
        }
        res(n) = sum;
    }
}
leissa commented 6 years ago

Can you give the pe_fix_point (impala + thorin) branch a try? Now, I solved this issue, by letting the PE run in the fix-point loop.

leissa commented 6 years ago

pe_fix_point works now