[m-rev.] for review: [CTGC] generate optimised versions, reuse pragmas
Nancy
Nancy.Mazur at cs.kuleuven.ac.be
Wed Jun 7 19:08:00 AEST 2006
Julien Fischer wrote:
> On Tue, 6 Jun 2006, Nancy Mazur wrote:
>
>> Hi,
>>
>> for anybody to review....
>>
>> I've got one problem with the change below which also contains the mechanism
>> to output structure_reuse pragma's, as well as reading them back in. Each
>> structure reuse pragma is related to a procedure. It dictates the
>> conditions which a caller of this procedure needs to meet in order to
>> safely replace the original call by a call to the optimised version of that
>> procedure. This means that for each procedure, we create a separate (optimised)
>> version (if optimisations are possible of course) with a compiler-generated
>> name. This name is generated using the function:
>>
>> generate_reuse_name(module_info, pred_proc_id) = reuse_name.
>>
>> defined in structure_reuse.split,
>> which uses the predicate
>>
>> prog_util.make_pred_name_with_context/7
>>
>> The problem is that this generates a name with a whole bunch of "__", and of
>> course, once you print this name out, and read it back in, you get a sym_name
>> with the strangest set of qualifiers.
>
> Why (and where) do you need to print it out and read it back in? In the .opt
> or .trans_opt files? I would have thought that the presence of a reuse pragma
> in those files would be sufficient to indicate the presence of optimized
> versions of the procedures.
Yes, I was coming to exactly the same conclusion. I'll remove the reuse
name altogether from the pragma.
[...]
> I don't see why the reuse pragmas need to include the name of the optimised
> version at all. It ought to be enough to know what the name of the original
> procedure, what the reuse description was and that an optimised version
> exists. The importing module ought to be able to reconstruct the name of the
> optimised version given this information.
>
> (I think we do a similar thing with the specialized versions created by
> unused argument analysis (compiler/unused_args.m) - so you might want
> to have a look there.)
I'll have a look there.
>> Estimated hours taken: 15
>> Branches: main
>>
>> Create optimised versions for all the procedures in which possibilities for
>> structure reuse are detected.
>
> s/in which/for which/
>
> That's potentially going to be a rather large number of them.
I don't remember that that was really an issue in the benchmarks I've
done.. but this should be checked yes.
>> Put the mechanism in place to generate reuse
>> pragma's, and to parse them back in.
>
> s/pragma's/pragmas/
>
>
>
>> compiler/add_pragma.m:
>> compiler/make_hlds_passes.m:
>> compiler/mercury_to_mercury.m:
>> compiler/prog_ctgc.m:
>> compiler/prog_io_pragma.m:
>> compiler/structure_reuse.analysis.m:
>> compiler/trans_opt.m:
>> Add the mechanism to output and parse the structure_reuse pragma's.
>>
>
> s/pragma's/pragmas/
>
>> compiler/hlds_module.m:
>> Simplify the type structure_reuse_info.
>>
>> compiler/hlds_pred.m:
>> Add structure sharing information at the level of each individual
>> procedure. This information consists of a description of any reuse
>> conditions that have been derived for that procedure.
>>
>> compiler/prog_item.m:
>> compiler/prog_data.m:
>> Add types for the public representation of reuse conditions.
>> (remove the previous name "reuse_tuple", which simply does not sound
>> adequate).
>>
>> compiler/prog_type.m:
>> Add functions to remove all typeinfo-vars from a
>> given list (resp. set) of vars.
>>
>> compiler/structure_reuse.domain.m:
>> Conversion procedures between the public and private representation
>> for structure reuse conditions.
>>
>> compiler/structure_reuse.indirect.m:
>> Do not try to replace call information even when you know the
>> pred_proc_id of the reuse version of that call (which is the case for
>> imported procedures with reuse). It is more consistent
>> to do this at the same time when all the other conversions are done,
>> i.e. when generating the optimised versions of the procedures with
>> reuse (even with unconditional reuse).
>>
>> compiler/structure_reuse.lbu.m:
>> compiler/structure_reuse.lfu.m:
>> Make sure that no lbu/lfu information regarding typeinfo-vars is
>> recorded. These variables are irrelevant for the analysis. On the
>> contrary, keeping these variables may cause errors:
>> the generated (reuse) pragma's may end up containing these
>> typeinfo-vars, when reading these pragma's back in, it becomes
>> troublesome to match them with the corresponding predicate signatures,
>> as these signatures do not contain such typeinfo-headvars.
>>
>> compiler/structure_reuse.analysis.m:
>> compiler/structure_reuse.m:
>> compiler/structure_reuse.split.m:
>> Create optimised versions for the procedures for which
>> reuse was detected.
>> (structure_reuse.split.m = new file)
>>
>
> Why is it called split? (That doesn't immediately mean anything to me.)
I'll use your suggestion of structure_reuse.versions.
>> compiler/structure_sharing.analysis.m:
>> Add some documentation.
>>
>>
>>
>>
>> Index: compiler/add_pragma.m
>> ===================================================================
>> RCS file: /home/mercury1/repository/mercury/compiler/add_pragma.m,v
>> retrieving revision 1.33
>> diff -u -d -r1.33 add_pragma.m
>> --- compiler/add_pragma.m 5 Jun 2006 02:26:06 -0000 1.33
>> +++ compiler/add_pragma.m 6 Jun 2006 13:31:22 -0000
>> @@ -56,6 +56,11 @@
>> maybe(structure_sharing_domain)::in, prog_context::in,
>> module_info::in, module_info::out, io::di, io::uo) is det.
>>
>> +:- pred add_pragma_structure_reuse(pred_or_func::in, sym_name::in,
>> + list(mer_mode)::in, list(prog_var)::in, list(mer_type)::in,
>> + maybe(structure_reuse_domain)::in, maybe(sym_name)::in, prog_context::in,
>> + module_info::in, module_info::out, io::di, io::uo) is det.
>> +
>> % module_add_pragma_import:
>> %
>> % Handles `pragma import' declarations, by figuring out which predicate
>> @@ -1227,6 +1232,99 @@
>> % module_info_incr_errors(!ModuleInfo)
>> ).
>>
>> +add_pragma_structure_reuse(_PredOrFunc, _SymName, _ModeList, _HeadVars,
>> + _Types, no, _MaybeReusePredName, _Context, !ModuleInfo, !IO).
>> +add_pragma_structure_reuse(PredOrFunc, SymName, ModeList, HeadVars,
>> + Types, yes(ReuseDomain), MaybeReusePredName,
>> + Context, !ModuleInfo, !IO):-
>> + module_info_get_predicate_table(!.ModuleInfo, Preds),
>> + list.length(ModeList, Arity),
>> + (
>> + predicate_table_search_pf_sym_arity(Preds, is_fully_qualified,
>> + PredOrFunc, SymName, Arity, PredIds),
>> + PredIds = [_ | _]
>> + ->
>> + ( PredIds = [PredId] ->
>> + module_info_preds(!.ModuleInfo, PredTable0),
>> + map.lookup(PredTable0, PredId, PredInfo0),
>> + pred_info_get_procedures(PredInfo0, ProcTable0),
>> + map.to_assoc_list(ProcTable0, ProcList),
>> + (
>> + get_procedure_matching_declmodes(ProcList, ModeList,
>> + !.ModuleInfo, ProcId)
>> + ->
>> + map.lookup(ProcTable0, ProcId, ProcInfo0),
>> +
>> + % Rename headvars/types to those used in the proc_info.
>> + proc_info_get_headvars(ProcInfo0, ProcHeadVars),
>> +
>> + % As the HeadVars recorded in the pragma may contain additional
>> + % vars (e.g. typeinfos), and in the same time ProcHeadVars does
>> + % not, make sure to remove all TypeInfo-vars from HeadVars,
>> + % the same for the list Types.
>> + Diff = list.length(HeadVars) - list.length(ProcHeadVars),
>> + (
>> + list.drop(Diff, HeadVars, RemHeadVars0),
>> + list.drop(Diff, Types, RemTypes0)
>> + ->
>> + RemHeadVars = RemHeadVars0,
>> + RemTypes = RemTypes0
>> + ;
>> + unexpected(this_file, "Impossible situation.")
>> + ),
>
> In my experience this sort of things tends to be highly breakable. The
> approach I took with the with termination2_info pragmas was to delay
> further processing of the pragam until after the polymorphism pass has
> been run (in fact until the beginning of the termination 2 pass - see
> term_constr_initial.preprocess_module/4).
>
> I think that kind of approach would also be better here, i.e. delay
> further processing of the structure_reuse pragmas until the information
> in them is actually needed.
I'll have a look at how it is done with termination2_info pragmas... On
the reuse branch we also took the approach of delaying the processing,
yet that involved some other ugly bits...
I'll have a look.
>> list.foldl(term_constr_main.output_pred_termination2_info(Module),
>> PredIds, !IO),
>>
>> + % XXX I have a strong feeling that also writing termination info and
>> + % exception information should be limited to those pred_ids that do not
>> + % correspond to compiler generated reuse versions of other predicates.
>> + %
>
> Yes, you should exclude the reuse versions. (Since reuse should not affect
> the termination/exception properties of a procedure, if we want to know
> what they are we should just look up the information for the original
> version.)
Ok!
Nancy
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
--------------------------------------------------------------------------
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