[m-dev.] for review: compiler-generated procedures
Zoltan Somogyi
zs at cs.mu.OZ.AU
Thu Sep 30 15:45:11 AEST 1999
By Fergus.
The code we were creating for the comparison procedure of an enumerated type
called mercury__compare_3_3, which called the comparison procedure of the
enumerated type (whose address was in the compare slot of the type_ctor_info).
This was an infinite loop. I think it only used to work because higher-order
specialization specialized the call to mercury__compare_3_3, but specialization
is turned off for debugging.
compiler/unify_proc.m:
Fix the generation of the compare procedures for enumerated types;
instead of calling mercury__compare_3_3, we cast the args to ints
and call builtin_compare_int.
At the same time, make the code that creates the special procedure
bodies more robust by explicitly checking for invalid kinds of types.
Zoltan.
cvs diff: Diffing .
Index: unify_proc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unify_proc.m,v
retrieving revision 1.78
diff -u -b -r1.78 unify_proc.m
--- unify_proc.m 1999/09/30 01:48:38 1.78
+++ unify_proc.m 1999/09/30 07:41:10
@@ -502,7 +502,8 @@
is det.
unify_proc__generate_unify_clauses(TypeBody, H1, H2, Context, Clauses) -->
- ( { TypeBody = du_type(Ctors, _, IsEnum, MaybeEqPred), IsEnum = no } ->
+ (
+ { TypeBody = du_type(Ctors, _, IsEnum, MaybeEqPred) },
( { MaybeEqPred = yes(PredName) } ->
%
% Just generate a call to the specified predicate,
@@ -521,15 +522,31 @@
{ Goal = Call - GoalInfo },
unify_proc__quantify_clause_body([H1, H2], Goal,
Context, Clauses)
- ;
- unify_proc__generate_du_unify_clauses(Ctors, H1, H2,
+ ; { IsEnum = yes } ->
+ { create_atomic_unification(H1, var(H2), Context,
+ explicit, [], Goal) },
+ unify_proc__quantify_clause_body([H1, H2], Goal,
Context, Clauses)
+ ;
+ unify_proc__generate_du_unify_clauses(Ctors,
+ H1, H2, Context, Clauses)
)
+
;
+ { TypeBody = eqv_type(_Type) },
+ % We should check whether _Type is abstract or not.
+ % If it is, we should call its unification procedure;
+ % if it is not, we should generate its body inline here.
{ create_atomic_unification(H1, var(H2), Context, explicit, [],
Goal) },
unify_proc__quantify_clause_body([H1, H2], Goal, Context,
Clauses)
+ ;
+ { TypeBody = uu_type(_) },
+ { error("trying to create unify proc for uu type") }
+ ;
+ { TypeBody = abstract_type },
+ { error("trying to create unify proc for abstract type") }
).
:- pred unify_proc__generate_index_clauses(hlds_type_body, prog_var, prog_var,
@@ -538,7 +555,8 @@
is det.
unify_proc__generate_index_clauses(TypeBody, X, Index, Context, Clauses) -->
- ( { TypeBody = du_type(Ctors, _, IsEnum, MaybeEqPred), IsEnum = no } ->
+ (
+ { TypeBody = du_type(Ctors, _, IsEnum, MaybeEqPred) },
( { MaybeEqPred = yes(_) } ->
%
% For non-canonical types, we just give up and
@@ -551,15 +569,30 @@
ArgVars, Context, Goal),
unify_proc__quantify_clause_body(ArgVars, Goal,
Context, Clauses)
+ ; { IsEnum = yes } ->
+ { ArgVars = [X, Index] },
+ unify_proc__build_call(
+ "index", ArgVars, Context, Goal),
+ unify_proc__quantify_clause_body(ArgVars, Goal,
+ Context, Clauses)
;
unify_proc__generate_du_index_clauses(Ctors, X, Index,
Context, 0, Clauses)
)
;
+ { TypeBody = eqv_type(_Type) },
+ % XXX zs: I believe this code works only by accident.
+ % XXX the point for unify also applies here
{ ArgVars = [X, Index] },
unify_proc__build_call("index", ArgVars, Context, Goal),
unify_proc__quantify_clause_body(ArgVars, Goal, Context,
Clauses)
+ ;
+ { TypeBody = uu_type(_) },
+ { error("trying to create index proc for uu type") }
+ ;
+ { TypeBody = abstract_type },
+ { error("trying to create index proc for abstract type") }
).
:- pred unify_proc__generate_compare_clauses(hlds_type_body, prog_var, prog_var,
@@ -570,7 +603,8 @@
unify_proc__generate_compare_clauses(TypeBody, Res, H1, H2, Context, Clauses)
-->
- ( { TypeBody = du_type(Ctors, _, IsEnum, MaybeEqPred), IsEnum = no } ->
+ (
+ { TypeBody = du_type(Ctors, _, IsEnum, MaybeEqPred) },
( { MaybeEqPred = yes(_) } ->
%
% just generate code that will call error/1
@@ -581,15 +615,47 @@
ArgVars, Context, Goal),
unify_proc__quantify_clause_body(ArgVars, Goal,
Context, Clauses)
+ ; { IsEnum = yes } ->
+ { construct_type(unqualified("int") - 0, [],
+ IntType) },
+ unify_proc__info_new_var(IntType, TC1),
+ unify_proc__info_new_var(IntType, TC2),
+ { TC1ArgVars = [H1, TC1] },
+ unify_proc__build_call(
+ "unsafe_type_cast",
+ TC1ArgVars, Context, TC1Goal),
+ { TC2ArgVars = [H2, TC2] },
+ unify_proc__build_call(
+ "unsafe_type_cast",
+ TC2ArgVars, Context, TC2Goal),
+ { CompareArgVars = [Res, TC1, TC2] },
+ unify_proc__build_call(
+ "builtin_compare_int",
+ CompareArgVars, Context, CompareGoal),
+ { goal_info_init(GoalInfo0) },
+ { goal_info_set_context(GoalInfo0, Context,
+ GoalInfo) },
+ { conj_list_to_goal([TC1Goal, TC2Goal, CompareGoal],
+ GoalInfo, Goal) },
+ { ArgVars = [Res, H1, H2] },
+ unify_proc__quantify_clause_body(ArgVars, Goal,
+ Context, Clauses)
;
unify_proc__generate_du_compare_clauses(Ctors,
Res, H1, H2, Context, Clauses)
)
;
+ { TypeBody = eqv_type(_) },
{ ArgVars = [Res, H1, H2] },
unify_proc__build_call("compare", ArgVars, Context, Goal),
unify_proc__quantify_clause_body(ArgVars, Goal, Context,
Clauses)
+ ;
+ { TypeBody = uu_type(_) },
+ { error("trying to create compare proc for uu type") }
+ ;
+ { TypeBody = abstract_type },
+ { error("trying to create compare proc for abstract type") }
).
:- pred unify_proc__quantify_clause_body(list(prog_var), hlds_goal,
cvs diff: Diffing notes
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list