[m-rev.] diff: split up some very big predicates
Zoltan Somogyi
zs at csse.unimelb.edu.au
Thu Feb 4 10:23:07 AEDT 2010
compiler/jumpopt.m:
compiler/type_constraints.m:
compiler/write_dep_file.m:
Split up some of the compiler's biggest predicates.
There are no algorithmic changes, but in jumpopt, this diff
bundles up a bunch of parameters into a single structure.
This is probably why this diff improves the speed of the compiler
by 1.8%.
compiler/llds.m:
Add some insts needed by jumpopt.m.
Zoltan.
cvs diff: Diffing .
cvs diff: Diffing analysis
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/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.112
diff -u -b -r1.112 jumpopt.m
--- compiler/jumpopt.m 21 Oct 2009 06:36:19 -0000 1.112
+++ compiler/jumpopt.m 3 Feb 2010 23:17:13 -0000
@@ -81,22 +81,22 @@
% We then traverse the instruction list, using the information in the
% tables to short-circuit jumps.
%
-% Instrmap: Maps each label to the next real (non-comment, non-livevals)
+% InstrMap: Maps each label to the next real (non-comment, non-livevals)
% instruction after that label.
-% Lvalmap: Maps each label to yes(Livevals) if the label is followed
+% LvalMap: Maps each label to yes(Livevals) if the label is followed
% by a livevals instruction, and to no otherwise.
-% Blockmap: Maps each label to the block following that label.
+% BlockMap: Maps each label to the block following that label.
% This includes all instructions up to the first one that
% cannot fall through.
-% Procmap: Maps each label that begins a det epilog to the epilog.
-% Succmap: Maps each label that begins a nondet epilog to the epilog.
-% Sdprocmap: Maps each label that begins a semidet epilog to the epilog.
+% ProcMap: Maps each label that begins a det epilog to the epilog.
+% SuccMap: Maps each label that begins a nondet epilog to the epilog.
+% SdprocMap: Maps each label that begins a semidet epilog to the epilog.
% This can be the success epilog or the failure epilog.
-% Forkmap: Maps each label that begins a full semidet epilog (code to
+% ForkMap: Maps each label that begins a full semidet epilog (code to
% test r1, and to execute the the success or failure epilog
% depending on the result) to the epilog.
%
-% Blockmap will not contain the initial block of the procedure unless
+% BlockMap will not contain the initial block of the procedure unless
% Recjump is set. The intention is that Recjump will not be set until
% frameopt, which can do a better job of optimizing this block, have
% been applied.
@@ -104,34 +104,35 @@
optimize_jumps_in_proc(LayoutLabels, MayAlterRtti, ProcLabel, Fulljumpopt,
Recjump, PessimizeTailCalls, CheckedNondetTailCall, !C, !Instrs,
Mod) :-
- some [!Instrmap, !Blockmap, !Lvalmap, !Procmap, !Sdprocmap, !Succmap,
- !Forkmap]
+ some [!InstrMap, !BlockMap, !LvalMap, !ProcMap, !SdprocMap, !SuccMap,
+ !ForkMap]
(
Instrs0 = !.Instrs,
- map.init(!:Instrmap),
- map.init(!:Blockmap),
- map.init(!:Lvalmap),
- map.init(!:Procmap),
- map.init(!:Sdprocmap),
- map.init(!:Succmap),
- jump_opt_build_maps(!.Instrs, Recjump, !Instrmap, !Blockmap, !Lvalmap,
- !Procmap, !Sdprocmap, !Succmap),
- jump_opt_build_forkmap(!.Instrs, !.Sdprocmap, map.init, !:Forkmap),
+ map.init(!:InstrMap),
+ map.init(!:BlockMap),
+ map.init(!:LvalMap),
+ map.init(!:ProcMap),
+ map.init(!:SdprocMap),
+ map.init(!:SuccMap),
+ jump_opt_build_maps(!.Instrs, Recjump, !InstrMap, !BlockMap, !LvalMap,
+ !ProcMap, !SdprocMap, !SuccMap),
+ jump_opt_build_forkmap(!.Instrs, !.SdprocMap, map.init, !:ForkMap),
(
PessimizeTailCalls = no
;
PessimizeTailCalls = yes,
- !:Procmap = map.init,
- !:Sdprocmap = map.init,
- !:Succmap = map.init,
- !:Forkmap = map.init
- ),
+ !:ProcMap = map.init,
+ !:SdprocMap = map.init,
+ !:SuccMap = map.init,
+ !:ForkMap = map.init
+ ),
+ JumpOptInfo = jump_opt_info(!.InstrMap, !.BlockMap, !.LvalMap,
+ !.ProcMap, !.SdprocMap, !.ForkMap, !.SuccMap, LayoutLabels,
+ Fulljumpopt, MayAlterRtti),
(
CheckedNondetTailCall = yes,
CheckedNondetTailCallInfo0 = yes(ProcLabel - !.C),
- jump_opt_instr_list(!.Instrs, comment(""), !.Instrmap, !.Blockmap,
- !.Lvalmap, !.Procmap, !.Sdprocmap, !.Forkmap, !.Succmap,
- LayoutLabels, Fulljumpopt, MayAlterRtti,
+ jump_opt_instr_list(!.Instrs, comment(""), JumpOptInfo,
CheckedNondetTailCallInfo0, CheckedNondetTailCallInfo,
[], RevInstrs),
(
@@ -144,9 +145,7 @@
;
CheckedNondetTailCall = no,
CheckedNondetTailCallInfo0 = no,
- jump_opt_instr_list(!.Instrs, comment(""), !.Instrmap, !.Blockmap,
- !.Lvalmap, !.Procmap, !.Sdprocmap, !.Forkmap, !.Succmap,
- LayoutLabels, Fulljumpopt, MayAlterRtti,
+ jump_opt_instr_list(!.Instrs, comment(""), JumpOptInfo,
CheckedNondetTailCallInfo0, _, [], RevInstrs)
),
list.reverse(RevInstrs, !:Instrs),
@@ -165,36 +164,36 @@
lvalmap::in, lvalmap::out, tailmap::in, tailmap::out,
tailmap::in, tailmap::out, tailmap::in, tailmap::out) is det.
-jump_opt_build_maps([], _, !Instrmap, !Blockmap,
- !Lvalmap, !Procmap, !Sdprocmap, !Succmap).
-jump_opt_build_maps([Instr0 | Instrs0], Recjump, !Instrmap, !Blockmap,
- !Lvalmap, !Procmap, !Sdprocmap, !Succmap) :-
+jump_opt_build_maps([], _, !InstrMap, !BlockMap,
+ !LvalMap, !ProcMap, !SdprocMap, !SuccMap).
+jump_opt_build_maps([Instr0 | Instrs0], Recjump, !InstrMap, !BlockMap,
+ !LvalMap, !ProcMap, !SdprocMap, !SuccMap) :-
Instr0 = llds_instr(Uinstr0, _),
( Uinstr0 = label(Label) ->
opt_util.skip_comments(Instrs0, Instrs1),
( Instrs1 = [Instr1 | _], Instr1 = llds_instr(livevals(_), _) ->
- svmap.det_insert(Label, yes(Instr1), !Lvalmap)
+ svmap.det_insert(Label, yes(Instr1), !LvalMap)
;
- svmap.det_insert(Label, no, !Lvalmap)
+ svmap.det_insert(Label, no, !LvalMap)
),
opt_util.skip_comments_livevals(Instrs1, Instrs2),
( Instrs2 = [Instr2 | _] ->
- svmap.det_insert(Label, Instr2, !Instrmap)
+ svmap.det_insert(Label, Instr2, !InstrMap)
;
true
),
( opt_util.is_proceed_next(Instrs1, Between1) ->
- svmap.det_insert(Label, Between1, !Procmap)
+ svmap.det_insert(Label, Between1, !ProcMap)
;
true
),
( opt_util.is_sdproceed_next(Instrs1, Between2) ->
- svmap.det_insert(Label, Between2, !Sdprocmap)
+ svmap.det_insert(Label, Between2, !SdprocMap)
;
true
),
( opt_util.is_succeed_next(Instrs1, Between3) ->
- svmap.det_insert(Label, Between3, !Succmap)
+ svmap.det_insert(Label, Between3, !SuccMap)
;
true
),
@@ -206,15 +205,15 @@
)
->
opt_util.find_no_fallthrough(Instrs1, Block),
- svmap.det_insert(Label, Block, !Blockmap)
+ svmap.det_insert(Label, Block, !BlockMap)
;
true
)
;
true
),
- jump_opt_build_maps(Instrs0, Recjump, !Instrmap, !Blockmap, !Lvalmap,
- !Procmap, !Sdprocmap, !Succmap).
+ jump_opt_build_maps(Instrs0, Recjump, !InstrMap, !BlockMap, !LvalMap,
+ !ProcMap, !SdprocMap, !SuccMap).
% Find labels followed by a test of r1 where both paths set r1 to
% its original value and proceed.
@@ -222,21 +221,35 @@
:- pred jump_opt_build_forkmap(list(instruction)::in, tailmap::in,
tailmap::in, tailmap::out) is det.
-jump_opt_build_forkmap([], _Sdprocmap, !Forkmap).
-jump_opt_build_forkmap([llds_instr(Uinstr, _Comment) | Instrs], Sdprocmap,
- !Forkmap) :-
+jump_opt_build_forkmap([], _SdprocMap, !ForkMap).
+jump_opt_build_forkmap([llds_instr(Uinstr, _Comment) | Instrs], SdprocMap,
+ !ForkMap) :-
(
Uinstr = label(Label),
- opt_util.is_forkproceed_next(Instrs, Sdprocmap, Between)
+ opt_util.is_forkproceed_next(Instrs, SdprocMap, Between)
->
- svmap.det_insert(Label, Between, !Forkmap)
+ svmap.det_insert(Label, Between, !ForkMap)
;
true
),
- jump_opt_build_forkmap(Instrs, Sdprocmap, !Forkmap).
+ jump_opt_build_forkmap(Instrs, SdprocMap, !ForkMap).
%-----------------------------------------------------------------------------%
+:- type jump_opt_info
+ ---> jump_opt_info(
+ joi_instr_map :: instrmap,
+ joi_block_map :: tailmap,
+ joi_lval_map :: lvalmap,
+ joi_proc_map :: tailmap,
+ joi_sdproc_map :: tailmap,
+ joi_fork_map :: tailmap,
+ joi_succ_map :: tailmap,
+ joi_layout_labels :: set(label),
+ joi_full_jump_opt :: bool,
+ joi_may_alter_rtti :: may_alter_rtti
+ ).
+
:- type new_remain
---> specified(
new_instructions :: list(instruction),
@@ -272,42 +285,212 @@
% building it in right order would make instr_list not tail recursive,
% and thus unable to handle very long instruction lists.
%
-:- pred jump_opt_instr_list(list(instruction)::in, instr::in, instrmap::in,
- tailmap::in, lvalmap::in, tailmap::in, tailmap::in, tailmap::in,
- tailmap::in, set(label)::in, bool::in, may_alter_rtti::in,
+:- pred jump_opt_instr_list(list(instruction)::in, instr::in,
+ jump_opt_info::in,
maybe(pair(proc_label, counter))::in,
maybe(pair(proc_label, counter))::out,
list(instruction)::in, list(instruction)::out) is det.
-jump_opt_instr_list([], _PrevInstr, _Instrmap, _Blockmap, _Lvalmap,
- _Procmap, _Sdprocmap, _Forkmap, _Succmap, _LayoutLabels,
- _Fulljumpopt, _MayAlterRtti, !CheckedNondetTailCallInfo, !RevInstrs).
-jump_opt_instr_list([Instr0 | Instrs0], PrevInstr, Instrmap, Blockmap,
- Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap, LayoutLabels,
- Fulljumpopt, MayAlterRtti, !CheckedNondetTailCallInfo, !RevInstrs) :-
+jump_opt_instr_list([], _PrevInstr, _, !CheckedNondetTailCallInfo, !RevInstrs).
+jump_opt_instr_list([Instr0 | Instrs0], PrevInstr, JumpOptInfo,
+ !CheckedNondetTailCallInfo, !RevInstrs) :-
Instr0 = llds_instr(Uinstr0, Comment0),
% We do a switch on the instruction type to ensure that we short circuit
- % all the labels that are in Instrmap but not in LayoutLabels in *all*
+ % all the labels that are in InstrMap but not in LayoutLabels in *all*
% instructions in which they occur. This means we must fully search
% every part of every instruction that may possibly hold a label.
% In theory, this means every lval and every rval, but in practice we
% know that rvals representing e.g. the tags of fields cannot contain
% labels.
(
- Uinstr0 = llcall(Proc, RetAddr, LiveInfos, Context, GoalPath,
- CallModel),
+ Uinstr0 = llcall(_, _, _, _, _, _),
+ jump_opt_llcall(Uinstr0, Comment0, Instrs0, PrevInstr, JumpOptInfo,
+ !CheckedNondetTailCallInfo, NewRemain)
+ ;
+ Uinstr0 = goto(_),
+ jump_opt_goto(Uinstr0, Comment0, Instrs0, PrevInstr, JumpOptInfo,
+ !CheckedNondetTailCallInfo, NewRemain)
+ ;
+ Uinstr0 = computed_goto(Index, MaybeTargets0),
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ % Short-circuit all the destination labels.
+ short_maybe_labels(InstrMap, MaybeTargets0, MaybeTargets),
+ ( MaybeTargets = MaybeTargets0 ->
+ NewRemain = usual_case
+ ;
+ Shorted = Comment0 ++ " (some shortcircuits)",
+ NewInstrs =
+ [llds_instr(computed_goto(Index, MaybeTargets), Shorted)],
+ NewRemain = specified(NewInstrs, Instrs0)
+ )
+ ;
+ Uinstr0 = if_val(_, _),
+ jump_opt_if_val(Uinstr0, Comment0, Instrs0, PrevInstr, JumpOptInfo,
+ !CheckedNondetTailCallInfo, NewRemain)
+ ;
+ Uinstr0 = assign(Lval, Rval0),
+ % Any labels mentioned in Rval0 should be short-circuited.
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ short_labels_rval(InstrMap, Rval0, Rval),
+ ( Rval = Rval0 ->
+ NewRemain = usual_case
+ ;
+ Shorted = Comment0 ++ " (some shortcircuits)",
+ NewInstrs = [llds_instr(assign(Lval, Rval), Shorted)],
+ NewRemain = specified(NewInstrs, Instrs0)
+ )
+ ;
+ Uinstr0 = keep_assign(Lval, Rval0),
+ % Any labels mentioned in Rval0 should be short-circuited.
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ short_labels_rval(InstrMap, Rval0, Rval),
+ ( Rval = Rval0 ->
+ NewRemain = usual_case
+ ;
+ Shorted = Comment0 ++ " (some shortcircuits)",
+ NewInstrs = [llds_instr(keep_assign(Lval, Rval), Shorted)],
+ NewRemain = specified(NewInstrs, Instrs0)
+ )
+ ;
+ Uinstr0 = mkframe(FrameInfo, Redoip),
+ ( Redoip = yes(code_label(Label0)) ->
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ short_label(InstrMap, Label0, Label),
+ ( Label = Label0 ->
+ NewRemain = usual_case
+ ;
+ Shorted = Comment0 ++ " (some shortcircuits)",
+ NewInstrs =
+ [llds_instr(mkframe(FrameInfo, yes(code_label(Label))),
+ Shorted)],
+ NewRemain = specified(NewInstrs, Instrs0)
+ )
+ ;
+ NewRemain = usual_case
+ )
+ ;
+ Uinstr0 = foreign_proc_code(_, _, _, _, _, _, _, _, _, _),
+ jump_opt_foreign_proc_code(Uinstr0, Comment0, Instrs0, PrevInstr,
+ JumpOptInfo, !CheckedNondetTailCallInfo, NewRemain)
+ ;
+ Uinstr0 = block(_, _, _),
+ % These are supposed to be introduced only after jumpopt is run
+ % for the last time.
+ unexpected(this_file, "jump_opt_instr_list: block")
+ ;
+ Uinstr0 = fork_new_child(SyncTerm, Child0),
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ short_label(InstrMap, Child0, Child),
+ ( Child = Child0 ->
+ NewRemain = usual_case
+ ;
+ Uinstr = fork_new_child(SyncTerm, Child),
+ Comment = Comment0 ++ " (redirect)",
+ Instr = llds_instr(Uinstr, Comment),
+ NewRemain = specified([Instr], Instrs0)
+ )
+ ;
+ Uinstr0 = join_and_continue(SyncTerm, Label0),
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ short_label(InstrMap, Label0, Label),
+ ( Label = Label0 ->
+ NewRemain = usual_case
+ ;
+ Uinstr = join_and_continue(SyncTerm, Label),
+ Comment = Comment0 ++ " (redirect)",
+ Instr = llds_instr(Uinstr, Comment),
+ NewRemain = specified([Instr], Instrs0)
+ )
+ ;
+ ( Uinstr0 = arbitrary_c_code(_, _, _)
+ ; Uinstr0 = comment(_)
+ ; Uinstr0 = livevals(_)
+ ; Uinstr0 = label(_)
+ ; Uinstr0 = save_maxfr(_)
+ ; Uinstr0 = restore_maxfr(_)
+ ; Uinstr0 = incr_sp(_, _, _)
+ ; Uinstr0 = decr_sp(_)
+ ; Uinstr0 = decr_sp_and_return(_)
+ ; Uinstr0 = push_region_frame(_, _)
+ ; Uinstr0 = region_fill_frame(_, _, _, _, _)
+ ; Uinstr0 = region_set_fixed_slot(_, _, _)
+ ; Uinstr0 = use_and_maybe_pop_region_frame(_, _)
+ ; Uinstr0 = store_ticket(_)
+ ; Uinstr0 = reset_ticket(_, _)
+ ; Uinstr0 = discard_ticket
+ ; Uinstr0 = prune_ticket
+ ; Uinstr0 = prune_tickets_to(_)
+ ; Uinstr0 = mark_ticket_stack(_)
+ ; Uinstr0 = mark_hp(_)
+ ; Uinstr0 = free_heap(_)
+ ; Uinstr0 = incr_hp(_, _, _, _, _, _, _, _)
+ ; Uinstr0 = restore_hp(_)
+ ; Uinstr0 = init_sync_term(_, _)
+ ),
+ NewRemain = usual_case
+ ),
+ (
+ NewRemain = usual_case,
+ ReplacementInstrsEmpty = no,
+ RecurseInstrs = Instrs0,
+ !:RevInstrs = [Instr0 | !.RevInstrs]
+ ;
+ NewRemain = specified(ReplacementInstrs, RecurseInstrs),
+ % ReplacementInstrs are in the right order, but they will be reversed
+ % by our caller. We therefore reverse them here, which allows that
+ % final reverse to put them in the right order.
+ !:RevInstrs = list.reverse(ReplacementInstrs) ++ !.RevInstrs,
+ (
+ ReplacementInstrs = [],
+ ReplacementInstrsEmpty = yes
+ ;
+ ReplacementInstrs = [_ | _],
+ ReplacementInstrsEmpty = no
+ )
+ ),
+ (
+ ( Uinstr0 = comment(_)
+ ; ReplacementInstrsEmpty = yes
+ )
+ ->
+ NewPrevInstr = PrevInstr
+ ;
+ NewPrevInstr = Uinstr0
+ ),
+ jump_opt_instr_list(RecurseInstrs, NewPrevInstr, JumpOptInfo,
+ !CheckedNondetTailCallInfo, !RevInstrs).
+
+:- pred jump_opt_llcall(instr::in(instr_llcall), string::in,
+ list(instruction)::in, instr::in, jump_opt_info::in,
+ maybe(pair(proc_label, counter))::in,
+ maybe(pair(proc_label, counter))::out,
+ new_remain::out) is det.
+
+jump_opt_llcall(Uinstr0, Comment0, Instrs0, PrevInstr, JumpOptInfo,
+ !CheckedNondetTailCallInfo, NewRemain) :-
+ Uinstr0 = llcall(Proc, RetAddr, LiveInfos, Context, GoalPath, CallModel),
( RetAddr = code_label(RetLabel) ->
(
+ (
+ JumpOptInfo ^ joi_may_alter_rtti = must_not_alter_rtti
+ ;
+ LayoutLabels = JumpOptInfo ^ joi_layout_labels,
+ set.member(RetLabel, LayoutLabels)
+ )
+ ->
+ % We cannot optimize the call. Test for this once, here, instead
+ % of at the end of each of the following conditions.
+ NewRemain = usual_case
+ ;
% Look for det style tailcalls. We look for this even if
% the call is semidet, because one of the optimizations below
% turns a pair of semidet epilogs into a det epilog.
( CallModel = call_model_det
; CallModel = call_model_semidet
),
- map.search(Procmap, RetLabel, Between0),
- PrevInstr = livevals(Livevals),
- MayAlterRtti = may_alter_rtti,
- not set.member(RetLabel, LayoutLabels)
+ ProcMap = JumpOptInfo ^ joi_proc_map,
+ map.search(ProcMap, RetLabel, Between0),
+ PrevInstr = livevals(Livevals)
->
opt_util.filter_out_livevals(Between0, Between1),
NewInstrs = Between1 ++ [llds_instr(livevals(Livevals), ""),
@@ -316,10 +499,9 @@
;
% Look for semidet style tailcalls.
CallModel = call_model_semidet,
- map.search(Forkmap, RetLabel, Between),
- PrevInstr = livevals(Livevals),
- MayAlterRtti = may_alter_rtti,
- not set.member(RetLabel, LayoutLabels)
+ ForkMap = JumpOptInfo ^ joi_fork_map,
+ map.search(ForkMap, RetLabel, Between),
+ PrevInstr = livevals(Livevals)
->
NewInstrs = Between ++ [llds_instr(livevals(Livevals), ""),
llds_instr(goto(Proc), redirect_comment(Comment0))],
@@ -328,12 +510,10 @@
% Look for nondet style tailcalls which do not need
% a runtime check.
CallModel = call_model_nondet(unchecked_tail_call),
- map.search(Succmap, RetLabel, BetweenIncl),
- BetweenIncl = [llds_instr(livevals(_), _),
- llds_instr(goto(_), _)],
- PrevInstr = livevals(Livevals),
- MayAlterRtti = may_alter_rtti,
- not set.member(RetLabel, LayoutLabels)
+ SuccMap = JumpOptInfo ^ joi_succ_map,
+ map.search(SuccMap, RetLabel, BetweenIncl),
+ BetweenIncl = [llds_instr(livevals(_), _), llds_instr(goto(_), _)],
+ PrevInstr = livevals(Livevals)
->
NewInstrs = [
llds_instr(assign(maxfr, lval(prevfr_slot(lval(curfr)))),
@@ -351,12 +531,11 @@
% a runtime check.
CallModel = call_model_nondet(checked_tail_call),
!.CheckedNondetTailCallInfo = yes(ProcLabel - Counter0),
- map.search(Succmap, RetLabel, BetweenIncl),
+ SuccMap = JumpOptInfo ^ joi_succ_map,
+ map.search(SuccMap, RetLabel, BetweenIncl),
BetweenIncl = [llds_instr(livevals(_), _),
llds_instr(goto(_), _)],
- PrevInstr = livevals(Livevals),
- MayAlterRtti = may_alter_rtti,
- not set.member(RetLabel, LayoutLabels)
+ PrevInstr = livevals(Livevals)
->
counter.allocate(LabelNum, Counter0, Counter1),
NewLabel = internal_label(LabelNum, ProcLabel),
@@ -374,20 +553,18 @@
llds_instr(goto(Proc), redirect_comment(Comment0)),
llds_instr(label(NewLabel), "non tail call"),
llds_instr(livevals(Livevals), ""),
- Instr0
+ llds_instr(Uinstr0, Comment0)
],
NewRemain = specified(NewInstrs, Instrs0),
!:CheckedNondetTailCallInfo = yes(ProcLabel - Counter1)
;
% Short circuit the return label if possible.
- map.search(Instrmap, RetLabel, RetInstr),
- MayAlterRtti = may_alter_rtti,
- not set.member(RetLabel, LayoutLabels)
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ map.search(InstrMap, RetLabel, RetInstr)
->
- final_dest(Instrmap, RetLabel, DestLabel,
- RetInstr, _DestInstr),
+ final_dest(InstrMap, RetLabel, DestLabel, RetInstr, _DestInstr),
( RetLabel = DestLabel ->
- NewInstrs = [Instr0]
+ NewInstrs = [llds_instr(Uinstr0, Comment0)]
;
NewInstrs = [llds_instr(llcall(Proc, code_label(DestLabel),
LiveInfos, Context, GoalPath, CallModel),
@@ -399,8 +576,16 @@
)
;
NewRemain = usual_case
- )
- ;
+ ).
+
+:- pred jump_opt_goto(instr::in(instr_goto), string::in,
+ list(instruction)::in, instr::in, jump_opt_info::in,
+ maybe(pair(proc_label, counter))::in,
+ maybe(pair(proc_label, counter))::out,
+ new_remain::out) is det.
+
+jump_opt_goto(Uinstr0, Comment0, Instrs0, PrevInstr, JumpOptInfo,
+ !CheckedNondetTailCallInfo, NewRemain) :-
Uinstr0 = goto(TargetAddr),
( TargetAddr = code_label(TargetLabel) ->
(
@@ -419,11 +604,12 @@
% we could use profiling feedback on this.
% We cannot eliminate the instruction here because
% that would require altering the if_val instruction.
- NewInstrs = [Instr0],
+ NewInstrs = [llds_instr(Uinstr0, Comment0)],
NewRemain = specified(NewInstrs, Instrs0)
;
% Replace a jump to a det epilog with the epilog.
- map.search(Procmap, TargetLabel, Between0)
+ ProcMap = JumpOptInfo ^ joi_proc_map,
+ map.search(ProcMap, TargetLabel, Between0)
->
adjust_livevals(PrevInstr, Between0, Between),
NewInstrs = Between ++
@@ -431,7 +617,8 @@
NewRemain = specified(NewInstrs, Instrs0)
;
% Replace a jump to a semidet epilog with the epilog.
- map.search(Sdprocmap, TargetLabel, Between0)
+ SdprocMap = JumpOptInfo ^ joi_sdproc_map,
+ map.search(SdprocMap, TargetLabel, Between0)
->
adjust_livevals(PrevInstr, Between0, Between),
NewInstrs = Between ++
@@ -439,50 +626,50 @@
NewRemain = specified(NewInstrs, Instrs0)
;
% Replace a jump to a nondet epilog with the epilog.
- map.search(Succmap, TargetLabel, BetweenIncl0)
+ SuccMap = JumpOptInfo ^ joi_succ_map,
+ map.search(SuccMap, TargetLabel, BetweenIncl0)
->
adjust_livevals(PrevInstr, BetweenIncl0, NewInstrs),
NewRemain = specified(NewInstrs, Instrs0)
;
- % Replace a jump to a non-epilog block with the
- % block itself. These jumps are treated separately
- % from jumps to epilog blocks, for two reasons.
- % First, epilog blocks are always short, so we
- % always want to replace jumps to them, whereas
- % other blocks may be long, so we want to replace
- % jumps to them only if the fulljumps option
- % was given. Second, non-epilog blocks may contain
- % branches to other labels in this procedure, and
- % we want to make sure that these are short-circuited.
- % This short-circuiting is necessary because
- % another optimization below eliminates labels,
- % which is correct only if jumps to those labels
- % are short-circuited everywhere.
- Fulljumpopt = yes,
- map.search(Instrmap, TargetLabel, TargetInstr),
- final_dest(Instrmap, TargetLabel, DestLabel,
+ % Replace a jump to a non-epilog block with the block itself.
+ % These jumps are treated separately from jumps to epilog blocks,
+ % for two reasons. First, epilog blocks are always short, so we
+ % always want to replace jumps to them, whereas other blocks
+ % may be long, so we want to replace jumps to them only if the
+ % fulljumps option was given. Second, non-epilog blocks may contain
+ % branches to other labels in this procedure, and we want to
+ % make sure that these are short-circuited. This short-circuiting
+ % is necessary because another optimization below eliminates
+ % labels, which is correct only if jumps to those labels are
+ % short-circuited everywhere.
+ JumpOptInfo ^ joi_full_jump_opt = yes,
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ map.search(InstrMap, TargetLabel, TargetInstr),
+ final_dest(InstrMap, TargetLabel, DestLabel,
TargetInstr, _DestInstr),
- map.search(Blockmap, DestLabel, Block),
+ BlockMap = JumpOptInfo ^ joi_block_map,
+ map.search(BlockMap, DestLabel, Block),
block_may_be_duplicated(Block) = yes
->
opt_util.filter_out_labels(Block, FilteredBlock),
- adjust_livevals(PrevInstr, FilteredBlock,
- AdjustedBlock),
- % Block may end with a goto to DestLabel. We avoid
- % infinite expansion in such cases by removing
- % DestLabel from Blockmap, though only while
- % processing AdjustedBlock.
- map.delete(Blockmap, DestLabel, CrippledBlockmap),
- jump_opt_instr_list(AdjustedBlock, comment(""), Instrmap,
- CrippledBlockmap, Lvalmap, Procmap, Sdprocmap, Forkmap,
- Succmap, LayoutLabels, Fulljumpopt, MayAlterRtti,
- !CheckedNondetTailCallInfo, [], RevNewInstrs),
+ adjust_livevals(PrevInstr, FilteredBlock, AdjustedBlock),
+ % Block may end with a goto to DestLabel. We avoid infinite
+ % expansion in such cases by removing DestLabel from BlockMap,
+ % though only while processing AdjustedBlock.
+ map.delete(BlockMap, DestLabel, CrippledBlockMap),
+ CrippledJumpOptInfo = JumpOptInfo ^ joi_block_map :=
+ CrippledBlockMap,
+ jump_opt_instr_list(AdjustedBlock, comment(""),
+ CrippledJumpOptInfo, !CheckedNondetTailCallInfo,
+ [], RevNewInstrs),
NewRemain = specified(list.reverse(RevNewInstrs), Instrs0)
;
% Short-circuit the goto.
- map.search(Instrmap, TargetLabel, TargetInstr)
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ map.search(InstrMap, TargetLabel, TargetInstr)
->
- final_dest(Instrmap, TargetLabel, DestLabel,
+ final_dest(InstrMap, TargetLabel, DestLabel,
TargetInstr, DestInstr),
DestInstr = llds_instr(UdestInstr, _Destcomment),
Shorted = "shortcircuited jump: " ++ Comment0,
@@ -493,15 +680,15 @@
;
Canfallthrough = yes,
( TargetLabel = DestLabel ->
- NewInstrs0 = [Instr0]
+ NewInstrs0 = [llds_instr(Uinstr0, Comment0)]
;
NewInstrs0 =
[llds_instr(goto(code_label(DestLabel)), Shorted)]
)
),
- ( map.search(Lvalmap, DestLabel, yes(Lvalinstr)) ->
- adjust_livevals(PrevInstr, [Lvalinstr | NewInstrs0],
- NewInstrs)
+ LvalMap = JumpOptInfo ^ joi_lval_map,
+ ( map.search(LvalMap, DestLabel, yes(Lvalinstr)) ->
+ adjust_livevals(PrevInstr, [Lvalinstr | NewInstrs0], NewInstrs)
;
NewInstrs = NewInstrs0
),
@@ -511,22 +698,21 @@
)
;
NewRemain = usual_case
- )
- ;
- Uinstr0 = computed_goto(Index, MaybeTargets0),
- % Short-circuit all the destination labels.
- short_maybe_labels(Instrmap, MaybeTargets0, MaybeTargets),
- ( MaybeTargets = MaybeTargets0 ->
- NewRemain = usual_case
- ;
- Shorted = Comment0 ++ " (some shortcircuits)",
- NewInstrs =
- [llds_instr(computed_goto(Index, MaybeTargets), Shorted)],
- NewRemain = specified(NewInstrs, Instrs0)
- )
- ;
+ ).
+
+:- pred jump_opt_if_val(instr::in(instr_if_val), string::in,
+ list(instruction)::in, instr::in, jump_opt_info::in,
+ maybe(pair(proc_label, counter))::in,
+ maybe(pair(proc_label, counter))::out,
+ new_remain::out) is det.
+
+jump_opt_if_val(Uinstr0, Comment0, Instrs0, _PrevInstr, JumpOptInfo,
+ !CheckedNondetTailCallInfo, NewRemain) :-
Uinstr0 = if_val(Cond, TargetAddr),
( TargetAddr = code_label(TargetLabel) ->
+ JumpOptInfo = jump_opt_info(InstrMap, BlockMap, _LvalMap,
+ _ProcMap, _SdprocMap, _ForkMap, _SuccMap, LayoutLabels,
+ Fulljumpopt, _MayAlterRtti),
(
% Attempt to transform code such as
%
@@ -565,8 +751,7 @@
LabelInstr = llds_instr(label(TargetLabel), _)
->
code_util.neg_rval(Cond, NotCond),
- NewInstr =
- llds_instr(if_val(NotCond, GotoTarget), GotoComment),
+ NewInstr = llds_instr(if_val(NotCond, GotoTarget), GotoComment),
NewInstrs = [],
% The transformed code may fit the pattern again,
% so make sure that we look for the pattern again
@@ -597,13 +782,13 @@
% if_val, to get the recursive call to replace the goto
% to L1 with the code at L1.
Fulljumpopt = yes,
- map.search(Blockmap, TargetLabel, _TargetBlock),
+ map.search(BlockMap, TargetLabel, _TargetBlock),
opt_util.skip_comments(Instrs0, Instrs1),
Instrs1 = [GotoInstr | AfterGoto],
GotoInstr = llds_instr(goto(GotoAddr), GotoComment),
\+ (
GotoAddr = code_label(GotoLabel),
- map.search(Blockmap, GotoLabel, _)
+ map.search(BlockMap, GotoLabel, _)
)
->
code_util.neg_rval(Cond, NotCond),
@@ -616,9 +801,9 @@
RemainInstrs = [NewGotoInstr | AfterGoto],
NewRemain = specified(NewInstrs, RemainInstrs)
;
- map.search(Instrmap, TargetLabel, TargetInstr)
+ map.search(InstrMap, TargetLabel, TargetInstr)
->
- final_dest(Instrmap, TargetLabel, DestLabel,
+ final_dest(InstrMap, TargetLabel, DestLabel,
TargetInstr, _DestInstr),
(
% Attempt to transform code such as
@@ -637,12 +822,10 @@
% <epilog>
%
opt_util.is_sdproceed_next(Instrs0, BetweenFT),
- map.search(Blockmap, DestLabel, Block),
+ map.search(BlockMap, DestLabel, Block),
opt_util.is_sdproceed_next(Block, BetweenBR),
- opt_util.filter_out_r1(BetweenFT, yes(SuccessFT),
- Between),
- opt_util.filter_out_r1(BetweenBR, yes(SuccessBR),
- Between),
+ opt_util.filter_out_r1(BetweenFT, yes(SuccessFT), Between),
+ opt_util.filter_out_r1(BetweenBR, yes(SuccessBR), Between),
(
SuccessFT = llconst_true,
SuccessBR = llconst_false,
@@ -669,8 +852,7 @@
->
Shorted = "shortcircuited jump: " ++ Comment0,
NewInstrs = [
- llds_instr(if_val(Cond, code_label(DestLabel)),
- Shorted)
+ llds_instr(if_val(Cond, code_label(DestLabel)), Shorted)
],
NewRemain = specified(NewInstrs, Instrs0)
;
@@ -681,55 +863,26 @@
)
;
NewRemain = usual_case
- )
- ;
- Uinstr0 = assign(Lval, Rval0),
- % Any labels mentioned in Rval0 should be short-circuited.
- short_labels_rval(Instrmap, Rval0, Rval),
- ( Rval = Rval0 ->
- NewRemain = usual_case
- ;
- Shorted = Comment0 ++ " (some shortcircuits)",
- NewInstrs = [llds_instr(assign(Lval, Rval), Shorted)],
- NewRemain = specified(NewInstrs, Instrs0)
- )
- ;
- Uinstr0 = keep_assign(Lval, Rval0),
- % Any labels mentioned in Rval0 should be short-circuited.
- short_labels_rval(Instrmap, Rval0, Rval),
- ( Rval = Rval0 ->
- NewRemain = usual_case
- ;
- Shorted = Comment0 ++ " (some shortcircuits)",
- NewInstrs = [llds_instr(keep_assign(Lval, Rval), Shorted)],
- NewRemain = specified(NewInstrs, Instrs0)
- )
- ;
- Uinstr0 = mkframe(FrameInfo, Redoip),
- ( Redoip = yes(code_label(Label0)) ->
- short_label(Instrmap, Label0, Label),
- ( Label = Label0 ->
- NewRemain = usual_case
- ;
- Shorted = Comment0 ++ " (some shortcircuits)",
- NewInstrs =
- [llds_instr(mkframe(FrameInfo, yes(code_label(Label))),
- Shorted)],
- NewRemain = specified(NewInstrs, Instrs0)
- )
- ;
- NewRemain = usual_case
- )
- ;
+ ).
+
+:- pred jump_opt_foreign_proc_code(instr::in(instr_foreign_proc_code),
+ string::in, list(instruction)::in, instr::in, jump_opt_info::in,
+ maybe(pair(proc_label, counter))::in,
+ maybe(pair(proc_label, counter))::out,
+ new_remain::out) is det.
+
+jump_opt_foreign_proc_code(Uinstr0, Comment0, Instrs0, _PrevInstr,
+ JumpOptInfo, !CheckedNondetTailCallInfo, NewRemain) :-
Uinstr0 = foreign_proc_code(Decls, Components0, MayCallMercury,
MaybeFixNoLayout, MaybeFixLayout, MaybeFixOnlyLayout,
MaybeNoFix0, MaybeDefLabel, StackSlotRef, MaybeDup),
some [!Redirect] (
- list.map_foldl(short_foreign_proc_component(Instrmap),
+ InstrMap = JumpOptInfo ^ joi_instr_map,
+ list.map_foldl(short_foreign_proc_component(InstrMap),
Components0, Components, no, !:Redirect),
(
MaybeNoFix0 = yes(NoFix),
- short_label(Instrmap, NoFix, NoFixDest),
+ short_label(InstrMap, NoFix, NoFixDest),
MaybeNoFix = yes(NoFixDest),
!:Redirect = yes
;
@@ -738,12 +891,12 @@
),
% These sanity checks are too strong, because we don't prohibit labels
% appearing these slots of foreign_proc_code instructions from appearing
-% in Instrmap; we only prohibit the use of those entries in Instrmap
+% in InstrMap; we only prohibit the use of those entries in InstrMap
% to optimize away these labels.
%
% (
% MaybeFixNoLayout = yes(FixNoLayout),
-% short_label(Instrmap, FixNoLayout, FixNoLayoutDest),
+% short_label(InstrMap, FixNoLayout, FixNoLayoutDest),
% FixNoLayoutDest \= FixNoLayout
% ->
% error("jump_opt_instr_list: foreign_proc_code fix_no_layout")
@@ -752,7 +905,7 @@
% ),
% (
% MaybeFixLayout = yes(FixLayout),
-% short_label(Instrmap, FixLayout, FixLayoutDest),
+% short_label(InstrMap, FixLayout, FixLayoutDest),
% FixLayoutDest \= FixLayout
% ->
% error("jump_opt_instr_list: foreign_proc_code fix_layout")
@@ -761,7 +914,7 @@
% ),
% (
% MaybeFixOnlyLayout = yes(FixOnlyLayout),
-% short_label(Instrmap, FixOnlyLayout, FixOnlyLayoutDest),
+% short_label(InstrMap, FixOnlyLayout, FixOnlyLayoutDest),
% FixOnlyLayoutDest \= FixOnlyLayout
% ->
% error("jump_opt_instr_list: foreign_proc_code fix_only_layout")
@@ -780,93 +933,7 @@
Instr = llds_instr(Uinstr, Comment),
NewRemain = specified([Instr], Instrs0)
)
- )
- ;
- Uinstr0 = block(_, _, _),
- % These are supposed to be introduced only after jumpopt is run
- % for the last time.
- unexpected(this_file, "instr_list: block")
- ;
- Uinstr0 = fork_new_child(SyncTerm, Child0),
- short_label(Instrmap, Child0, Child),
- ( Child = Child0 ->
- NewRemain = usual_case
- ;
- Uinstr = fork_new_child(SyncTerm, Child),
- Comment = Comment0 ++ " (redirect)",
- Instr = llds_instr(Uinstr, Comment),
- NewRemain = specified([Instr], Instrs0)
- )
- ;
- Uinstr0 = join_and_continue(SyncTerm, Label0),
- short_label(Instrmap, Label0, Label),
- ( Label = Label0 ->
- NewRemain = usual_case
- ;
- Uinstr = join_and_continue(SyncTerm, Label),
- Comment = Comment0 ++ " (redirect)",
- Instr = llds_instr(Uinstr, Comment),
- NewRemain = specified([Instr], Instrs0)
- )
- ;
- ( Uinstr0 = arbitrary_c_code(_, _, _)
- ; Uinstr0 = comment(_)
- ; Uinstr0 = livevals(_)
- ; Uinstr0 = label(_)
- ; Uinstr0 = save_maxfr(_)
- ; Uinstr0 = restore_maxfr(_)
- ; Uinstr0 = incr_sp(_, _, _)
- ; Uinstr0 = decr_sp(_)
- ; Uinstr0 = decr_sp_and_return(_)
- ; Uinstr0 = push_region_frame(_, _)
- ; Uinstr0 = region_fill_frame(_, _, _, _, _)
- ; Uinstr0 = region_set_fixed_slot(_, _, _)
- ; Uinstr0 = use_and_maybe_pop_region_frame(_, _)
- ; Uinstr0 = store_ticket(_)
- ; Uinstr0 = reset_ticket(_, _)
- ; Uinstr0 = discard_ticket
- ; Uinstr0 = prune_ticket
- ; Uinstr0 = prune_tickets_to(_)
- ; Uinstr0 = mark_ticket_stack(_)
- ; Uinstr0 = mark_hp(_)
- ; Uinstr0 = free_heap(_)
- ; Uinstr0 = incr_hp(_, _, _, _, _, _, _, _)
- ; Uinstr0 = restore_hp(_)
- ; Uinstr0 = init_sync_term(_, _)
- ),
- NewRemain = usual_case
- ),
- (
- NewRemain = usual_case,
- ReplacementInstrsEmpty = no,
- RecurseInstrs = Instrs0,
- !:RevInstrs = [Instr0 | !.RevInstrs]
- ;
- NewRemain = specified(ReplacementInstrs, RecurseInstrs),
- % ReplacementInstrs are in the right order, but they will be reversed
- % by our caller. We therefore reverse them here, which allows that
- % final reverse to put them in the right order.
- !:RevInstrs = list.reverse(ReplacementInstrs) ++ !.RevInstrs,
- (
- ReplacementInstrs = [],
- ReplacementInstrsEmpty = yes
- ;
- ReplacementInstrs = [_ | _],
- ReplacementInstrsEmpty = no
- )
- ),
- (
- ( Uinstr0 = comment(_)
- ; ReplacementInstrsEmpty = yes
- )
- ->
- NewPrevInstr = PrevInstr
- ;
- NewPrevInstr = Uinstr0
- ),
- jump_opt_instr_list(RecurseInstrs, NewPrevInstr, Instrmap, Blockmap,
- Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap, LayoutLabels,
- Fulljumpopt, MayAlterRtti, !CheckedNondetTailCallInfo, !RevInstrs).
+ ).
:- func block_may_be_duplicated(list(instruction)) = bool.
@@ -963,9 +1030,9 @@
%
:- pred short_label(instrmap::in, label::in, label::out) is det.
-short_label(Instrmap, Label0, Label) :-
- ( map.search(Instrmap, Label0, Instr0) ->
- final_dest(Instrmap, Label0, Label, Instr0, _Instr)
+short_label(InstrMap, Label0, Label) :-
+ ( map.search(InstrMap, Label0, Instr0) ->
+ final_dest(InstrMap, Label0, Label, Instr0, _Instr)
;
Label = Label0
).
@@ -973,18 +1040,18 @@
:- pred short_maybe_labels(instrmap::in,
list(maybe(label))::in, list(maybe(label))::out) is det.
-short_maybe_labels(_Instrmap, [], []).
-short_maybe_labels(Instrmap, [MaybeLabel0 | MaybeLabels0],
+short_maybe_labels(_InstrMap, [], []).
+short_maybe_labels(InstrMap, [MaybeLabel0 | MaybeLabels0],
[MaybeLabel | MaybeLabels]) :-
(
MaybeLabel0 = yes(Label0),
- short_label(Instrmap, Label0, Label),
+ short_label(InstrMap, Label0, Label),
MaybeLabel = yes(Label)
;
MaybeLabel0 = no,
MaybeLabel = no
),
- short_maybe_labels(Instrmap, MaybeLabels0, MaybeLabels).
+ short_maybe_labels(InstrMap, MaybeLabels0, MaybeLabels).
%-----------------------------------------------------------------------------%
@@ -994,13 +1061,13 @@
:- pred final_dest(instrmap::in, label::in, label::out, instruction::in,
instruction::out) is det.
-final_dest(Instrmap, SrcLabel, DestLabel, SrcInstr, DestInstr) :-
- final_dest_2(Instrmap, [], SrcLabel, DestLabel, SrcInstr, DestInstr).
+final_dest(InstrMap, SrcLabel, DestLabel, SrcInstr, DestInstr) :-
+ final_dest_2(InstrMap, [], SrcLabel, DestLabel, SrcInstr, DestInstr).
:- pred final_dest_2(instrmap::in, list(label)::in,
label::in, label::out, instruction::in, instruction::out) is det.
-final_dest_2(Instrmap, LabelsSofar, SrcLabel, DestLabel,
+final_dest_2(InstrMap, LabelsSofar, SrcLabel, DestLabel,
SrcInstr, DestInstr) :-
(
SrcInstr = llds_instr(SrcUinstr, _Comment),
@@ -1009,10 +1076,10 @@
;
SrcUinstr = label(TargetLabel)
),
- map.search(Instrmap, TargetLabel, TargetInstr),
+ map.search(InstrMap, TargetLabel, TargetInstr),
\+ list.member(SrcLabel, LabelsSofar)
->
- final_dest_2(Instrmap, [SrcLabel | LabelsSofar],
+ final_dest_2(InstrMap, [SrcLabel | LabelsSofar],
TargetLabel, DestLabel, TargetInstr, DestInstr)
;
DestLabel = SrcLabel,
@@ -1023,20 +1090,20 @@
:- pred short_labels_rval(instrmap::in, rval::in, rval::out) is det.
-short_labels_rval(Instrmap, lval(Lval0), lval(Lval)) :-
- short_labels_lval(Instrmap, Lval0, Lval).
+short_labels_rval(InstrMap, lval(Lval0), lval(Lval)) :-
+ short_labels_lval(InstrMap, Lval0, Lval).
short_labels_rval(_, var(_), _) :-
unexpected(this_file, "var rval in short_labels_rval").
-short_labels_rval(Instrmap, mkword(Tag, Rval0), mkword(Tag, Rval)) :-
- short_labels_rval(Instrmap, Rval0, Rval).
-short_labels_rval(Instrmap, const(Const0), const(Const)) :-
- short_labels_const(Instrmap, Const0, Const).
-short_labels_rval(Instrmap, unop(Op, Rval0), unop(Op, Rval)) :-
- short_labels_rval(Instrmap, Rval0, Rval).
-short_labels_rval(Instrmap, binop(Op, LRval0, RRval0),
+short_labels_rval(InstrMap, mkword(Tag, Rval0), mkword(Tag, Rval)) :-
+ short_labels_rval(InstrMap, Rval0, Rval).
+short_labels_rval(InstrMap, const(Const0), const(Const)) :-
+ short_labels_const(InstrMap, Const0, Const).
+short_labels_rval(InstrMap, unop(Op, Rval0), unop(Op, Rval)) :-
+ short_labels_rval(InstrMap, Rval0, Rval).
+short_labels_rval(InstrMap, binop(Op, LRval0, RRval0),
binop(Op, LRval, RRval)) :-
- short_labels_rval(Instrmap, LRval0, LRval),
- short_labels_rval(Instrmap, RRval0, RRval).
+ short_labels_rval(InstrMap, LRval0, LRval),
+ short_labels_rval(InstrMap, RRval0, RRval).
short_labels_rval(_, mem_addr(MemRef), mem_addr(MemRef)).
:- pred short_labels_const(instrmap::in,
@@ -1049,10 +1116,10 @@
short_labels_const(_, llconst_float(F), llconst_float(F)).
short_labels_const(_, llconst_string(S), llconst_string(S)).
short_labels_const(_, llconst_multi_string(S), llconst_multi_string(S)).
-short_labels_const(Instrmap, llconst_code_addr(CodeAddr0),
+short_labels_const(InstrMap, llconst_code_addr(CodeAddr0),
llconst_code_addr(CodeAddr)) :-
( CodeAddr0 = code_label(Label0) ->
- short_label(Instrmap, Label0, Label),
+ short_label(InstrMap, Label0, Label),
CodeAddr = code_label(Label)
;
CodeAddr = CodeAddr0
@@ -1064,21 +1131,21 @@
list(maybe(rval))::out) is det.
short_labels_maybe_rvals(_, [], []).
-short_labels_maybe_rvals(Instrmap, [MaybeRval0 | MaybeRvals0],
+short_labels_maybe_rvals(InstrMap, [MaybeRval0 | MaybeRvals0],
[MaybeRval | MaybeRvals]) :-
- short_labels_maybe_rval(Instrmap, MaybeRval0, MaybeRval),
- short_labels_maybe_rvals(Instrmap, MaybeRvals0, MaybeRvals).
+ short_labels_maybe_rval(InstrMap, MaybeRval0, MaybeRval),
+ short_labels_maybe_rvals(InstrMap, MaybeRvals0, MaybeRvals).
:- pred short_labels_maybe_rval(instrmap::in,
maybe(rval)::in, maybe(rval)::out) is det.
-short_labels_maybe_rval(Instrmap, MaybeRval0, MaybeRval) :-
+short_labels_maybe_rval(InstrMap, MaybeRval0, MaybeRval) :-
(
MaybeRval0 = no,
MaybeRval = no
;
MaybeRval0 = yes(Rval0),
- short_labels_rval(Instrmap, Rval0, Rval),
+ short_labels_rval(InstrMap, Rval0, Rval),
MaybeRval = yes(Rval)
).
@@ -1096,22 +1163,22 @@
short_labels_lval(_, parent_stackvar(N), parent_stackvar(N)).
short_labels_lval(_, framevar(N), framevar(N)).
short_labels_lval(_, global_var_ref(Var), global_var_ref(Var)).
-short_labels_lval(Instrmap, succip_slot(Rval0), succip_slot(Rval)) :-
- short_labels_rval(Instrmap, Rval0, Rval).
-short_labels_lval(Instrmap, redoip_slot(Rval0), redoip_slot(Rval)) :-
- short_labels_rval(Instrmap, Rval0, Rval).
-short_labels_lval(Instrmap, redofr_slot(Rval0), redofr_slot(Rval)) :-
- short_labels_rval(Instrmap, Rval0, Rval).
-short_labels_lval(Instrmap, succfr_slot(Rval0), succfr_slot(Rval)) :-
- short_labels_rval(Instrmap, Rval0, Rval).
-short_labels_lval(Instrmap, prevfr_slot(Rval0), prevfr_slot(Rval)) :-
- short_labels_rval(Instrmap, Rval0, Rval).
-short_labels_lval(Instrmap, field(Tag, Rval0, Field0),
+short_labels_lval(InstrMap, succip_slot(Rval0), succip_slot(Rval)) :-
+ short_labels_rval(InstrMap, Rval0, Rval).
+short_labels_lval(InstrMap, redoip_slot(Rval0), redoip_slot(Rval)) :-
+ short_labels_rval(InstrMap, Rval0, Rval).
+short_labels_lval(InstrMap, redofr_slot(Rval0), redofr_slot(Rval)) :-
+ short_labels_rval(InstrMap, Rval0, Rval).
+short_labels_lval(InstrMap, succfr_slot(Rval0), succfr_slot(Rval)) :-
+ short_labels_rval(InstrMap, Rval0, Rval).
+short_labels_lval(InstrMap, prevfr_slot(Rval0), prevfr_slot(Rval)) :-
+ short_labels_rval(InstrMap, Rval0, Rval).
+short_labels_lval(InstrMap, field(Tag, Rval0, Field0),
field(Tag, Rval, Field)) :-
- short_labels_rval(Instrmap, Rval0, Rval),
- short_labels_rval(Instrmap, Field0, Field).
-short_labels_lval(Instrmap, mem_ref(Rval0), mem_ref(Rval)) :-
- short_labels_rval(Instrmap, Rval0, Rval).
+ short_labels_rval(InstrMap, Rval0, Rval),
+ short_labels_rval(InstrMap, Field0, Field).
+short_labels_lval(InstrMap, mem_ref(Rval0), mem_ref(Rval)) :-
+ short_labels_rval(InstrMap, Rval0, Rval).
short_labels_lval(_, lvar(_), _) :-
unexpected(this_file, "lvar lval in short_labels_lval").
@@ -1119,7 +1186,7 @@
foreign_proc_component::in, foreign_proc_component::out,
bool::in, bool::out) is det.
-short_foreign_proc_component(Instrmap, !Component, !Redirect) :-
+short_foreign_proc_component(InstrMap, !Component, !Redirect) :-
(
!.Component = foreign_proc_inputs(_)
;
@@ -1130,7 +1197,7 @@
!.Component = foreign_proc_raw_code(_, _, _, _)
;
!.Component = foreign_proc_fail_to(Label0),
- short_label(Instrmap, Label0, Label),
+ short_label(InstrMap, Label0, Label),
!:Component = foreign_proc_fail_to(Label),
( Label = Label0 ->
true
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.365
diff -u -b -r1.365 llds.m
--- compiler/llds.m 30 Oct 2009 03:33:14 -0000 1.365
+++ compiler/llds.m 3 Feb 2010 23:17:13 -0000
@@ -629,6 +629,16 @@
% The label gives the address of the code following the parallel
% conjunction.
+:- inst instr_llcall
+ ---> llcall(ground, ground, ground, ground, ground, ground).
+:- inst instr_goto
+ ---> goto(ground).
+:- inst instr_if_val
+ ---> if_val(ground, ground).
+:- inst instr_foreign_proc_code
+ ---> foreign_proc_code(ground, ground, ground, ground, ground,
+ ground, ground, ground, ground, ground).
+
:- type stack_incr_kind
---> stack_incr_leaf % The incr_sp creates the stack frame
% of a leaf procedure.
Index: compiler/type_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/type_constraints.m,v
retrieving revision 1.7
diff -u -b -r1.7 type_constraints.m
--- compiler/type_constraints.m 4 Sep 2009 02:27:55 -0000 1.7
+++ compiler/type_constraints.m 3 Feb 2010 23:17:13 -0000
@@ -352,7 +352,8 @@
%-----------------------------------------------------------------------------%
%
-% General typechecking utility predicates
+% General typechecking utility predicates.
+%
% A compiler-generated predicate only needs type checking if
% (a) it is a user-defined equality pred, or
@@ -544,7 +545,9 @@
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
-% Constraint solving
+%
+% Constraint solving.
+%
% Tries to solve a constraint on the types of variables in a predicate.
% If a definite solution cannot be found, use labeling to guess the value
@@ -951,6 +954,7 @@
%-----------------------------------------------------------------------------%
%
% Constraint solving utility predicates.
+%
% Returns the type variable that is unified with Target in the constraint.
% Fails if no such variable exists.
@@ -1451,7 +1455,8 @@
%-----------------------------------------------------------------------------%
%
-% Error diagnosis
+% Error diagnosis.
+%
% If the list of type constraints contains more than one predicate call
% constraint, return an error message describing the ambiguity and one
@@ -1609,7 +1614,8 @@
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
%
-% Constraint generation
+% Constraint generation.
+%
% Turn a goal expression to a constraint on the types of variable
% appearing within that goal, then update all relevant maps with the
@@ -1619,14 +1625,58 @@
type_constraint_info::in, type_constraint_info::out) is det.
goal_to_constraint(Environment, Goal, !TCInfo) :-
- Environment = tconstr_environment(_, _, FuncEnv, PredEnv),
+ % Environment = tconstr_environment(_, _, FuncEnv, PredEnv),
Goal = hlds_goal(GoalExpr, GoalInfo),
(
- GoalExpr = unify(L, RHS, _, _, _),
+ GoalExpr = unify(_, _, _, _, _),
+ unify_goal_to_constraint(Environment, GoalExpr, GoalInfo, !TCInfo)
+ ;
+ GoalExpr = plain_call(_, _, _, _, _, _),
+ plain_call_goal_to_constraint(Environment, GoalExpr, GoalInfo, !TCInfo)
+ ;
+ GoalExpr = call_foreign_proc(_, _, _, _, _, _, _),
+ foreign_proc_goal_to_constraint(Environment, GoalExpr, GoalInfo,
+ !TCInfo)
+ ;
+ GoalExpr = generic_call(_, _, _, _),
+ generic_call_goal_to_constraint(Environment, GoalExpr, GoalInfo,
+ !TCInfo)
+ ;
+ GoalExpr = conj(_, Goals),
+ list.foldl(goal_to_constraint(Environment), Goals, !TCInfo)
+ ;
+ GoalExpr = disj(Goals),
+ list.foldl(goal_to_constraint(Environment), Goals, !TCInfo)
+ ;
+ GoalExpr = negation(SubGoal),
+ goal_to_constraint(Environment, SubGoal, !TCInfo)
+ ;
+ GoalExpr = scope(_, SubGoal),
+ goal_to_constraint(Environment, SubGoal, !TCInfo)
+ ;
+ GoalExpr = if_then_else(_, Cond, Then, Else),
+ goal_to_constraint(Environment, Cond, !TCInfo),
+ goal_to_constraint(Environment, Then, !TCInfo),
+ goal_to_constraint(Environment, Else, !TCInfo)
+ ;
+ GoalExpr = switch(_, _, Cases),
+ list.map(get_case_goal, Cases, Goals),
+ list.foldl(goal_to_constraint(Environment), Goals, !TCInfo)
+ ;
+ GoalExpr = shorthand(_),
+ shorthand_goal_to_constraint(Environment, GoalExpr, GoalInfo, !TCInfo)
+ ).
+
% Transform a unification constraint into an assignment of types
% to the variables being unified.
+ %
+:- pred unify_goal_to_constraint(tconstr_environment::in,
+ hlds_goal_expr::in(goal_expr_unify), hlds_goal_info::in,
+ type_constraint_info::in, type_constraint_info::out) is det.
+unify_goal_to_constraint(Environment, GoalExpr, GoalInfo, !TCInfo) :-
Context = goal_info_get_context(GoalInfo),
+ GoalExpr = unify(L, RHS, _, _, _),
get_var_type(L, LTVar, !TCInfo),
(
RHS = rhs_var(R),
@@ -1649,8 +1699,9 @@
Arity = list.length(Args)
->
list.map_foldl(get_var_type, Args, ArgTypeVars, !TCInfo),
- % If it is a data constructor, create a disjunction
- % constraint with each possible type of the constructor.
+ % If it is a data constructor, create a disjunction constraint
+ % with each possible type of the constructor.
+ Environment = tconstr_environment(_, _, FuncEnv, PredEnv),
( map.search(FuncEnv, ConsId, Cons_Defns) ->
list.map_foldl(
functor_unif_constraint(LTVar, ArgTypeVars, GoalInfo),
@@ -1704,28 +1755,38 @@
RelevantTVars = [LTVar | ArgTVars],
goal_to_constraint(Environment, LambdaGoal, !TCInfo)
),
- add_type_constraint(Constraints, RelevantTVars, !TCInfo)
- ;
+ add_type_constraint(Constraints, RelevantTVars, !TCInfo).
+
+:- pred plain_call_goal_to_constraint(tconstr_environment::in,
+ hlds_goal_expr::in(goal_expr_plain_call), hlds_goal_info::in,
+ type_constraint_info::in, type_constraint_info::out) is det.
+
+plain_call_goal_to_constraint(Environment, GoalExpr, GoalInfo, !TCInfo) :-
+ Environment = tconstr_environment(_, _, _FuncEnv, PredEnv),
GoalExpr = plain_call(_, _, Args, _, _, Name),
% Transform a call to variable assignments of the variables
% used in the call.
(
- predicate_table_search_pred_sym(PredEnv,
- may_be_partially_qualified, Name, PredIds0)
+ predicate_table_search_pred_sym(PredEnv, may_be_partially_qualified,
+ Name, PredIds0)
->
PredIds1 = PredIds0
;
PredIds1 = []
),
predicate_table_get_preds(PredEnv, Preds),
- list.filter(pred_has_arity(Preds, list.length(Args)),
- PredIds1, PredIds),
+ list.filter(pred_has_arity(Preds, list.length(Args)), PredIds1, PredIds),
list.map_foldl(get_var_type, Args, ArgTVars, !TCInfo),
list.map2_foldl(pred_call_constraint(Preds, GoalInfo, ArgTVars),
PredIds, Constraints, PredTVars, !TCInfo),
list.condense([ArgTVars | PredTVars], TVars),
- add_type_constraint(Constraints, TVars, !TCInfo)
- ;
+ add_type_constraint(Constraints, TVars, !TCInfo).
+
+:- pred foreign_proc_goal_to_constraint(tconstr_environment::in,
+ hlds_goal_expr::in(goal_expr_foreign_proc), hlds_goal_info::in,
+ type_constraint_info::in, type_constraint_info::out) is det.
+
+foreign_proc_goal_to_constraint(Environment, GoalExpr, GoalInfo, !TCInfo) :-
GoalExpr = call_foreign_proc(_, PredId, _, ForeignArgs, _, _, _),
Context = goal_info_get_context(GoalInfo),
ArgVars = list.map(foreign_arg_var, ForeignArgs),
@@ -1742,8 +1803,13 @@
ArgVars, ArgTypes, !TCInfo)
;
unexpected(this_file, "cannot find pred_info for foreign_proc")
- )
- ;
+ ).
+
+:- pred generic_call_goal_to_constraint(tconstr_environment::in,
+ hlds_goal_expr::in(goal_expr_generic_call), hlds_goal_info::in,
+ type_constraint_info::in, type_constraint_info::out) is det.
+
+generic_call_goal_to_constraint(Environment, GoalExpr, GoalInfo, !TCInfo) :-
GoalExpr = generic_call(Details, Vars, _, _),
Context = goal_info_get_context(GoalInfo),
list.map_foldl(get_var_type, Vars, ArgTVars, !TCInfo),
@@ -1815,35 +1881,17 @@
;
% Casts do not contain any type information.
Details = cast(_)
- )
- ;
- GoalExpr = conj(_, Goals),
- list.foldl(goal_to_constraint(Environment), Goals, !TCInfo)
- ;
- GoalExpr = disj(Goals),
- list.foldl(goal_to_constraint(Environment), Goals, !TCInfo)
- ;
- GoalExpr = negation(SubGoal),
- goal_to_constraint(Environment, SubGoal, !TCInfo)
- ;
- GoalExpr = scope(_, SubGoal),
- goal_to_constraint(Environment, SubGoal, !TCInfo)
- ;
- GoalExpr = if_then_else(_, Cond, Then, Else),
- goal_to_constraint(Environment, Cond, !TCInfo),
- goal_to_constraint(Environment, Then, !TCInfo),
- goal_to_constraint(Environment, Else, !TCInfo)
- ;
- GoalExpr = switch(_, _, Cases),
- list.map(get_case_goal, Cases, Goals),
- list.foldl(goal_to_constraint(Environment), Goals, !TCInfo)
- ;
- GoalExpr = shorthand(bi_implication(GoalA, GoalB)),
- goal_to_constraint(Environment, GoalA, !TCInfo),
- goal_to_constraint(Environment, GoalB, !TCInfo)
- ;
- GoalExpr = shorthand(atomic_goal(GoalType, Outer, Inner,
- _, Main, Alternatives, _)),
+ ).
+
+:- pred shorthand_goal_to_constraint(tconstr_environment::in,
+ hlds_goal_expr::in(goal_expr_shorthand), hlds_goal_info::in,
+ type_constraint_info::in, type_constraint_info::out) is det.
+
+shorthand_goal_to_constraint(Environment, GoalExpr, GoalInfo, !TCInfo) :-
+ GoalExpr = shorthand(Shorthand),
+ (
+ Shorthand = atomic_goal(GoalType, Outer, Inner, _,
+ Main, Alternatives, _),
% Atomic goals are handled by forcing their inner arguments
% to be of type stm_atomic_type, their outer arguments to be
% of type stm_atomic_type or io_state_type, depending on the type
@@ -1889,7 +1937,7 @@
list.foldl(goal_to_constraint(Environment), [Main | Alternatives],
!TCInfo)
;
- GoalExpr = shorthand(try_goal(MaybeIO, _ResultVar, SubGoal)),
+ Shorthand = try_goal(MaybeIO, _ResultVar, SubGoal),
Context = goal_info_get_context(GoalInfo),
(
MaybeIO = yes(try_io_state_vars(IOVarA, IOVarB)),
@@ -1905,6 +1953,10 @@
MaybeIO = no
),
goal_to_constraint(Environment, SubGoal, !TCInfo)
+ ;
+ Shorthand = bi_implication(GoalA, GoalB),
+ goal_to_constraint(Environment, GoalA, !TCInfo),
+ goal_to_constraint(Environment, GoalB, !TCInfo)
).
% Creates a constraint from the information stored in a predicate
@@ -2053,6 +2105,7 @@
%-----------------------------------------------------------------------------%
%
% Constraint generation utility predicates.
+%
:- pred pred_has_arity(pred_table::in, int::in, pred_id::in) is semidet.
@@ -2162,6 +2215,7 @@
%-----------------------------------------------------------------------------%
%
% Constraint printing.
+%
:- pred print_guess(tvarset::in, pair(tvar, type_domain)::in, io::di, io::uo)
is det.
@@ -2428,6 +2482,7 @@
%-----------------------------------------------------------------------------%
%
% General purpose utilities.
+%
:- pred remove_maybe(maybe(T)::in, T::out) is semidet.
Index: compiler/write_deps_file.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/write_deps_file.m,v
retrieving revision 1.7
diff -u -b -r1.7 write_deps_file.m
--- compiler/write_deps_file.m 14 Oct 2009 05:28:45 -0000 1.7
+++ compiler/write_deps_file.m 3 Feb 2010 23:17:13 -0000
@@ -1730,6 +1730,40 @@
module_name_to_file_name(Globals, ModuleName, "_init.pic_o",
do_create_dirs, InitPicObjFileName, !IO),
+ globals.lookup_bool_option(Globals, intermodule_optimization, Intermod),
+ globals.lookup_bool_option(Globals, transitive_optimization, TransOpt),
+ globals.lookup_bool_option(Globals, generate_mmc_make_module_dependencies,
+ MmcMakeDeps),
+
+ generate_dep_file_exec_library_targets(Globals, DepStream, ModuleName,
+ MakeVarName, InitFileName, InitObjFileName,
+ Intermod, TransOpt, MmcMakeDeps,
+ MaybeOptsVar, MaybeTransOptsVar, MaybeModuleDepsVar,
+ ExeFileName, JarFileName, LibFileName, SharedLibFileName, !IO),
+ generate_dep_file_init_targets(Globals, DepStream, ModuleName,
+ MakeVarName, InitCFileName, InitFileName, DepFileName, DvFileName,
+ !IO),
+ generate_dep_file_install_targets(Globals, DepStream, ModuleName, DepsMap,
+ MakeVarName, MmcMakeDeps, Intermod, TransOpt,
+ MaybeModuleDepsVar, MaybeOptsVar, MaybeTransOptsVar, !IO),
+ generate_dep_file_collective_targets(Globals, DepStream, ModuleName,
+ MakeVarName, !IO),
+ generate_dep_file_clean_targets(Globals, DepStream, ModuleName,
+ MakeVarName, ExeFileName, InitCFileName, InitAsmFileName,
+ InitObjFileName, InitPicObjFileName, InitFileName,
+ LibFileName, SharedLibFileName, JarFileName, DepFileName, DvFileName,
+ !IO).
+
+:- pred generate_dep_file_exec_library_targets(globals::in,
+ io.output_stream::in, module_name::in, string::in, string::in, string::in,
+ bool::in, bool::in, bool::in, string::out, string::out, string::out,
+ string::out, string::out, string::out, string::out, io::di, io::uo) is det.
+
+generate_dep_file_exec_library_targets(Globals, DepStream, ModuleName,
+ MakeVarName, InitFileName, InitObjFileName,
+ Intermod, TransOpt, MmcMakeDeps,
+ MaybeOptsVar, MaybeTransOptsVar, MaybeModuleDepsVar,
+ ExeFileName, JarFileName, LibFileName, SharedLibFileName, !IO) :-
% Note we have to do some ``interesting'' hacks to get
% `$(ALL_MLLIBS_DEP)' to work in the dependency list
% (and not complain about undefined variables).
@@ -1773,10 +1807,12 @@
ILMainRule = [ExeFileName, " : ", ExeFileName, ".exe\n",
ExeFileName, ".exe : ", "$(", MakeVarName, ".dlls) ",
"$(", MakeVarName, ".foreign_dlls)\n"],
- Else = ["else\n"],
- IfJava = [" ifeq ($(findstring java,$(GRADE)),java)\n"],
+ IfJava2 = [" ifeq ($(findstring java,$(GRADE)),java)\n"],
JavaMainRule = [ExeFileName, " : $(", MakeVarName, ".classes)\n"],
+
+ Else = ["else\n"],
Else2 = [" else\n"],
+ EndIf = ["endif\n"],
EndIf2 = [" endif\n"],
% XXX The output here is GNU Make-specific.
@@ -1794,13 +1830,12 @@
"\t$(ML) $(ALL_GRADEFLAGS) $(ALL_MLFLAGS) -- $(ALL_LDFLAGS) ",
"-o ", ExeFileName, "$(EXT_FOR_EXE) ", InitObjFileName, " \\\n",
"\t\t$(", MakeVarName, ".os) ", All_MLObjsString, " $(ALL_MLLIBS)\n"],
- EndIf = ["endif\n"],
globals.get_target(Globals, Target),
(
Gmake = yes,
Rules = IfIL ++ ILMainRule ++ Else ++
- IfJava ++ JavaMainRule ++ Else2 ++
+ IfJava2 ++ JavaMainRule ++ Else2 ++
MainRule ++ EndIf2 ++ EndIf
;
Gmake = no,
@@ -1824,29 +1859,23 @@
),
io.write_strings(DepStream, Rules, !IO),
- globals.lookup_bool_option(Globals, intermodule_optimization, Intermod),
(
Intermod = yes,
- string.append_list(["$(", MakeVarName, ".opts) "], MaybeOptsVar)
+ MaybeOptsVar = "$(" ++ MakeVarName ++ ".opts) "
;
Intermod = no,
MaybeOptsVar = ""
),
- globals.lookup_bool_option(Globals, transitive_optimization, TransOpt),
(
TransOpt = yes,
- string.append_list(["$(", MakeVarName, ".trans_opts) "],
- MaybeTransOptsVar)
+ MaybeTransOptsVar = "$(" ++ MakeVarName ++ ".trans_opts) "
;
TransOpt = no,
MaybeTransOptsVar = ""
),
- globals.lookup_bool_option(Globals, generate_mmc_make_module_dependencies,
- MmcMakeDeps),
(
MmcMakeDeps = yes,
- string.append_list(["$(", MakeVarName, ".module_deps) "],
- MaybeModuleDepsVar)
+ MaybeModuleDepsVar = "$(" ++ MakeVarName ++ ".module_deps) "
;
MmcMakeDeps = no,
MaybeModuleDepsVar = ""
@@ -1899,7 +1928,7 @@
(
Gmake = yes,
LibRules = IfIL ++ ILLibRule ++ Else ++
- IfJava ++ JavaLibRule ++ Else2 ++
+ IfJava2 ++ JavaLibRule ++ Else2 ++
LibRule ++ EndIf2 ++ EndIf
;
Gmake = no,
@@ -1954,8 +1983,15 @@
JarFileName, " : ", "$(", MakeVarName, ".classes)\n",
"\t$(JAR) $(JAR_CREATE_FLAGS) ", JarFileName, " ",
ListClassFiles, "\n\n"
- ], !IO),
+ ], !IO).
+:- pred generate_dep_file_init_targets(globals::in, io.output_stream::in,
+ module_name::in, string::in, string::in, string::in,
+ string::out, string::out, io::di, io::uo) is det.
+
+generate_dep_file_init_targets(Globals, DepStream, ModuleName,
+ MakeVarName, InitCFileName, InitFileName, DepFileName, DvFileName,
+ !IO) :-
module_name_to_file_name(Globals, ModuleName, ".dep",
do_not_create_dirs, DepFileName, !IO),
module_name_to_file_name(Globals, ModuleName, ".dv",
@@ -1990,7 +2026,19 @@
"--init-c-file ", TmpInitCFileName,
" $(", MakeVarName, ".init_cs) $(ALL_C2INITARGS)\n",
"\t at mercury_update_interface ", InitCFileName, "\n\n"
- ], !IO),
+ ], !IO).
+
+:- pred generate_dep_file_install_targets(globals::in, io.output_stream::in,
+ module_name::in, deps_map::in, string::in, bool::in, bool::in, bool::in,
+ string::in, string::in, string::in, io::di, io::uo) is det.
+
+generate_dep_file_install_targets(Globals, DepStream, ModuleName, DepsMap,
+ MakeVarName, MmcMakeDeps, Intermod, TransOpt,
+ MaybeModuleDepsVar, MaybeOptsVar, MaybeTransOptsVar, !IO) :-
+ % XXX Note that we install the `.opt' and `.trans_opt' files
+ % in two places: in the `lib/$(GRADE)/opts' directory, so
+ % that mmc will find them, and also in the `ints' directory,
+ % so that Mmake will find them. That's not ideal, but it works.
module_name_to_lib_file_name(Globals, "lib", ModuleName, ".install_ints",
do_not_create_dirs, LibInstallIntsTargetName, !IO),
@@ -2063,11 +2111,6 @@
"\tdone\n\n"
], !IO),
- % XXX Note that we install the `.opt' and `.trans_opt' files
- % in two places: in the `lib/$(GRADE)/opts' directory, so
- % that mmc will find them, and also in the `ints' directory,
- % so that Mmake will find them. That's not ideal, but it works.
-
module_name_to_lib_file_name(Globals, "lib", ModuleName, ".install_opts",
do_not_create_dirs, LibInstallOptsTargetName, !IO),
io.write_strings(DepStream,
@@ -2091,12 +2134,12 @@
"\t\t\t$(INSTALL) ""$$file"" ""$$target""; \\\n",
"\t\tfi; \\\n",
"\tdone\n",
- "\t# The following is needed to support the `--use-subdirs' option\n",
- "\t# We try using `$(LN_S)', but if that fails, then we just use\n",
+ "\t# The following is needed to support the",
+ " `--use-subdirs' option\n",
+ "\t# We try using `$(LN_S)', but if that fails,",
+ " then we just use\n",
"\t# `$(INSTALL)'.\n",
- "\tfor ext in ",
- OptStr, TransOptStr,
- "; do \\\n",
+ "\tfor ext in ", OptStr, TransOptStr, "; do \\\n",
"\t\tdir=""$(INSTALL_GRADE_INT_DIR)/Mercury/$${ext}s""; \\\n",
"\t\trm -rf ""$$dir""; \\\n",
"\t\t$(LN_S) .. ""$$dir"" || { \\\n",
@@ -2170,8 +2213,13 @@
"\t\t$(INSTALL) $(INSTALL_GRADE_INC_DIR)/*.mih \\\n",
"\t\t\t$(INSTALL_INT_DIR); \\\n",
"\t} || exit 1\n",
- "endif\n\n"], !IO),
+ "endif\n\n"], !IO).
+
+:- pred generate_dep_file_collective_targets(globals::in, io.output_stream::in,
+ module_name::in, string::in, io::di, io::uo) is det.
+generate_dep_file_collective_targets(Globals, DepStream, ModuleName,
+ MakeVarName, !IO) :-
module_name_to_file_name(Globals, ModuleName, ".check",
do_not_create_dirs, CheckTargetName, !IO),
module_name_to_file_name(Globals, ModuleName, ".ints",
@@ -2193,11 +2241,10 @@
module_name_to_file_name(Globals, ModuleName, ".classes",
do_not_create_dirs, ClassesTargetName, !IO),
- % We need to explicitly mention
- % $(foo.pic_ss) somewhere in the Mmakefile, otherwise it
- % won't build properly with --target asm: GNU Make's pattern rule
- % algorithm will try to use the .m -> .c_date -> .c -> .pic_o rule chain
- % rather than the .m -> .pic_s_date -> .pic_s -> .pic_o chain.
+ % We need to explicitly mention $(foo.pic_ss) somewhere in the Mmakefile,
+ % otherwise it won't build properly with --target asm: GNU Make's pattern
+ % rule algorithm will try to use the .m -> .c_date -> .c -> .pic_o rule
+ % chain rather than the .m -> .pic_s_date -> .pic_s -> .pic_o chain.
% So don't remove the pic_ss target here.
io.write_strings(DepStream, [
@@ -2222,8 +2269,17 @@
JavasTargetName, " : $(", MakeVarName, ".javas)\n\n",
".PHONY : ", ClassesTargetName, "\n",
ClassesTargetName, " : $(", MakeVarName, ".classes)\n\n"
- ], !IO),
+ ], !IO).
+:- pred generate_dep_file_clean_targets(globals::in, io.output_stream::in,
+ module_name::in, string::in, string::in, string::in, string::in,
+ string::in, string::in, string::in, string::in, string::in, string::in,
+ string::in, string::in, io::di, io::uo) is det.
+
+generate_dep_file_clean_targets(Globals, DepStream, ModuleName, MakeVarName,
+ ExeFileName, InitCFileName, InitAsmFileName,
+ InitObjFileName, InitPicObjFileName, InitFileName, LibFileName,
+ SharedLibFileName, JarFileName, DepFileName, DvFileName, !IO) :-
% If you change the clean targets below, please also update the
% documentation in doc/user_guide.texi.
%
@@ -2262,11 +2318,10 @@
"\t-echo $(", MakeVarName, ".javas) | xargs rm -f\n",
"\t-echo $(", MakeVarName, ".profs) | xargs rm -f\n",
"\t-echo $(", MakeVarName, ".errs) | xargs rm -f\n",
- "\t-echo $(", MakeVarName, ".foreign_cs) | xargs rm -f\n"
+ "\t-echo $(", MakeVarName, ".foreign_cs) | xargs rm -f\n",
+ "\n"
], !IO),
- io.write_string(DepStream, "\n", !IO),
-
module_name_to_file_name(Globals, ModuleName, ".realclean",
do_not_create_dirs, RealCleanTargetName, !IO),
io.write_strings(DepStream, [
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
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/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
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/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list