summaryrefslogtreecommitdiff
path: root/backend/RRE.v
diff options
context:
space:
mode:
Diffstat (limited to 'backend/RRE.v')
-rw-r--r--backend/RRE.v46
1 files changed, 25 insertions, 21 deletions
diff --git a/backend/RRE.v b/backend/RRE.v
index b8409e3..bee57f6 100644
--- a/backend/RRE.v
+++ b/backend/RRE.v
@@ -109,57 +109,61 @@ Fixpoint safe_move_insertion (c: code) : bool :=
into register-to-register move whenever possible. Simultaneously,
it propagates valid (register, slot) equations across basic blocks. *)
-Fixpoint transf_code (eqs: equations) (c: code) : code :=
+(** [transf_code] is written in accumulator-passing style so that it runs
+ in constant stack space. The [k] parameter accumulates the instructions
+ to be generated, in reverse order, and is then reversed at the end *)
+
+Fixpoint transf_code (eqs: equations) (c: code) (k: code) : code :=
match c with
- | nil => nil
+ | nil => List.rev' k
| Lgetstack s r :: c =>
if is_incoming s then
- Lgetstack s r :: transf_code (kill_loc (R r) (kill_loc (R IT1) eqs)) c
+ transf_code (kill_loc (R r) (kill_loc (R IT1) eqs)) c (Lgetstack s r :: k)
else if contains_equation s r eqs then
- transf_code eqs c
+ transf_code eqs c k
else
match find_reg_containing s eqs with
| Some r' =>
if safe_move_insertion c then
- Lop Omove (r' :: nil) r :: transf_code (kill_at_move (mkeq r s :: kill_loc (R r) eqs)) c
+ transf_code (kill_at_move (mkeq r s :: kill_loc (R r) eqs)) c (Lop Omove (r' :: nil) r :: k)
else
- Lgetstack s r:: transf_code (mkeq r s :: kill_loc (R r) eqs) c
+ transf_code (mkeq r s :: kill_loc (R r) eqs) c (Lgetstack s r :: k)
| None =>
- Lgetstack s r:: transf_code (mkeq r s :: kill_loc (R r) eqs) c
+ transf_code (mkeq r s :: kill_loc (R r) eqs) c (Lgetstack s r :: k)
end
| Lsetstack r s :: c =>
- Lsetstack r s :: transf_code (kill_at_move (mkeq r s :: kill_loc (S s) eqs)) c
+ transf_code (kill_at_move (mkeq r s :: kill_loc (S s) eqs)) c (Lsetstack r s :: k)
| Lop op args res :: c =>
- Lop op args res :: transf_code (kill_loc (R res) (kill_op op eqs)) c
+ transf_code (kill_loc (R res) (kill_op op eqs)) c (Lop op args res :: k)
| Lload chunk addr args res :: c =>
- Lload chunk addr args res :: transf_code (kill_loc (R res) (kill_temps eqs)) c
+ transf_code (kill_loc (R res) (kill_temps eqs)) c (Lload chunk addr args res :: k)
| Lstore chunk addr args src :: c =>
- Lstore chunk addr args src :: transf_code (kill_temps eqs) c
+ transf_code (kill_temps eqs) c (Lstore chunk addr args src :: k)
| Lcall sg ros :: c =>
- Lcall sg ros :: transf_code nil c
+ transf_code nil c (Lcall sg ros :: k)
| Ltailcall sg ros :: c =>
- Ltailcall sg ros :: transf_code nil c
+ transf_code nil c (Ltailcall sg ros :: k)
| Lbuiltin ef args res :: c =>
- Lbuiltin ef args res :: transf_code (kill_loc (R res) (kill_temps eqs)) c
+ transf_code (kill_loc (R res) (kill_temps eqs)) c (Lbuiltin ef args res :: k)
| Lannot ef args :: c =>
- Lannot ef args :: transf_code eqs c
+ transf_code eqs c (Lannot ef args :: k)
| Llabel lbl :: c =>
- Llabel lbl :: transf_code nil c
+ transf_code nil c (Llabel lbl :: k)
| Lgoto lbl :: c =>
- Lgoto lbl :: transf_code nil c
+ transf_code nil c (Lgoto lbl :: k)
| Lcond cond args lbl :: c =>
- Lcond cond args lbl :: transf_code (kill_temps eqs) c
+ transf_code (kill_temps eqs) c (Lcond cond args lbl :: k)
| Ljumptable arg lbls :: c =>
- Ljumptable arg lbls :: transf_code nil c
+ transf_code nil c (Ljumptable arg lbls :: k)
| Lreturn :: c =>
- Lreturn :: transf_code nil c
+ transf_code nil c (Lreturn :: k)
end.
Definition transf_function (f: function) : function :=
mkfunction
(fn_sig f)
(fn_stacksize f)
- (transf_code nil (fn_code f)).
+ (transf_code nil (fn_code f) nil).
Definition transf_fundef (fd: fundef) : fundef :=
transf_fundef transf_function fd.