[m-rev.] diff: minor jumpopt-related cleanups

Zoltan Somogyi zs at cs.mu.OZ.AU
Thu Jun 16 13:48:37 AEST 2005


Minor cleanups I did while browsing files related to the bug in jumpopt.

compiler/dupelim.m:
	Factor out some common code dealing with pragma_c instructions.
	Reorder arguments to allow the use of state variable notation.
	Use switches in preference to if-then-elses if possible.

compiler/labelopt.m:
	Convert comments to our preferred format.
	Use switches in preference to if-then-elses if possible.

compiler/opt_util.m:
	Convert comments to our preferred format.
	Factor out some common code.
	Use switches in preference to if-then-elses if possible.
	Use state variable notation where appropriate.

Zoltan.

cvs diff: Diffing .
Index: dupelim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.63
diff -u -b -r1.63 dupelim.m
--- dupelim.m	24 Mar 2005 02:00:24 -0000	1.63
+++ dupelim.m	14 Jun 2005 02:10:11 -0000
@@ -65,6 +65,7 @@
 :- import_module require.
 :- import_module set.
 :- import_module std_util.
+:- import_module svset.
 
 	% A std_map maps a list of standardized instructions to the list
 	% of labels whose basic blocks have that standardized form.
@@ -86,11 +87,13 @@
 		Fixed0, Fixed),
 	map__values(StdMap, StdList),
 	find_clusters(StdList, Fixed, [], Clusters),
-	( Clusters = [] ->
+	(
+		Clusters = [],
 			% We don't want to introduce any incidental changes
 			% if we cannot eliminate any blocks.
 		Instrs = Instrs0
 	;
+		Clusters = [_ | _],
 		map__init(ReplMap0),
 		process_clusters(Clusters, LabelSeq0, LabelSeq,
 			BlockMap0, BlockMap, ReplMap0, ReplMap),
@@ -120,41 +123,45 @@
 	;
 		map__det_insert(!.StdMap, StdInstrs, [Label], !:StdMap)
 	),
-	( MaybeFallThrough = yes(FallIntoLabel) ->
+	(
+		MaybeFallThrough = yes(FallIntoLabel),
 		set__insert(!.Fixed, FallIntoLabel, !:Fixed)
 	;
-		true
+		MaybeFallThrough = no
 	),
-	AddPragmaReferredLabels =
-		(pred(Instr::in, FoldFixed0::in, FoldFixed::out) is det :-
+	list__foldl(add_pragma_pref_labels, Instrs, !Fixed),
+	dupelim__build_maps(Labels, BlockMap, !StdMap, !Fixed).
+
+
+:- pred add_pragma_pref_labels(instruction::in,
+	set(label)::in, set(label)::out) is det.
+
+add_pragma_pref_labels(Instr, !FoldFixed) :-
 		(
-			Instr = pragma_c(_, _, _,
-				MaybeFixedLabel, MaybeLayoutLabel,
+		Instr = pragma_c(_, _, _, MaybeFixedLabel, MaybeLayoutLabel,
 				MaybeOnlyLayoutLabel, _, _, _) - _
 		->
-			( MaybeFixedLabel = yes(FixedLabel) ->
-				set__insert(FoldFixed0, FixedLabel, FoldFixed1)
+		(
+			MaybeFixedLabel = yes(FixedLabel),
+			svset__insert(FixedLabel, !FoldFixed)
 			;
-				FoldFixed1 = FoldFixed0
+			MaybeFixedLabel = no
 			),
-			( MaybeLayoutLabel = yes(LayoutLabel) ->
-				set__insert(FoldFixed1, LayoutLabel,
-					FoldFixed2)
+		(
+			MaybeLayoutLabel = yes(LayoutLabel),
+			svset__insert(LayoutLabel, !FoldFixed)
 			;
-				FoldFixed2 = FoldFixed1
+			MaybeLayoutLabel = no
 			),
-			( MaybeOnlyLayoutLabel = yes(OnlyLayoutLabel) ->
-				set__insert(FoldFixed2, OnlyLayoutLabel,
-					FoldFixed)
+		(
+			MaybeOnlyLayoutLabel = yes(OnlyLayoutLabel),
+			svset__insert(OnlyLayoutLabel, !FoldFixed)
 			;
-				FoldFixed = FoldFixed2
+			MaybeOnlyLayoutLabel = no
 			)
 		;
-			FoldFixed = FoldFixed0
-		)
-	),
-	list__foldl(AddPragmaReferredLabels, Instrs, !Fixed),
-	dupelim__build_maps(Labels, BlockMap, !StdMap, !Fixed).
+		true
+	).
 
 % For each set of labels that start basic blocks with identical standard forms,
 % find_clusters finds out whether we can eliminate some of those blocks;
@@ -186,9 +193,11 @@
 			FixedLabels, NonFixedLabels),
 		NonFixedLabels = [FirstNonFixed | OtherNonFixed]
 	->
-		( FixedLabels = [ChosenLabel | _] ->
+		(
+			FixedLabels = [ChosenLabel | _],
 			Cluster = cluster(ChosenLabel, NonFixedLabels)
 		;
+			FixedLabels = [],
 			Cluster = cluster(FirstNonFixed, OtherNonFixed)
 		),
 		!:Clusters = [Cluster | !.Clusters]
@@ -216,9 +225,9 @@
 	ExemplarInfo0 = block_info(ExLabel, ExLabelInstr, ExInstrs0,
 		ExSideLabels, ExMaybeFallThrough),
 	require(unify(Exemplar, ExLabel), "exemplar label mismatch"),
-	process_elim_labels(ElimLabels, ExInstrs0, ExMaybeFallThrough,
-		!LabelSeq, !.BlockMap, Exemplar, !ReplMap,
-		UnifiedInstrs, UnifiedMaybeFallThrough),
+	process_elim_labels(ElimLabels, ExInstrs0, !LabelSeq, !.BlockMap,
+		Exemplar, !ReplMap, UnifiedInstrs,
+		ExMaybeFallThrough, UnifiedMaybeFallThrough),
 	ExemplarInfo = block_info(ExLabel, ExLabelInstr, UnifiedInstrs,
 		ExSideLabels, UnifiedMaybeFallThrough),
 	map__det_update(!.BlockMap, Exemplar, ExemplarInfo, !:BlockMap),
@@ -235,29 +244,27 @@
 % that will need to be done.
 
 :- pred process_elim_labels(list(label)::in, list(instruction)::in,
-	maybe(label)::in, list(label)::in, list(label)::out, block_map::in,
+	list(label)::in, list(label)::out, block_map::in,
 	label::in, map(label, label)::in, map(label, label)::out,
-	list(instruction)::out, maybe(label)::out) is det.
+	list(instruction)::out, maybe(label)::in, maybe(label)::out) is det.
 
-process_elim_labels([], Instrs, MaybeFT, !LabelSeq, _,
-		_, !ReplMap, Instrs, MaybeFT).
-process_elim_labels([ElimLabel | ElimLabels], Instrs0, MaybeFallThrough0,
-		!LabelSeq, BlockMap, Exemplar, !ReplMap, Instrs,
-		MaybeFallThrough) :-
+process_elim_labels([], Instrs, !LabelSeq, _, _, !ReplMap, Instrs,
+		!MaybeFallThrough).
+process_elim_labels([ElimLabel | ElimLabels], Instrs0, !LabelSeq, BlockMap,
+		Exemplar, !ReplMap, Instrs, !MaybeFallThrough) :-
 	map__lookup(BlockMap, ElimLabel, ElimLabelInfo),
 	ElimLabelInfo = block_info(ElimLabel2, _, ElimInstrs,
 		_, ElimMaybeFallThrough),
 	require(unify(ElimLabel, ElimLabel2), "elim label mismatch"),
 	(
-		most_specific_block(Instrs0, MaybeFallThrough0,
+		most_specific_block(Instrs0, !.MaybeFallThrough,
 			ElimInstrs, ElimMaybeFallThrough,
-			Instrs1, MaybeFallThrough1)
+			Instrs1, !:MaybeFallThrough)
 	->
 		list__delete_all(!.LabelSeq, ElimLabel, !:LabelSeq),
 		map__det_insert(!.ReplMap, ElimLabel, Exemplar, !:ReplMap),
-		process_elim_labels(ElimLabels, Instrs1, MaybeFallThrough1,
-			!LabelSeq, BlockMap, Exemplar, !ReplMap, Instrs,
-			MaybeFallThrough)
+		process_elim_labels(ElimLabels, Instrs1, !LabelSeq, BlockMap,
+			Exemplar, !ReplMap, Instrs, !MaybeFallThrough)
 	;
 		error("blocks with same standard form don't antiunify")
 	).
Index: labelopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/labelopt.m,v
retrieving revision 1.24
diff -u -b -r1.24 labelopt.m
--- labelopt.m	22 Mar 2005 06:40:02 -0000	1.24
+++ labelopt.m	14 Jun 2005 05:30:34 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1994-1999, 2003-2005 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.
@@ -24,14 +26,14 @@
 	% then traverse the instruction list removing unnecessary labels.
 	% If the instruction before the label branches away, we also
 	% remove the instruction block following the label.
-
+    %
 :- pred labelopt_main(bool::in, set(label)::in,
 	list(instruction)::in, list(instruction)::out, bool::out) is det.
 
 	% Build up a set showing which labels are referred to.
 	% The input set is the list of labels referred to from outside
 	% the given list of instructions.
-
+    %
 :- pred labelopt__build_useset(list(instruction)::in, set(label)::in,
 	set(label)::out) is det.
 
@@ -68,7 +70,7 @@
 	% the procedure or from the outside. If yes, we leave it alone.
 	% If not, we delete it. We delete the following code as well if
 	% the label was preceded by code that cannot fall through.
-
+    %
 :- pred labelopt__instr_list(list(instruction)::in, bool::in, set(label)::in,
 	list(instruction)::out, bool::out) is det.
 
@@ -91,26 +93,28 @@
 			Fallthrough1 = yes,
 			Mod0 = no
 		;
-			labelopt__eliminate(Instr0, yes(Fallthrough),
-				ReplInstrs, Mod0),
+            labelopt__eliminate(Instr0, yes(Fallthrough), ReplInstrs, Mod0),
 			Fallthrough1 = Fallthrough
 		)
 	;
-		( Fallthrough = yes ->
+        (
+            Fallthrough = yes,
 			ReplInstrs = [Instr0],
 			Mod0 = no
 		;
+            Fallthrough = no,
 			labelopt__eliminate(Instr0, no, ReplInstrs, Mod0)
 		),
 		opt_util__can_instr_fall_through(Uinstr0, Canfallthrough),
-		( Canfallthrough = yes ->
+        (
+            Canfallthrough = yes,
 			Fallthrough1 = Fallthrough
 		;
+            Canfallthrough = no,
 			Fallthrough1 = no
 		)
 	),
-	labelopt__instr_list(MoreInstrs0, Fallthrough1, Useset,
-		MoreInstrs1, Mod1),
+    labelopt__instr_list(MoreInstrs0, Fallthrough1, Useset, MoreInstrs1, Mod1),
 	list__append(ReplInstrs, MoreInstrs1, MoreInstrs),
 	( Mod0 = no, Mod1 = no ->
 		Mod = no
@@ -122,7 +126,7 @@
 	% we can replace them by placeholder comments. The original comment
 	% field on the instruction is often enough to deduce what the
 	% eliminated instruction was.
-
+    %
 :- pred labelopt__eliminate(instruction::in, maybe(bool)::in,
 	list(instruction)::out, bool::out) is det.
 
@@ -139,15 +143,17 @@
 			Uinstr = Uinstr0,
 			Mod = no
 		;
-			( Label = yes(Follow) ->
-				( Follow = yes ->
+            (
+                Label = yes(Follow),
+                (
+                    Follow = yes,
 					Uinstr = comment("eliminated label only")
 				;
-					% Follow = no,
+                    Follow = no,
 					Uinstr = comment("eliminated label and block")
 				)
 			;
-				% Label = no,
+                Label = no,
 				Uinstr = comment("eliminated instruction")
 			),
 			Comment = Comment0,
Index: opt_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.129
diff -u -b -r1.129 opt_util.m
--- opt_util.m	22 Mar 2005 06:40:15 -0000	1.129
+++ opt_util.m	14 Jun 2005 05:58:20 -0000
@@ -4,7 +4,7 @@
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
 
-% Utilities for LLDS to LLDS peephole optimization.
+% Utilities for LLDS to LLDS optimization.
 
 % Main author: zs.
 
@@ -49,7 +49,7 @@
 	% Find the next assignment to the redoip of the frame whose address
 	% is given by the base addresses in the second argument, provided
 	% it is guaranteed to be reached from here.
-
+	%
 :- pred next_assign_to_redoip(list(instruction)::in, list(lval)::in,
 	list(instruction)::in, code_addr::out, list(instruction)::out,
 	list(instruction)::out) is semidet.
@@ -57,28 +57,28 @@
 	% See if these instructions touch nondet stack controls, i.e.
 	% the virtual machine registers that point to the nondet stack
 	% (curfr and maxfr) and the fixed slots in nondet stack frames.
-
+	%
 :- pred touches_nondet_ctrl(list(instruction)::in, bool::out) is det.
 
 	% Find the instructions up to and including
 	% the next one that cannot fall through
-
+	%
 :- pred find_no_fallthrough(list(instruction)::in,
 	list(instruction)::out) is det.
 
 	% Find the first label in the instruction stream.
-
+	%
 :- pred find_first_label(list(instruction)::in, label::out) is det.
 
 	% Skip to the next label, returning the code before the label,
 	% and the label together with the code after the label.
-
+	%
 :- pred skip_to_next_label(list(instruction)::in,
 	list(instruction)::out, list(instruction)::out) is det.
 
 	% Check whether the named label follows without any intervening code.
 	% If yes, return the instructions after the label.
-
+	%
 :- pred is_this_label_next(label::in, list(instruction)::in,
 	list(instruction)::out) is semidet.
 
@@ -86,7 +86,7 @@
  	% next in the instruction list, possibly preceded by a restoration
  	% of succip and a det stack frame removal? If yes, return the
  	% instructions up to the proceed.
-
+	%
 :- pred is_proceed_next(list(instruction)::in,
 	list(instruction)::out) is semidet.
 
@@ -94,20 +94,20 @@
  	% next in the instruction list, possibly preceded by an assignment
 	% to r1, a restoration of succip and a det stack frame removal?
 	% If yes, return the instructions up to the proceed.
-
+	%
 :- pred is_sdproceed_next(list(instruction)::in,
 	list(instruction)::out) is semidet.
 
 	% Same as the previous predicate, but also return whether it is
 	% a success or a fail.
-
+	%
 :- pred is_sdproceed_next_sf(list(instruction)::in,
 	list(instruction)::out, bool::out) is semidet.
 
  	% Is a succeed instruction (i.e. a goto(do_succeed(_)) instruction)
  	% next in the instruction list? If yes, return the instructions
 	% up to and including the succeed.
-
+	%
 :- pred is_succeed_next(list(instruction)::in,
 	list(instruction)::out) is semidet.
 
@@ -117,13 +117,13 @@
 	% assigned to r1 in the success continuation and MR_FALSE in the failure
 	% continuation? If the answer is yes to all these questions, return
 	% the code shared by the two continuations.
-
+	%
 :- pred is_forkproceed_next(list(instruction)::in, tailmap::in,
 	list(instruction)::out) is semidet.
 
 	% Remove the assignment to r1 from the list returned by
 	% is_sdproceed_next.
-
+	%
 :- pred filter_out_r1(list(instruction)::in, maybe(rval_const)::out,
 	list(instruction)::out) is det.
 
@@ -132,78 +132,78 @@
 	% if_val(..., dofail), and then a succeed?
 	% If yes, then return all the instructions up to the succeed,
 	% and all the following instructions.
-
+	%
 :- pred straight_alternative(list(instruction)::in,
 	list(instruction)::out, list(instruction)::out) is semidet.
 
 	% Find and return the initial sequence of instructions that do not
 	% refer to stackvars and do not branch.
-
+	%
 :- pred no_stack_straight_line(list(instruction)::in,
 	list(instruction)::out, list(instruction)::out) is det.
 
 	% Remove the labels from a block of code for jumpopt.
-
-:- pred filter_out_labels(list(instruction)::in,
-	list(instruction)::out) is det.
+	%
+:- pred filter_out_labels(list(instruction)::in, list(instruction)::out)
+	is det.
 
 	% Remove any livevals instructions that do not precede an instruction
 	% that needs one.
-
-:- pred filter_out_bad_livevals(list(instruction)::in,
-	list(instruction)::out) is det.
+	%
+:- pred filter_out_bad_livevals(list(instruction)::in, list(instruction)::out)
+	is det.
 
 	% Remove the livevals instruction from the list returned by
 	% is_proceed_next.
-
-:- pred filter_out_livevals(list(instruction)::in,
-	list(instruction)::out) is det.
+	%
+:- pred filter_out_livevals(list(instruction)::in, list(instruction)::out)
+	is det.
 
 	% Get just the livevals instructions from a list of instructions.
-
+	%
 :- pred filter_in_livevals(list(instruction)::in,
 	list(instruction)::out) is det.
 
 	% See if the condition of an if-then-else is constant,
 	% and if yes, whether the branch will be taken or not.
-
+	%
 :- pred is_const_condition(rval::in, bool::out) is semidet.
 
 	% Check whether an instruction can possibly branch away.
-
+	%
 :- pred can_instr_branch_away(instr::in, bool::out) is det.
 
 	% Check whether an instruction can possibly fall through
 	% to the next instruction without using its label.
-
+	%
 :- pred can_instr_fall_through(instr::in, bool::out) is det.
 
 	% Check whether a code_addr, when the target of a goto, represents
 	% either a call or a proceed/succeed; if so, it is the end of an
 	% extended basic block and needs a livevals in front of it.
-
+	%
 :- pred livevals_addr(code_addr::in, bool::out) is det.
 
 	% Determine all the labels and code addresses which are referenced
 	% by an instruction. The code addresses that are labels are returned
 	% in both output arguments.
-
+	%
 :- pred instr_labels(instr::in, list(label)::out, list(code_addr)::out) is det.
 
 	% Determine all the labels and code addresses which are referenced
 	% by a list of instructions.
-
+	%
 :- pred instr_list_labels(list(instruction)::in,
 	list(label)::out, list(code_addr)::out) is det.
 
 	% Given an instruction, find the set of labels to which it can cause
 	% control to transfer. In the case of calls, this includes transfer
 	% via return from the called procedure.
-
+	%
 :- pred possible_targets(instr::in, list(label)::out) is det.
 
 	% Find the maximum temp variable number used.
-
+	%
 :- pred count_temps_instr_list(list(instruction)::in, int::in, int::out,
 	int::in, int::out) is det.
 
@@ -211,15 +211,15 @@
 	int::in, int::out) is det.
 
 	% See whether an lval references any stackvars.
-
+	%
 :- pred lval_refers_stackvars(lval::in, bool::out) is det.
 
 	% See whether an rval references any stackvars.
-
+	%
 :- pred rval_refers_stackvars(rval::in, bool::out) is det.
 
 	% See whether a list of maybe rvals references any stackvars.
-
+	%
 :- pred rvals_refer_stackvars(list(maybe(rval))::in, bool::out) is det.
 
 	% See whether instructions until the next decr_sp (if any) refer to
@@ -228,36 +228,36 @@
 	% is allowed; this instruction is not returned in the output.
 	% The same thing applies to assignments to detstackvars; these are
 	% not useful if we throw away the stack frame.
-
+	%
 :- pred no_stackvars_til_decr_sp(list(instruction)::in, int::in,
 	list(instruction)::out, list(instruction)::out) is semidet.
 
 	% See whether a list of instructions references any stackvars.
-
+	%
 :- pred block_refers_stackvars(list(instruction)::in, bool::out) is det.
 
 	% Format a label for verbose messages during compilation
-
+	%
 :- pred format_label(label::in, string::out) is det.
 
 	% Find out if an instruction sequence has both incr_sp and decr_sp.
-
+	%
 :- pred has_both_incr_decr_sp(list(instruction)::in) is semidet.
 
 	% Find out what rvals, if any, are needed to access an lval.
-
+	%
 :- pred lval_access_rvals(lval::in, list(rval)::out) is det.
 
 	% See whether an rval is free of references to a given lval.
-
+	%
 :- pred rval_free_of_lval(rval::in, lval::in) is semidet.
 
 	% See whether a list of rvals is free of references to a given lval.
-
+	%
 :- pred rvals_free_of_lval(list(rval)::in, lval::in) is semidet.
 
 	% Count the number of hp increments in a block of code.
-
+	%
 :- pred count_incr_hp(list(instruction)::in, int::out) is det.
 
 	% Whenever the input list of instructions contains two livevals
@@ -266,7 +266,7 @@
 	% that is live in the second, except those that are assigned to
 	% by intervening instructions. This makes the shadowing of the
 	% second livevals by the first benign.
-
+	%
 :- pred propagate_livevals(list(instruction)::in, list(instruction)::out)
 	is det.
 
@@ -277,7 +277,7 @@
 	% directly or via return from a called procedure) are always replaced;
 	% references that treat the label as data are replaced iff the third
 	% argument is set to "yes".
-
+	%
 :- pred replace_labels_instr(instr::in, map(label, label)::in,
 	bool::in, instr::out) is det.
 
@@ -450,8 +450,7 @@
 		( Label = NextLabel ->
 			Remainder = Moreinstr
 		;
-			is_this_label_next(Label, Moreinstr,
-				Remainder)
+			is_this_label_next(Label, Moreinstr, Remainder)
 		)
 	;
 		fail
@@ -568,8 +567,7 @@
 :- pred straight_alternative_2(list(instruction)::in, list(instruction)::in,
 	list(instruction)::out, list(instruction)::out) is semidet.
 
-straight_alternative_2([Instr0 | Instrs0], Between0, Between,
-		After) :-
+straight_alternative_2([Instr0 | Instrs0], Between0, Between, After) :-
 	Instr0 = Uinstr0 - _,
 	(
 		(
@@ -691,13 +689,11 @@
 	Instr0 = Uinstr0 - _,
 	(
 		Uinstr0 = comment(_),
-		no_stackvars_til_decr_sp(Instrs0, FrameSize,
-			Between0, Remain),
+		no_stackvars_til_decr_sp(Instrs0, FrameSize, Between0, Remain),
 		Between = [Instr0 | Between0]
 	;
 		Uinstr0 = livevals(_),
-		no_stackvars_til_decr_sp(Instrs0, FrameSize,
-			Between0, Remain),
+		no_stackvars_til_decr_sp(Instrs0, FrameSize, Between0, Remain),
 		Between = [Instr0 | Between0]
 	;
 		Uinstr0 = assign(Lval, Rval),
@@ -751,11 +747,7 @@
 		lval_refers_stackvars(Lval, Use1),
 		rval_refers_stackvars(Rval, Use2),
 		bool__or(Use1, Use2, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		Uinstr0 = call(_, _, _, _, _, _),
 		Need = no
@@ -771,72 +763,40 @@
 	;
 		Uinstr0 = computed_goto(Rval, _),
 		rval_refers_stackvars(Rval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			Need = no
-		)
+		Need = Use
 	;
 		Uinstr0 = c_code(_, _),
 		Need = no
 	;
 		Uinstr0 = if_val(Rval, _),
 		rval_refers_stackvars(Rval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			Need = no
-		)
+		Need = Use
 	;
 		Uinstr0 = incr_hp(Lval, _, _, Rval, _),
 		lval_refers_stackvars(Lval, Use1),
 		rval_refers_stackvars(Rval, Use2),
 		bool__or(Use1, Use2, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		Uinstr0 = mark_hp(Lval),
 		lval_refers_stackvars(Lval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		Uinstr0 = restore_hp(Rval),
 		rval_refers_stackvars(Rval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		Uinstr0 = free_heap(Rval),
 		rval_refers_stackvars(Rval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		Uinstr0 = store_ticket(Lval),
 		lval_refers_stackvars(Lval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		Uinstr0 = reset_ticket(Rval, _Reason),
 		rval_refers_stackvars(Rval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		Uinstr0 = discard_ticket,
 		block_refers_stackvars(Instrs0, Need)
@@ -846,19 +806,11 @@
 	;
 		Uinstr0 = mark_ticket_stack(Lval),
 		lval_refers_stackvars(Lval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		Uinstr0 = prune_tickets_to(Rval),
 		rval_refers_stackvars(Rval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		% handled specially
 		Uinstr0 = incr_sp(_, _),
@@ -879,19 +831,26 @@
 	;
 		Uinstr0 = join_and_terminate(Lval),
 		lval_refers_stackvars(Lval, Use),
-		( Use = yes ->
-			Need = yes
-		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
 	;
 		Uinstr0 = join_and_continue(Lval, _),
 		lval_refers_stackvars(Lval, Use),
-		( Use = yes ->
+		need_if_use_or_refers_stackvars(Use, Instrs0, Need)
+	).
+
+	% This is to make block_refers_stackvars tail recursive.
+:- pragma inline(need_if_use_or_refers_stackvars/3).
+
+:- pred need_if_use_or_refers_stackvars(bool::in, list(instruction)::in,
+	bool::out) is det.
+
+need_if_use_or_refers_stackvars(Use, Instrs, Need) :-
+	(
+		Use = yes,
 			Need = yes
 		;
-			block_refers_stackvars(Instrs0, Need)
-		)
+		Use = no,
+		block_refers_stackvars(Instrs, Need)
 	).
 
 filter_out_labels([], []).
@@ -983,8 +942,7 @@
 can_instr_branch_away(fork(_, _, _), yes).
 can_instr_branch_away(join_and_terminate(_), no).
 can_instr_branch_away(join_and_continue(_, _), yes).
-can_instr_branch_away(pragma_c(_, Comps, _, _, _, _, _, _, _),
-		BranchAway) :-
+can_instr_branch_away(pragma_c(_, Comps, _, _, _, _, _, _, _), BranchAway) :-
 	can_components_branch_away(Comps, BranchAway).
 
 :- pred can_components_branch_away(list(pragma_c_component)::in,
@@ -993,9 +951,11 @@
 can_components_branch_away([], no).
 can_components_branch_away([Component | Components], BranchAway) :-
 	can_component_branch_away(Component, BranchAway1),
-	( BranchAway1 = yes ->
+	(
+		BranchAway1 = yes,
 		BranchAway = yes
 	;
+		BranchAway1 = no,
 		can_components_branch_away(Components, BranchAway)
 	).
 
@@ -1012,11 +972,10 @@
 	% this one. We the developers could write C code that branched away,
 	% but we are careful to preserve a declarative interface, and that
 	% is incompatible with branching away.)
-
+	%
 can_component_branch_away(pragma_c_inputs(_), no).
 can_component_branch_away(pragma_c_outputs(_), no).
-can_component_branch_away(pragma_c_raw_code(Code, _),
-		CanBranchAway) :-
+can_component_branch_away(pragma_c_raw_code(Code, _), CanBranchAway) :-
 	( Code = "" -> CanBranchAway = no ; CanBranchAway = yes ).
 can_component_branch_away(pragma_c_user_code(_, _), no).
 can_component_branch_away(pragma_c_fail_to(_), yes).
@@ -1054,7 +1013,7 @@
 
 	% Check whether an instruction sequence can possibly fall through
 	% to the next instruction without using its label.
-
+	%
 :- pred can_block_fall_through(list(instruction)::in, bool::out) is det.
 
 can_block_fall_through([], yes).
@@ -1096,8 +1055,6 @@
 can_use_livevals(join_and_continue(_, _), no).
 can_use_livevals(pragma_c(_, _, _, _, _, _, _, _, _), no).
 
-% determine all the labels and code_addresses that are referenced by Instr
-
 instr_labels(Instr, Labels, CodeAddrs) :-
 	instr_labels_2(Instr, Labels0, CodeAddrs1),
 	instr_rvals_and_lvals(Instr, Rvals, Lvals),
@@ -1107,11 +1064,11 @@
 	list__append(CodeAddrs12, CodeAddrs3, CodeAddrs),
 	find_label_code_addrs(CodeAddrs, Labels0, Labels).
 
+	% Find out which code addresses are also labels.
+	%
 :- pred find_label_code_addrs(list(code_addr)::in,
 	list(label)::in, list(label)::out) is det.
 
-	% Find out which code addresses are also labels.
-
 find_label_code_addrs([], Labels, Labels).
 find_label_code_addrs([CodeAddr | Rest], Labels0, Labels) :-
 	( CodeAddr = label(Label) ->
@@ -1121,13 +1078,13 @@
 	),
 	find_label_code_addrs(Rest, Labels1, Labels).
 
+	% Determine all the labels and code_addresses that are directly
+	% referenced by an instruction (not counting ones referenced indirectly
+	% via rvals or lvals).
+	%
 :- pred instr_labels_2(instr::in, list(label)::out, list(code_addr)::out)
 	is det.
 
-% determine all the labels and code_addresses that are directly
-% referenced by an instruction (not counting ones referenced indirectly
-% via rvals or lvals)
-
 instr_labels_2(comment(_), [], []).
 instr_labels_2(livevals(_), [], []).
 instr_labels_2(block(_, _, Instrs), Labels, CodeAddrs) :-
@@ -1214,33 +1171,38 @@
 	maybe(label)::in, list(label)::out) is det.
 
 pragma_c_labels(MaybeFixedLabel, MaybeLayoutLabel,
-		MaybeOnlyLayoutLabel, MaybeSubLabel, Labels) :-
-	( MaybeFixedLabel = yes(FixedLabel) ->
-		Labels0 = [FixedLabel]
+		MaybeOnlyLayoutLabel, MaybeSubLabel, !:Labels) :-
+	!:Labels = [],
+	(
+		MaybeFixedLabel = yes(FixedLabel),
+		!:Labels = [FixedLabel | !.Labels]
 	;
-		Labels0 = []
+		MaybeFixedLabel = no
 	),
-	( MaybeLayoutLabel = yes(LayoutLabel) ->
-		Labels1 = [LayoutLabel | Labels0]
+	(
+		MaybeLayoutLabel = yes(LayoutLabel),
+		!:Labels = [LayoutLabel | !.Labels]
 	;
-		Labels1 = Labels0
+		MaybeLayoutLabel = no
 	),
-	( MaybeOnlyLayoutLabel = yes(OnlyLayoutLabel) ->
-		Labels2 = [OnlyLayoutLabel | Labels1]
+	(
+		MaybeOnlyLayoutLabel = yes(OnlyLayoutLabel),
+		!:Labels = [OnlyLayoutLabel | !.Labels]
 	;
-		Labels2 = Labels1
+		MaybeOnlyLayoutLabel = no
 	),
-	( MaybeSubLabel = yes(SubLabel) ->
-		Labels = [SubLabel | Labels2]
+	(
+		MaybeSubLabel = yes(SubLabel),
+		!:Labels = [SubLabel | !.Labels]
 	;
-		Labels = Labels2
+		MaybeSubLabel = no
 	).
 
+	% Determine all the rvals and lvals referenced by an instruction.
+	%
 :- pred instr_rvals_and_lvals(instr::in, list(rval)::out, list(lval)::out)
 	is det.
 
-% determine all the rvals and lvals referenced by an instruction
-
 instr_rvals_and_lvals(comment(_), [], []).
 instr_rvals_and_lvals(livevals(_), [], []).
 instr_rvals_and_lvals(block(_, _, Instrs), Labels, CodeAddrs) :-
@@ -1273,7 +1235,8 @@
 		Rvals, Lvals) :-
 	pragma_c_components_get_rvals_and_lvals(Cs, Rvals, Lvals).
 
-	% extract the rvals and lvals from the pragma_c_components
+	% Extract the rvals and lvals from the pragma_c_components.
+	%
 :- pred pragma_c_components_get_rvals_and_lvals(list(pragma_c_component)::in,
 	list(rval)::out, list(lval)::out) is det.
 
@@ -1283,8 +1246,9 @@
 	pragma_c_component_get_rvals_and_lvals(Comp,
 		Rvals1, Rvals, Lvals1, Lvals).
 
-	% extract the rvals and lvals from the pragma_c_component
+	% Extract the rvals and lvals from the pragma_c_component
 	% and add them to the list.
+	%
 :- pred pragma_c_component_get_rvals_and_lvals(pragma_c_component::in,
 	list(rval)::in, list(rval)::out, list(lval)::in, list(lval)::out)
 	is det.
@@ -1306,7 +1270,8 @@
 pragma_c_component_get_rvals_and_lvals(pragma_c_noop,
 		Rvals, Rvals, Lvals, Lvals).
 
-	% extract the rvals from the pragma_c_input
+	% Extract the rvals from the pragma_c_input.
+	%
 :- pred pragma_c_inputs_get_rvals(list(pragma_c_input)::in, list(rval)::out)
 	is det.
 
@@ -1315,7 +1280,8 @@
 	I = pragma_c_input(_Name, _VarType, _OrigType, R, _),
 	pragma_c_inputs_get_rvals(Inputs, Rvals).
 
-	% extract the lvals from the pragma_c_output
+	% Extract the lvals from the pragma_c_output.
+	%
 :- pred pragma_c_outputs_get_lvals(list(pragma_c_output)::in, list(lval)::out)
 	is det.
 
@@ -1324,8 +1290,9 @@
 	O = pragma_c_output(L, _VarType, _OrigType, _Name, _),
 	pragma_c_outputs_get_lvals(Outputs, Lvals).
 
-% determine all the rvals and lvals referenced by a list of instructions
-
+	% Determine all the rvals and lvals referenced by a list of
+	% instructions.
+	%
 :- pred instr_list_rvals_and_lvals(list(pair(instr, string))::in,
 	list(rval)::out, list(lval)::out) is det.
 
@@ -1434,7 +1401,7 @@
 :- pred count_temps_rval(rval::in, int::in, int::out, int::in, int::out)
 	is det.
 
-% XXX assume that we don't generate code
+% XXX We assume that we don't generate code
 % that uses a temp var without defining it.
 count_temps_rval(_, !R, !F).
 
@@ -1464,21 +1431,19 @@
 :- pred has_both_incr_decr_sp_2(list(instruction)::in,
 	bool::in, bool::out, bool::in, bool::out) is det.
 
-has_both_incr_decr_sp_2([], HasIncr, HasIncr, HasDecr, HasDecr).
-has_both_incr_decr_sp_2([Uinstr - _ | Instrs],
-		HasIncr0, HasIncr, HasDecr0, HasDecr) :-
+has_both_incr_decr_sp_2([], !HasIncr, !HasDecr).
+has_both_incr_decr_sp_2([Uinstr - _ | Instrs], !HasIncr, !HasDecr) :-
 	( Uinstr = incr_sp(_, _) ->
-		HasIncr1 = yes
+		!:HasIncr = yes
 	;
-		HasIncr1 = HasIncr0
+		true
 	),
 	( Uinstr = decr_sp(_) ->
-		HasDecr1 = yes
+		!:HasDecr = yes
 	;
-		HasDecr1 = HasDecr0
+		true
 	),
-	has_both_incr_decr_sp_2(Instrs,
-		HasIncr1, HasIncr, HasDecr1, HasDecr).
+	has_both_incr_decr_sp_2(Instrs, !HasIncr, !HasDecr).
 
 touches_nondet_ctrl([], no).
 touches_nondet_ctrl([Uinstr - _ | Instrs], Touch) :-
@@ -1569,15 +1534,15 @@
 	touches_nondet_ctrl_components(Cs, Touch2),
 	bool__or(Touch1, Touch2, Touch).
 
-:- pred touches_nondet_ctrl_component(pragma_c_component::in, bool::out)
-	is det.
-
 	% The inputs and outputs components get emitted as simple
 	% straight-line code that do not refer to control slots.
 	% The compiler does not generate raw_code that refers to control slots.
 	% User code shouldn't either, but until we have prohibited the
 	% use of ordinary pragma C codes for model_non procedures,
 	% some user code will need to ignore this restriction.
+	%
+:- pred touches_nondet_ctrl_component(pragma_c_component::in, bool::out)
+	is det.
 
 touches_nondet_ctrl_component(pragma_c_inputs(_), no).
 touches_nondet_ctrl_component(pragma_c_outputs(_), no).
@@ -1636,14 +1601,14 @@
 
 :- pred count_incr_hp_2(list(instruction)::in, int::in, int::out) is det.
 
-count_incr_hp_2([], N, N).
-count_incr_hp_2([Uinstr0 - _ | Instrs], N0, N) :-
+count_incr_hp_2([], !N).
+count_incr_hp_2([Uinstr0 - _ | Instrs], !N) :-
 	( Uinstr0 = incr_hp(_, _, _, _, _) ->
-		N1 = N0 + 1
+		!:N = !.N + 1
 	;
-		N1 = N0
+		true
 	),
-	count_incr_hp_2(Instrs, N1, N).
+	count_incr_hp_2(Instrs, !N).
 
 %-----------------------------------------------------------------------------%
 
@@ -1872,7 +1837,7 @@
 		MaybeLayout = yes(LayoutLabel0),
 		replace_labels_label(LayoutLabel0, ReplMap,
 			LayoutLabel),
-			% We cannot replace the label that has a layout
+			% We cannot replace a label that has a layout
 			% structure.
 		require(unify(LayoutLabel0, LayoutLabel),
 			"trying to replace Mercury label with layout")
@@ -1883,7 +1848,7 @@
 		MaybeOnlyLayout = yes(OnlyLayoutLabel0),
 		replace_labels_label(OnlyLayoutLabel0, ReplMap,
 			OnlyLayoutLabel),
-			% We cannot replace the label that has a layout
+			% We cannot replace a label that has a layout
 			% structure.
 		require(unify(OnlyLayoutLabel0, OnlyLayoutLabel),
 			"trying to replace Mercury label with layout")
@@ -2019,8 +1984,7 @@
 	map(label, label)::in, list(label)::out) is det.
 
 replace_labels_label_list([], _ReplMap, []).
-replace_labels_label_list([Label0 | Labels0], ReplMap,
-		[Label | Labels]) :-
+replace_labels_label_list([Label0 | Labels0], ReplMap, [Label | Labels]) :-
 	replace_labels_label(Label0, ReplMap, Label),
 	replace_labels_label_list(Labels0, ReplMap, Labels).
 
cvs diff: Diffing notes
--------------------------------------------------------------------------
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