Section TRANSF.
Variable transf: node -> instruction -> instruction.
Definition transf_function (f: function) : function :=
mkfunction
f.(fn_sig)
f.(fn_params)
f.(fn_stacksize)
(PTree.map transf f.(fn_code))
f.(fn_entrypoint).
End TRANSF.
(** Computation of the possible successors of an instruction. This is used in particular for dataflow analyses. *)
Definition successors_instr (i: instruction) : list node :=
match i with
| Inop s => s :: nil
| Iop op args res s => s :: nil
| Iload chunk addr args dst s => s :: nil
| Istore chunk addr args src s => s :: nil
| Icall sig ros args res s => s :: nil
| Itailcall sig ros args => nil
| Ibuiltin ef args res s => s :: nil
| Icond cond args ifso ifnot => ifso :: ifnot :: nil
| Ijumptable arg tbl => tbl
| Ireturn optarg => nil
end.
Definition successors_map (f: function) : PTree.t (list node) :=
PTree.map1 successors_instr f.(fn_code).
(** The registers used by an instruction *)
Definition instr_uses (i: instruction) : list reg :=
match i with
| Inop s => nil
| Iop op args res s => args
| Iload chunk addr args dst s => args
| Istore chunk addr args src s => src :: args
| Icall sig (inl r) args res s => r :: args
| Icall sig (inr id) args res s => args
| Itailcall sig (inl r) args => r :: args
| Itailcall sig (inr id) args => args
| Ibuiltin ef args res s => params_of_builtin_args args
| Icond cond args ifso ifnot => args
| Ijumptable arg tbl => arg :: nil
| Ireturn None => nil
| Ireturn (Some arg) => arg :: nil
end.
(** The register defined by an instruction, if any *)
Definition instr_defs (i: instruction) : option reg :=
match i with
| Inop s => None
| Iop op args res s => Some res
| Iload chunk addr args dst s => Some dst
| Istore chunk addr args src s => None
| Icall sig ros args res s => Some res
| Itailcall sig ros args => None
| Ibuiltin ef args res s =>
match res with BR r => Some r | _ => None end
| Icond cond args ifso ifnot => None
| Ijumptable arg tbl => None
| Ireturn optarg => None
end.
(** Maximum PC (node number) in the CFG of a function.  All nodes of the CFG of [f] are between 1 and [max_pc_function f] (inclusive). *)
Definition max_pc_function (f: function) :=
PTree.fold (fun m pc i => Pos.max m pc) f.(fn_code) 1%positive.
(** Maximum pseudo-register mentioned in a function.  All results or arguments of an instruction of [f], as well as all parameters of [f], are between 1 and [max_reg_function] (inclusive). *)
Definition max_reg_instr (m: positive) (pc: node) (i: instruction) :=
match i with
| Inop s => m
| Iop op args res s => fold_left Pos.max args (Pos.max res m)
| Iload chunk addr args dst s => fold_left Pos.max args (Pos.max dst m)
| Istore chunk addr args src s => fold_left Pos.max args (Pos.max src m)
| Icall sig (inl r) args res s => fold_left Pos.max args (Pos.max r (Pos.max res m))
| Icall sig (inr id) args res s => fold_left Pos.max args (Pos.max res m)
| Itailcall sig (inl r) args => fold_left Pos.max args (Pos.max r m)
| Itailcall sig (inr id) args => fold_left Pos.max args m
| Ibuiltin ef args res s =>
fold_left Pos.max (params_of_builtin_args args)
(fold_left Pos.max (params_of_builtin_res res) m)
| Icond cond args ifso ifnot => fold_left Pos.max args m
| Ijumptable arg tbl => Pos.max arg m
| Ireturn None => m
| Ireturn (Some arg) => Pos.max arg m
end.
Definition max_reg_function (f: function) :=
Pos.max
(PTree.fold max_reg_instr f.(fn_code) 1%positive)
(fold_left Pos.max f.(fn_params) 1%positive).
Remark max_reg_instr_ge:
forall m pc i, Ple m (max_reg_instr m pc i).
Remark max_reg_instr_def:
forall m pc i r, instr_defs i = Some r -> Ple r (max_reg_instr m pc i).
Remark max_reg_instr_uses:
forall m pc i r, In r (instr_uses i) -> Ple r (max_reg_instr m pc i).

Lemma max_reg_function_use:
forall f pc i r,
f.(fn_code)!pc = Some i -> In r (instr_uses i) -> Ple r (max_reg_function f).