[m-dev.] for review: direct reuse

Peter Ross Peter.Ross at cs.kuleuven.ac.be
Wed Sep 20 22:32:45 AEDT 2000


I buggered up and checked this diff in when I was checking in my change to
move structure reuse analysis to the end of mercury_compile.

However here is the code for doing direct structure reuse in the MLDS
back end.  This code is not safe to use. For example a call to
list__append(X, X, TwoX) does the wrong thing.  I am just posting the
in case I am going down the wrong path for doing this.


Index: sr_reuse_run.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Attic/sr_reuse_run.m,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- sr_reuse_run.m	2000/09/19 10:02:13	1.1.2.1
+++ sr_reuse_run.m	2000/09/20 11:16:51	1.1.2.2
@@ -41,7 +41,7 @@
 
 % library modules
 :- import_module require.
-:- import_module set, list, map, int.
+:- import_module bool, set, list, map, int.
 :- import_module std_util, string.
 
 % compiler modules
@@ -286,16 +286,30 @@
 		
 	; 
 		% 5. unification
-		Expr0 = unify( _, _, _, Unification, _ )
+		Expr0 = unify(Var, Rhs, Mode, Unification0, Context)
 	->
-		unification_verify_reuse( Unification, Alias0, 
-						Reuses0, Reuses, 
-						Info0, Info ),
-		pa_alias_as__extend_unification( ProcInfo, HLDS, 
-					Unification, Info, 
-					Alias0, Alias),	
+		unification_verify_reuse(Unification0, Alias0, 
+				Reuses0, Reuses, Info0, Info),
+		pa_alias_as__extend_unification(ProcInfo, HLDS, 
+				Unification, Info, Alias0, Alias),	
+
+		goal_info_get_reuse(Info, GoalInfoReuse),
+		(
+			Unification0 = construct(Var, ConsId, Vars,
+					Modes, _, IsUnique, Aditi),
+			GoalInfoReuse = cell_reused(ReuseVar)
+		->
+			CorrectVals = list__duplicate(list__length(Vars), no),
+			Cell = cell_to_reuse(ReuseVar, ConsId, CorrectVals),
+			HowToConstruct = reuse_cell(Cell),
+			Unification = construct(Var, ConsId, Vars,
+					Modes, HowToConstruct, IsUnique, Aditi)
+		;
+			Unification = Unification0
+		),
+			
 		FP = FP0,
-		Expr = Expr0
+		Expr = unify(Var, Rhs, Mode, Unification, Context)
 
 	;
 		% 6. disjunction	
Index: ml_unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.16
retrieving revision 1.16.2.1
diff -u -r1.16 -r1.16.2.1
--- ml_unify_gen.m	2000/09/06 05:20:58	1.16
+++ ml_unify_gen.m	2000/09/20 11:16:50	1.16.2.1
@@ -132,11 +132,6 @@
 	;
 		true
 	},
-	{ HowToConstruct = reuse_cell(_) ->
-		sorry("cell reuse")
-	;
-		true
-	},
 	ml_gen_construct(Var, ConsId, Args, ArgModes, HowToConstruct, Context,
 		MLDS_Decls, MLDS_Statements).
 ml_gen_unification(deconstruct(Var, ConsId, Args, ArgModes, CanFail),
@@ -984,8 +979,33 @@
 		{ MLDS_Decls = list__append(BoxConstDefns, [ConstDefn]) },
 		{ MLDS_Statements = [AssignStatement] }
 	;
-		{ HowToConstruct = reuse_cell(_) },
-		{ sorry("cell reuse") }
+		{ HowToConstruct = reuse_cell(CellToReuse) },
+		{ CellToReuse = cell_to_reuse(ReuseVar, ConsId, _CorrectVals) },
+
+		%
+		% Currently structure reuse will only reuse a cell that
+		% is using the same cons_id, so it is safe to just do an
+		% assignment.
+		%
+		ml_gen_unification(assign(Var, ReuseVar), model_det, Context,
+				MLDS_Decls, MLDS_StatementsA),
+
+		%
+		% For each field in the construction unification we need
+		% to generate an rval.
+		% XXX we do more work then we need to here, as some of
+		% the cells may already contain the correct values.
+		%
+		ml_cons_id_to_tag(ConsId, Type, ConsIdTag),
+		ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
+		{ ml_tag_offset_and_argnum(ConsIdTag,
+				PrimaryTag, OffSet, ArgNum) },
+
+		ml_gen_unify_args(ConsId, ArgVars, ArgModes, ArgTypes,
+				Fields, Type, VarLval, OffSet,
+				ArgNum, PrimaryTag, Context, MLDS_StatementsB),
+
+		{ MLDS_Statements = MLDS_StatementsA `append` MLDS_StatementsB }
 	).
 
 :- pred ml_gen_box_const_rval_list(list(mlds__type), list(mlds__rval),
@@ -1230,19 +1250,75 @@
 		ml_gen_var(Var, VarLval),
 		ml_variable_types(Args, ArgTypes),
 		ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
+		{ ml_tag_offset_and_argnum(Tag, _, OffSet, ArgNum) },
 		ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields, Type,
-			VarLval, 0, 1, UnsharedTag, Context, MLDS_Statements)
+				VarLval, OffSet, ArgNum,
+				UnsharedTag, Context, MLDS_Statements)
 	;
 		{ Tag = shared_remote_tag(PrimaryTag, _SecondaryTag) },
 		ml_gen_var(Var, VarLval),
 		ml_variable_types(Args, ArgTypes),
 		ml_field_names_and_types(Type, ConsId, ArgTypes, Fields),
+		{ ml_tag_offset_and_argnum(Tag, _, OffSet, ArgNum) },
 		ml_gen_unify_args(ConsId, Args, Modes, ArgTypes, Fields, Type,
-			VarLval, 1, 1, PrimaryTag, Context, MLDS_Statements)
+				VarLval, OffSet, ArgNum,
+				PrimaryTag, Context, MLDS_Statements)
 	;
 		{ Tag = shared_local_tag(_Bits1, _Num1) },
 		{ MLDS_Statements = [] } % if this is det, then nothing happens
 	).
+
+	% Calculate the integer offset used to reference the first field
+	% of a structure for lowlevel data or the first argument number
+	% to access the field using the highlevel data representation.
+	% Abort if the tag indicates that the data doesn't have any
+	% fields.
+:- pred ml_tag_offset_and_argnum(cons_tag::in, tag_bits::out,
+		int::out, int::out) is det.
+
+ml_tag_offset_and_argnum(Tag, TagBits, OffSet, ArgNum) :-
+	(
+		Tag = unshared_tag(UnsharedTag),
+		TagBits = UnsharedTag,
+		OffSet = 0,
+		ArgNum = 1
+	;
+		Tag = shared_remote_tag(PrimaryTag, _SecondaryTag),
+		TagBits = PrimaryTag,
+		OffSet = 1,
+		ArgNum = 1
+	;
+		Tag = string_constant(_String),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = int_constant(_Int),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = float_constant(_Float),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = pred_closure_tag(_, _, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = code_addr_constant(_, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = type_ctor_info_constant(_, _, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = base_typeclass_info_constant(_, _, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = tabling_pointer_constant(_, _),
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = no_tag,
+		error("ml_tag_offset_and_argnum")
+	;
+		Tag = shared_local_tag(_Bits1, _Num1),
+		error("ml_tag_offset_and_argnum")
+	).
+
 
 	% Given a type and a cons_id, and also the types of the actual
 	% arguments of that cons_id in some particular use of it,
--------------------------------------------------------------------------
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