diff: improvement to lookup_switch

Fergus Henderson fjh at cs.mu.oz.au
Wed May 7 04:23:45 AEST 1997


Hi Tom,

Could you please review this one?

compiler/lookup_switch.m:
	Optimize the bit-vector test for small semidet lookup switches:
	in the situation where all the cases fit into a single word,
	we don't need to figure out at runtime which word to use.

	Also, some minor improvements to the maintainability of the
	code: move the code for figuring out how many bits per word
	to use into a separate procedure, and use more informative
	variable names in that procedure.

Index: lookup_switch.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/lookup_switch.m,v
retrieving revision 1.21
diff -u -r1.21 lookup_switch.m
--- lookup_switch.m	1997/02/23 06:06:59	1.21
+++ lookup_switch.m	1997/05/06 18:18:51
@@ -326,45 +326,59 @@
 	% iff we have a case for that tag value.
 lookup_switch__generate_bitvec_test(Index, CaseVals, Start, _End,
 		CheckCode) -->
-	generate_bit_vec(CaseVals, Start, BitVec),
-	code_info__get_globals(Globals),
-	{ globals__get_options(Globals, Options) },
-	{ getopt__lookup_int_option(Options, bits_per_word, WordBits0) },
-	{ int__bits_per_int(MachineBits) },
-		% prevent cross-compilation errors by making sure that
-		% the bitvector uses a number of bits that will fit both
-		% on this machine (so that we can correctly generate it),
-		% and on the target machine (so that it can be executed
-		% correctly)
-	{ int__min(WordBits0, MachineBits, WordBits) },
+	lookup_switch__get_word_bits(WordBits),
+	generate_bit_vec(CaseVals, Start, WordBits, BitVec),
+
 	{ UIndex = unop(cast_to_unsigned, Index) },
-	{ Word = lval(field(0, BitVec,
-			binop(/, UIndex,const(int_const(WordBits)))))},
-	{ HasBit = binop((&), binop((<<),
-			const(int_const(1)),
-			binop(mod, UIndex, const(int_const(WordBits)))),Word) },
+		%
+		% Optimize the single-word case:
+		% if all the cases fit into a single word, then
+		% the word to use is always that word, and the index
+		% specifies which bit.  Otherwise, the high bits
+		% of the index specify which word to use and the
+		% low bits specify which bit.
+		%
+	{
+		BitVec = create(_, [yes(SingleWord)], _, _)
+	->
+		Word = SingleWord,
+		BitNum = UIndex
+	;
+		WordNum = binop(/, UIndex, const(int_const(WordBits))),
+		Word = lval(field(0, BitVec, WordNum)),
+		BitNum = binop(mod, UIndex, const(int_const(WordBits)))
+	},
+	{ HasBit = binop((&),
+			binop((<<), const(int_const(1)), BitNum),
+			Word) },
 	code_info__fail_if_rval_is_false(HasBit, CheckCode).
 
-:- pred generate_bit_vec(case_consts, int, rval,
-		code_info, code_info).
-:- mode generate_bit_vec(in, in, out, in, out) is det.
+
+:- pred lookup_switch__get_word_bits(int, code_info, code_info).
+:- mode lookup_switch__get_word_bits(out, in, out) is det.
+
+	% Prevent cross-compilation errors by making sure that
+	% the bitvector uses a number of bits that will fit both
+	% on this machine (so that we can correctly generate it),
+	% and on the target machine (so that it can be executed
+	% correctly)
+
+lookup_switch__get_word_bits(WordBits) -->
+	{ int__bits_per_int(HostWordBits) },
+	code_info__get_globals(Globals),
+	{ globals__get_options(Globals, Options) },
+	{ getopt__lookup_int_option(Options, bits_per_word, TargetWordBits) },
+	{ int__min(HostWordBits, TargetWordBits, WordBits) }.
+
+:- pred generate_bit_vec(case_consts, int, int, rval, code_info, code_info).
+:- mode generate_bit_vec(in, in, in, out, in, out) is det.
 
 	% we generate the bitvector by iterating through the cases
 	% marking the bit for each case. (We represent the bitvector
 	% here as a map from the word number in the vector to the bits
 	% for that word.
-generate_bit_vec(CaseVals, Start, BitVec) -->
+generate_bit_vec(CaseVals, Start, WordBits, BitVec) -->
 	{ map__init(Empty) },
-	code_info__get_globals(Globals),
-	{ globals__get_options(Globals, Options) },
-	{ getopt__lookup_int_option(Options, bits_per_word, WordBits0) },
-	{ int__bits_per_int(MachineBits) },
-		% prevent cross-compilation errors by making sure that
-		% the bitvector uses a number of bits that will fit both
-		% on this machine (so that we can correctly generate it),
-		% and on the target machine (so that it can be executed
-		% correctly)
-	{ int__min(WordBits0, MachineBits, WordBits) },
 	{ generate_bit_vec_2(CaseVals, Start, WordBits, Empty, BitMap) },
 	{ map__to_assoc_list(BitMap, WordVals) },
 	{ generate_bit_vec_args(WordVals, 0, Args) },
@@ -372,7 +386,7 @@
 	{ BitVec = create(0, Args, no, CellNo) }.
 
 :- pred generate_bit_vec_2(case_consts, int, int,
-		map(int, int), map(int, int)).
+			map(int, int), map(int, int)).
 :- mode generate_bit_vec_2(in, in, in, in, out) is det.
 
 generate_bit_vec_2([], _, _, Bits, Bits).


-- 
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