Require Import Coqlib.
Require Import AST.
Require Import Integers.
Require Import Floats.
Require Import Values.
Require Import Memory.
Require Import Globalenvs.
Require Import Op.
Require Import NeedDomain.
Require Import RTL.
Neededness analysis for ARM operators
Definition needs_of_condition (
cond:
condition):
list nval :=
nil.
Definition needs_of_shift (
s:
shift) (
nv:
nval):
nval :=
match s with
|
Slsl x =>
shlimm nv x
|
Slsr x =>
shruimm nv x
|
Sasr x =>
shrimm nv x
|
Sror x =>
ror nv x
end.
Definition op1 (
nv:
nval) :=
nv ::
nil.
Definition op2 (
nv:
nval) :=
nv ::
nv ::
nil.
Definition op3 (
nv:
nval) :=
nv ::
nv ::
nv ::
nil.
Definition op4 (
nv:
nval) :=
nv ::
nv ::
nv ::
nv ::
nil.
Definition op2shift (
s:
shift) (
nv:
nval) :=
nv ::
needs_of_shift s nv ::
nil.
Definition clearf lsb sz post :=
if ExtValues.is_bitfield lsb sz
then andimm post (
Int.not (
ExtValues.bitfield_mask lsb sz))
else Nothing.
Lemma clearf_sound:
forall lsb sz v w post,
vagree v w (
clearf lsb sz post) ->
vagree (
ExtValues.clearf lsb sz v) (
ExtValues.clearf lsb sz w)
post.
Proof.
Definition insf1 lsb sz post :=
if ExtValues.is_bitfield lsb sz
then andimm (
bitwise post) (
Int.not (
ExtValues.bitfield_mask lsb sz))
else Nothing.
Definition insf2 lsb sz post :=
if ExtValues.is_bitfield lsb sz
then shlimm (
andimm (
bitwise post) (
ExtValues.bitfield_mask lsb sz))
lsb
else Nothing.
Lemma insf_sound:
forall lsb sz v1 w1 v2 w2 post,
vagree v1 w1 (
insf1 lsb sz post) ->
vagree v2 w2 (
insf2 lsb sz post) ->
vagree (
ExtValues.insf lsb sz v1 v2) (
ExtValues.insf lsb sz w1 w2)
post.
Proof.
Definition needs_of_operation (
op:
operation) (
nv:
nval):
list nval :=
match op with
|
Omove =>
nv::
nil
|
Ocopy =>
op2 (
default nv)
|
Ocopyimm _ =>
op1 (
default nv)
|
Ointconst n =>
nil
|
Ofloatconst n =>
nil
|
Osingleconst n =>
nil
|
Oaddrsymbol id ofs =>
nil
|
Oaddrstack ofs =>
nil
|
Ocast8signed =>
op1 (
sign_ext 8
nv)
|
Ocast16signed =>
op1 (
sign_ext 16
nv)
|
Oadd =>
op2 (
modarith nv)
|
Oaddshift s =>
op2shift s (
modarith nv)
|
Oaddimm _ =>
op1 (
modarith nv)
|
Osub =>
op2 (
default nv)
|
Osubshift s =>
op2shift s (
default nv)
|
Orsubshift s =>
op2shift s (
default nv)
|
Orsubimm _ =>
op1 (
default nv)
|
Omul =>
op2 (
modarith nv)
|
Omla =>
let n :=
modarith nv in let n2 :=
modarith n in n2::
n2::
n::
nil
|
Omls =>
op3 (
default nv)
|
Omulhu |
Omulhs |
Odiv |
Odivu =>
let n :=
default nv in n::
n::
nil
|
Oand =>
op2 (
bitwise nv)
|
Oandshift s =>
op2shift s (
bitwise nv)
|
Oandimm n =>
op1 (
andimm nv n)
|
Oor =>
op2 (
bitwise nv)
|
Oorshift s =>
op2shift s (
bitwise nv)
|
Oorimm n =>
op1 (
orimm nv n)
|
Oxor =>
op2 (
bitwise nv)
|
Oxorshift s =>
op2shift s (
bitwise nv)
|
Oxorimm n =>
op1 (
bitwise nv)
|
Obic =>
let n :=
bitwise nv in n::
bitwise n::
nil
|
Obicshift s =>
let n :=
bitwise nv in n::
needs_of_shift s (
bitwise n)::
nil
|
Onot =>
op1 (
bitwise nv)
|
Onotshift s =>
op1 (
needs_of_shift s (
bitwise nv))
|
Oshl |
Oshr |
Oshru |
Oror =>
op2 (
default nv)
|
Oshift s =>
op1 (
needs_of_shift s nv)
|
Oshrximm _ =>
op1 (
default nv)
|
Onegf |
Oabsf |
Osqrtf =>
op1 (
default nv)
|
Oaddf |
Osubf |
Omulf |
Odivf =>
op2 (
default nv)
|
Omlaf |
Omlsf =>
op3 (
default nv)
|
Onegfs |
Oabsfs |
Osqrtfs =>
op1 (
default nv)
|
Oaddfs |
Osubfs |
Omulfs |
Odivfs =>
op2 (
default nv)
|
Omlafs |
Omlsfs =>
op3 (
default nv)
|
Ofloatofsingle |
Osingleoffloat =>
op1 (
default nv)
|
Ointoffloat |
Ointuoffloat |
Ofloatofint |
Ofloatofintu =>
op1 (
default nv)
|
Ointofsingle |
Ointuofsingle |
Osingleofint |
Osingleofintu =>
op1 (
default nv)
|
Omakelong =>
makelong_hi nv ::
makelong_lo nv ::
nil
|
Olowlong =>
op1 (
loword nv)
|
Ohighlong =>
op1 (
hiword nv)
|
Ocmp c =>
needs_of_condition c
|
Osel c =>
nv ::
nv ::
needs_of_condition c
|
Oselimm c _ =>
nv ::
needs_of_condition c
|
Oselimm2 c _ _ =>
needs_of_condition c
|
Oclz =>
op1 (
default nv)
|
Oreverse_bits =>
op1 (
default nv)
|
Obswap32 =>
op1 (
default nv)
|
Obits_of_single =>
op1 (
default nv)
|
Osingle_of_bits =>
op1 (
default nv)
|
Ohibits_of_float =>
op1 (
default nv)
|
Osbfx _ _ |
Oubfx _ _ =>
op1 (
default nv)
|
Obfc lsb sz =>
op1 (
clearf lsb sz nv)
|
Obfi lsb sz => (
insf1 lsb sz nv)::(
insf2 lsb sz nv)::
nil
|
Oaddimm_reg _ =>
op1 (
modarith nv)
|
Ogetcanary =>
nil
|
OEaddimm _ =>
nil
|
OEsubimm _ =>
nil
|
OErsbimm _ =>
nil
|
OEandimm _ =>
nil
|
OEbicimm _ =>
nil
|
OEorrimm _ =>
nil
|
OEeorimm _ =>
nil
|
OEmovimm _ =>
nil
|
OEmvnimm _ =>
nil
|
Ocmpcarryu _ =>
op4 (
default nv)
|
Ocmpcarry _ =>
op4 (
default nv)
end.
Definition clearf_redundant lsb sz (
x:
nval) :=
andimm_redundant x (
Int.not (
ExtValues.bitfield_mask lsb sz)).
Lemma clearf_redundant_sound:
forall lsb sz v w x,
clearf_redundant lsb sz x =
true ->
vagree v w (
clearf lsb sz x) ->
vagree (
ExtValues.clearf lsb sz v)
w x.
Proof.
Definition insf_redundant :=
clearf_redundant.
Lemma vagree_vundef:
forall b c,
vagree Vundef b c.
Proof.
Lemma insf_redundant_sound:
forall lsb sz v1 w1 v2 x
(
REDUNDANT :
insf_redundant lsb sz x =
true)
(
AGREE1 :
vagree v1 w1 (
insf1 lsb sz x)),
vagree (
ExtValues.insf lsb sz v1 v2)
w1 x.
Proof.
Definition operation_is_redundant (
op:
operation) (
nv:
nval):
bool :=
match op with
|
Ocast8signed =>
sign_ext_redundant 8
nv
|
Ocast16signed =>
sign_ext_redundant 16
nv
|
Oandimm n =>
andimm_redundant nv n
|
Oorimm n =>
orimm_redundant nv n
|
Obfc lsb sz =>
clearf_redundant lsb sz nv
|
Obfi lsb sz =>
insf_redundant lsb sz nv
| _ =>
false
end.
Ltac InvAgree :=
match goal with
| [
H:
vagree_list nil _ _ |- _ ] =>
inv H;
InvAgree
| [
H:
vagree_list (_::_) _ _ |- _ ] =>
inv H;
InvAgree
| _ =>
idtac
end.
Ltac TrivialExists :=
match goal with
| [ |-
exists v,
Some ?
x =
Some v /\ _ ] =>
exists x;
split;
auto
| _ =>
idtac
end.
Section SOUNDNESS.
Variable ge:
genv.
Variable sp:
block.
Variables m m':
mem.
Hypothesis PERM:
forall b ofs k p,
Mem.perm m b ofs k p ->
Mem.perm m' b ofs k p.
Lemma needs_of_condition_sound:
forall cond args b args',
eval_condition cond args m =
Some b ->
vagree_list args args' (
needs_of_condition cond) ->
eval_condition cond args' m' =
Some b.
Proof.
Lemma needs_of_shift_sound:
forall v v' s nv,
vagree v v' (
needs_of_shift s nv) ->
vagree (
eval_shift s v) (
eval_shift s v')
nv.
Proof.
Lemma val_sub_lessdef:
forall v1 v1' v2 v2',
Val.lessdef v1 v1' ->
Val.lessdef v2 v2' ->
Val.lessdef (
Val.sub v1 v2) (
Val.sub v1' v2').
Proof.
intros. inv H. inv H0. auto. destruct v1'; simpl; auto. simpl; auto.
Qed.
Lemma needs_of_operation_sound:
forall op args v nv args',
eval_operation ge (
Vptr sp Ptrofs.zero)
op args m =
Some v ->
vagree_list args args' (
needs_of_operation op nv) ->
nv <>
Nothing ->
exists v',
eval_operation ge (
Vptr sp Ptrofs.zero)
op args' m' =
Some v'
/\
vagree v v' nv.
Proof.
Lemma operation_is_redundant_sound:
forall op nv arg1 args v arg1' args',
operation_is_redundant op nv =
true ->
eval_operation ge (
Vptr sp Ptrofs.zero)
op (
arg1 ::
args)
m =
Some v ->
vagree_list (
arg1 ::
args) (
arg1' ::
args') (
needs_of_operation op nv) ->
vagree v arg1' nv.
Proof.
End SOUNDNESS.