[m-rev.] for review: model_non lookup switches
Julien Fischer
juliensf at cs.mu.OZ.AU
Mon Apr 24 17:10:45 AEST 2006
On Mon, 24 Apr 2006, Zoltan Somogyi wrote:
> Implement lookup switches in which a switch arm may contain more than one
> solution, such as this code here:
>
> p(d, "four", f1, 4.4).
> p(e, "five", f2, 5.5).
> p(e, "five2", f3(5), 55.5).
> p(f, "six", f4("hex"), 6.6).
> p(g, "seven", f5(77.7), 7.7).
> p(g, "seven2", f1, 777.7).
> p(g, "seven3", f2, 7777.7).
>
> Such code occurs frequently in benchmark programs used to evaluate the
> performance of tabled logic programming systems.
>
> Change frameopt.m, which previously worked only on det and semidet code,
> to also work for nondet code. For predicates such as the one above, frameopt
> can now arrange for the predicate's nondet stack frame to be created only
> when a switch arm that has more than one solution is selected.
>
> compiler/lookup_switch.m:
> Extend the existing code for recognizing and implementing lookup
> switches to recognize and implement them even if they are model_non.
>
> compiler/lookup_util.m:
> New module containing utility predicates useful for implementing
> both lookup switches, and in the future, lookup disjunctions (i.e.
> disjunctions that correspond to a nondet arm of a lookup switch).
>
> compiler/ll_backend.m:
> Include the new module.
You also need to mention it in compiler/notes/compiler_design.html.
> compiler/global_data.m:
> Move the job of filling in dummy slots to our caller, in this case
> lookup_switch.m.
>
> compiler/frameopt.m:
> Generalize the existing code for delaying stack frame creation,
> which worked only on predicates that live on the det stack, to work
> also on predicates that live on the nondet stack. Without this,
> predicates whose bodies are model_non lookup switches would create
> a nonstack stack frame before the switch is ever entered, which
> is wasteful if the selected switch arm has at most one solution.
>
> Since the structure of model_non predicates is more complex (you can
> cause a branch to a label by storing its address in a redoip slot,
> you can succeed from the frame without removing the frame), this
> required considerable extra work. To make the new code debuggable,
> record, for each basic block that needs a stack frame, *why* it
> needs that stack frame.
>
> compiler/opt_util.m:
> Be more conservative about what refers to the stack. Export some
> previously internal functionality for frameopt. Turn some predicates
> into functions, and rename them to better reflect their purpose.
>
> compiler/opt_debug.m:
> Print much more information about pragma_c and call LLDS instructions.
>
> compiler/prog_data.m:
> Add an extra attribute to foreign_procs that says that the code
> of the foreign_proc assumes the existence of a stack frame.
> This is needed to avoid frameopt optimizing the stack frame away.
>
> compiler/add_pragma.m:
> When processing fact tables, we create foreign_procs that assume
> the existence of the stack frame, so set the new attribute.
>
> compiler/pragma_c_gen.m:
> When processing foreign_procs, transmit the information in the
> attribute to the generated LLDS code.
>
> compiler/llds.m:
> Rename the function symbols referring to the fixed slots in nondet
> stack frames to make them clearer and to avoid overloading function
> symbols such as curfr and succip.
>
> Rename the function symbols of the call_model type to avoid overloading
> the function symbols of the code_model type.
>
> Add a new field to the c_procedure type giving the code_model of the
> procedure, and give names to all the fields.
>
> Describe the stack slots used by lookup switches to the debugger
> and native gc.
>
> compiler/options.m:
> doc/user_guide.texi:
> Add a new option, --debug-opt-pred-name, that does when the existing
> --debug-opt-pred-id options does, but taking a user-friendly predicate
> name rather than a pred_id as its argument.
>
> compiler/handle_options.m:
> Process --debug-opt-pred-name, and make --frameopt-comments imply
> --auto-comments, since it is not useful without it.
>
> Reformat some existing comments that were written in the days of
> 8-space indentation.
>
> compiler/optimize.m:
> Implement the new option.
>
> Use the new field of the c_procedure type to try only the version
> of frameopt appropriate for the code model of the current procedure.
>
> Do a peephole pass after frameopt, since frameopt can generate code
> sequences that peephole can optimize.
>
> Make the mechanism for recording the process of optimizing procedure
> bodies more easily usable by including the name of the optimization
> that created a given version of the code in the name of the file
> that contains that version of the code, and ensuring that all numbers
> are two characters long, so that "vi procname*.opt*" looks at the
> relevant files in the proper chronological sequence, instead of having
> version 11 appear before version 2.
>
> compiler/peephole.m:
> Add a new optimization pattern: a "mkframe, goto fail" pair (which
> can be generated by frameopt) should be replaced by a simple "goto
> redo".
>
> compiler/code_gen.m:
> Factor out some common code.
>
> compiler/llds_out.m:
> Ensure that C comments nested inside comment(_) LLDS instructions
> aren't emitted as nested C comments, since C compilers cannot handle
> these.
>
> compiler/code_info.m:
> compiler/code_util.m:
> compiler/continuation_info.m:
> compiler/dupelim.m:
> compiler/exprn_aux.m:
> compiler/jumpopt.m:
> compiler/livemap.m:
> compiler/llds_out.m:
> compiler/mercury_compile.m:
> compiler/middle_rec.m:
> compiler/ml_code_gen.m:
> compiler/opt_debug.m:
> compiler/opt_util.m:
> compiler/peephole.m:
> compiler/stack_layout.m:
> compiler/transform_llds.m:
> compiler/var_locn.m:
> Conform to the change to prog_data.m, opt_util.m and/or llds.m.
>
> tests/hard_coded/dense_lookup_switch_non.{m,exp}:
> New test case to exercise the new algorithm.
>
> tests/hard_coded/Mmakefile:
> Enable the new test case.
>
> tests/hard_coded/cycles.m:
> Make this test case conform to our coding convention.
...
> +:- typeclass block_entry_exit(En, Ex) <= ((En -> Ex), (Ex -> En)) where [
> + pred detect_entry(list(instruction)::in, list(instruction)::out,
> + list(instruction)::out, En::out) is semidet,
> + pred detect_exit(list(instruction)::in, En::in, list(instruction)::out,
> + list(instruction)::out, list(instruction)::out, Ex::out) is semidet,
> + func late_setup_code(En) = list(instruction),
> + func non_teardown_exit_code(Ex) = list(instruction),
> + func describe_entry(En) = string,
> + func describe_exit(proc_label, Ex) = string
> +].
That appears to be the first use of functional dependencies in the compiler
itself.
...
> @@ -1261,39 +1745,43 @@
> % that sets up the resumption point saves the address of Label on
> % the stack, and thus is already known to need a stack frame.
> Predecessors = [],
> - svmap.det_update(Label, block_needs_frame, !OrdNeedsFrame)
> + ord_needs_frame(Label, Reason, !OrdNeedsFrame)
> ),
> list.filter(all_successors_need_frame(BlockMap, !.OrdNeedsFrame),
> Predecessors, NowNeedFrameLabels),
> - list.foldl2(record_frame_need(BlockMap), NowNeedFrameLabels,
> + list.foldl2(record_frame_need(BlockMap, Reason), NowNeedFrameLabels,
> !OrdNeedsFrame, !CanTransform),
> - svqueue.put_list(NowNeedFrameLabels, !Queue),
> + % XXX map.lookup(BlockMap, Label, BlockInfo),
> + % XXX Successors = successors(BlockInfo),
> + list.map(pair_with(pred_propagated(Label, Reason)), NowNeedFrameLabels,
Why is the commented out code with the XXXs there?
If you haven't already done so then I suggest bootstrapping it with
`--intermodule-optimization' enabled, otherwise that looks fine.
Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list