[m-rev.] diff: state vars for instr_to_x86_64

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Jul 17 15:30:45 AEST 2007


compiler/llds_out.m:
	Convert instr_to_x86_64 to using state variables for the register map.
	Factor out some common code by making get_last_instr_opand det (and fix
	the spelling of "operand" in its name).

	Fix some overly complicated code.

Zoltan.

cvs diff: Diffing .
Index: llds_to_x86_64.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_to_x86_64.m,v
retrieving revision 1.5
diff -u -b -r1.5 llds_to_x86_64.m
--- llds_to_x86_64.m	9 Jul 2007 13:28:32 -0000	1.5
+++ llds_to_x86_64.m	14 Jul 2007 01:30:37 -0000
@@ -25,6 +25,7 @@
 % 		- trailing ops
 % 		- heap ops
 % 		- parallelism
+%
 %-----------------------------------------------------------------------------%
 
 :- module ll_backend.llds_to_x86_64.
@@ -67,18 +68,18 @@
 %
 
 :- type binop 
-    --->    binop_simple_opands(operand, operand)
+    --->    binop_simple_operands(operand, operand)
             % A binary operation with two simple operands, such as X + Y
             % where X and Y are primitive values (ie. integers). 
-    ;       binop_simple_and_compound_opands(operand, list(x86_64_instr))
+    ;       binop_simple_and_compound_operands(operand, list(x86_64_instr))
             % A binary operation can consist of one simple operand at the 
             % left hand side and a compound operand at the right hand side.
             % ie. X + Y where X can consist of further operations (such 
             % as Z + W, Z * W, etc) and Y is a primitive value. 
-    ;       binop_compound_and_simple_opands(list(x86_64_instr), operand)
+    ;       binop_compound_and_simple_operands(list(x86_64_instr), operand)
             % A binary operation can consist of a compound operand at the 
             % left hand side and a simple operand at the right hand side.
-    ;       binop_compound_opands(list(x86_64_instr), list(x86_64_instr)).
+    ;       binop_compound_operands(list(x86_64_instr), list(x86_64_instr)).
             % Both operands in the binary operation are compound operands.
 
 %----------------------------------------------------------------------------%
@@ -100,16 +101,16 @@
 transform_c_proc_list(RegMap, [CProc | CProcs], [AsmProc | AsmProcs]) :-
     AsmProc0 = ll_backend.x86_64_instrs.init_x86_64_proc(CProc),
     ProcInstr0 = ll_backend.x86_64_instrs.init_x86_64_instruction,
-    % 
+
     % Get the procedure's label and append it as an x86_64 instruction
     % list before the output of the llds->x86_64 procedure transformation.
-    % 
+
     ProcStr = backend_libs.name_mangle.proc_label_to_c_string(
         AsmProc0 ^ x86_64_proc_label, no),
     ProcName = x86_64_directive(x86_64_pseudo_type(ProcStr, function)),
     ProcInstr = ProcInstr0 ^ x86_64_inst := [ProcName],
     transform_c_instr_list(RegMap, CProc ^ cproc_code, AsmInstr0),
-    list.append([ProcInstr], AsmInstr0, AsmInstr),
+    AsmInstr = [ProcInstr | AsmInstr0],
     AsmProc = AsmProc0 ^ x86_64_code := AsmInstr,
     transform_c_proc_list(RegMap, CProcs, AsmProcs).
 
@@ -119,14 +120,15 @@
     list(x86_64_instruction)::out) is det.
 
 transform_c_instr_list(_, [], []).
-transform_c_instr_list(RegMap, [CInstr0 | CInstr0s], [AsmInstr | AsmInstrs]) :-
+transform_c_instr_list(!.RegMap, [CInstr0 | CInstr0s],
+        [AsmInstr | AsmInstrs]) :-
     CInstr0 = llds_instr(CInstr1, Comment),
-    instr_to_x86_64(RegMap, CInstr1, RegMap1, AsmInstrList),
-    ll_backend.x86_64_regs.reg_map_reset_scratch_reg_info(RegMap1, RegMap2),
+    instr_to_x86_64(!RegMap, CInstr1, AsmInstrList),
+    ll_backend.x86_64_regs.reg_map_reset_scratch_reg_info(!RegMap),
     AsmInstr0 = ll_backend.x86_64_instrs.init_x86_64_instruction,
     AsmInstr1 = AsmInstr0 ^ x86_64_inst := AsmInstrList,
     AsmInstr = AsmInstr1 ^ x86_64_inst_comment := Comment,
-    transform_c_instr_list(RegMap2, CInstr0s, AsmInstrs).
+    transform_c_instr_list(!.RegMap, CInstr0s, AsmInstrs).
 
     % Transform a block instruction of an llds instruction into a list of 
     % x86_64 instructions.
@@ -138,60 +140,61 @@
     transform_block_instr_list(RegMap, CInstrs, ListInstrs),
     list.condense(ListInstrs, Instrs).
 
+    % XXX Why do we throw away the final RegMap?
+    %
 :- pred transform_block_instr_list(reg_map::in, list(instruction)::in, 
     list(list(x86_64_instr))::out) is det. 
 
 transform_block_instr_list(_, [], []).
-transform_block_instr_list(RegMap, [CInstr0 | CInstr0s], [Instr0 | Instr0s]) :-
+transform_block_instr_list(!.RegMap, [CInstr0 | CInstr0s],
+        [Instr0 | Instr0s]) :-
     CInstr0 = llds_instr(CInstr, _),
-    instr_to_x86_64(RegMap, CInstr, RegMap1, Instr0),
-    ll_backend.x86_64_regs.reg_map_reset_scratch_reg_info(RegMap1, RegMap2),
-    transform_block_instr_list(RegMap2, CInstr0s, Instr0s).
+    instr_to_x86_64(!RegMap, CInstr, Instr0),
+    ll_backend.x86_64_regs.reg_map_reset_scratch_reg_info(!RegMap),
+    transform_block_instr_list(!.RegMap, CInstr0s, Instr0s).
 
-    % Transform livevals of llds instruction into a list of x86_64 instructions.
+    % Transform the livevals of llds instruction into a list of x86_64
+    % instructions.
     %
-:- pred transform_livevals(reg_map::in, list(lval)::in, list(x86_64_instr)::out)
-    is det.
+    % XXX Why do we throw away the final RegMap?
+    %
+:- pred transform_livevals(reg_map::in, list(lval)::in,
+    list(x86_64_instr)::out) is det.
 
 transform_livevals(_, [], []). 
-transform_livevals(RegMap, [Lval | Lvals], [Instr | Instrs]) :-
-    transform_lval(RegMap, Lval, RegMap1, Res0, Res1),
+transform_livevals(!.RegMap, [Lval | Lvals], [Instr | Instrs]) :-
+    transform_lval(!RegMap, Lval, Res0, Res1),
     (
         Res0 = yes(LvalOp)
     ;
         Res0 = no,
         ( 
             Res1 = yes(LvalInstrs),
-            ( get_last_instr_opand(LvalInstrs, LastOp) ->
-                LvalOp = LastOp
-            ;
-                unexpected(this_file, "transform_livevals: unexpected:"
-                    ++ " get_last_instr_opand failed")
-            )
+            get_last_instr_operand(LvalInstrs, LvalOp)
         ;
             Res1 = no,
-            unexpected(this_file, "transform_livevals: unexpected:"
-                ++ " get_last_instr_opand failed")
+            unexpected(this_file,
+                "transform_livevals: unexpected: no results")
         )
     ),
     Instr = x86_64_instr(mov(operand_label("<<liveval>>"), LvalOp)),
-    transform_livevals(RegMap1, Lvals, Instrs).
+    transform_livevals(!.RegMap, Lvals, Instrs).
 
     % Given an llds instruction, transform it into equivalent x86_64 
     % instructions. 
     %
-:- pred instr_to_x86_64(reg_map::in, instr::in, reg_map::out, 
-    list(x86_64_instr)::out) is det.
+:- pred instr_to_x86_64(reg_map::in, reg_map::out,
+    instr::in, list(x86_64_instr)::out) is det.
 
-instr_to_x86_64(RegMap, comment(Comment), RegMap, [x86_64_comment(Comment)]).
-instr_to_x86_64(RegMap, livevals(RegsAndStackLocs), RegMap, Instrs) :-
+instr_to_x86_64(!RegMap, comment(Comment), [x86_64_comment(Comment)]).
+instr_to_x86_64(!RegMap, livevals(RegsAndStackLocs), Instrs) :-
     set.to_sorted_list(RegsAndStackLocs, List),
-    transform_livevals(RegMap, List, Instrs).
-instr_to_x86_64(RegMap, block(_, _, CInstrs), RegMap, Instrs) :-
-    transform_block_instr(RegMap, CInstrs, Instrs).
-instr_to_x86_64(RegMap0, assign(Lval, Rval), RegMap, Instrs) :-
-    transform_lval(RegMap0, Lval, RegMap1, Res0, Res1),
-    transform_rval(RegMap1, Rval, RegMap, Res2, Res3),
+    transform_livevals(!.RegMap, List, Instrs).
+instr_to_x86_64(!RegMap, block(_, _, CInstrs), Instrs) :-
+    transform_block_instr(!.RegMap, CInstrs, Instrs).
+instr_to_x86_64(!RegMap, assign(Lval, Rval), Instrs) :-
+    transform_lval(!RegMap, Lval, Res0, Res1),
+    transform_rval(!RegMap, Rval, Res2, Res3),
     (
         Res0 = yes(LvalOp),
         ( 
@@ -201,24 +204,20 @@
             Res2 = no,
             ( 
                 Res3 = yes(RvalInstrs),
-                ( get_last_instr_opand(RvalInstrs, LastOp) ->
+                get_last_instr_operand(RvalInstrs, LastOp),
                     LastInstr = x86_64_instr(mov(LastOp, LvalOp)),
                     Instrs = RvalInstrs ++ [LastInstr]
                 ;
-                    unexpected(this_file, "instr_to_x86_64: assign: unexpected:"
-                        ++ " get_last_instr_opand failed")
-                )
-            ;
                 Res3 = no,
-                unexpected(this_file, "instr_to_x86_64: assign: unexpected:"
-                    ++ " Rval")
+                unexpected(this_file,
+                    "instr_to_x86_64: assign: unexpected: Rval")
             )
         )
     ;
         Res0 = no,
         ( 
             Res1 = yes(LvalInstrs),
-            ( get_last_instr_opand(LvalInstrs, LvalLastOp) ->
+            get_last_instr_operand(LvalInstrs, LvalLastOp),
                 (
                     Res2 = yes(RvalOp),
                     Instr1 = x86_64_instr(mov(RvalOp, LvalLastOp)),
@@ -227,65 +226,51 @@
                     Res2 = no,
                     ( 
                         Res3 = yes(RvalInstrs),
-                        ( get_last_instr_opand(RvalInstrs, RvalLastOp) ->
+                    get_last_instr_operand(RvalInstrs, RvalLastOp),
                             Instr1 = x86_64_instr(mov(RvalLastOp, LvalLastOp)),
                             Instrs = LvalInstrs ++ RvalInstrs ++ [Instr1]
                         ;
-                            unexpected(this_file, "instr_to_x86_64: assign:" 
-                                ++ " unexpected:get_last_instr_opand failed")
-                        )
-                    ;
                         Res3 = no,
-                        unexpected(this_file, "instr_to_x86_64: assign:"
-                            ++ " unexpected: Rval")
+                    unexpected(this_file,
+                        "instr_to_x86_64: assign: unexpected: Rval")
                     )
                 )
             ;
-                unexpected(this_file, "instr_to_x86_64: assign: unexpected:"
-                    ++ " get_last_instr_opand failed")
-            )
-        ;
             Res1 = no,
-            unexpected(this_file, "instr_to_x86_64: assign: unexpected:"
-                ++ "Lval")
+            unexpected(this_file,
+                "instr_to_x86_64: assign: unexpected: Lval")
         )
     ).
-instr_to_x86_64(RegMap0, llcall(Target0, Continuation0, _, _, _, _), RegMap, 
-        Instrs) :-
+instr_to_x86_64(!RegMap, llcall(Target0, Continuation0, _, _, _, _), Instrs) :-
     code_addr_type(Target0, Target1),
     code_addr_type(Continuation0, Continuation1),
-    lval_reg_locn(RegMap0, succip, Op0, Instr0),
-    ll_backend.x86_64_regs.reg_map_remove_scratch_reg(RegMap0, RegMap),
+    lval_reg_locn(!.RegMap, succip, Op0, Instr0),
+    ll_backend.x86_64_regs.reg_map_remove_scratch_reg(!RegMap),
     (
         Op0 = yes(Op)
     ;
         Op0 = no,
         ( 
             Instr0 = yes(Instr),
-            ( get_last_instr_opand(Instr, LastOpand) ->
-                Op = LastOpand
-            ;
-                unexpected(this_file, "instr_to_x86_64: llcall: unexpected:"
-                    ++ " get_last_instr_opand failed")
-            )
+            get_last_instr_operand(Instr, Op)
         ;
             Instr0 = no,
-            unexpected(this_file, "instr_to_x86_64: llcall: unexpected:" ++
-               " lval_reg_locn failed")
+            unexpected(this_file,
+                "instr_to_x86_64: llcall: unexpected: lval_reg_locn failed")
         )
     ),
     Instr1 = x86_64_instr(mov(operand_label(Continuation1), Op)),
     Instr2 = x86_64_instr(jmp(operand_label(Target1))),
     Instrs = [Instr1, Instr2].
-instr_to_x86_64(RegMap, mkframe(_, _), RegMap, [x86_64_comment("<<mkframe>>")]).
-instr_to_x86_64(RegMap, label(Label), RegMap, Instrs) :-
+instr_to_x86_64(!RegMap, mkframe(_, _), [x86_64_comment("<<mkframe>>")]).
+instr_to_x86_64(!RegMap, label(Label), Instrs) :-
     LabelStr = ll_backend.llds_out.label_to_c_string(Label, no),
     Instrs = [x86_64_label(LabelStr)]. 
-instr_to_x86_64(RegMap, goto(CodeAddr), RegMap, Instrs) :-
+instr_to_x86_64(!RegMap, goto(CodeAddr), Instrs) :-
     code_addr_type(CodeAddr, Label),
     Instrs = [x86_64_instr(jmp(operand_label(Label)))].
-instr_to_x86_64(RegMap0, computed_goto(Rval, Labels), RegMap, Instrs) :-
-    transform_rval(RegMap0, Rval, RegMap1, Res0, Res1),
+instr_to_x86_64(!RegMap, computed_goto(Rval, Labels), Instrs) :-
+    transform_rval(!RegMap, Rval, Res0, Res1),
     (
         Res0 = yes(RvalOp),
         RvalInstrs = []
@@ -293,84 +278,67 @@
         Res0 = no,
         ( 
             Res1 = yes(RvalInstrs),
-            ( get_last_instr_opand(RvalInstrs, RvalOp0) ->
+            get_last_instr_operand(RvalInstrs, RvalOp0),
                 RvalOp = RvalOp0
             ;
-                unexpected(this_file, "instr_to_x86_64: computed_goto:" 
-                    ++ " unexpected: get_last_instr_opand failed")
-            )
-        ;
             Res1 = no,
-            unexpected(this_file, "instr_to_x86_64: computed_goto: unexpected:"
-                ++ " Rval")
+            unexpected(this_file,
+                "instr_to_x86_64: computed_goto: unexpected: Rval")
         )
     ),
     labels_to_string(Labels, "", LabelStr),
-    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(RegMap1),
-    ll_backend.x86_64_regs.reg_map_remove_scratch_reg(RegMap1, RegMap),
+    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(!.RegMap),
+    ll_backend.x86_64_regs.reg_map_remove_scratch_reg(!RegMap),
     TempReg = operand_reg(ScratchReg),
     Instr0 = x86_64_instr(mov(operand_mem_ref(mem_abs(base_expr(LabelStr))), 
         TempReg)),
     Instr1 = x86_64_instr(add(RvalOp, TempReg)),
     Instr2 = x86_64_instr(jmp(TempReg)),
     Instrs = RvalInstrs ++ [Instr0] ++ [Instr1] ++ [Instr2].
-instr_to_x86_64(RegMap, arbitrary_c_code(_, _, _), RegMap, Instrs) :-
+instr_to_x86_64(!RegMap, arbitrary_c_code(_, _, _), Instrs) :-
     Instrs = [x86_64_comment("<<arbitrary_c_code>>")].
-instr_to_x86_64(RegMap0, if_val(Rval, CodeAddr), RegMap, Instrs) :-
+instr_to_x86_64(!RegMap, if_val(Rval, CodeAddr), Instrs) :-
     code_addr_type(CodeAddr, Target),
-    transform_rval(RegMap0, Rval, RegMap, Res0, Res1),
+    transform_rval(!RegMap, Rval, Res0, Res1),
     (
         Res0 = yes(RvalOp)
     ;
         Res0 = no,
         ( 
             Res1 = yes(RvalInstrs),
-            ( get_last_instr_opand(RvalInstrs, LastOp) ->
-                RvalOp = LastOp
-            ;
-                unexpected(this_file, "instr_to_x86_64: if_val: unexpected:"
-                    ++ " get_last_instr_opand failed")
-            )
+            get_last_instr_operand(RvalInstrs, RvalOp)
         ;
             Res1 = no,
-            unexpected(this_file, "instr_to_x86_64: if_val: unexpected:"
-                ++ " Rval")
+            unexpected(this_file, "instr_to_x86_64: if_val: unexpected: Rval")
         )
     ),
     ll_backend.x86_64_out.operand_to_string(RvalOp, RvalStr),
-    Instrs = [x86_64_directive(x86_64_pseudo_if(RvalStr)), x86_64_instr(j(
-        operand_label(Target), e)), x86_64_directive(endif)].
-instr_to_x86_64(RegMap, save_maxfr(_), RegMap, Instr) :-
+    Instrs = [x86_64_directive(x86_64_pseudo_if(RvalStr)),
+        x86_64_instr(j(operand_label(Target), e)), x86_64_directive(endif)].
+instr_to_x86_64(!RegMap, save_maxfr(_), Instr) :-
     Instr = [x86_64_comment("<<save_maxfr>>")].
-instr_to_x86_64(RegMap, restore_maxfr(_), RegMap, Instr) :-
+instr_to_x86_64(!RegMap, restore_maxfr(_), Instr) :-
     Instr = [x86_64_comment("<<restore_maxfr>>")].
-instr_to_x86_64(RegMap0,
-        incr_hp(Lval, Tag0, Words0, Rval, _, _, MaybeRegionRval),
-        RegMap, Instrs) :-
+instr_to_x86_64(!RegMap,
+        incr_hp(Lval, Tag0, Words0, Rval, _, _, MaybeRegionRval), Instrs) :-
     (
         MaybeRegionRval = no
     ;
         MaybeRegionRval = yes(_),
         unexpected(this_file, "instr_to_x86_64: encounter a region variable")
     ),
-    transform_rval(RegMap0, Rval, RegMap1, Res0, Res1),
-    transform_lval(RegMap1, Lval, RegMap2, Res2, Res3),
+    transform_rval(!RegMap, Rval, Res0, Res1),
+    transform_lval(!RegMap, Lval, Res2, Res3),
     (
         Res0 = yes(RvalOp)
     ;
         Res0 = no,
         (  
             Res1 = yes(RvalInstrs),
-            ( get_last_instr_opand(RvalInstrs, RvalLastOp) ->
-                RvalOp = RvalLastOp
-            ;
-                unexpected(this_file, "instr_to_x86_64: incr_hp: unexpected:"
-                    ++ " get_last_instr_opand failed")
-            )
+            get_last_instr_operand(RvalInstrs, RvalOp)
         ;
             Res1 = no,
-            unexpected(this_file, "instr_to_x86_64: incr_hp: unexpected:"
-                ++ " Rval")
+            unexpected(this_file, "instr_to_x86_64: incr_hp: unexpected: Rval")
         )
     ),
     (
@@ -379,32 +347,25 @@
         Res2 = no,
         ( 
             Res3 = yes(LvalInstrs),
-            ( get_last_instr_opand(LvalInstrs, LvalLastOp) ->
-                LvalOp = LvalLastOp    
-            ;
-                unexpected(this_file, "instr_to_x86_64: incr_hp: unexpected:"
-                    ++ " get_last_instr_opand failed")
-            )
+            get_last_instr_operand(LvalInstrs, LvalOp)
         ;
             Res3 = no,
-            unexpected(this_file, "instr_to_x86_64: incr_hp: unexpected:" 
-                ++ " Lval")
+            unexpected(this_file, "instr_to_x86_64: incr_hp: unexpected: Lval")
         ) 
     ),
     (
         Words0 = yes(Words),
         IncrVal = operand_imm(imm32(int32(Words))),
-        ScratchReg0 = ll_backend.x86_64_regs.reg_map_get_scratch_reg(RegMap2),
-        reg_map_remove_scratch_reg(RegMap2, RegMap3),
+        ScratchReg0 = ll_backend.x86_64_regs.reg_map_get_scratch_reg(!.RegMap),
+        reg_map_remove_scratch_reg(!RegMap),
         TempReg1 = operand_reg(ScratchReg0),
         ll_backend.x86_64_out.operand_to_string(RvalOp, RvalStr),
         MemRef = operand_mem_ref(mem_abs(base_expr(RvalStr))),
         LoadAddr = x86_64_instr(lea(MemRef, TempReg1)),
         IncrAddInstr = x86_64_instr(add(IncrVal, TempReg1)),
-        list.append([LoadAddr], [IncrAddInstr], IncrAddrInstrs)
+        IncrAddrInstrs = [LoadAddr, IncrAddInstr]
     ;
         Words0 = no,
-        RegMap3 = RegMap2,
         IncrAddrInstrs = []
     ),
     ( 
@@ -413,89 +374,91 @@
         Tag0 = no,
         Tag = 0
     ),
-    ScratchReg1 = ll_backend.x86_64_regs.reg_map_get_scratch_reg(RegMap3),
-    reg_map_remove_scratch_reg(RegMap3, RegMap),
+    ScratchReg1 = ll_backend.x86_64_regs.reg_map_get_scratch_reg(!.RegMap),
+    reg_map_remove_scratch_reg(!RegMap),
     TempReg2 = operand_reg(ScratchReg1),
     ImmToReg = x86_64_instr(mov(RvalOp, TempReg2)),
     SetTag = x86_64_instr(or(operand_imm(imm32(int32(Tag))), TempReg2)),
     Instr1 = x86_64_instr(mov(TempReg2, LvalOp)),
     Instrs = IncrAddrInstrs ++ [ImmToReg] ++ [SetTag] ++ [Instr1]. 
-instr_to_x86_64(RegMap, mark_hp(_), RegMap, [x86_64_comment("<<mark_hp>>")]).
-instr_to_x86_64(RegMap, restore_hp(_), RegMap, Instr) :-
+instr_to_x86_64(!RegMap, mark_hp(_), [x86_64_comment("<<mark_hp>>")]).
+instr_to_x86_64(!RegMap, restore_hp(_), Instr) :-
     Instr = [x86_64_comment("<<restore_hp>>")].
-instr_to_x86_64(RegMap, free_heap(_), RegMap, Instr) :-
+instr_to_x86_64(!RegMap, free_heap(_), Instr) :-
     Instr = [x86_64_comment("<<free_heap>>")].
-instr_to_x86_64(RegMap, store_ticket(_), RegMap, Instr) :-
+instr_to_x86_64(!RegMap, store_ticket(_), Instr) :-
     Instr = [x86_64_comment("<<store_ticket>>")].
-instr_to_x86_64(RegMap, reset_ticket(_, _), RegMap, Instr) :-
+instr_to_x86_64(!RegMap, reset_ticket(_, _), Instr) :-
     Instr = [x86_64_comment("<<reset_ticket>>")].
-instr_to_x86_64(RegMap, prune_ticket, RegMap, Instr) :-
+instr_to_x86_64(!RegMap, prune_ticket, Instr) :-
     Instr = [x86_64_comment("<<prune_ticket>>")].
-instr_to_x86_64(RegMap, discard_ticket, RegMap, Instr) :-
+instr_to_x86_64(!RegMap, discard_ticket, Instr) :-
     Instr = [x86_64_comment("<<discard_ticket>>")].
-instr_to_x86_64(RegMap, mark_ticket_stack(_), RegMap, Instr) :-
+instr_to_x86_64(!RegMap, mark_ticket_stack(_), Instr) :-
     Instr = [x86_64_comment("<<mark_ticket_stack>>")].
-instr_to_x86_64(RegMap, prune_tickets_to(_), RegMap, Instr) :-
+instr_to_x86_64(!RegMap, prune_tickets_to(_), Instr) :-
     Instr = [x86_64_comment("<<prune_tickets_to>>")].
-instr_to_x86_64(RegMap, incr_sp(NumSlots, ProcName, _), RegMap, Instrs) :-
+instr_to_x86_64(!RegMap, incr_sp(NumSlots, ProcName, _), Instrs) :-
     Instr1 = x86_64_comment("<<incr_sp>> " ++ ProcName),
     Instr2 = x86_64_instr(enter(uint16(NumSlots), uint8(0))),
     Instrs = [Instr1, Instr2].
-instr_to_x86_64(RegMap0, decr_sp(NumSlots), RegMap, Instrs) :-
+instr_to_x86_64(!RegMap, decr_sp(NumSlots), Instrs) :-
     DecrOp = operand_imm(imm32(int32(NumSlots))),
-    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(RegMap0),
-    ll_backend.x86_64_regs.reg_map_remove_scratch_reg(RegMap0, RegMap),
+    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(!.RegMap),
+    ll_backend.x86_64_regs.reg_map_remove_scratch_reg(!RegMap),
     Instr = x86_64_instr(sub(DecrOp, operand_reg(ScratchReg))),
-    list.append([x86_64_comment("<<decr_sp>> ")], [Instr], Instrs).
-instr_to_x86_64(RegMap, decr_sp_and_return(NumSlots), RegMap, Instrs) :-
+    Instrs = [x86_64_comment("<<decr_sp>> "), Instr].
+instr_to_x86_64(!RegMap, decr_sp_and_return(NumSlots), Instrs) :-
     Instrs = [x86_64_comment("<<decr_sp_and_return>> " ++ 
         string.int_to_string(NumSlots))].
-instr_to_x86_64(RegMap, foreign_proc_code(_, _, _, _, _, _, _, _, _), RegMap, 
+instr_to_x86_64(!RegMap, foreign_proc_code(_, _, _, _, _, _, _, _, _),
         Instr) :-
     Instr = [x86_64_comment("<<foreign_proc_code>>")].
-instr_to_x86_64(RegMap, init_sync_term(_, _), RegMap, Instr) :-
+instr_to_x86_64(!RegMap, init_sync_term(_, _), Instr) :-
     Instr = [x86_64_comment("<<init_sync_term>>")].
-instr_to_x86_64(RegMap, fork(_), RegMap, [x86_64_comment("<<fork>>")]).
-instr_to_x86_64(RegMap, join_and_continue(_, _), RegMap, Instr) :-
+instr_to_x86_64(!RegMap, fork(_), [x86_64_comment("<<fork>>")]).
+instr_to_x86_64(!RegMap, join_and_continue(_, _), Instr) :-
     Instr = [x86_64_comment("<<join_and_continue>>")].
 
     % Transform lval into either an x86_64 operand or x86_64 instructions.
     %
-:- pred transform_lval(reg_map::in, lval::in, reg_map::out, maybe(operand)::out,
-    maybe(list(x86_64_instr))::out) is det. 
+:- pred transform_lval(reg_map::in, reg_map::out, lval::in,
+    maybe(operand)::out, maybe(list(x86_64_instr))::out) is det.
 
-transform_lval(RegMap0, reg(CReg, CRegNum), RegMap, Op, Instr) :-
+transform_lval(!RegMap, reg(CReg, CRegNum), Op, Instr) :-
     (
         CReg = reg_r,
-        lval_reg_locn(RegMap, reg(CReg, CRegNum), Op, Instr),
-        reg_map_remove_scratch_reg(RegMap0, RegMap)
+        % XXX Should we call lval_reg_locn first, or
+        % reg_map_remove_scratch_reg?
+        lval_reg_locn(!.RegMap, reg(CReg, CRegNum), Op, Instr),
+        reg_map_remove_scratch_reg(!RegMap)
     ;
         CReg = reg_f,
         unexpected(this_file, "transform_lval: unexpected: llds reg_f")
     ).
-transform_lval(RegMap0, succip, RegMap, Op, Instr) :-
-    lval_reg_locn(RegMap0, succip, Op, Instr),
-    reg_map_remove_scratch_reg(RegMap0, RegMap).
-transform_lval(RegMap0, maxfr, RegMap, Op, Instr) :-
-    lval_reg_locn(RegMap0, maxfr, Op, Instr),
-    reg_map_remove_scratch_reg(RegMap0, RegMap).
-transform_lval(RegMap0, curfr, RegMap, Op, Instr) :-
-    lval_reg_locn(RegMap0, curfr, Op, Instr),
-    reg_map_remove_scratch_reg(RegMap0, RegMap).
-transform_lval(RegMap0, hp, RegMap, Op, Instr) :-
-    lval_reg_locn(RegMap0, hp, Op, Instr),
-    reg_map_remove_scratch_reg(RegMap0, RegMap).
-transform_lval(RegMap0, sp, RegMap, Op, Instr) :-
-    lval_reg_locn(RegMap0, sp, Op, Instr),
-    reg_map_remove_scratch_reg(RegMap0, RegMap).
-transform_lval(RegMap, parent_sp, RegMap, _, _) :-
+transform_lval(!RegMap, succip, Op, Instr) :-
+    lval_reg_locn(!.RegMap, succip, Op, Instr),
+    reg_map_remove_scratch_reg(!RegMap).
+transform_lval(!RegMap, maxfr, Op, Instr) :-
+    lval_reg_locn(!.RegMap, maxfr, Op, Instr),
+    reg_map_remove_scratch_reg(!RegMap).
+transform_lval(!RegMap, curfr, Op, Instr) :-
+    lval_reg_locn(!.RegMap, curfr, Op, Instr),
+    reg_map_remove_scratch_reg(!RegMap).
+transform_lval(!RegMap, hp, Op, Instr) :-
+    lval_reg_locn(!.RegMap, hp, Op, Instr),
+    reg_map_remove_scratch_reg(!RegMap).
+transform_lval(!RegMap, sp, Op, Instr) :-
+    lval_reg_locn(!.RegMap, sp, Op, Instr),
+    reg_map_remove_scratch_reg(!RegMap).
+transform_lval(!RegMap, parent_sp, _, _) :-
     sorry(this_file, "parallelism is not supported").
-transform_lval(RegMap, temp(CReg, CRegNum), RegMap1, Op, Instr) :-
-    transform_lval(RegMap, reg(CReg, CRegNum), RegMap1, Op, Instr).
-transform_lval(RegMap0, stackvar(Offset), RegMap, Op, Instr) :-
-    RegLocn = reg_map_lookup_reg_locn(RegMap, sp),
-    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(RegMap0),
-    reg_map_remove_scratch_reg(RegMap0, RegMap),
+transform_lval(!RegMap, temp(CReg, CRegNum), Op, Instr) :-
+    transform_lval(!RegMap, reg(CReg, CRegNum), Op, Instr).
+transform_lval(!RegMap, stackvar(Offset), Op, Instr) :-
+    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(!.RegMap),
+    reg_map_remove_scratch_reg(!RegMap),
+    RegLocn = reg_map_lookup_reg_locn(!.RegMap, sp),
     (
         RegLocn = actual(Reg),
         Op = no, 
@@ -504,19 +467,21 @@
     ;
         RegLocn = virtual(SlotNum),
         Op = no,
-        FakeRegVal = "$" ++ "virtual_reg(" ++ string.int_to_string(SlotNum) 
-            ++ ") + " ++ string.int_to_string(Offset),
+        FakeRegVal = "$virtual_reg(" ++ string.int_to_string(SlotNum) ++ ") + "
+            ++ string.int_to_string(Offset),
         Instr = yes([x86_64_instr(mov(
             operand_label(FakeRegVal), operand_reg(ScratchReg)))])
     ).
-transform_lval(RegMap, parent_stackvar(_), RegMap, _, _) :-
+transform_lval(!RegMap, parent_stackvar(_), _, _) :-
     sorry(this_file, "parallelism is not supported").
-transform_lval(RegMap0, framevar(Offset), RegMap, Op, Instr) :-
-    ScratchReg= ll_backend.x86_64_regs.reg_map_get_scratch_reg(RegMap),
-    reg_map_remove_scratch_reg(RegMap0, RegMap),
-    RegLocn = reg_map_lookup_reg_locn(RegMap, curfr),
+transform_lval(!RegMap, framevar(Offset), Op, Instr) :-
+    % XXX The original code here was out of order: it executed
+    % reg_map_remove_scratch_reg *before* reg_map_get_scratch_reg.
+    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(!.RegMap),
+    reg_map_remove_scratch_reg(!RegMap),
+    RegLocn = reg_map_lookup_reg_locn(!.RegMap, curfr),
     % framevar(Int) refers to an offset Int relative to the current value of 
-    % 'curfr'
+    % 'curfr'.
     (
         RegLocn = actual(Reg),
         Op = no, 
@@ -525,29 +490,29 @@
     ;
         RegLocn = virtual(SlotNum),
         Op = no,
-        FakeRegVal = "$" ++ "virtual_reg(" ++ string.int_to_string(SlotNum) 
-            ++ ") + " ++ string.int_to_string(Offset),
+        FakeRegVal = "$virtual_reg(" ++ string.int_to_string(SlotNum) ++ ") + "
+            ++ string.int_to_string(Offset),
         Instr = yes([x86_64_instr(mov(
             operand_label(FakeRegVal), operand_reg(ScratchReg)))])
     ).
-transform_lval(RegMap0, succip_slot(Rval), RegMap, Op, Instr) :-
-    transform_rval(RegMap0, Rval, RegMap, Op, Instr).
-transform_lval(RegMap0, redoip_slot(Rval), RegMap, Op, Instr) :-
-    transform_rval(RegMap0, Rval, RegMap, Op, Instr).
-transform_lval(RegMap0, redofr_slot(Rval), RegMap, Op, Instr) :-
-    transform_rval(RegMap0, Rval, RegMap, Op, Instr).
-transform_lval(RegMap0, succfr_slot(Rval), RegMap, Op, Instr) :-
-    transform_rval(RegMap0, Rval, RegMap, Op, Instr).
-transform_lval(RegMap0, prevfr_slot(Rval), RegMap, Op, Instr) :-
-    transform_rval(RegMap0, Rval, RegMap, Op, Instr).
-transform_lval(RegMap0, mem_ref(Rval), RegMap, Op, Instr) :-
-    transform_rval(RegMap0, Rval, RegMap, Op, Instr).
-transform_lval(RegMap, global_var_ref(env_var_ref(Name)), RegMap, Op, no) :-
+transform_lval(!RegMap, succip_slot(Rval), Op, Instr) :-
+    transform_rval(!RegMap, Rval, Op, Instr).
+transform_lval(!RegMap, redoip_slot(Rval), Op, Instr) :-
+    transform_rval(!RegMap, Rval, Op, Instr).
+transform_lval(!RegMap, redofr_slot(Rval), Op, Instr) :-
+    transform_rval(!RegMap, Rval, Op, Instr).
+transform_lval(!RegMap, succfr_slot(Rval), Op, Instr) :-
+    transform_rval(!RegMap, Rval, Op, Instr).
+transform_lval(!RegMap, prevfr_slot(Rval), Op, Instr) :-
+    transform_rval(!RegMap, Rval, Op, Instr).
+transform_lval(!RegMap, mem_ref(Rval), Op, Instr) :-
+    transform_rval(!RegMap, Rval, Op, Instr).
+transform_lval(!RegMap, global_var_ref(env_var_ref(Name)), Op, no) :-
     Op = yes(operand_label(Name)).
-transform_lval(RegMap, lvar(_), RegMap, yes(operand_label("<<lvar>>")), no).
-transform_lval(RegMap0, field(Tag0, Rval1, Rval2), RegMap, no, Instrs) :-
-    transform_rval(RegMap0, Rval1, RegMap1, Res0, Res1),
-    transform_rval(RegMap1, Rval2, RegMap2, Res2, Res3),
+transform_lval(!RegMap, lvar(_), yes(operand_label("<<lvar>>")), no).
+transform_lval(!RegMap, field(Tag0, Rval1, Rval2), no, Instrs) :-
+    transform_rval(!RegMap, Rval1, Res0, Res1),
+    transform_rval(!RegMap, Rval2, Res2, Res3),
     (
         Res0 = yes(RvalOp1),
         Instrs1 = []
@@ -555,14 +520,9 @@
         Res0 = no,
         ( 
             Res1 = yes(RvalInstrs1),
-            ( get_last_instr_opand(RvalInstrs1, LastOp1) ->
-                RvalOp1 = LastOp1,
+            get_last_instr_operand(RvalInstrs1, RvalOp1),
                 Instrs1 = RvalInstrs1
             ;
-                unexpected(this_file, "lval_instrs: field: unexpected:"
-                    ++ " get_last_instr_opand failed")
-            )
-        ;
             Res1 = no,
             unexpected(this_file, "lval_instrs: field: unexpected: Rval1")
         )
@@ -574,20 +534,15 @@
         Res2 = no,
         (
             Res3 = yes(RvalInstrs2),
-            ( get_last_instr_opand(RvalInstrs2, LastOp2) ->
-                RvalOp2 = LastOp2,
+            get_last_instr_operand(RvalInstrs2, RvalOp2),
                 Instrs2 = RvalInstrs2
             ;
-                unexpected(this_file, "lval_instrs: field: unexpected:"
-                    ++ " get_last_instr_opand failed")
-            )
-        ;
             Res3 = no,
             unexpected(this_file, "lval_instrs: field: unexpected: Rval2")
         )
     ),
-    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(RegMap2),
-    reg_map_remove_scratch_reg(RegMap2, RegMap),
+    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(!.RegMap),
+    reg_map_remove_scratch_reg(!RegMap),
     TempReg1 = operand_reg(ScratchReg),
     ll_backend.x86_64_out.operand_to_string(RvalOp1, RvalStr1),
     MemRef = operand_mem_ref(mem_abs(base_expr(RvalStr1))),
@@ -605,60 +560,55 @@
 
     % Translates rval into its corresponding x86_64 operand. 
     %
-:- pred transform_rval(reg_map::in, rval::in, reg_map::out, maybe(operand)::out,
-    maybe(list(x86_64_instr)) ::out) is det. 
+:- pred transform_rval(reg_map::in, reg_map::out, rval::in,
+    maybe(operand)::out, maybe(list(x86_64_instr)) ::out) is det.
 
-transform_rval(RegMap0, lval(Lval0), RegMap, Op, Instrs) :-
-    transform_lval(RegMap0, Lval0, RegMap, Op, Instrs).
-transform_rval(RegMap, var(_), RegMap, yes(operand_label("<<var>>")), no).
-transform_rval(RegMap0, mkword(Tag, Rval), RegMap, no, Instrs) :-
-    transform_rval(RegMap0, Rval, RegMap1, Res0, Res1),
+transform_rval(!RegMap, lval(Lval0), Op, Instrs) :-
+    transform_lval(!RegMap, Lval0, Op, Instrs).
+transform_rval(!RegMap, var(_), yes(operand_label("<<var>>")), no).
+transform_rval(!RegMap, mkword(Tag, Rval), no, Instrs) :-
+    transform_rval(!RegMap, Rval, Res0, Res1),
     (
         Res0 = yes(RvalOp),
-        list.append([x86_64_comment("<<mkword>>")], [], Instr0)
+        Instr0 = [x86_64_comment("<<mkword>>")]
     ;
         Res0 = no,
         (
             Res1 = yes(RvalInstrs),
-            ( get_last_instr_opand(RvalInstrs, LastOp) ->
-                RvalOp = LastOp,
-                list.append(RvalInstrs, [x86_64_comment("<<mkword>>")], Instr0)
-            ;
-                unexpected(this_file, "transform_rval: mkword: unexpected:"
-                    ++ " get_last_instr_opand failed")
-            )
+            get_last_instr_operand(RvalInstrs, RvalOp),
+            Instr0 = RvalInstrs ++ [x86_64_comment("<<mkword>>")]
         ;
             Res1 = no,
             unexpected(this_file, "transform_rval: mkword unexpected: Rval")
         )
     ),
-    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(RegMap1),
-    reg_map_remove_scratch_reg(RegMap1, RegMap),
+    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(!.RegMap),
+    reg_map_remove_scratch_reg(!RegMap),
     TempReg = operand_reg(ScratchReg),
     ll_backend.x86_64_out.operand_to_string(RvalOp, RvalStr),
     MemRef = operand_mem_ref(mem_abs(base_expr(RvalStr))),
     LoadAddr = x86_64_instr(lea(MemRef, TempReg)),
     SetTag = x86_64_instr(add(operand_imm(imm32(int32(Tag))), TempReg)),
     Instrs = yes(Instr0 ++ [LoadAddr] ++ [SetTag]).
-transform_rval(RegMap, const(llconst_true), RegMap, Op, no) :-
+transform_rval(!RegMap, const(llconst_true), Op, no) :-
     Op = yes(operand_label("<<llconst_true>>")).
-transform_rval(RegMap, const(llconst_false), RegMap, Op, no) :-
+transform_rval(!RegMap, const(llconst_false), Op, no) :-
     Op = yes(operand_label("<<llconst_false>>")).
-transform_rval(RegMap, const(llconst_int(Val)), RegMap, Op, no) :-
+transform_rval(!RegMap, const(llconst_int(Val)), Op, no) :-
     Op = yes(operand_imm(imm32(int32(Val)))).
-transform_rval(RegMap, const(llconst_float(_)), RegMap, Op, no) :-
+transform_rval(!RegMap, const(llconst_float(_)), Op, no) :-
     Op = yes(operand_label("<<llconst_float>>")).
-transform_rval(RegMap, const(llconst_string(String)), RegMap, no, yes(Op)) :-
+transform_rval(!RegMap, const(llconst_string(String)), no, yes(Op)) :-
     Op = [x86_64_directive(string([String]))].
-transform_rval(RegMap, const(llconst_multi_string(_)), RegMap, Op, no) :-
+transform_rval(!RegMap, const(llconst_multi_string(_)), Op, no) :-
     Op = yes(operand_label("<<llconst_multi_string>>")).
-transform_rval(RegMap, const(llconst_code_addr(CodeAddr)), RegMap, Op, no) :-
+transform_rval(!RegMap, const(llconst_code_addr(CodeAddr)), Op, no) :-
     code_addr_type(CodeAddr, CodeAddrType),
     Op = yes(operand_label(CodeAddrType)).
-transform_rval(RegMap, const(llconst_data_addr(_, _)), RegMap, Op, no) :-
+transform_rval(!RegMap, const(llconst_data_addr(_, _)), Op, no) :-
     Op = yes(operand_label("<<llconst_data_addr>>")).
-transform_rval(RegMap0, unop(Op, Rval), RegMap, no, Instrs) :-
-    transform_rval(RegMap0, Rval, RegMap, Res0, Res1),
+transform_rval(!RegMap, unop(Op, Rval), no, Instrs) :-
+    transform_rval(!RegMap, Rval, Res0, Res1),
     (
         Res0 = yes(_),
         unop_instrs(Op, Res0, no, Instrs0),
@@ -674,20 +624,21 @@
             unexpected(this_file, "transform_rval: unop: unexpected: Rval")
         )
     ).
-transform_rval(RegMap0, binop(Op, Rval1, Rval2), RegMap, no, Instrs) :-
-    transform_rval(RegMap0, Rval1, RegMap1, Res1, Res2),
-    transform_rval(RegMap1, Rval2, RegMap, Res3, Res4),
+transform_rval(!RegMap, binop(Op, Rval1, Rval2), no, Instrs) :-
+    transform_rval(!RegMap, Rval1, Res1, Res2),
+    transform_rval(!RegMap, Rval2, Res3, Res4),
     (
         Res1 = yes(Val1),
         (
             Res3 = yes(Val2),
-            binop_instrs(binop_simple_opands(Val1, Val2), Op, Instrs0),
+            binop_instrs(binop_simple_operands(Val1, Val2), Op, Instrs0),
             Instrs = yes(Instrs0)
         ;
             Res3 = no,
             (
                 Res4 = yes(RvalInstr2),
-                binop_instrs(binop_simple_and_compound_opands(Val1, RvalInstr2),
+                binop_instrs(
+                    binop_simple_and_compound_operands(Val1, RvalInstr2),
                     Op, Instrs0),
                 Instrs = yes(Instrs0)
             ;
@@ -701,20 +652,22 @@
             Res2 = yes(RvalInstr1),
             (
                 Res3 = yes(Val2),
-                binop_instrs(binop_compound_and_simple_opands(RvalInstr1, Val2),
+                binop_instrs(
+                    binop_compound_and_simple_operands(RvalInstr1, Val2),
                     Op, Instrs0),
                 Instrs = yes(Instrs0)
             ;
                 Res3 = no,
                 (
                     Res4 = yes(RvalInstr2),
-                    binop_instrs(binop_compound_opands(RvalInstr1, RvalInstr2), 
+                    binop_instrs(
+                        binop_compound_operands(RvalInstr1, RvalInstr2),
                         Op, Instrs0),
                     Instrs = yes(Instrs0)
                 ;
                     Res4 = no,
-                    unexpected(this_file, "rval_instrs: binop: unexpected:" 
-                        ++ " Rval2")
+                    unexpected(this_file,
+                        "rval_instrs: binop: unexpected: Rval2")
                 )
             )
         ;
@@ -722,14 +675,13 @@
             unexpected(this_file, "rval_instrs: binop: unexpected: Rval1")
         )
     ).
-transform_rval(RegMap0, mem_addr(stackvar_ref(Rval)), RegMap, Op, no) :-
-    transform_rval(RegMap0, Rval, RegMap, Op, _). 
-transform_rval(RegMap0, mem_addr(framevar_ref(Rval)), RegMap, Op, no) :-
-    transform_rval(RegMap0, Rval, RegMap, Op, _). 
-transform_rval(RegMap0, mem_addr(heap_ref(Rval1, Tag, Rval2)), RegMap, 
-        no, Instrs) :-
-    transform_rval(RegMap0, Rval1, RegMap1, Res0, Res1),
-    transform_rval(RegMap1, Rval2, RegMap2, Res2, Res3),
+transform_rval(!RegMap, mem_addr(stackvar_ref(Rval)), Op, no) :-
+    transform_rval(!RegMap, Rval, Op, _).
+transform_rval(!RegMap, mem_addr(framevar_ref(Rval)), Op, no) :-
+    transform_rval(!RegMap, Rval, Op, _).
+transform_rval(!RegMap, mem_addr(heap_ref(Rval1, Tag, Rval2)), no, Instrs) :-
+    transform_rval(!RegMap, Rval1, Res0, Res1),
+    transform_rval(!RegMap, Rval2, Res2, Res3),
     (
         Res0 = yes(Rval1Op),
         (
@@ -740,24 +692,18 @@
             ( 
                 Res3 = yes(Rval2Instr),
                 Instrs0 = Rval2Instr,
-                ( get_last_instr_opand(Rval2Instr, LastOp) ->
-                     Rval2Op = LastOp
-                ;
-                    unexpected(this_file, "transform_rval: mem_addr(heap_ref):"
-                        ++ " unexpected: get_last_instr_opand failed")
-                )
+                get_last_instr_operand(Rval2Instr, Rval2Op)
             ;
                 Res3 = no,
-                unexpected(this_file, "transform_rval: mem_addr(heap_ref):"
-                    ++ " unexpected: Rval2")
+                unexpected(this_file,
+                    "transform_rval: mem_addr(heap_ref): unexpected: Rval2")
             )
         )
     ;
         Res0 = no,
         (
             Res1 = yes(Rval1Instr),
-            ( get_last_instr_opand(Rval1Instr, LastOp) ->
-                Rval1Op = LastOp,
+            get_last_instr_operand(Rval1Instr, Rval1Op),
                 (
                     Res2 = yes(Rval2Op),
                     Instrs0 = Rval1Instr
@@ -765,32 +711,23 @@
                     Res2 = no,
                     ( 
                         Res3 = yes(Rval2Instr),
-                        ( get_last_instr_opand(Rval2Instr, LastOp) ->
-                            Rval2Op = LastOp,
-                            list.append(Rval1Instr, Rval2Instr, Instrs0)
-                        ;
-                            unexpected(this_file, "transform_rval:"
-                                ++ " mem_addr(heap_ref): unexpected:"
-                                ++ " get_last_instr_opand failed")
-                        )
+                    get_last_instr_operand(Rval2Instr, Rval2Op),
+                    Instrs0 = Rval1Instr ++ Rval2Instr
                     ;
                         Res3 = no,
-                        unexpected(this_file, "transform_rval:"
-                            ++ " mem_addr(heap_ref): unexpected: Rval2")
-                    )
+                    unexpected(this_file,
+                        "transform_rval: mem_addr(heap_ref): unexpected: " ++
+                        "Rval2")
                 )
-            ;
-                unexpected(this_file, "transform_rval: mem_addr(heap_ref):" 
-                    ++ " unexpected: get_last_instr_opand failed")
             )
        ;
             Res1 = no, 
-            unexpected(this_file, "transform_rval: mem_addr(heap_ref)" 
-                ++ " unexpected: Rval1")
+            unexpected(this_file,
+                "transform_rval: mem_addr(heap_ref) unexpected: Rval1")
        )
     ),
-    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(RegMap2),
-    reg_map_remove_scratch_reg(RegMap2, RegMap),
+    ScratchReg = ll_backend.x86_64_regs.reg_map_get_scratch_reg(!.RegMap),
+    reg_map_remove_scratch_reg(!RegMap),
     TempReg = operand_reg(ScratchReg),
     ll_backend.x86_64_out.operand_to_string(Rval1Op, Rval1Str),
     MemRef = operand_mem_ref(mem_abs(base_expr(Rval1Str))),
@@ -799,13 +736,12 @@
     Instr1 = x86_64_instr(add(operand_imm(imm32(int32(Tag))), TempReg)),
     Instrs = yes(Instrs0 ++ [LoadAddr] ++ [Instr0] ++ [Instr1]).
 
-
-    % Given an llds-lval, returns either an operand or instructions (actually, 
-    % it only a single move instruction. It returns a list so that the calling
-    % predicate won't have to do any rearrangements for the return value). If 
-    % lval is located in an actual register, returns the actual register which 
-    % corresponds to that lval. Otherwise, move lval from the fake-reg array
-    % to a temporary register. 
+    % Given an llds-lval, returns either an operand or instructions. (Actually,
+    % it only a single move instruction; it returns a list so that the calling
+    % predicate won't have to do any rearrangements for the return value.)
+    % If lval is located in an actual register, returns the actual register
+    % which corresponds to that lval. Otherwise, move lval from the fake reg
+    % array to a temporary register.
     %
 :- pred lval_reg_locn(reg_map::in, lval::in, maybe(operand)::out, 
     maybe(list(x86_64_instr))::out) is det. 
@@ -831,35 +767,21 @@
     %
 :- pred binop_instrs(binop::in, binary_op::in, list(x86_64_instr)::out) is det. 
 
-binop_instrs(binop_simple_opands(Op1, Op2), Op, Instrs) :-
+binop_instrs(binop_simple_operands(Op1, Op2), Op, Instrs) :-
     binop_instr(Op, Op1, Op2, Instrs).
-binop_instrs(binop_simple_and_compound_opands(Op1, InstrsOp), Op, Instrs) :-
-    ( get_last_instr_opand(InstrsOp, LastOp) ->
+binop_instrs(binop_simple_and_compound_operands(Op1, InstrsOp), Op, Instrs) :-
+    get_last_instr_operand(InstrsOp, LastOp),
         binop_instr(Op, Op1, LastOp, Instrs0),
-        list.append(InstrsOp, Instrs0, Instrs)
-    ;
-        unexpected(this_file, "binop_instrs: binop_simple_and_compound_opands"
-            ++ " unexpected: get_last_instr_opand failed")
-    ).
-binop_instrs(binop_compound_and_simple_opands(InstrsOp, Op2), Op, Instrs) :-
-    ( get_last_instr_opand(InstrsOp, LastOp) ->
+    Instrs = InstrsOp ++ Instrs0.
+binop_instrs(binop_compound_and_simple_operands(InstrsOp, Op2), Op, Instrs) :-
+    get_last_instr_operand(InstrsOp, LastOp),
         binop_instr(Op, LastOp, Op2, Instrs0),
-        list.append(InstrsOp, Instrs0, Instrs)
-    ;
-        unexpected(this_file, "binop_instrs: binop_compound_and_simple_opands:" 
-            ++ " unexpected: get_last_instr_opand failed")
-    ).
-binop_instrs(binop_compound_opands(InstrsOp1, InstrsOp2), Op, Instrs) :-
-    (
-        get_last_instr_opand(InstrsOp1, LastOp1),
-        get_last_instr_opand(InstrsOp2, LastOp2)
-    ->
+    Instrs = InstrsOp ++ Instrs0.
+binop_instrs(binop_compound_operands(InstrsOp1, InstrsOp2), Op, Instrs) :-
+    get_last_instr_operand(InstrsOp1, LastOp1),
+    get_last_instr_operand(InstrsOp2, LastOp2),
         binop_instr(Op, LastOp1, LastOp2, Instrs0), 
-        Instrs = InstrsOp1 ++ InstrsOp2 ++ Instrs0
-    ;
-        unexpected(this_file, "binop_instrs: binop_compound_opands: unexpected:"
-            ++ " get_last_instr_opand failed")
-    ).
+    Instrs = InstrsOp1 ++ InstrsOp2 ++ Instrs0.
 
     % Equivalent x86_64 instructions for a unary operation. A unary operation
     % may consist of an operand or an expression (as a list of x86_64 
@@ -883,17 +805,13 @@
         Op = no,
         (
             Instrs0 = yes(InsRes),
-            ( get_last_instr_opand(InsRes, LastOp) ->
-                list.append(InsRes, [x86_64_instr(x86_64_instr_not(LastOp))], 
-                    Instrs)
-            ;
-                unexpected(this_file, "unop_instrs: bitwise_complement:" 
-                    ++ " unexpected: get_last_instr_opand failed")
-            )
+            get_last_instr_operand(InsRes, LastOp),
+            Instrs = InsRes ++ [x86_64_instr(x86_64_instr_not(LastOp))]
         ;
             Instrs0 = no,
-            unexpected(this_file, "unop_instrs: bitwise_complement:"
-                ++ " unexpected: instruction operand Instrs0")
+            unexpected(this_file,
+                "unop_instrs: bitwise_complement: unexpected: " ++
+                "instruction operand Instrs0")
         )
     ).
 unop_instrs(logical_not, _, _, [x86_64_comment("<<logical_not>>")]).
@@ -909,7 +827,7 @@
 binop_instr(int_mod, _, _, [x86_64_comment("<<int_mod>>")]).
 binop_instr(int_div, Op1, Op2, Instrs) :-
     LoadDividend = x86_64_instr(mov(Op2, operand_label("<<int_div>>"))),
-    list.cons(LoadDividend, [x86_64_instr(idiv(Op1))], Instrs).
+    Instrs = [LoadDividend, x86_64_instr(idiv(Op1))].
 binop_instr(unchecked_left_shift, Op1, Op2, [x86_64_instr(shl(Op1, Op2))]). 
 binop_instr(unchecked_right_shift, Op1, Op2, [x86_64_instr(shr(Op1, Op2))]). 
 binop_instr(bitwise_and, Op1, Op2, [x86_64_instr(and(Op1, Op2))]). 
@@ -976,9 +894,9 @@
     % Given a list of x86_64 instructions, figure out the operand of the last 
     % instruction in the list. 
     %
-:- pred get_last_instr_opand(list(x86_64_instr)::in, operand::out) is semidet.
+:- pred get_last_instr_operand(list(x86_64_instr)::in, operand::out) is det.
 
-get_last_instr_opand(Instrs, Op) :-
+get_last_instr_operand(Instrs, Op) :-
     list.last_det(Instrs, LastInstr),
     (  
        LastInstr = x86_64_comment(Comment),
@@ -988,7 +906,12 @@
        Op = operand_label(Label)
     ;
        LastInstr = x86_64_instr(Instr),
-       last_instr_dest(Instr, Op)
+        ( last_instr_dest(Instr, OpPrime) ->
+            Op = OpPrime
+        ;
+            unexpected(this_file,
+                "get_last_instr_operand: last_instr_dest failed")
+        )
     ;
        LastInstr = x86_64_directive(_), 
        Op = operand_label("<<directive>>")
cvs diff: Diffing notes
--------------------------------------------------------------------------
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