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.
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.
The following example loops forever:
After investigation, it turns out that
bar
is mangled with an additional parameter that representsn
(the parameter offoo
used withinbar
). For new parameters, we currently emit a PE profile which is always false (mangle.cpp:82
):In this case, the choice of pe_profile should be the pe_profile of
n
forfoo
. If you agree with this decision, I'll write the fix for this issue.