for review: fixes to frameopt and value numbering
Zoltan Somogyi
zs at cs.mu.oz.au
Wed Jul 23 17:49:14 AEST 1997
compiler/frameopt:
Bug fix: make sure that the transformation that keeps stack frames
put the instruction that restores succip before a livevals/goto pair.
It used to put it in between the livevals and the goto, which violates
an invariant that value numbering depends on.
compiler/vn_table:
Allow the two operands of an operator to be the same.
compiler/vn_util:
Add simplification rules for dealing with boolean and and or,
and rules exploiting the identities of several operators.
tests/hard_coded/float_map:
A test case for the fix to builtin_float_compare recently checked in
by Fergus.
tests/hard_coded/Mmake:
Enable the new test case.
tests/valid/livevals_seq:
A new test case for the fix to frameopt.
tests/valid/double_vn:
A new test case for the fix to vn_table.
tests/valid/Mmake:
Enable the new test cases.
Zoltan.
cvs diff: Diffing .
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/frameopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/frameopt.m,v
retrieving revision 1.59
diff -u -r1.59 frameopt.m
--- 1.59 1997/07/20 23:54:48
+++ frameopt.m 1997/07/23 05:27:14
@@ -194,15 +194,16 @@
% setup or teardown. The bool
% says whether the code in the
% block needs a stack frame.
- ; teardown(list(instruction), list(instruction)).
+ ; teardown(list(instruction), list(instruction),
+ instruction).
% This block contains stack
- % teardown and goto code;
- % the two args give the instr
- % that restores succip (if any)
- % and the goto code (which must
- % be a list because it may or
- % mey not contain a liveness
- % annotation).
+ % teardown and goto code.
+ % The three args give
+ % (1) the instr that restores
+ % succip (if any),
+ % (2) the livevals instr
+ % before the goto (if any),
+ % (3) the goto instr
%-----------------------------------------------------------------------------%
@@ -301,17 +302,19 @@
LabelSeq = [Label | LabelSeq0]
;
frameopt__detstack_teardown(Instrs0, FrameSize,
- Tail, Teardown, RestoreSuccip, Goto, Remain)
+ Tail, Succip, Decrsp, Livevals, Goto, Remain)
->
+ list__append(Livevals, [Goto], Teardown0),
+ list__append(Decrsp, Teardown0, Teardown1),
+ list__append(Succip, Teardown1, Teardown),
( Tail = [] ->
MaybeTailInfo = no,
N1 = N0,
- list__append([Instr0 | Teardown], Goto,
- TeardownBlock),
+ LabelledBlock = [Instr0 | Teardown],
TeardownLabel = Label,
TeardownInfo = block_info(TeardownLabel,
- TeardownBlock, [], no,
- teardown(RestoreSuccip, Goto))
+ LabelledBlock, [], no,
+ teardown(Succip, Livevals, Goto))
;
block_needs_frame(Tail, Needs),
TailInfo = block_info(Label, [Instr0 | Tail],
@@ -320,12 +323,11 @@
N1 is N0 + 1,
NewLabel = local(ProcLabel, N0),
NewInstr = label(NewLabel) - "",
- list__append([NewInstr | Teardown], Goto,
- TeardownBlock),
+ LabelledBlock = [NewInstr | Teardown],
TeardownLabel = NewLabel,
TeardownInfo = block_info(TeardownLabel,
- TeardownBlock, [], no,
- teardown(RestoreSuccip, Goto))
+ LabelledBlock, [], no,
+ teardown(Succip, Livevals, Goto))
),
build_block_map(Remain, FrameSize, LabelSeq0,
BlockMap0, BlockMap1, ProcLabel, N1, N),
@@ -414,24 +416,26 @@
%-----------------------------------------------------------------------------%
% Does the following block contain a teardown of a det stack frame,
- % and a proceed or tailcall?
- % Return the teardown instructions and the branch away, together with
- % the instructions that either are before the teardown or can be
- % reordered to be before the teardown, and the instructions remaining
- % after all that.
-
- % We are looking for the teardown components in any order, since
- % value numbering may change the original order. This is also the
- % reason why we allow teardown instructions to be interleaved with
- % instructions that do not access the stack, and why some teardown
- % instructions (e.g. the one that restores succip) may be missing.
+ % and a proceed or tailcall? If yes, we return
+ %
+ % - the instruction that restores succip as Succip
+ % - the decr_sp instruction as Decrsp
+ % - the livevals instruction as Livevals
+ % - the goto instruction as Goto
+ %
+ % The first three can appear in any order or may be missing, due to
+ % value numbering. This is also why we allow the teardown instructions
+ % to be interleaved with instructions that do not access the stack;
+ % any such instructions are returned as Extra. Remain is all the
+ % instructions after the teardown.
:- pred frameopt__detstack_teardown(list(instruction)::in, int::in,
- list(instruction)::out, list(instruction)::out, list(instruction)::out,
- list(instruction)::out, list(instruction)::out) is semidet.
+ list(instruction)::out, list(instruction)::out,
+ list(instruction)::out, list(instruction)::out,
+ instruction::out, list(instruction)::out) is semidet.
frameopt__detstack_teardown([Instr0 | Instrs0], FrameSize,
- Tail, Teardown, RestoreSuccip, Goto, Remain) :-
+ Extra, Succip, Decrsp, Livevals, Goto, Remain) :-
(
Instr0 = label(_) - _
->
@@ -439,29 +443,31 @@
;
frameopt__detstack_teardown_2([Instr0 | Instrs0], FrameSize,
[], [], [], [],
- TailPrime, TeardownPrime, RestoreSuccipPrime,
+ ExtraPrime, SuccipPrime, DecrspPrime, LivevalsPrime,
GotoPrime, RemainPrime)
->
- Tail = TailPrime,
- Teardown = TeardownPrime,
- RestoreSuccip = RestoreSuccipPrime,
+ Extra = ExtraPrime,
+ Succip = SuccipPrime,
+ Decrsp = DecrspPrime,
+ Livevals = LivevalsPrime,
Goto = GotoPrime,
Remain = RemainPrime
;
frameopt__detstack_teardown(Instrs0, FrameSize,
- Tail1, Teardown, RestoreSuccip, Goto, Remain),
- Tail = [Instr0 | Tail1]
+ Extra1, Succip, Decrsp, Livevals, Goto, Remain),
+ Extra = [Instr0 | Extra1]
).
:- pred frameopt__detstack_teardown_2(list(instruction)::in, int::in,
- list(instruction)::in, list(instruction)::in, list(instruction)::in,
- list(instruction)::in, list(instruction)::out, list(instruction)::out,
- list(instruction)::out, list(instruction)::out, list(instruction)::out)
- is semidet.
+ list(instruction)::in, list(instruction)::in,
+ list(instruction)::in, list(instruction)::in,
+ list(instruction)::out, list(instruction)::out,
+ list(instruction)::out, list(instruction)::out,
+ instruction::out, list(instruction)::out) is semidet.
frameopt__detstack_teardown_2(Instrs0, FrameSize,
- SeenSuccip0, SeenDecrsp0, SeenExtra0, SeenLivevals0,
- Tail, Teardown, RestoreSuccip, Goto, Remain) :-
+ Extra0, Succip0, Decrsp0, Livevals0,
+ Extra, Succip, Decrsp, Livevals, Goto, Remain) :-
opt_util__skip_comments(Instrs0, Instrs1),
Instrs1 = [Instr1 | Instrs2],
Instr1 = Uinstr1 - _,
@@ -471,43 +477,42 @@
Lval = succip,
Rval = lval(stackvar(FrameSize))
->
- SeenSuccip0 = [],
- SeenDecrsp0 = [],
- SeenSuccip1 = [Instr1],
+ Succip0 = [],
+ Decrsp0 = [],
+ Succip1 = [Instr1],
frameopt__detstack_teardown_2(Instrs2, FrameSize,
- SeenSuccip1, SeenDecrsp0, SeenExtra0,
- SeenLivevals0, Tail, Teardown,
- RestoreSuccip, Goto, Remain)
+ Extra0, Succip1, Decrsp0, Livevals0,
+ Extra, Succip, Decrsp, Livevals, Goto, Remain)
;
opt_util__lval_refers_stackvars(Lval, no),
opt_util__rval_refers_stackvars(Rval, no),
- list__append(SeenExtra0, [Instr1], SeenExtra1),
+ list__append(Extra0, [Instr1], Extra1),
frameopt__detstack_teardown_2(Instrs2, FrameSize,
- SeenSuccip0, SeenDecrsp0, SeenExtra1,
- SeenLivevals0, Tail, Teardown,
- RestoreSuccip, Goto, Remain)
+ Extra1, Succip0, Decrsp0, Livevals0,
+ Extra, Succip, Decrsp, Livevals, Goto, Remain)
)
;
Uinstr1 = decr_sp(FrameSize),
- SeenDecrsp0 = [],
- SeenDecrsp1 = [Instr1],
+ Decrsp0 = [],
+ Decrsp1 = [Instr1],
frameopt__detstack_teardown_2(Instrs2, FrameSize,
- SeenSuccip0, SeenDecrsp1, SeenExtra0, SeenLivevals0,
- Tail, Teardown, RestoreSuccip, Goto, Remain)
+ Extra0, Succip0, Decrsp1, Livevals0,
+ Extra, Succip, Decrsp, Livevals, Goto, Remain)
;
Uinstr1 = livevals(_),
- SeenLivevals0 = [],
- SeenLivevals1 = [Instr1],
+ Livevals0 = [],
+ Livevals1 = [Instr1],
frameopt__detstack_teardown_2(Instrs2, FrameSize,
- SeenSuccip0, SeenDecrsp0, SeenExtra0, SeenLivevals1,
- Tail, Teardown, RestoreSuccip, Goto, Remain)
+ Extra0, Succip0, Decrsp0, Livevals1,
+ Extra, Succip, Decrsp, Livevals, Goto, Remain)
;
Uinstr1 = goto(_),
- SeenDecrsp0 = [_],
- list__append(SeenSuccip0, SeenDecrsp0, Teardown),
- Tail = SeenExtra0,
- RestoreSuccip = SeenSuccip0,
- list__append(SeenLivevals0, [Instr1], Goto),
+ Decrsp0 = [_],
+ Extra = Extra0,
+ Succip = Succip0,
+ Decrsp = Decrsp0,
+ Livevals = Livevals0,
+ Goto = Instr1,
Remain = Instrs2
).
@@ -727,29 +732,27 @@
map__lookup(BlockMap0, Label, BlockInfo0),
(
BlockInfo0 = block_info(Label, OrigInstrs, [_], no,
- teardown(RestoreSuccip, BareInstrs)),
- pick_last(OrigInstrs, _NonLastOrigInstrs, LastOrigInstr),
- LastOrigInstr = goto(label(GotoLabel)) - Comment,
+ teardown(Succip, Livevals, Goto)),
+ Goto = goto(label(GotoLabel)) - Comment,
same_label_ref(FirstLabel, GotoLabel)
->
(
OrigInstrs = [OrigInstr0 | _],
OrigInstr0 = label(_) - _
->
- NewLabelInstr = OrigInstr0
+ OrigLabelInstr = OrigInstr0
;
error("block does not begin with label")
),
- pick_last(BareInstrs, NonLastBareInstrs, _LastBareInstr),
string__append(Comment, " (keeping frame)", NewComment),
NewGoto = goto(label(SecondLabel)) - NewComment,
- NewFrontInstrs = [NewLabelInstr | NonLastBareInstrs],
+ list__append(Livevals, [NewGoto], LivevalsGoto),
( CanClobberSuccip = yes ->
- list__append(RestoreSuccip, [NewGoto], NewBackInstrs)
+ list__append(Succip, LivevalsGoto, BackInstrs)
;
- NewBackInstrs = [NewGoto]
+ BackInstrs = LivevalsGoto
),
- list__append(NewFrontInstrs, NewBackInstrs, Instrs),
+ Instrs = [OrigLabelInstr | BackInstrs],
BlockInfo = block_info(Label, Instrs, [SecondLabel], no,
ordinary(yes)),
map__det_update(BlockMap0, Label, BlockInfo, BlockMap1)
@@ -914,7 +917,7 @@
queue__put(Queue0, Label, Queue1)
)
;
- BlockType = teardown(_, _),
+ BlockType = teardown(_, _, _),
Queue1 = Queue0
),
rev_map_side_labels(SideLabels, Label, RevMap0, RevMap1),
@@ -1077,7 +1080,7 @@
Labels, BlockMap, ParMap, FallIntoParallel)
)
;
- Type = teardown(_, _),
+ Type = teardown(_, _, _),
process_frame_delay(Labels0, BlockMap0,
ParMap0, FallIntoParallel0, FramedLabels,
FrameSize, Msg, ProcLabel, N0,
@@ -1140,7 +1143,7 @@
N2 = N1
)
;
- FallThroughType = teardown(_, _),
+ FallThroughType = teardown(_, _, _),
MaybeFallThrough = yes(FallThrough),
BlockMap1 = BlockMap0,
set__insert(FallIntoParallel0,
@@ -1199,7 +1202,7 @@
N1 = N0,
ParMap1 = ParMap0
;
- Type = teardown(_, _),
+ Type = teardown(_, _, _),
mark_parallel(Label0, Label, ProcLabel, N0, N1,
ParMap0, ParMap1)
),
@@ -1334,9 +1337,10 @@
;
error("block with parallel has fall through")
),
- ( Type = teardown(_, Replacement0) ->
+ ( Type = teardown(_, Livevals, Goto) ->
LabelInstr = label(ParallelLabel)
- "non-teardown parallel",
+ list__append(Livevals, [Goto], Replacement0),
Replacement = [LabelInstr | Replacement0],
NewBlockInfo = block_info(ParallelLabel, Replacement,
SideLabels, no, ordinary(no)),
Index: compiler/vn_table.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_table.m,v
retrieving revision 1.15
diff -u -r1.15 vn_table.m
--- 1.15 1997/06/29 23:11:41
+++ vn_table.m 1997/07/22 08:47:09
@@ -298,33 +298,36 @@
;
error("cannot find old use set in add_new_use")
),
- (
- list__member(NewUse, Uses0),
- \+ (
- NewUse = src_access(_)
- ;
- NewUse = src_vn(UserVn),
- map__lookup(Vn_to_rval_table0, UserVn, VnRval),
- VnRval = vn_binop(Operator, _, _),
- ( Operator = (+)
- ; Operator = (*)
- ; Operator = float_plus
- ; Operator = float_times
- ; Operator = (<<)
- ; Operator = (>>)
- )
- )
- ->
- opt_debug__dump_tables(VnTables0, T_str),
- opt_debug__dump_vn(Vn, V_str),
- opt_debug__dump_use(NewUse, U_str),
- string__append_list(["\n", T_str, "\n",
- "new use for vn ", V_str, " = ", U_str, "\n",
- "new use already known"], Msg),
- error(Msg)
- ;
- Uses1 = [NewUse | Uses0]
- ),
+% Reenable the commented out stuff if you want the compiler
+% to fail when an operator is used with two identical operands
+% in a situation that might be optimizable.
+% (
+% list__member(NewUse, Uses0),
+% \+ (
+% NewUse = src_access(_)
+% ;
+% NewUse = src_vn(UserVn),
+% map__lookup(Vn_to_rval_table0, UserVn, VnRval),
+% VnRval = vn_binop(Operator, _, _),
+% ( Operator = (+)
+% ; Operator = (*)
+% ; Operator = float_plus
+% ; Operator = float_times
+% ; Operator = (<<)
+% ; Operator = (>>)
+% )
+% )
+% ->
+% opt_debug__dump_tables(VnTables0, T_str),
+% opt_debug__dump_vn(Vn, V_str),
+% opt_debug__dump_use(NewUse, U_str),
+% string__append_list(["\n", T_str, "\n",
+% "new use for vn ", V_str, " = ", U_str, "\n",
+% "new use already known"], Msg),
+% error(Msg)
+% ;
+ Uses1 = [NewUse | Uses0],
+% ),
map__det_update(Vn_to_uses_table0, Vn, Uses1, Vn_to_uses_table1),
VnTables = vn_tables(NextVn0,
Lval_to_vn_table0, Rval_to_vn_table0,
Index: compiler/vn_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_util.m,v
retrieving revision 1.53
diff -u -r1.53 vn_util.m
--- 1.53 1997/04/10 20:10:34
+++ vn_util.m 1997/07/22 09:13:55
@@ -340,6 +340,12 @@
VnTables0, VnTables),
Vnrval = vn_binop((+), VnExpr, Vn12)
;
+ % e+0 => e
+ Vnrval2 = vn_const(int_const(0))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
fail
)
;
@@ -412,6 +418,12 @@
Vn2), VnExpr, VnTables0, VnTables),
Vnrval = vn_binop((float_plus), VnExpr, Vn12)
;
+ % e+0 => e
+ Vnrval2 = vn_const(float_const(0.0))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
fail
)
;
@@ -443,6 +455,12 @@
Vnrval = vn_const(int_const(0)),
VnTables = VnTables0
;
+ % e-0 => e
+ Vnrval2 = vn_const(int_const(0))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
fail
)
;
@@ -474,6 +492,12 @@
Vnrval = vn_const(int_const(0)),
VnTables = VnTables0
;
+ % e-0 => e
+ Vnrval2 = vn_const(float_const(0.0))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
fail
)
;
@@ -487,6 +511,18 @@
Vnrval = vn_const(int_const(I)),
VnTables = VnTables0
;
+ % e*1 => e
+ Vnrval2 = vn_const(int_const(1))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
+ % 1*e => e
+ Vnrval1 = vn_const(int_const(1))
+ ->
+ Vnrval = Vnrval2,
+ VnTables = VnTables0
+ ;
fail
)
;
@@ -500,6 +536,18 @@
Vnrval = vn_const(float_const(F)),
VnTables = VnTables0
;
+ % e*1 => e
+ Vnrval2 = vn_const(float_const(1.0))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
+ % 1*e => e
+ Vnrval1 = vn_const(float_const(1.0))
+ ->
+ Vnrval = Vnrval2,
+ VnTables = VnTables0
+ ;
fail
)
;
@@ -514,6 +562,12 @@
Vnrval = vn_const(int_const(I)),
VnTables = VnTables0
;
+ % e/1 => e
+ Vnrval2 = vn_const(int_const(1))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
fail
)
;
@@ -528,11 +582,80 @@
Vnrval = vn_const(float_const(F)),
VnTables = VnTables0
;
+ % e/1 => e
+ Vnrval2 = vn_const(float_const(1.0))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
+ fail
+ )
+ ;
+ Binop = ('|'),
+ (
+ % c1\/c2 => c
+ Vnrval1 = vn_const(int_const(I1)),
+ Vnrval2 = vn_const(int_const(I2))
+ ->
+ I is I1 \/ I2,
+ Vnrval = vn_const(int_const(I)),
+ VnTables = VnTables0
+ ;
+ % e\/0 => e
+ Vnrval2 = vn_const(int_const(0))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
+ % 0\/e => e
+ Vnrval1 = vn_const(int_const(0))
+ ->
+ Vnrval = Vnrval2,
+ VnTables = VnTables0
+ ;
+ % e\/e => e
+ Vn1 = Vn2
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
+ fail
+ )
+ ;
+ Binop = (&),
+ (
+ % c1/\c2 => c
+ Vnrval1 = vn_const(int_const(I1)),
+ Vnrval2 = vn_const(int_const(I2))
+ ->
+ I is I1 /\ I2,
+ Vnrval = vn_const(int_const(I)),
+ VnTables = VnTables0
+ ;
+ % e/\0 => 0
+ Vnrval2 = vn_const(int_const(0))
+ ->
+ Vnrval = vn_const(int_const(0)),
+ VnTables = VnTables0
+ ;
+ % 0/\e => 0
+ Vnrval1 = vn_const(int_const(0))
+ ->
+ Vnrval = vn_const(int_const(0)),
+ VnTables = VnTables0
+ ;
+ % e/\e => e
+ Vn1 = Vn2
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
fail
)
;
Binop = (>>),
(
+ % c1>>c2 => c
Vnrval1 = vn_const(int_const(I1)),
Vnrval2 = vn_const(int_const(I2))
->
@@ -540,16 +663,29 @@
Vnrval = vn_const(int_const(I)),
VnTables = VnTables0
;
+ % e>>0 => e
+ Vnrval2 = vn_const(int_const(0))
+ ->
+ Vnrval = Vnrval1,
+ VnTables = VnTables0
+ ;
fail
)
;
Binop = (<<),
(
+ % c1<<c2 => c
Vnrval1 = vn_const(int_const(I1)),
Vnrval2 = vn_const(int_const(I2))
->
I is I1 << I2,
Vnrval = vn_const(int_const(I)),
+ VnTables = VnTables0
+ ;
+ % e<<0 => e
+ Vnrval2 = vn_const(int_const(0))
+ ->
+ Vnrval = Vnrval1,
VnTables = VnTables0
;
fail
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/Togl-1.2
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing library
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/diff
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/general
cvs diff: Diffing tests/hard_coded
Index: tests/hard_coded/Mmake
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmake,v
retrieving revision 1.52
diff -u -r1.52 Mmake
--- 1.52 1997/07/17 04:25:54
+++ Mmake 1997/07/23 04:39:07
@@ -23,6 +23,7 @@
elim_special_pred \
error_func \
expand \
+ float_map \
float_reg \
float_rounding_bug \
free_free_mode \
cvs diff: float_map.exp is a new entry, no comparison available
cvs diff: float_map.m is a new entry, no comparison available
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/valid
Index: tests/valid/Mmake
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmake,v
retrieving revision 1.47
diff -u -r1.47 Mmake
--- 1.47 1997/07/12 17:53:56
+++ Mmake 1997/07/23 07:04:32
@@ -21,6 +21,7 @@
det_condition.m \
det_inference.m \
det_switch.m \
+ double_vn.m \
easy_nondet_test.m \
easy_nondet_test_2.m \
empty_switch.m \
@@ -45,6 +46,7 @@
lambda_switch.m \
lambda_type.m \
lazy_list.m \
+ livevals_seq.m \
loop.m \
loop_in_disj.m \
middle_rec_labels.m \
@@ -93,7 +95,9 @@
GRADE-agc_unbound_typevars2 = asm_fast.agc
GRADE-agc_unused_in = asm_fast.agc
MCFLAGS-compl_unify_bug = -O3
+MCFLAGS-double_vn = -O4
MCFLAGS-higher_order_implied_mode = -O-1
+MCFLAGS-livevals_seq = -O5 --opt-space
MCFLAGS-middle_rec_labels = --middle-rec --no-follow-vars
MCFLAGS-pred_with_no_modes = --infer-all
MCFLAGS-simplify_bug = -O-1
cvs diff: double_vn.m is a new entry, no comparison available
cvs diff: livevals_seq.m is a new entry, no comparison available
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trial
cvs diff: Diffing util
::::::::::::::
tests/hard_coded/float_map.exp
::::::::::::::
did not find it: ok
::::::::::::::
tests/hard_coded/float_map.m
::::::::::::::
% This is a regression test. Some versions of the compiler fail it
% because of an improper implementation of comparison for floats.
:- module float_map.
:- interface.
:- import_module io.
:- pred main(io__state::di, io__state::uo) is det.
:- implementation.
:- import_module map, float.
main(S0, S) :-
map__init(M1),
map__det_insert(M1, 1.0, 5, M2),
( map__search(M2, 14.5, _) ->
io__write_string("found it: bug\n", S0, S)
;
io__write_string("did not find it: ok\n", S0, S)
).
::::::::::::::
tests/valid/double_vn.m
::::::::::::::
:- module double_vn.
:- interface.
:- pred p(int::out) is det.
:- implementation.
:- import_module int.
p(X) :-
X is 1 \/ 1 \/ 1.
::::::::::::::
tests/valid/livevals_seq.m
::::::::::::::
% This is a regression test. The compiler used to abort in this code
% when both frame optimization and value numbering were turned on but
% full jump optimization wasn't.
%
% The reason was that frameopt, in keeping the stack frame of det_insert_fcl,
% would generate the instruction sequence "livevals, assign to succip, goto",
% which violated an invariant expected by value numbering, namely that
% the livevals giving info about the variables live at a goto must
% immediately precede the goto. (Fulljump fixes the problem by eliminating
% the goto.)
:- module livevals_seq.
:- interface.
:- import_module list, tree234.
:- type map(K,V) == tree234(K,V).
:- pred det_insert_fcl(map(K,V), list(K),
list(V), map(K,V)).
:- mode det_insert_fcl(in, in, in, out) is det.
:- implementation.
:- import_module require.
det_insert_fcl(Map0, Ks, Vs, Map) :-
(
Ks = [Key | Keys], Vs = [Value | Values]
->
det_insert(Map0, Key, Value, Map1),
det_insert_fcl(Map1, Keys, Values, Map)
;
Ks = [], Vs = []
->
Map = Map0
;
error("lists do not correspond")
).
:- pred det_insert(map(K,V), K, V, map(K,V)).
:- mode det_insert(in, in, in, out) is det.
:- external(det_insert/4).
More information about the developers
mailing list