diff options
Diffstat (limited to 'html/057static_dispatch.cc.html')
-rw-r--r-- | html/057static_dispatch.cc.html | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/html/057static_dispatch.cc.html b/html/057static_dispatch.cc.html index 319c72e9..adcf7995 100644 --- a/html/057static_dispatch.cc.html +++ b/html/057static_dispatch.cc.html @@ -175,6 +175,15 @@ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</ <span class="Delimiter">:(after "Transform.push_back(transform_names)")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>resolve_ambiguous_calls<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> +<span class="Comment">//: In a later layer we'll introduce recursion in resolve_ambiguous_calls, by</span> +<span class="Comment">//: having it generate code for shape-shifting recipes and then transform such</span> +<span class="Comment">//: code. This data structure will help error messages be more useful.</span> +<span class="Comment">//:</span> +<span class="Comment">//: We're punning the 'call' data structure just because it has slots for</span> +<span class="Comment">//: calling recipe and calling instruction.</span> +<span class="Delimiter">:(before "End Globals")</span> +list<call> resolve_stack<span class="Delimiter">;</span> + <span class="Delimiter">:(code)</span> void resolve_ambiguous_calls<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> recipe& caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> @@ -184,7 +193,12 @@ void resolve_ambiguous_calls<span class="Delimiter">(</span>recipe_ordinal r<spa instruction& inst = caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + resolve_stack<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>r<span class="Delimiter">));</span> + resolve_stack<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index = index<span class="Delimiter">;</span> replace_best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>resolve_stack<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe == r<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>resolve_stack<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index == index<span class="Delimiter">);</span> + resolve_stack<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -195,6 +209,7 @@ void replace_best_variant<span class="Delimiter">(</span>instruction& inst<s long long int best_score = variant_score<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">));</span> trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"score for base: "</span> << best_score << end<span class="Delimiter">();</span> for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="CommentedCode">//? trace(9992, "transform") << "checking variant " << i << ": " << variants.at(i) << end();</span> long long int current_score = variant_score<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"score for variant "</span> << i << <span class="Constant">": "</span> << current_score << end<span class="Delimiter">();</span> @@ -206,7 +221,38 @@ void replace_best_variant<span class="Delimiter">(</span>instruction& inst<s <span class="Comment">// End Instruction Dispatch(inst, best_score)</span> if <span class="Delimiter">(</span>best_score == -<span class="Constant">1</span> && get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">)</span> >= MAX_PRIMITIVE_RECIPES<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise_error << maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"failed to find a matching call for '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + for <span class="Delimiter">(</span>list<call>::iterator p = <span class="Comment">/*</span><span class="Comment">skip</span><span class="Comment">*/</span>++resolve_stack<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != resolve_stack<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const recipe& specializer_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> p<span class="Delimiter">-></span>running_recipe<span class="Delimiter">);</span> + const instruction& specializer_inst = specializer_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>p<span class="Delimiter">-></span>running_step_index<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>specializer_recipe<span class="Delimiter">.</span>name != <span class="Constant">"interactive"</span><span class="Delimiter">)</span> + raise_error << <span class="Constant">" (from '"</span> << specializer_inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' in "</span> << specializer_recipe<span class="Delimiter">.</span>name << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + else + raise_error << <span class="Constant">" (from '"</span> << specializer_inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"')</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Comment">// One special-case to help with the rewrite_stash transform. (cross-layer)</span> + if <span class="Delimiter">(</span>specializer_inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"stash_"</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + instruction stash_inst<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>next_stash<span class="Delimiter">(</span>*p<span class="Delimiter">,</span> &stash_inst<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>specializer_recipe<span class="Delimiter">.</span>name != <span class="Constant">"interactive"</span><span class="Delimiter">)</span> + raise_error << <span class="Constant">" (part of '"</span> << stash_inst<span class="Delimiter">.</span>original_string << <span class="Constant">"' in "</span> << specializer_recipe<span class="Delimiter">.</span>name << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + else + raise_error << <span class="Constant">" (part of '"</span> << stash_inst<span class="Delimiter">.</span>original_string << <span class="Constant">"')</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> + +bool next_stash<span class="Delimiter">(</span>const call& c<span class="Delimiter">,</span> instruction* stash_inst<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const recipe& specializer_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> c<span class="Delimiter">.</span>running_recipe<span class="Delimiter">);</span> + long long int index = c<span class="Delimiter">.</span>running_step_index<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>++index<span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>specializer_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const instruction& inst = specializer_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"stash"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + *stash_inst = inst<span class="Delimiter">;</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> long long int variant_score<span class="Delimiter">(</span>const instruction& inst<span class="Delimiter">,</span> recipe_ordinal variant<span class="Delimiter">)</span> <span class="Delimiter">{</span> |