summaryrefslogtreecommitdiff
path: root/arm
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2012-05-26 07:32:01 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2012-05-26 07:32:01 +0000
commit132e36fa0be63eb5672eda9168403d3fb74af2fa (patch)
tree33955e0ccb4210271c82326b941523e6e4b2c289 /arm
parent9ea00d39bb32c1f188f1af2745c3368da6a349c1 (diff)
CSE: add recognition of some combined operators, conditions, and addressing modes (cf. CombineOp.v)
Memory model: cleaning up Memdata Inlining and new Constprop: updated for ARM. git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1902 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'arm')
-rw-r--r--arm/CombineOp.v107
-rw-r--r--arm/CombineOpproof.v127
-rw-r--r--arm/Op.v28
-rw-r--r--arm/SelectOp.vp2
-rw-r--r--arm/SelectOpproof.v12
-rw-r--r--arm/Unusedglob1.ml2
6 files changed, 253 insertions, 25 deletions
diff --git a/arm/CombineOp.v b/arm/CombineOp.v
new file mode 100644
index 0000000..8048653
--- /dev/null
+++ b/arm/CombineOp.v
@@ -0,0 +1,107 @@
+(* *********************************************************************)
+(* *)
+(* The Compcert verified compiler *)
+(* *)
+(* Xavier Leroy, INRIA Paris-Rocquencourt *)
+(* *)
+(* Copyright Institut National de Recherche en Informatique et en *)
+(* Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* *)
+(* *********************************************************************)
+
+(** Recognition of combined operations, addressing modes and conditions
+ during the [CSE] phase. *)
+
+Require Import Coqlib.
+Require Import AST.
+Require Import Integers.
+Require Import Op.
+Require SelectOp.
+
+Definition valnum := positive.
+
+Inductive rhs : Type :=
+ | Op: operation -> list valnum -> rhs
+ | Load: memory_chunk -> addressing -> list valnum -> rhs.
+
+Section COMBINE.
+
+Variable get: valnum -> option rhs.
+
+Function combine_compimm_ne_0 (x: valnum) : option(condition * list valnum) :=
+ match get x with
+ | Some(Op (Ocmp c) ys) => Some (c, ys)
+ | _ => None
+ end.
+
+Function combine_compimm_eq_0 (x: valnum) : option(condition * list valnum) :=
+ match get x with
+ | Some(Op (Ocmp c) ys) => Some (negate_condition c, ys)
+ | _ => None
+ end.
+
+Function combine_cond (cond: condition) (args: list valnum) : option(condition * list valnum) :=
+ match cond, args with
+ | Ccompimm Cne n, x::nil =>
+ if Int.eq_dec n Int.zero then combine_compimm_ne_0 x else None
+ | Ccompimm Ceq n, x::nil =>
+ if Int.eq_dec n Int.zero then combine_compimm_eq_0 x else None
+ | Ccompuimm Cne n, x::nil =>
+ if Int.eq_dec n Int.zero then combine_compimm_ne_0 x else None
+ | Ccompuimm Ceq n, x::nil =>
+ if Int.eq_dec n Int.zero then combine_compimm_eq_0 x else None
+ | _, _ => None
+ end.
+
+Function combine_addr (addr: addressing) (args: list valnum) : option(addressing * list valnum) :=
+ match addr, args with
+ | Aindexed n, x::nil =>
+ match get x with
+ | Some(Op (Oaddimm m) ys) => Some(Aindexed (Int.add m n), ys)
+ | Some(Op Oadd ys) => if Int.eq_dec n Int.zero then Some(Aindexed2, ys) else None
+ | Some(Op (Oaddshift s) ys) => if Int.eq_dec n Int.zero then Some(Aindexed2shift s, ys) else None
+ | _ => None
+ end
+ | _, _ => None
+ end.
+
+Function combine_op (op: operation) (args: list valnum) : option(operation * list valnum) :=
+ match op, args with
+ | Oaddimm n, x :: nil =>
+ match get x with
+ | Some(Op (Oaddimm m) ys) => Some(Oaddimm (Int.add m n), ys)
+ | Some(Op (Orsubimm m) ys) => Some(Orsubimm (Int.add m n), ys)
+ | _ => None
+ end
+ | Orsubimm n, x :: nil =>
+ match get x with
+ | Some(Op (Oaddimm m) ys) => Some(Orsubimm (Int.sub n m), ys)
+ | _ => None
+ end
+ | Oandimm n, x :: nil =>
+ match get x with
+ | Some(Op (Oandimm m) ys) => Some(Oandimm (Int.and m n), ys)
+ | _ => None
+ end
+ | Oorimm n, x :: nil =>
+ match get x with
+ | Some(Op (Oorimm m) ys) => Some(Oorimm (Int.or m n), ys)
+ | _ => None
+ end
+ | Oxorimm n, x :: nil =>
+ match get x with
+ | Some(Op (Oxorimm m) ys) => Some(Oxorimm (Int.xor m n), ys)
+ | _ => None
+ end
+ | Ocmp cond, _ =>
+ match combine_cond cond args with
+ | Some(cond', args') => Some(Ocmp cond', args')
+ | None => None
+ end
+ | _, _ => None
+ end.
+
+End COMBINE.
+
+
diff --git a/arm/CombineOpproof.v b/arm/CombineOpproof.v
new file mode 100644
index 0000000..9d297ac
--- /dev/null
+++ b/arm/CombineOpproof.v
@@ -0,0 +1,127 @@
+(* *********************************************************************)
+(* *)
+(* The Compcert verified compiler *)
+(* *)
+(* Xavier Leroy, INRIA Paris-Rocquencourt *)
+(* *)
+(* Copyright Institut National de Recherche en Informatique et en *)
+(* Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* *)
+(* *********************************************************************)
+
+(** Recognition of combined operations, addressing modes and conditions
+ during the [CSE] phase. *)
+
+Require Import Coqlib.
+Require Import AST.
+Require Import Integers.
+Require Import Values.
+Require Import Memory.
+Require Import Op.
+Require Import Registers.
+Require Import RTL.
+Require Import CombineOp.
+Require Import CSE.
+
+Section COMBINE.
+
+Variable ge: genv.
+Variable sp: val.
+Variable m: mem.
+Variable get: valnum -> option rhs.
+Variable valu: valnum -> val.
+Hypothesis get_sound: forall v rhs, get v = Some rhs -> equation_holds valu ge sp m v rhs.
+
+Lemma combine_compimm_ne_0_sound:
+ forall x cond args,
+ combine_compimm_ne_0 get x = Some(cond, args) ->
+ eval_condition cond (map valu args) m = Val.cmp_bool Cne (valu x) (Vint Int.zero) /\
+ eval_condition cond (map valu args) m = Val.cmpu_bool (Mem.valid_pointer m) Cne (valu x) (Vint Int.zero).
+Proof.
+ intros until args. functional induction (combine_compimm_ne_0 get x); intros EQ; inv EQ.
+ (* of cmp *)
+ exploit get_sound; eauto. unfold equation_holds. simpl. intro EQ; inv EQ.
+ destruct (eval_condition cond (map valu args) m); simpl; auto. destruct b; auto.
+Qed.
+
+Lemma combine_compimm_eq_0_sound:
+ forall x cond args,
+ combine_compimm_eq_0 get x = Some(cond, args) ->
+ eval_condition cond (map valu args) m = Val.cmp_bool Ceq (valu x) (Vint Int.zero) /\
+ eval_condition cond (map valu args) m = Val.cmpu_bool (Mem.valid_pointer m) Ceq (valu x) (Vint Int.zero).
+Proof.
+ intros until args. functional induction (combine_compimm_eq_0 get x); intros EQ; inv EQ.
+ (* of cmp *)
+ exploit get_sound; eauto. unfold equation_holds. simpl. intro EQ; inv EQ.
+ rewrite eval_negate_condition.
+ destruct (eval_condition c (map valu args) m); simpl; auto. destruct b; auto.
+Qed.
+
+Theorem combine_cond_sound:
+ forall cond args cond' args',
+ combine_cond get cond args = Some(cond', args') ->
+ eval_condition cond' (map valu args') m = eval_condition cond (map valu args) m.
+Proof.
+ intros. functional inversion H; subst.
+ (* compimm ne zero *)
+ simpl; eapply combine_compimm_ne_0_sound; eauto.
+ (* compimm eq zero *)
+ simpl; eapply combine_compimm_eq_0_sound; eauto.
+ (* compuimm ne zero *)
+ simpl; eapply combine_compimm_ne_0_sound; eauto.
+ (* compuimm eq zero *)
+ simpl; eapply combine_compimm_eq_0_sound; eauto.
+Qed.
+
+Theorem combine_addr_sound:
+ forall addr args addr' args',
+ combine_addr get addr args = Some(addr', args') ->
+ eval_addressing ge sp addr' (map valu args') = eval_addressing ge sp addr (map valu args).
+Proof.
+ intros. functional inversion H; subst.
+ (* indexed - addimm *)
+ exploit get_sound; eauto. unfold equation_holds; simpl; intro EQ. FuncInv.
+ rewrite <- H0. rewrite Val.add_assoc. auto.
+ (* indexed 0 - add *)
+ exploit get_sound; eauto. unfold equation_holds; simpl; intro EQ. FuncInv.
+ rewrite <- H0. destruct v; destruct v0; simpl; auto; rewrite Int.add_zero; auto.
+ (* indexed 0 - addshift *)
+ exploit get_sound; eauto. unfold equation_holds; simpl; intro EQ. FuncInv.
+ rewrite <- H0. destruct v; destruct (eval_shift s v0); simpl; auto; rewrite Int.add_zero; auto.
+Qed.
+
+Theorem combine_op_sound:
+ forall op args op' args',
+ combine_op get op args = Some(op', args') ->
+ eval_operation ge sp op' (map valu args') m = eval_operation ge sp op (map valu args) m.
+Proof.
+ intros. functional inversion H; subst.
+(* addimm - addimm *)
+ exploit get_sound; eauto. unfold equation_holds; simpl; intros. FuncInv.
+ rewrite <- H1. rewrite Val.add_assoc. auto.
+(* addimm - subimm *)
+Opaque Val.sub.
+ exploit get_sound; eauto. unfold equation_holds; simpl; intros. FuncInv.
+ rewrite <- H1. change (Vint (Int.add m0 n)) with (Val.add (Vint m0) (Vint n)).
+ rewrite Val.sub_add_l. auto.
+(* subimm - addimm *)
+ exploit get_sound; eauto. unfold equation_holds; simpl; intros. FuncInv.
+ rewrite <- H1.
+Transparent Val.sub.
+ destruct v; simpl; auto. repeat rewrite Int.sub_add_opp. rewrite Int.add_assoc.
+ rewrite Int.neg_add_distr. decEq. decEq. decEq. apply Int.add_commut.
+(* andimm - andimm *)
+ exploit get_sound; eauto. unfold equation_holds; simpl; intros. FuncInv.
+ rewrite <- H1. rewrite Val.and_assoc. auto.
+(* orimm - orimm *)
+ exploit get_sound; eauto. unfold equation_holds; simpl; intros. FuncInv.
+ rewrite <- H1. rewrite Val.or_assoc. auto.
+(* xorimm - xorimm *)
+ exploit get_sound; eauto. unfold equation_holds; simpl; intros. FuncInv.
+ rewrite <- H1. rewrite Val.xor_assoc. auto.
+(* cmp *)
+ simpl. decEq; decEq. eapply combine_cond_sound; eauto.
+Qed.
+
+End COMBINE.
diff --git a/arm/Op.v b/arm/Op.v
index a5502c0..3353416 100644
--- a/arm/Op.v
+++ b/arm/Op.v
@@ -492,22 +492,20 @@ Definition negate_condition (cond: condition): condition :=
end.
Lemma eval_negate_condition:
- forall (cond: condition) (vl: list val) (b: bool) (m: mem),
- eval_condition cond vl m = Some b ->
- eval_condition (negate_condition cond) vl m = Some (negb b).
+ forall cond vl m,
+ eval_condition (negate_condition cond) vl m = option_map negb (eval_condition cond vl m).
Proof.
- intros.
- destruct cond; simpl in H; FuncInv; simpl.
- rewrite Val.negate_cmp_bool; rewrite H; auto.
- rewrite Val.negate_cmpu_bool; rewrite H; auto.
- rewrite Val.negate_cmp_bool; rewrite H; auto.
- rewrite Val.negate_cmpu_bool; rewrite H; auto.
- rewrite Val.negate_cmp_bool; rewrite H; auto.
- rewrite Val.negate_cmpu_bool; rewrite H; auto.
- rewrite H; auto.
- destruct (Val.cmpf_bool c v v0); simpl in H; inv H. rewrite negb_elim; auto.
- rewrite H; auto.
- destruct (Val.cmpf_bool c v (Vfloat Float.zero)); simpl in H; inv H. rewrite negb_elim; auto.
+ intros. destruct cond; simpl.
+ repeat (destruct vl; auto). apply Val.negate_cmp_bool.
+ repeat (destruct vl; auto). apply Val.negate_cmpu_bool.
+ repeat (destruct vl; auto). apply Val.negate_cmp_bool.
+ repeat (destruct vl; auto). apply Val.negate_cmpu_bool.
+ repeat (destruct vl; auto). apply Val.negate_cmp_bool.
+ repeat (destruct vl; auto). apply Val.negate_cmpu_bool.
+ repeat (destruct vl; auto).
+ repeat (destruct vl; auto). destruct (Val.cmpf_bool c v v0); auto. destruct b; auto.
+ repeat (destruct vl; auto).
+ repeat (destruct vl; auto). destruct (Val.cmpf_bool c v (Vfloat Float.zero)); auto. destruct b; auto.
Qed.
(** Shifting stack-relative references. This is used in [Stacking]. *)
diff --git a/arm/SelectOp.vp b/arm/SelectOp.vp
index 27b5f53..6049017 100644
--- a/arm/SelectOp.vp
+++ b/arm/SelectOp.vp
@@ -111,10 +111,10 @@ Nondetfunction addimm (n: int) (e: expr) :=
Nondetfunction add (e1: expr) (e2: expr) :=
match e1, e2 with
| Eop (Ointconst n1) Enil, t2 => addimm n1 t2
+ | t1, Eop (Ointconst n2) Enil => addimm n2 t1
| Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) =>
addimm (Int.add n1 n2) (Eop Oadd (t1:::t2:::Enil))
| Eop(Oaddimm n1) (t1:::Enil), t2 => addimm n1 (Eop Oadd (t1:::t2:::Enil))
- | t1, Eop (Ointconst n2) Enil => addimm n2 t1
| t1, Eop (Oaddimm n2) (t2:::Enil) => addimm n2 (Eop Oadd (t1:::t2:::Enil))
| Eop (Oshift s) (t1:::Enil), t2 => Eop (Oaddshift s) (t2:::t1:::Enil)
| t1, Eop (Oshift s) (t2:::Enil) => Eop (Oaddshift s) (t1:::t2:::Enil)
diff --git a/arm/SelectOpproof.v b/arm/SelectOpproof.v
index 1a2f560..dc4fb54 100644
--- a/arm/SelectOpproof.v
+++ b/arm/SelectOpproof.v
@@ -179,13 +179,9 @@ Proof.
(* intconst *)
destruct e0; eauto. InvEval. TrivialExists. simpl. destruct (Int.eq i Int.zero); auto.
(* cmp *)
- inv H. simpl in H5.
- destruct (eval_condition c vl m) as []_eqn.
- TrivialExists. simpl. rewrite (eval_negate_condition _ _ _ Heqo). destruct b; inv H5; auto.
- inv H5. simpl.
- destruct (eval_condition (negate_condition c) vl m) as []_eqn.
- destruct b; [exists Vtrue | exists Vfalse]; split; auto; EvalOp; simpl. rewrite Heqo0; auto. rewrite Heqo0; auto.
- exists Vundef; split; auto; EvalOp; simpl. rewrite Heqo0; auto.
+ inv H. simpl in H5. inv H5.
+ TrivialExists. simpl. rewrite eval_negate_condition.
+ destruct (eval_condition c vl m); auto. destruct b; auto.
(* condition *)
inv H. destruct v1.
exploit IHa1; eauto. intros [v [A B]]. exists v; split; auto. eapply eval_Econdition; eauto.
@@ -211,6 +207,7 @@ Proof.
red; intros until y.
unfold add; case (add_match a b); intros; InvEval.
rewrite Val.add_commut. apply eval_addimm; auto.
+ apply eval_addimm; auto.
subst.
replace (Val.add (Val.add v1 (Vint n1)) (Val.add v0 (Vint n2)))
with (Val.add (Val.add v1 v0) (Val.add (Vint n1) (Vint n2))).
@@ -221,7 +218,6 @@ Proof.
with (Val.add (Val.add v1 y) (Vint n1)).
apply eval_addimm. EvalOp.
repeat rewrite Val.add_assoc. decEq. apply Val.add_commut.
- apply eval_addimm; auto.
subst. rewrite <- Val.add_assoc. apply eval_addimm. EvalOp.
subst. rewrite Val.add_commut. TrivialExists.
subst. TrivialExists.
diff --git a/arm/Unusedglob1.ml b/arm/Unusedglob1.ml
index 04ef89a..33a9bf8 100644
--- a/arm/Unusedglob1.ml
+++ b/arm/Unusedglob1.ml
@@ -26,7 +26,7 @@ let referenced_instr = function
| Pbsymb(s, _) -> [s]
| Pblsymb(s, _) -> [s]
| Ploadsymbol(_, s, _) -> [s]
- | Pbuiltin ef -> referenced_builtin ef
+ | Pbuiltin(ef, _, _) -> referenced_builtin ef
| _ -> []
let code_of_function f = f.fn_code