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] #86

Closed madmann91 closed 6 years ago

madmann91 commented 6 years ago

The following example loops forever:

extern "thorin" {
    fn pe_info[T](&[u8], T) -> (); 
}

fn @(?n) foo(n: int) -> () {
    fn @(?k) bar(k: int) -> () {
        if k < n { bar(k + 1) } else { () }
    }   
    if n > 22 {
        pe_info("n", n); 
        foo(n - 1)
    } else {
        bar(0)
    }   
}

fn main() -> () {
    foo(42);
}

After investigation, it turns out that bar is mangled with an additional parameter that represents n (the parameter of foo used within bar). For new parameters, we currently emit a PE profile which is always false (mangle.cpp:82):

// mangle pe_profile
if (!old_entry()->pe_profile().empty()) {
    Array<const Def*> new_pe_profile(new_entry()->num_params());
    size_t j = 0;
    for (size_t i = 0, e = old_entry()->num_params(); i != e; ++i) {
        if (args_[i] == nullptr)
            new_pe_profile[j++] = mangle(old_entry()->pe_profile(i));
    }

    for (size_t e = new_entry()->num_params(); j != e; ++j)
        new_pe_profile[j] = world().literal_bool(false, Debug{});

    new_entry()->set_pe_profile(new_pe_profile);
}

In this case, the choice of pe_profile should be the pe_profile of n for foo. If you agree with this decision, I'll write the fix for this issue.

leissa commented 6 years ago

The problem is the higher_order_lifting phase that does stuff before PE. I want to get rid of this phase anyway. Removing this phase fixes this problem.

leissa commented 6 years ago

fixed in pe_fix_point