Files
mercury/compiler/proc_label.m
Zoltan Somogyi 599ef915d9 Instead of being relied on all over the place, centralize the compiler's
Estimated hours taken: 16
Branches: main

Instead of being relied on all over the place, centralize the compiler's
knowledge of the names of unify, compare and index predicates in one place,
special_pred.m. This should make it easy to change the naming scheme once
we switch over to compiler-generated type_ctor_infos for builtin types,
which will eliminate the runtime system's knowledge of the naming scheme.

compiler/hlds_pred.m:
	Add a field to pred_infos that says whether the predicate is a unify,
	compare or index predicate, and if so, for which type constructor.
	Code that used to test the predicate's name for __Unify__ etc now
	tests this field instead. Similarly the code that used to employ
	devious tricks to find out the type the unify/compare/index predicate
	is for.

compiler/rtti.m:
	Include this field in rtti_proc_labels as well as pred_infos.

compiler/make_hlds.m:
	Fill in this field as appropriate.

compiler/proc_label.m:
	Replace the predicate name with special_pred_id in the proc_labels
	of unify, index and compare preds.

compiler/special_pred.m:
	Narrow the interface to prevent reliance on the naming scheme
	for compiler-generated unify, compare and index predicates,
	except when absolutely necessary, i.e. when creating names for
	them.

	Narrow the mechanism required to reverse-engineer the type constructor
	a unify/compare/index predicate is for from the types to the
	functionality required by higher_order.m.

compiler/code_gen.m:
compiler/det_report.m:
compiler/higher_order.m:
compiler/intermod.m:
compiler/layout_out.m:
compiler/magic_util.m:
compiler/ml_code_util.m:
compiler/name_mangle.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/optimize.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/proc_label.m:
compiler/rl_exprn.m:
compiler/rl_key.m:
compiler/simplify.m:
compiler/termination.m:
compiler/typecheck.m:
compiler/unify_proc.m:
compiler/unused_args.m:
	Update code and comments to conform to the changes above.

compiler/hlds_out.m:
	Don't refer to the 'type' that a unify, compare or index predicate
	is for; refer to the type *constructor*.

compiler/mlds_to_java.m:
	Delete an unused predicate.

tests/invalid/purity/purity.err_exp:
	Update this expected output for the change in hlds_out.m.
2003-05-27 05:57:30 +00:00

164 lines
5.1 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 2003 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
% file: proc_label.m
% main author: zs
% This file defines backend-independent identifiers for procedures that a
% backend can use as the basis for the names of the labels or functions
% implementing those procedures. It also has functions for creating these
% identifiers.
%-----------------------------------------------------------------------------%
:- module backend_libs__proc_label.
:- interface.
:- import_module backend_libs__rtti.
:- import_module hlds__hlds_module.
:- import_module hlds__hlds_pred.
:- import_module hlds__special_pred.
:- import_module parse_tree__prog_data.
:- import_module bool.
% A proc_label is a data structure a backend can use to as the basis
% of the label used as the entry point of a procedure.
%
% The defining module is the module that provides the code for the
% predicate, the declaring module contains the `:- pred' declaration.
% When these are different, as for specialised versions of predicates
% from `.opt' files, the defining module's name may need to be added
% as a qualifier to the label.
:- type proc_label
---> proc(
module_name, % defining module
pred_or_func,
module_name, % declaring module
string, % name
int, % arity
proc_id % mode number
)
; special_proc(
module_name, % defining module
special_pred_id,% indirectly defines pred name
module_name, % type module
string, % type name
int, % type arity
proc_id % mode number
).
% Return the id of the procedure specified by the rtti_proc_label.
:- func make_proc_label_from_rtti(rtti_proc_label) = proc_label.
% Return the id of the specified procedure.
:- func make_proc_label(module_info, pred_id, proc_id) = proc_label.
% make_user_proc_label(ModuleName, PredIsImported,
% PredOrFunc, ModuleName, PredName, Arity, ProcId) = Label:
% Make a proc_label for a user-defined procedure.
%
% The PredIsImported argument should be the result of
% calling pred_info_is_imported.
:- func make_user_proc_label(module_name, bool, pred_or_func, module_name,
string, arity, proc_id) = proc_label.
% Return the id of the specified mode of the unification procedure
% for the given type.
:- func make_uni_label(module_info, type_ctor, proc_id) = proc_label.
:- implementation.
:- import_module backend_libs__rtti.
:- import_module check_hlds__type_util.
:- import_module hlds__special_pred.
:- import_module parse_tree__prog_util.
:- import_module string, list, std_util, require.
make_proc_label_from_rtti(RttiProcLabel) = ProcLabel :-
RttiProcLabel = rtti_proc_label(PredOrFunc, ThisModule,
PredModule, PredName, PredArity, _ArgTypes, _PredId, ProcId,
_ProcHeadVarsWithNames, _ArgModes, _CodeModel,
IsImported, _IsPseudoImported, _IsExported,
IsSpecialPredInstance),
( IsSpecialPredInstance = yes(SpecialPred - TypeCtor) ->
(
% All type_ctors other than tuples here should be
% module qualified, since builtin types are
% handled separately in polymorphism.m.
(
TypeCtor = unqualified(TypeName) - _,
type_ctor_is_tuple(TypeCtor),
mercury_public_builtin_module(TypeModule)
;
TypeCtor = qualified(TypeModule, TypeName) - _
)
->
TypeCtor = _ - TypeArity,
(
ThisModule \= TypeModule,
SpecialPred = unify,
\+ hlds_pred__in_in_unification_proc_id(ProcId)
->
DefiningModule = ThisModule
;
DefiningModule = TypeModule
),
ProcLabel = special_proc(DefiningModule, SpecialPred,
TypeModule, TypeName, TypeArity, ProcId)
;
string__append_list(["make_proc_label:\n",
"cannot make label for special pred `",
PredName, "'"], ErrorMessage),
error(ErrorMessage)
)
;
ProcLabel = make_user_proc_label(ThisModule, IsImported,
PredOrFunc, PredModule, PredName, PredArity, ProcId)
).
make_proc_label(ModuleInfo, PredId, ProcId) = ProcLabel :-
RttiProcLabel = rtti__make_rtti_proc_label(ModuleInfo, PredId, ProcId),
make_proc_label_from_rtti(RttiProcLabel) = ProcLabel.
make_user_proc_label(ThisModule, PredIsImported, PredOrFunc, PredModule,
PredName, PredArity, ProcId) = ProcLabel :-
(
% Work out which module supplies the code for
% the predicate.
ThisModule \= PredModule,
PredIsImported = no
->
% This predicate is a specialized version of
% a pred from a `.opt' file.
DefiningModule = ThisModule
;
DefiningModule = PredModule
),
ProcLabel = proc(DefiningModule, PredOrFunc,
PredModule, PredName, PredArity, ProcId).
make_uni_label(ModuleInfo, TypeCtor, UniModeNum) = ProcLabel :-
module_info_name(ModuleInfo, ModuleName),
( TypeCtor = qualified(TypeModule, TypeName) - Arity ->
( hlds_pred__in_in_unification_proc_id(UniModeNum) ->
Module = TypeModule
;
Module = ModuleName
),
ProcLabel = special_proc(Module, unify, TypeModule,
TypeName, Arity, UniModeNum)
;
error("make_uni_label: unqualified type_ctor")
).