diff: lookup_switch.m bug fix

David Glen JEFFERY dgj at cs.mu.oz.au
Tue Sep 23 14:03:38 AEST 1997


Estimated hours taken: 6 (to track it down).

Fix a bug in lookup switch generation which meant that some semidet switches
were always succeeding. The problem was that, when the switch was dense enough
to get rid of the range check, getting rid of the range check meant that the
bit vector test could now fail.

It may be better to turn these on in the other order.

compiler/lookup_switch.m:
	When we get rid of the range check, turn the bit vector test on.


Index: lookup_switch.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/lookup_switch.m,v
retrieving revision 1.24
diff -u -r1.24 lookup_switch.m
--- lookup_switch.m	1997/07/27 15:00:54	1.24
+++ lookup_switch.m	1997/09/22 06:45:48
@@ -111,16 +111,17 @@
 	(
 		{ NumCases = Range }
 	->
-		{ NeedBitVecTest = cannot_fail }
+		{ NeedBitVecTest0 = cannot_fail }
 	;
-		{ NeedBitVecTest = can_fail }
+		{ NeedBitVecTest0 = can_fail }
 	),
 	( { CanFail0 = can_fail } ->
 		% For semidet switches, we normally need to check that
 		% the variable is in range before we index into the jump table.
 		% However, if the range of the type is sufficiently small,
 		% we can make the jump table large enough to hold all
-		% of the values for the type.
+		% of the values for the type, but then we will need to do the
+		% bitvector test.
 		code_info__variable_type(CaseVar, Type),
 		code_info__get_module_info(ModuleInfo),
 		{ classify_type(Type, ModuleInfo, TypeCategory) },
@@ -130,15 +131,18 @@
 			{ DetDensity > ReqDensity }
 		->
 			{ NeedRangeCheck = cannot_fail },
+			{ NeedBitVecTest = can_fail },
 			{ FirstVal = 0 },
 			{ LastVal is TypeRange - 1 }
 		;
 			{ NeedRangeCheck = CanFail0 },
+			{ NeedBitVecTest = NeedBitVecTest0 },
 			{ FirstVal = FirstCaseVal },
 			{ LastVal = LastCaseVal }
 		)
 	;
 		{ NeedRangeCheck = CanFail0 },
+		{ NeedBitVecTest = NeedBitVecTest0 },
 		{ FirstVal = FirstCaseVal },
 		{ LastVal = LastCaseVal }
 	),


===================================================================

Here's a test case for it:


:- module test_lookup_switch.

:- interface.

:- import_module io.

:- pred main(io__state::di, io__state::uo) is det.

:- implementation.

:- type foo ---> a;b;c;d;e;f;g;h.

main --> bar(e).

:- pred bar(foo::in, io__state::di, io__state::uo) is det.
bar(X) -->
	(
		{ X = a ; X = b ; X = c ; X = d }
	->
		io__write_string("a or b or c or d\n")
	;
		io__write_string("e or f or g or h\n")
	).






love and cuddles,
dgj
-- 
David Jeffery (dgj at cs.mu.oz.au)     |  Kids, you tried your best and 
MEngSc student,                     |  you failed miserably. The lesson
Department of Computer Science      |  is, never try.
University of Melbourne, Australia  |           -- Homer Simpson



More information about the developers mailing list