diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2017-12-04 10:24:50 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2017-12-04 10:24:50 -0800 |
commit | a87118d98906d2eda0265fba6cfef8b979f8d8ec (patch) | |
tree | 74d0e584aad6ad6990e1c63be0ef53bdd818d406 | |
parent | 8050782c17560ef33a85bd739da8158f9c530e39 (diff) | |
download | mu-a87118d98906d2eda0265fba6cfef8b979f8d8ec.tar.gz |
4137 - perform specialization on indirect calls
https://lobste.rs/s/esqphf/what_are_you_working_on_this_week#c_ajgfim
-rw-r--r-- | 054static_dispatch.cc | 23 | ||||
-rw-r--r-- | 072recipe.cc | 25 |
2 files changed, 39 insertions, 9 deletions
diff --git a/054static_dispatch.cc b/054static_dispatch.cc index 566bb7ad..8037892e 100644 --- a/054static_dispatch.cc +++ b/054static_dispatch.cc @@ -166,18 +166,23 @@ void resolve_ambiguous_calls(const recipe_ordinal r) { for (int index = 0; index < SIZE(caller_recipe.steps); ++index) { instruction& inst = caller_recipe.steps.at(index); if (inst.is_label) continue; - if (non_ghost_size(get_or_insert(Recipe_variants, inst.name)) == 0) continue; - trace(9992, "transform") << "instruction " << to_original_string(inst) << end(); - Resolve_stack.push_front(call(r, index)); - string new_name = best_variant(inst, caller_recipe); - if (!new_name.empty()) - inst.name = new_name; - assert(Resolve_stack.front().running_recipe == r); - assert(Resolve_stack.front().running_step_index == index); - Resolve_stack.pop_front(); + resolve_ambiguous_call(r, index, inst, caller_recipe); } } +void resolve_ambiguous_call(const recipe_ordinal r, int index, instruction& inst, const recipe& caller_recipe) { + // End resolve_ambiguous_call(r, index, inst, caller_recipe) Special-cases + if (non_ghost_size(get_or_insert(Recipe_variants, inst.name)) == 0) return; + trace(9992, "transform") << "instruction " << to_original_string(inst) << end(); + Resolve_stack.push_front(call(r, index)); + string new_name = best_variant(inst, caller_recipe); + if (!new_name.empty()) + inst.name = new_name; + assert(Resolve_stack.front().running_recipe == r); + assert(Resolve_stack.front().running_step_index == index); + Resolve_stack.pop_front(); +} + string best_variant(const instruction& inst, const recipe& caller_recipe) { const vector<recipe_ordinal>& variants = get(Recipe_variants, inst.name); vector<recipe_ordinal> candidates; diff --git a/072recipe.cc b/072recipe.cc index ca8932ed..f77949e1 100644 --- a/072recipe.cc +++ b/072recipe.cc @@ -159,6 +159,31 @@ def f x:point -> y:point [ +error: main: ingredient 0 has the wrong type at '2:num <- call {1: (recipe point -> point)}, 34' +error: main: product 0 has the wrong type at '2:num <- call {1: (recipe point -> point)}, 34' +:(scenario call_check_shape_shifting_recipe) +def main [ + 1:num <- call f, 34 +] +def f x:_elem -> y:_elem [ + local-scope + load-ingredients + y <- copy x +] ++mem: storing 34 in location 1 + +:(before "End resolve_ambiguous_call(r, index, inst, caller_recipe) Special-cases") +if (inst.name == "call" && !inst.ingredients.empty() && inst.ingredients.at(0).type && inst.ingredients.at(0).type->atom && inst.ingredients.at(0).type->name == "recipe-literal") { + instruction inst2; + inst2.name = inst.ingredients.at(0).name; + for (int i = /*skip recipe*/1; i < SIZE(inst.ingredients); ++i) + inst2.ingredients.push_back(inst.ingredients.at(i)); + for (int i = 0; i < SIZE(inst.products); ++i) + inst2.products.push_back(inst.products.at(i)); + resolve_ambiguous_call(r, index, inst2, caller_recipe); + inst.ingredients.at(0).name = inst2.name; + inst.ingredients.at(0).set_value(get(Recipe_ordinal, inst2.name)); + return; +} + :(after "Transform.push_back(check_instruction)") Transform.push_back(check_indirect_calls_against_header); // idempotent :(code) |