for review: bug fix for det tag_switch problem

Fergus Henderson fjh at cs.mu.oz.au
Thu Apr 17 17:49:57 AEST 1997


Hi,

Zoltan, can you please review this one?

Estimated hours taken: 4

Fix a bug where tag_switch.m was generating references to non-existent
labels for det switches that don't cover the full range of the type.

llds.m:
	Add new alternative `do_not_reached' to the code_addr type.

exprn_aux.m:
dupelim.m:
livemap.m:
llds_out.m:
opt_util.m:
opt_debug.m:
	Add new code to handle `do_not_reached'.

tag_switch.m:
	When generating tag switch jump tables for det switches that do
	not cover the whole type, which can happen if the initial inst of
	the switch variable is a bound(...) inst that represents a
	subtype, make sure that we don't generate references to
	undefined labels for cases that occur in the switch var's type
	but not in the switch var's initial inst.  Instead, make such
	references refer to a label that jumps to `do_not_reached'.

cvs diff: Diffing .
Index: tag_switch.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/tag_switch.m,v
retrieving revision 1.34
diff -u -r1.34 tag_switch.m
--- tag_switch.m	1997/04/07 05:39:50	1.34
+++ tag_switch.m	1997/04/17 07:15:35
@@ -197,18 +197,21 @@
 	% a primary tag may not be the last case overall
 
 	code_info__get_next_label(FailLabel),
+	{ FailLabelCode = node([
+		label(FailLabel) -
+			"switch has failed"
+	]) },
 	(
 		{ CanFail = cannot_fail },
-		{ LabelledFailCode = empty }
+		{ FailCode = node([
+			goto(do_not_reached) - "oh-oh, det switch failed"
+		]) }
 	;
 		{ CanFail = can_fail },
-		code_info__generate_failure(FailCode),
-		{ FailLabelCode = node([
-			label(FailLabel) -
-				"switch has failed"
-		]) },
-		{ LabelledFailCode = tree(FailLabelCode, FailCode) }
+		code_info__generate_failure(FailCode)
 	),
+	{ LabelledFailCode = tree(FailLabelCode, FailCode) },
+
 	{ EndCode = node([label(EndLabel) - "end of tag switch"]) },
 
 	(
@@ -502,6 +505,8 @@
 				tree(SaveCode,
 				     GotoCode))
 			}
+		; { GoalList = [] } ->
+			{ error("no goal for non-shared tag") }
 		;
 			{ error("more than one goal for non-shared tag") }
 		)
@@ -945,8 +950,10 @@
 	% Order the primary tags based on the number of secondary tags
 	% associated with them, putting the ones with the most secondary tags
 	% first. We use selection sort.
-	% Note that it is not an error for a primary tag to have no case list,
-	% since this can happen in semideterministic switches.
+	% Note that it is not an error for a primary tag to have no case list;
+	% this can happen in semideterministic switches, or in det switches
+	% where the initial inst of the switch variable is a bound(...) inst
+	% representing a subtype.
 
 :- pred tag_switch__order_ptags_by_count(ptag_count_list, ptag_case_map,
 	ptag_case_list).
Index: dupelim.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/dupelim.m,v
retrieving revision 1.18
diff -u -r1.18 dupelim.m
--- dupelim.m	1997/02/23 06:06:13	1.18
+++ dupelim.m	1997/04/17 05:18:49
@@ -277,6 +277,7 @@
 dupelim__replace_labels_code_addr(do_det_closure, _, do_det_closure).
 dupelim__replace_labels_code_addr(do_semidet_closure, _, do_semidet_closure).
 dupelim__replace_labels_code_addr(do_nondet_closure, _, do_nondet_closure).
+dupelim__replace_labels_code_addr(do_not_reached, _, do_not_reached).
 
 :- pred dupelim__replace_labels_label_list(list(label), map(label, label),
 	list(label)).
Index: exprn_aux.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/exprn_aux.m,v
retrieving revision 1.19
diff -u -r1.19 exprn_aux.m
--- exprn_aux.m	1997/01/21 05:04:58	1.19
+++ exprn_aux.m	1997/04/17 05:45:53
@@ -148,6 +148,7 @@
 exprn_aux__addr_is_constant(do_det_closure, _, no).
 exprn_aux__addr_is_constant(do_semidet_closure, _, no).
 exprn_aux__addr_is_constant(do_nondet_closure, _, no).
+exprn_aux__addr_is_constant(do_not_reached, _, no).
 
 :- pred exprn_aux__label_is_constant(label, bool, bool, bool).
 :- mode exprn_aux__label_is_constant(in, in, in, out) is det.
Index: livemap.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/livemap.m,v
retrieving revision 1.22
diff -u -r1.22 livemap.m
--- livemap.m	1997/01/21 05:05:04	1.22
+++ livemap.m	1997/04/17 07:26:50
@@ -184,7 +184,12 @@
 			set__init(Livevals2),
 			livemap__insert_label_livevals([Label],
 				Livemap0, Livevals2, Livevals3)
-		; ( CodeAddr = do_redo ; CodeAddr = do_fail ) ->
+		;
+			( CodeAddr = do_redo
+			; CodeAddr = do_fail
+			; CodeAddr = do_not_reached
+			)
+		->
 			Livevals3 = Livevals1
 		;
 			error("unknown label type in build_livemap")
@@ -340,6 +345,7 @@
 livemap__special_code_addr(do_det_closure, no).
 livemap__special_code_addr(do_semidet_closure, no).
 livemap__special_code_addr(do_nondet_closure, no).
+livemap__special_code_addr(do_not_reached, no).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: llds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds.m,v
retrieving revision 1.203
diff -u -r1.203 llds.m
--- llds.m	1997/03/21 10:25:41	1.203
+++ llds.m	1997/04/17 05:17:55
@@ -470,7 +470,8 @@
 	;	do_fail
 	;	do_det_closure
 	;	do_semidet_closure
-	;	do_nondet_closure.
+	;	do_nondet_closure
+	;	do_not_reached.		% we should never jump to this address
 
 	% A proc_label is a label used for the entry point to a procedure.
 	% The defining module is the module that provides the code for the
Index: llds_out.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/llds_out.m,v
retrieving revision 1.42
diff -u -r1.42 llds_out.m
--- llds_out.m	1997/04/05 07:16:46	1.42
+++ llds_out.m	1997/04/17 05:26:31
@@ -1743,6 +1743,7 @@
 need_code_addr_decls(do_det_closure, yes) --> [].
 need_code_addr_decls(do_semidet_closure, yes) --> [].
 need_code_addr_decls(do_nondet_closure, yes) --> [].
+need_code_addr_decls(do_not_reached, yes) --> [].
 
 :- pred output_code_addr_decls(code_addr, io__state, io__state).
 :- mode output_code_addr_decls(in, di, uo) is det.
@@ -1781,6 +1782,8 @@
 	io__write_string("Declare_entry(do_call_semidet_closure);\n").
 output_code_addr_decls(do_nondet_closure) -->
 	io__write_string("Declare_entry(do_call_nondet_closure);\n").
+output_code_addr_decls(do_not_reached) -->
+	io__write_string("Declare_entry(do_not_reached);\n").
 
 :- pred output_label_as_code_addr_decls(label, io__state, io__state).
 :- mode output_label_as_code_addr_decls(in, di, uo) is det.
@@ -1942,6 +1945,11 @@
 	io__write_string("tailcall(ENTRY(do_call_nondet_closure),\n\t\t"),
 	output_label_as_code_addr(CallerLabel),
 	io__write_string(");\n").
+output_goto(do_not_reached, CallerLabel) -->
+	io__write_string("tailcall(ENTRY(do_not_reached),\n\t\t"),
+	output_label_as_code_addr(CallerLabel),
+	io__write_string(");\n").
+
 
 	% Note that we also do some optimization here by
 	% outputting `localcall' rather than `call' for
@@ -2008,6 +2016,8 @@
 	io__write_string("ENTRY(do_call_semidet_closure)").
 output_code_addr(do_nondet_closure) -->
 	io__write_string("ENTRY(do_call_nondet_closure)").
+output_code_addr(do_not_reached) -->
+	io__write_string("ENTRY(do_not_reached)").
 
 :- pred output_data_addr(string, data_name, io__state, io__state).
 :- mode output_data_addr(in, in, di, uo) is det.
Index: opt_debug.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/opt_debug.m,v
retrieving revision 1.67
diff -u -r1.67 opt_debug.m
--- opt_debug.m	1997/03/06 05:09:41	1.67
+++ opt_debug.m	1997/04/17 05:27:50
@@ -726,6 +726,7 @@
 opt_debug__dump_code_addr(do_det_closure, "do_det_closure").
 opt_debug__dump_code_addr(do_semidet_closure, "do_semidet_closure").
 opt_debug__dump_code_addr(do_nondet_closure, "do_nondet_closure").
+opt_debug__dump_code_addr(do_not_reached, "do_not_reached").
 
 opt_debug__dump_code_addrs([], "").
 opt_debug__dump_code_addrs([Addr | Addrs], Str) :-
Index: opt_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/opt_util.m,v
retrieving revision 1.80
diff -u -r1.80 opt_util.m
--- opt_util.m	1997/03/06 05:09:43	1.80
+++ opt_util.m	1997/04/17 05:30:23
@@ -1173,6 +1173,7 @@
 opt_util__livevals_addr(do_det_closure, yes).
 opt_util__livevals_addr(do_semidet_closure, yes).
 opt_util__livevals_addr(do_nondet_closure, yes).
+opt_util__livevals_addr(do_not_reached, no).
 
 opt_util__count_temps_instr_list([], R, R, F, F).
 opt_util__count_temps_instr_list([Uinstr - _Comment | Instrs], R0, R, F0, F) :-
cvs diff: Diffing notes

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list