Program Definition function_bounds := {|
used_callee_save := RegSet.elements record_regs_of_function;
bound_local := max_over_slots_of_funct local_slot;
bound_outgoing := Z.max (max_over_instrs outgoing_space) (max_over_slots_of_funct outgoing_slot);
bound_stack_data := Z.max f.(fn_stacksize) 0
|}.
Next Obligation.
apply max_over_slots_of_funct_pos.
Qed.
Next Obligation.
apply Z.le_ge. eapply Z.le_trans. 2: apply Z.le_max_r.
apply Z.ge_le. apply max_over_slots_of_funct_pos.
Qed.
Next Obligation.
apply Z.le_ge. apply Z.le_max_r.
Qed.
Next Obligation.
generalize (RegSet.elements_3w record_regs_of_function).
generalize (RegSet.elements record_regs_of_function).
induction 1. constructor. constructor; auto.
red; intros; elim H. apply InA_alt. exists x; auto.
Qed.
Next Obligation.
apply record_regs_of_function_only. apply RegSet.elements_2.
apply InA_alt. exists r; auto.
Qed.
(** We now show the correctness of the inferred bounds. *)

Lemma record_regs_of_instr_incr: forall r' u i, RegSet.In r' u -> RegSet.In r' (record_regs_of_instr u i).
Definition defined_by_instr (r': mreg) (i: instruction) :=
match i with
| Lgetstack sl ofs ty r => r' = r
| Lop op args res => r' = res
| Lload chunk addr args dst => r' = dst
| Lbuiltin ef args res => In r' (params_of_builtin_res res) \/ In r' (destroyed_by_builtin ef)
| _ => False
end.