aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2021-02-02 20:34:04 +0000
committerYann Herklotz <git@yannherklotz.com>2021-02-02 20:34:04 +0000
commite68848fc6970acc9b973a2c9dff5eddedb833914 (patch)
treebbc04591544a6361924a9ca9fc1d1830340544d4
parentab62ee5a82fcde31bbb45e2ddd66c1917cd57383 (diff)
downloadvericert-kvx-e68848fc6970acc9b973a2c9dff5eddedb833914.tar.gz
vericert-kvx-e68848fc6970acc9b973a2c9dff5eddedb833914.zip
Add if conversion pass
-rw-r--r--src/hls/IfConversion.v68
1 files changed, 65 insertions, 3 deletions
diff --git a/src/hls/IfConversion.v b/src/hls/IfConversion.v
index 2e200f8..9e600af 100644
--- a/src/hls/IfConversion.v
+++ b/src/hls/IfConversion.v
@@ -17,11 +17,15 @@
*)
Require Import compcert.common.AST.
-Require compcert.common.Errors.
-Require compcert.common.Globalenvs.
-Require compcert.lib.Integers.
+Require Import compcert.common.Errors.
+Require Import compcert.common.Globalenvs.
+Require Import compcert.lib.Integers.
Require Import compcert.lib.Maps.
+Require Import vericert.common.Vericertlib.
+Require Import vericert.hls.RTLBlockInstr.
+Require Import vericert.hls.RTLBlock.
+
(*|
=============
If conversion
@@ -30,3 +34,61 @@ If conversion
This conversion is a verified conversion from RTLBlock back to itself, which performs if-conversion
on basic blocks to make basic blocks larger.
|*)
+
+Definition combine_pred (p: pred_op) (optp: option pred_op) :=
+ match optp with
+ | Some p' => Pand p p'
+ | None => p
+ end.
+
+Definition map_if_convert (p: pred_op) (i: instr) :=
+ match i with
+ | RBop p' op args dst => RBop (Some (combine_pred p p')) op args dst
+ | RBload p' chunk addr args dst =>
+ RBload (Some (combine_pred p p')) chunk addr args dst
+ | RBstore p' chunk addr args src =>
+ RBstore (Some (combine_pred p p')) chunk addr args src
+ | _ => i
+ end.
+
+Definition if_convert_block (c: code) (p: pred_op) (bb: bblock) : bblock :=
+ let cfi := bb_exit bb in
+ match cfi with
+ | RBcond cond args n1 n2 =>
+ match PTree.get n1 c, PTree.get n2 c with
+ | Some bb1, Some bb2 =>
+ let bb1' := List.map (map_if_convert p) bb1.(bb_body) in
+ let bb2' := List.map (map_if_convert (Pnot p)) bb2.(bb_body) in
+ mk_bblock (List.concat (bb.(bb_body) :: bb1' :: bb2' :: nil))
+ (RBpred_cf p bb1.(bb_exit) bb2.(bb_exit))
+ | _, _ => bb
+ end
+ | _ => bb
+ end.
+
+Definition is_cond_cfi (cfi: cf_instr) :=
+ match cfi with
+ | RBcond _ _ _ _ => true
+ | _ => false
+ end.
+
+Definition find_block_with_cond (c: code) : option (node * bblock) :=
+ match List.filter (fun x => is_cond_cfi (snd x).(bb_exit)) (PTree.elements c) with
+ | (a :: b)%list => Some a
+ | nil => None
+ end.
+
+Definition transf_function (f: function) : function :=
+ match find_block_with_cond f.(fn_code) with
+ | Some (n, bb) =>
+ let nbb := if_convert_block f.(fn_code) (Pvar 1%positive) bb in
+ mkfunction f.(fn_sig) f.(fn_params) f.(fn_stacksize)
+ (PTree.set n nbb f.(fn_code)) f.(fn_entrypoint)
+ | None => f
+ end.
+
+Definition transf_fundef (fd: fundef) : fundef :=
+ transf_fundef transf_function fd.
+
+Definition transf_program (p: program) : program :=
+ transform_program transf_fundef p.