Gible Seq Generation
Definition check_valid_node (tc: code) (e: node) :=
match tc ! e with
| Some _ => true
| _ => false
end.
Fixpoint check_code (c: RTL.code) (tc: code) (pc: node) (b: SeqBB.t) :=
match c ! pc, b with
| Some (RTL.Inop pc'), RBnop :: (_ :: _ :: _) as b' =>
check_code c tc pc' b'
| Some (RTL.Iop op' args' dst' pc'), RBop None op args dst :: (_ :: _ :: _) as b' =>
ceq operation_eq op op'
&& ceq list_pos_eq args args'
&& ceq peq dst dst'
&& check_code c tc pc' b'
| Some (RTL.Iload chunk' addr' args' dst' pc'),
RBload None chunk addr args dst :: (_ :: _ :: _) as b' =>
ceq memory_chunk_eq chunk chunk'
&& ceq addressing_eq addr addr'
&& ceq list_pos_eq args args'
&& ceq peq dst dst'
&& check_code c tc pc' b'
| Some (RTL.Istore chunk' addr' args' src' pc'),
RBstore None chunk addr args src :: (_ :: _ :: _) as b' =>
ceq memory_chunk_eq chunk chunk'
&& ceq addressing_eq addr addr'
&& ceq list_pos_eq args args'
&& ceq peq src src'
&& check_code c tc pc' b'
| Some (RTL.Inop pc''), RBnop :: RBexit None (RBgoto pc') :: nil =>
check_valid_node tc pc'
&& ceq peq pc' pc''
| Some (RTL.Iop op' args' dst' pc''), RBop None op args dst :: RBexit None (RBgoto pc') :: nil =>
check_valid_node tc pc'
&& ceq peq pc' pc''
&& ceq operation_eq op op'
&& ceq list_pos_eq args args'
&& ceq peq dst dst'
| Some (RTL.Iload chunk' addr' args' dst' pc''),
RBload None chunk addr args dst :: RBexit None (RBgoto pc') :: nil =>
check_valid_node tc pc'
&& ceq peq pc' pc''
&& ceq memory_chunk_eq chunk chunk'
&& ceq addressing_eq addr addr'
&& ceq list_pos_eq args args'
&& ceq peq dst dst'
| Some (RTL.Istore chunk' addr' args' src' pc''),
RBstore None chunk addr args src :: RBexit None (RBgoto pc') :: nil =>
check_valid_node tc pc'
&& ceq peq pc' pc''
&& ceq memory_chunk_eq chunk chunk'
&& ceq addressing_eq addr addr'
&& ceq list_pos_eq args args'
&& ceq peq src src'
| Some (RTL.Icall sig' (inl r') args' dst' pc''),
RBnop :: RBexit None (RBcall sig (inl r) args dst pc') :: nil =>
check_valid_node tc pc'
&& ceq peq pc' pc''
&& ceq signature_eq sig sig'
&& ceq peq r r'
&& ceq list_pos_eq args args'
&& ceq peq dst dst'
| Some (RTL.Icall sig' (inr i') args' dst' pc''),
RBnop :: RBexit None (RBcall sig (inr i) args dst pc') :: nil =>
check_valid_node tc pc'
&& ceq peq pc' pc''
&& ceq signature_eq sig sig'
&& ceq peq i i'
&& ceq list_pos_eq args args'
&& ceq peq dst dst'
| Some (RTL.Itailcall sig (inl r) args),
RBnop :: RBexit None (RBtailcall sig' (inl r') args') :: nil =>
ceq signature_eq sig sig'
&& ceq peq r r'
&& ceq list_pos_eq args args'
| Some (RTL.Itailcall sig (inr r) args),
RBnop :: RBexit None (RBtailcall sig' (inr r') args') :: nil =>
ceq signature_eq sig sig'
&& ceq peq r r'
&& ceq list_pos_eq args args'
| Some (RTL.Icond cond args n1 n2), RBnop :: RBexit None (RBcond cond' args' n1' n2') :: nil =>
check_valid_node tc n1
&& check_valid_node tc n2
&& ceq condition_eq cond cond'
&& ceq list_pos_eq args args'
&& ceq peq n1 n1'
&& ceq peq n2 n2'
| Some (RTL.Ijumptable r ns), RBnop :: RBexit None (RBjumptable r' ns') :: nil =>
ceq peq r r'
&& ceq list_pos_eq ns ns'
&& forallb (check_valid_node tc) ns
| Some (RTL.Ireturn (Some r)), RBnop :: RBexit None (RBreturn (Some r')) :: nil =>
ceq peq r r'
| Some (RTL.Ireturn None), RBnop :: RBexit None (RBreturn None) :: nil => true
| _, _ => false
end.
Parameter partition : RTL.function -> Errors.res function.
Definition transl_function (f: RTL.function) :=
match partition f with
| Errors.OK f' =>
if check_valid_node f'.(fn_code) f.(RTL.fn_entrypoint) then
if forall_ptree (check_code f.(RTL.fn_code) f'.(fn_code)) f'.(fn_code) then
Errors.OK
(mkfunction f.(RTL.fn_sig) f.(RTL.fn_params) f.(RTL.fn_stacksize) f'.(fn_code) f.(RTL.fn_entrypoint))
else Errors.Error (Errors.msg "check_present_blocks failed")
else Errors.Error (Errors.msg "entrypoint does not exists")
| Errors.Error msg => Errors.Error msg
end.
Definition transl_fundef := transf_partial_fundef transl_function.
Definition transl_program : RTL.program -> Errors.res program :=
transform_partial_program transl_fundef.