Commit a15858a0 authored by xleroy's avatar xleroy
Browse files

Merge of branches/full-expr-4:

- Csyntax, Csem: source C language has side-effects within expressions,
  performs implicit casts, and has nondeterministic reduction semantics
  for expressions
- Cstrategy: deterministic red. sem. for the above
- Clight: the previous source C language, with pure expressions.
  Added: temporary variables + implicit casts.
- New pass SimplExpr to pull side-effects out of expressions
  (previously done in untrusted Caml code in cparser/)
- Csharpminor: added temporary variables to match Clight.
- Cminorgen: adapted, removed cast optimization (moved to back-end)
- CastOptim: RTL-level optimization of casts
- cparser: transformations Bitfields, StructByValue and StructAssign
  now work on non-simplified expressions
- Added pretty-printers for several intermediate languages,
  and matching -dxxx command-line flags.



git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1467 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
parent adedca3a
......@@ -36,6 +36,8 @@ backend/Tailcall.vo: backend/Tailcall.v lib/Coqlib.vo lib/Maps.vo common/AST.vo
backend/Tailcallproof.vo: backend/Tailcallproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Memory.vo $(ARCH)/Op.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Registers.vo backend/RTL.vo backend/Conventions.vo backend/Tailcall.vo
backend/RTLtyping.vo: backend/RTLtyping.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo common/AST.vo $(ARCH)/Op.vo backend/Registers.vo common/Globalenvs.vo common/Values.vo common/Memory.vo lib/Integers.vo common/Events.vo common/Smallstep.vo backend/RTL.vo backend/Conventions.vo
backend/Kildall.vo: backend/Kildall.v lib/Coqlib.vo lib/Iteration.vo lib/Maps.vo lib/Lattice.vo lib/Ordered.vo
backend/CastOptim.vo: backend/CastOptim.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Globalenvs.vo $(ARCH)/Op.vo backend/Registers.vo backend/RTL.vo lib/Lattice.vo backend/Kildall.vo
backend/CastOptimproof.vo: backend/CastOptimproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Events.vo common/Memory.vo common/Globalenvs.vo common/Smallstep.vo $(ARCH)/Op.vo backend/Registers.vo backend/RTL.vo lib/Lattice.vo backend/Kildall.vo backend/CastOptim.vo
$(ARCH)/ConstpropOp.vo: $(ARCH)/ConstpropOp.v lib/Coqlib.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo $(ARCH)/Op.vo backend/Registers.vo
backend/Constprop.vo: backend/Constprop.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Globalenvs.vo $(ARCH)/Op.vo backend/Registers.vo backend/RTL.vo lib/Lattice.vo backend/Kildall.vo $(ARCH)/ConstpropOp.vo
$(ARCH)/ConstpropOpproof.vo: $(ARCH)/ConstpropOpproof.v lib/Coqlib.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Memory.vo common/Globalenvs.vo $(ARCH)/Op.vo backend/Registers.vo backend/RTL.vo $(ARCH)/ConstpropOp.vo backend/Constprop.vo
......@@ -83,15 +85,17 @@ $(ARCH)/Asmgen.vo: $(ARCH)/Asmgen.v lib/Coqlib.vo lib/Maps.vo common/Errors.vo c
$(ARCH)/Asmgenretaddr.vo: $(ARCH)/Asmgenretaddr.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Memory.vo common/Globalenvs.vo $(ARCH)/Op.vo backend/Locations.vo backend/Mach.vo $(ARCH)/Asm.vo $(ARCH)/Asmgen.vo
$(ARCH)/Asmgenproof1.vo: $(ARCH)/Asmgenproof1.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Memory.vo common/Globalenvs.vo $(ARCH)/Op.vo backend/Locations.vo backend/Mach.vo backend/Machconcr.vo backend/Machtyping.vo $(ARCH)/Asm.vo $(ARCH)/Asmgen.vo backend/Conventions.vo
$(ARCH)/Asmgenproof.vo: $(ARCH)/Asmgenproof.v lib/Coqlib.vo lib/Maps.vo common/Errors.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Memory.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo $(ARCH)/Op.vo backend/Locations.vo backend/Conventions.vo backend/Mach.vo backend/Machconcr.vo backend/Machtyping.vo $(ARCH)/Asm.vo $(ARCH)/Asmgen.vo $(ARCH)/Asmgenretaddr.vo $(ARCH)/Asmgenproof1.vo
cfrontend/Csyntax.vo: cfrontend/Csyntax.v lib/Coqlib.vo common/Errors.vo lib/Integers.vo lib/Floats.vo common/AST.vo
cfrontend/Csyntax.vo: cfrontend/Csyntax.v lib/Coqlib.vo common/Errors.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/AST.vo
cfrontend/Csem.vo: cfrontend/Csem.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/AST.vo common/Memory.vo common/Events.vo common/Globalenvs.vo cfrontend/Csyntax.vo common/Smallstep.vo
cfrontend/Ctyping.vo: cfrontend/Ctyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo cfrontend/Csyntax.vo
cfrontend/Cshmgen.vo: cfrontend/Cshmgen.v lib/Coqlib.vo common/Errors.vo lib/Integers.vo lib/Floats.vo common/AST.vo cfrontend/Csyntax.vo backend/Cminor.vo cfrontend/Csharpminor.vo
cfrontend/Cshmgenproof1.vo: cfrontend/Cshmgenproof1.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Memory.vo common/Globalenvs.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Ctyping.vo backend/Cminor.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo
cfrontend/Cshmgenproof2.vo: cfrontend/Cshmgenproof2.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Memory.vo common/Globalenvs.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Ctyping.vo backend/Cminor.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo cfrontend/Cshmgenproof1.vo
cfrontend/Cshmgenproof3.vo: cfrontend/Cshmgenproof3.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Memory.vo common/Globalenvs.vo common/Smallstep.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Ctyping.vo backend/Cminor.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo cfrontend/Cshmgenproof1.vo cfrontend/Cshmgenproof2.vo
cfrontend/Cstrategy.vo: cfrontend/Cstrategy.v lib/Axioms.vo lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/AST.vo common/Memory.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo common/Determinism.vo cfrontend/Csyntax.vo cfrontend/Csem.vo
cfrontend/SimplExpr.vo: cfrontend/SimplExpr.v lib/Coqlib.vo common/Errors.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/AST.vo cfrontend/Csyntax.vo cfrontend/Clight.vo
cfrontend/SimplExprspec.vo: cfrontend/SimplExprspec.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Memory.vo common/AST.vo cfrontend/Csyntax.vo cfrontend/Clight.vo cfrontend/SimplExpr.vo
cfrontend/SimplExprproof.vo: cfrontend/SimplExprproof.v lib/Axioms.vo lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Errors.vo lib/Integers.vo common/Values.vo common/Memory.vo common/Events.vo common/Smallstep.vo common/Globalenvs.vo common/Determinism.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Cstrategy.vo cfrontend/Clight.vo cfrontend/SimplExpr.vo cfrontend/SimplExprspec.vo
cfrontend/Clight.vo: cfrontend/Clight.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/AST.vo common/Memory.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo cfrontend/Csyntax.vo cfrontend/Csem.vo
cfrontend/Cshmgen.vo: cfrontend/Cshmgen.v lib/Coqlib.vo common/Errors.vo lib/Integers.vo lib/Floats.vo common/AST.vo cfrontend/Csyntax.vo cfrontend/Clight.vo backend/Cminor.vo cfrontend/Csharpminor.vo
cfrontend/Cshmgenproof.vo: cfrontend/Cshmgenproof.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Memory.vo common/Globalenvs.vo common/Smallstep.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Clight.vo backend/Cminor.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo
cfrontend/Csharpminor.vo: cfrontend/Csharpminor.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Memory.vo common/Events.vo common/Globalenvs.vo backend/Cminor.vo common/Smallstep.vo
cfrontend/Cminorgen.vo: cfrontend/Cminorgen.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Ordered.vo common/AST.vo lib/Integers.vo common/Memdata.vo cfrontend/Csharpminor.vo backend/Cminor.vo
cfrontend/Cminorgenproof.vo: cfrontend/Cminorgenproof.v lib/Coqlib.vo lib/Intv.vo common/Errors.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Memdata.vo common/Memory.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo common/Switch.vo cfrontend/Csharpminor.vo backend/Cminor.vo cfrontend/Cminorgen.vo
driver/Compiler.vo: driver/Compiler.v lib/Axioms.vo lib/Coqlib.vo lib/Maps.vo common/Errors.vo common/AST.vo common/Values.vo common/Smallstep.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Csharpminor.vo backend/Cminor.vo backend/CminorSel.vo backend/RTL.vo backend/LTL.vo backend/LTLin.vo backend/Linear.vo backend/Mach.vo $(ARCH)/Asm.vo cfrontend/Cshmgen.vo cfrontend/Cminorgen.vo backend/Selection.vo backend/RTLgen.vo backend/Tailcall.vo backend/Constprop.vo backend/CSE.vo backend/Allocation.vo backend/Tunneling.vo backend/Linearize.vo backend/Reload.vo backend/Stacking.vo $(ARCH)/Asmgen.vo cfrontend/Ctyping.vo backend/RTLtyping.vo backend/LTLtyping.vo backend/LTLintyping.vo backend/Lineartyping.vo backend/Machtyping.vo cfrontend/Cshmgenproof3.vo cfrontend/Cminorgenproof.vo backend/Selectionproof.vo backend/RTLgenproof.vo backend/Tailcallproof.vo backend/Constpropproof.vo backend/CSEproof.vo backend/Allocproof.vo backend/Alloctyping.vo backend/Tunnelingproof.vo backend/Tunnelingtyping.vo backend/Linearizeproof.vo backend/Linearizetyping.vo backend/Reloadproof.vo backend/Reloadtyping.vo backend/Stackingproof.vo backend/Stackingtyping.vo backend/Machabstr2concr.vo $(ARCH)/Asmgenproof.vo
driver/Complements.vo: driver/Complements.v lib/Coqlib.vo common/AST.vo lib/Integers.vo common/Values.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo common/Determinism.vo cfrontend/Csyntax.vo cfrontend/Csem.vo $(ARCH)/Asm.vo driver/Compiler.vo common/Errors.vo
driver/Compiler.vo: driver/Compiler.v lib/Axioms.vo lib/Coqlib.vo lib/Maps.vo common/Errors.vo common/AST.vo common/Values.vo common/Smallstep.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Cstrategy.vo cfrontend/Clight.vo cfrontend/Csharpminor.vo backend/Cminor.vo backend/CminorSel.vo backend/RTL.vo backend/LTL.vo backend/LTLin.vo backend/Linear.vo backend/Mach.vo $(ARCH)/Asm.vo cfrontend/SimplExpr.vo cfrontend/Cshmgen.vo cfrontend/Cminorgen.vo backend/Selection.vo backend/RTLgen.vo backend/Tailcall.vo backend/CastOptim.vo backend/Constprop.vo backend/CSE.vo backend/Allocation.vo backend/Tunneling.vo backend/Linearize.vo backend/Reload.vo backend/Stacking.vo $(ARCH)/Asmgen.vo backend/RTLtyping.vo backend/LTLtyping.vo backend/LTLintyping.vo backend/Lineartyping.vo backend/Machtyping.vo cfrontend/SimplExprproof.vo cfrontend/Cshmgenproof.vo cfrontend/Cminorgenproof.vo backend/Selectionproof.vo backend/RTLgenproof.vo backend/Tailcallproof.vo backend/CastOptimproof.vo backend/Constpropproof.vo backend/CSEproof.vo backend/Allocproof.vo backend/Alloctyping.vo backend/Tunnelingproof.vo backend/Tunnelingtyping.vo backend/Linearizeproof.vo backend/Linearizetyping.vo backend/Reloadproof.vo backend/Reloadtyping.vo backend/Stackingproof.vo backend/Stackingtyping.vo backend/Machabstr2concr.vo $(ARCH)/Asmgenproof.vo
driver/Complements.vo: driver/Complements.v lib/Coqlib.vo common/AST.vo lib/Integers.vo common/Values.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo common/Determinism.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Cstrategy.vo $(ARCH)/Asm.vo driver/Compiler.vo common/Errors.vo
......@@ -51,6 +51,7 @@ BACKEND=\
Tailcall.v Tailcallproof.v \
RTLtyping.v \
Kildall.v \
CastOptim.v CastOptimproof.v \
ConstpropOp.v Constprop.v ConstpropOpproof.v Constpropproof.v \
CSE.v CSEproof.v \
Machregs.v Locations.v Conventions1.v Conventions.v LTL.v LTLtyping.v \
......@@ -68,8 +69,9 @@ BACKEND=\
# C front-end modules (in cfrontend/)
CFRONTEND=Csyntax.v Csem.v Ctyping.v Cshmgen.v \
Cshmgenproof1.v Cshmgenproof2.v Cshmgenproof3.v \
CFRONTEND=Csyntax.v Csem.v Cstrategy.v \
SimplExpr.v SimplExprspec.v SimplExprproof.v \
Clight.v Cshmgen.v Cshmgenproof.v \
Csharpminor.v Cminorgen.v Cminorgenproof.v
# Putting everything together (in driver/)
......
......@@ -79,7 +79,7 @@ Inductive operation : Type :=
| Osub: operation (**r [rd = r1 - r2] *)
| Osubshift: shift -> operation (**r [rd = r1 - shifted r2] *)
| Orsubshift: shift -> operation (**r [rd = shifted r2 - r1] *)
| Orsubimm: int -> operation (**r [rd = r1 - n] *)
| Orsubimm: int -> operation (**r [rd = n - r1] *)
| Omul: operation (**r [rd = r1 * r2] *)
| Odiv: operation (**r [rd = r1 / r2] (signed) *)
| Odivu: operation (**r [rd = r1 / r2] (unsigned) *)
......
(* *********************************************************************)
(* *)
(* 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. *)
(* *)
(* *********************************************************************)
(** Pretty-printing of operators, conditions, addressing modes *)
open Format
open Camlcoq
open Integers
open Op
let comparison_name = function
| Ceq -> "=="
| Cne -> "!="
| Clt -> "<"
| Cle -> "<="
| Cgt -> ">"
| Cge -> ">="
let shift pp = function
| Slsl a -> fprintf pp "<< %ld" (camlint_of_coqint a)
| Slsr a -> fprintf pp ">>u %ld" (camlint_of_coqint a)
| Sasr a -> fprintf pp ">>s %ld" (camlint_of_coqint a)
| Sror a -> fprintf pp "ror %ld" (camlint_of_coqint a)
let print_condition reg pp = function
| (Ccomp c, [r1;r2]) ->
fprintf pp "%a %ss %a" reg r1 (comparison_name c) reg r2
| (Ccompu c, [r1;r2]) ->
fprintf pp "%a %su %a" reg r1 (comparison_name c) reg r2
| (Ccompshift(c, s), [r1;r2]) ->
fprintf pp "%a %ss %a %a" reg r1 (comparison_name c) reg r2 shift s
| (Ccompu(c, s), [r1;r2]) ->
fprintf pp "%a %su %a %a" reg r1 (comparison_name c) reg r2 shift s
| (Ccompimm(c, n), [r1]) ->
fprintf pp "%a %ss %ld" reg r1 (comparison_name c) (camlint_of_coqint n)
| (Ccompuimm(c, n), [r1]) ->
fprintf pp "%a %su %ld" reg r1 (comparison_name c) (camlint_of_coqint n)
| (Ccompf c, [r1;r2]) ->
fprintf pp "%a %sf %a" reg r1 (comparison_name c) reg r2
| (Cnotcompf c, [r1;r2]) ->
fprintf pp "%a not(%sf) %a" reg r1 (comparison_name c) reg r2
| _ ->
fprintf pp "<bad condition>"
let print_operation reg pp = function
| Omove, [r1] -> reg pp r1
| Ointconst n, [] -> fprintf pp "%ld" (camlint_of_coqint n)
| Ofloatconst n, [] -> fprintf pp "%F" n
| Oaddrsymbol(id, ofs), [] ->
fprintf pp "\"%s\" + %ld" (extern_atom id) (camlint_of_coqint ofs)
| Oaddrstack ofs, [] ->
fprintf pp "stack(%ld)" (camlint_of_coqint ofs)
| Ocast8signed, [r1] -> fprintf pp "int8signed(%a)" reg r1
| Ocast8unsigned, [r1] -> fprintf pp "int8unsigned(%a)" reg r1
| Ocast16signed, [r1] -> fprintf pp "int16signed(%a)" reg r1
| Ocast16unsigned, [r1] -> fprintf pp "int16unsigned(%a)" reg r1
| Oadd, [r1;r2] -> fprintf pp "%a + %a" reg r1 reg r2
| Oaddshift s, [r1;r2] -> fprintf pp "%a + %a %a" reg r1 reg r2 shift s
| Oaddimm n, [r1] -> fprintf pp "%a + %ld" reg r1 (camlint_of_coqint n)
| Osub, [r1;r2] -> fprintf pp "%a - %a" reg r1 reg r2
| Osubshift s, [r1;r2] -> fprintf pp "%a - %a %a" reg r1 reg r2 shift s
| Osubrshift s, [r1;r2] -> fprintf pp "%a %a - %a" reg r2 shift s reg r1
| Orsubimm n, [r1] -> fprintf pp "%ld - %a" (camlint_of_coqint n) reg r1
| Omul, [r1;r2] -> fprintf pp "%a * %a" reg r1 reg r2
| Odiv, [r1;r2] -> fprintf pp "%a /s %a" reg r1 reg r2
| Odivu, [r1;r2] -> fprintf pp "%a /u %a" reg r1 reg r2
| Oand, [r1;r2] -> fprintf pp "%a & %a" reg r1 reg r2
| Oandshift s, [r1;r2] -> fprintf pp "%a & %a %a" reg r1 reg r2 shift s
| Oandimm n, [r1] -> fprintf pp "%a & %ld" reg r1 (camlint_of_coqint n)
| Oor, [r1;r2] -> fprintf pp "%a | %a" reg r1 reg r2
| Oorshift s, [r1;r2] -> fprintf pp "%a | %a %a" reg r1 reg r2 shift s
| Oorimm n, [r1] -> fprintf pp "%a | %ld" reg r1 (camlint_of_coqint n)
| Oxor, [r1;r2] -> fprintf pp "%a ^ %a" reg r1 reg r2
| Oxorshift s, [r1;r2] -> fprintf pp "%a ^ %a %a" reg r1 reg r2 shift s
| Oxorimm n, [r1] -> fprintf pp "%a ^ %ld" reg r1 (camlint_of_coqint n)
| Obic, [r1;r2] -> fprintf pp "%a & not %a" reg r1 reg r2
| Obicshift s, [r1;r2] -> fprintf pp "%a & not(%a %a)" reg r1 reg r2 shift s
| Onot, [r1] -> fprintf pp "not(%a)" reg r1
| Onotshift s, [r1] -> fprintf pp "not(%a %a)" reg r1 shift s
| Oshl, [r1;r2] -> fprintf pp "%a << %a" reg r1 reg r2
| Oshr, [r1;r2] -> fprintf pp "%a >>s %a" reg r1 reg r2
| Oshru, [r1;r2] -> fprintf pp "%a >>u %a" reg r1 reg r2
| Oshift s, [r1] -> fprintf pp "%a %a" reg r1 shift s
| Oshrximm n, [r1] -> fprintf pp "%a >>x %ld" reg r1 (camlint_of_coqint n)
| Onegf, [r1] -> fprintf pp "negf(%a)" reg r1
| Oabsf, [r1] -> fprintf pp "absf(%a)" reg r1
| Oaddf, [r1;r2] -> fprintf pp "%a +f %a" reg r1 reg r2
| Osubf, [r1;r2] -> fprintf pp "%a -f %a" reg r1 reg r2
| Omulf, [r1;r2] -> fprintf pp "%a *f %a" reg r1 reg r2
| Odivf, [r1;r2] -> fprintf pp "%a /f %a" reg r1 reg r2
| Osingleoffloat, [r1] -> fprintf pp "singleoffloat(%a)" reg r1
| Ointoffloat, [r1] -> fprintf pp "intoffloat(%a)" reg r1
| Ointuoffloat, [r1] -> fprintf pp "intuoffloat(%a)" reg r1
| Ofloatofint, [r1] -> fprintf pp "floatofint(%a)" reg r1
| Ofloatofintu, [r1] -> fprintf pp "floatofintu(%a)" reg r1
| Ocmp c, args -> print_condition reg pp (c, args)
| _ -> fprintf pp "<bad operator>"
let print_addressing reg pp = function
| Aindexed n, [r1] -> fprintf pp "%a + %ld" reg r1 (camlint_of_coqint n)
| Aindexed2, [r1; r2] -> fprintf pp "%a + %a" reg r1 reg r2
| Aindexed2shift s, [r1; r2] -> fprintf pp "%a + %a %a" reg r1 reg r2 shift s
| Ainstack ofs, [] -> fprintf pp "stack(%ld)" (camlint_of_coqint ofs)
| _ -> fprintf pp "<bad addressing>"
(* *********************************************************************)
(* *)
(* 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. *)
(* *)
(* *********************************************************************)
(** Elimination of redundant conversions to small numerical types. *)
Require Import Coqlib.
Require Import Maps.
Require Import AST.
Require Import Integers.
Require Import Floats.
Require Import Values.
Require Import Globalenvs.
Require Import Op.
Require Import Registers.
Require Import RTL.
Require Import Lattice.
Require Import Kildall.
(** * Static analysis *)
(** Compile-time approximations *)
Inductive approx : Type :=
| Unknown (**r any value *)
| Int7 (**r [[0,127]] *)
| Int8s (**r [[-128,127] *)
| Int8u (**r [[0,255]] *)
| Int15 (**r [[0,32767]] *)
| Int16s (**r [[-32768,32767]] *)
| Int16u (**r [[0,65535] *)
| Single (**r single-precision float *)
| Novalue. (**r empty *)
(** We equip this type of approximations with a semi-lattice structure.
The ordering is inclusion between the sets of values denoted by
the approximations. *)
Module Approx <: SEMILATTICE_WITH_TOP.
Definition t := approx.
Definition eq (x y: t) := (x = y).
Definition eq_refl: forall x, eq x x := (@refl_equal t).
Definition eq_sym: forall x y, eq x y -> eq y x := (@sym_equal t).
Definition eq_trans: forall x y z, eq x y -> eq y z -> eq x z := (@trans_equal t).
Lemma eq_dec: forall (x y: t), {x=y} + {x<>y}.
Proof.
decide equality.
Qed.
Definition beq (x y: t) := if eq_dec x y then true else false.
Lemma beq_correct: forall x y, beq x y = true -> x = y.
Proof.
unfold beq; intros. destruct (eq_dec x y). auto. congruence.
Qed.
Definition ge (x y: t) : Prop :=
match x, y with
| Unknown, _ => True
| _, Novalue => True
| Int7, Int7 => True
| Int8s, (Int7 | Int8s) => True
| Int8u, (Int7 | Int8u) => True
| Int15, (Int7 | Int8u | Int15) => True
| Int16s, (Int7 | Int8s | Int8u | Int15 | Int16s) => True
| Int16u, (Int7 | Int8u | Int15 | Int16u) => True
| Single, Single => True
| _, _ => False
end.
Lemma ge_refl: forall x y, eq x y -> ge x y.
Proof.
unfold eq, ge; intros. subst y. destruct x; auto.
Qed.
Lemma ge_trans: forall x y z, ge x y -> ge y z -> ge x z.
Proof.
unfold ge; intros.
destruct x; auto; (destruct y; auto; try contradiction; destruct z; auto).
Qed.
Lemma ge_compat: forall x x' y y', eq x x' -> eq y y' -> ge x y -> ge x' y'.
Proof.
unfold eq; intros. congruence.
Qed.
Definition bge (x y: t) : bool :=
match x, y with
| Unknown, _ => true
| _, Novalue => true
| Int7, Int7 => true
| Int8s, (Int7 | Int8s) => true
| Int8u, (Int7 | Int8u) => true
| Int15, (Int7 | Int8u | Int15) => true
| Int16s, (Int7 | Int8s | Int8u | Int15 | Int16s) => true
| Int16u, (Int7 | Int8u | Int15 | Int16u) => true
| Single, Single => true
| _, _ => false
end.
Lemma bge_correct: forall x y, bge x y = true -> ge x y.
Proof.
destruct x; destruct y; simpl; auto || congruence.
Qed.
Definition bot := Novalue.
Definition top := Unknown.
Lemma ge_bot: forall x, ge x bot.
Proof.
unfold ge, bot. destruct x; auto.
Qed.
Lemma ge_top: forall x, ge top x.
Proof.
unfold ge, top. auto.
Qed.
Definition lub (x y: t) : t :=
match x, y with
| Novalue, _ => y
| _, Novalue => x
| Int7, Int7 => Int7
| Int7, Int8u => Int8u
| Int7, Int8s => Int8s
| Int7, Int15 => Int15
| Int7, Int16u => Int16u
| Int7, Int16s => Int16s
| Int8u, (Int7|Int8u) => Int8u
| Int8u, Int15 => Int15
| Int8u, Int16u => Int16u
| Int8u, Int16s => Int16s
| Int8s, (Int7|Int8s) => Int8s
| Int8s, (Int15|Int16s) => Int16s
| Int15, (Int7|Int8u|Int15) => Int15
| Int15, Int16u => Int16u
| Int15, (Int8s|Int16s) => Int16s
| Int16u, (Int7|Int8u|Int15|Int16u) => Int16u
| Int16s, (Int7|Int8u|Int8s|Int15|Int16s) => Int16s
| Single, Single => Single
| _, _ => Unknown
end.
Lemma lub_commut: forall x y, eq (lub x y) (lub y x).
Proof.
unfold lub, eq; intros.
destruct x; destruct y; auto.
Qed.
Lemma ge_lub_left: forall x y, ge (lub x y) x.
Proof.
unfold lub, ge; intros.
destruct x; destruct y; auto.
Qed.
End Approx.
Module D := LPMap Approx.
(** Abstract interpretation of operators *)
Definition approx_bitwise_op (v1 v2: approx) : approx :=
if Approx.bge Int8u v1 && Approx.bge Int8u v2 then Int8u
else if Approx.bge Int16u v1 && Approx.bge Int16u v2 then Int16u
else Unknown.
Function approx_operation (op: operation) (vl: list approx) : approx :=
match op, vl with
| Omove, v1 :: nil => v1
| Ointconst n, _ =>
if Int.eq_dec n (Int.zero_ext 7 n) then Int7
else if Int.eq_dec n (Int.zero_ext 8 n) then Int8u
else if Int.eq_dec n (Int.sign_ext 8 n) then Int8s
else if Int.eq_dec n (Int.zero_ext 15 n) then Int15
else if Int.eq_dec n (Int.zero_ext 16 n) then Int16u
else if Int.eq_dec n (Int.sign_ext 16 n) then Int16s
else Unknown
| Ofloatconst n, _ =>
if Float.eq_dec n (Float.singleoffloat n) then Single else Unknown
| Ocast8signed, _ => Int8s
| Ocast8unsigned, _ => Int8u
| Ocast16signed, _ => Int16s
| Ocast16unsigned, _ => Int16u
| Osingleoffloat, _ => Single
| Oand, v1 :: v2 :: nil => approx_bitwise_op v1 v2
| Oor, v1 :: v2 :: nil => approx_bitwise_op v1 v2
| Oxor, v1 :: v2 :: nil => approx_bitwise_op v1 v2
(* Problem: what about and/or/xor immediate? and other
machine-specific operators? *)
| Ocmp c, _ => Int7
| _, _ => Unknown
end.
Definition approx_of_chunk (chunk: memory_chunk) :=
match chunk with
| Mint8signed => Int8s
| Mint8unsigned => Int8u
| Mint16signed => Int16s
| Mint16unsigned => Int16u
| Mint32 => Unknown
| Mfloat32 => Single
| Mfloat64 => Unknown
end.
(** Transfer function for the analysis *)
Definition approx_reg (app: D.t) (r: reg) :=
D.get r app.
Definition approx_regs (app: D.t) (rl: list reg):=
List.map (approx_reg app) rl.
Definition transfer (f: function) (pc: node) (before: D.t) :=
match f.(fn_code)!pc with
| None => before
| Some i =>
match i with
| Iop op args res s =>
let a := approx_operation op (approx_regs before args) in
D.set res a before
| Iload chunk addr args dst s =>
D.set dst (approx_of_chunk chunk) before
| Icall sig ros args res s =>
D.set res Unknown before
| Ibuiltin ef args res s =>
D.set res Unknown before
| _ =>
before
end
end.
(** The static analysis is a forward dataflow analysis. *)
Module DS := Dataflow_Solver(D)(NodeSetForward).
Definition analyze (f: RTL.function): PMap.t D.t :=
match DS.fixpoint (successors f) (transfer f)
((f.(fn_entrypoint), D.top) :: nil) with
| None => PMap.init D.top
| Some res => res
end.
(** * Code transformation *)
(** Cast operations that have no effect (because the argument is already
in the right range) are turned into moves. *)
Function transf_operation (op: operation) (vl: list approx) : operation :=
match op, vl with
| Ocast8signed, v :: nil => if Approx.bge Int8s v then Omove else op
| Ocast8unsigned, v :: nil => if Approx.bge Int8u v then Omove else op
| Ocast16signed, v :: nil => if Approx.bge Int16s v then Omove else op
| Ocast16unsigned, v :: nil => if Approx.bge Int16u v then Omove else op
| Osingleoffloat, v :: nil => if Approx.bge Single v then Omove else op
| _, _ => op
end.
Definition transf_instr (app: D.t) (instr: instruction) :=
match instr with
| Iop op args res s =>
let op' := transf_operation op (approx_regs app args) in
Iop op' args res s
| _ =>
instr
end.
Definition transf_code (approxs: PMap.t D.t) (instrs: code) : code :=
PTree.map (fun pc instr => transf_instr approxs!!pc instr) instrs.
Definition transf_function (f: function) : function :=
let approxs := analyze f in
mkfunction
f.(fn_sig)
f.(fn_params)
f.(fn_stacksize)
(transf_code approxs f.(fn_code))
f.(fn_entrypoint).
Definition transf_fundef (fd: fundef) : fundef :=
AST.transf_fundef transf_function fd.
Definition transf_program (p: program) : program :=
transform_program transf_fundef p.
This diff is collapsed.
......@@ -39,6 +39,7 @@ open Conventions
type node =
{ ident: int; (*r unique identifier *)
typ: typ; (*r its type *)
regname: reg option; (*r the RTL register it comes from *)
regclass: int; (*r identifier of register class *)
mutable spillcost: float; (*r estimated cost of spilling *)
mutable adjlist: node list; (*r all nodes it interferes with *)
......@@ -84,14 +85,15 @@ and movestate =
(*i
let name_of_node n =
match n.color with
| Some(R r) ->
match n.color, n.regname with
| Some(R r), _ ->
begin match Machregsaux.name_of_register r with
| None -> "fixed-reg"
| Some s -> s
end
| Some(S _) -> "fixed-slot"
| None -> string_of_int n.ident
| Some(S _), _ -> "fixed-slot"
| None, Some r -> Printf.sprintf "x%ld" (camlint_of_positive r)
| None, None -> "unknown-reg"
*)
(* The algorithm manipulates partitions of the nodes and of the moves
......@@ -106,7 +108,7 @@ module DLinkNode = struct
type t = node
let make state =
let rec empty =
{ ident = 0; typ = Tint; regclass = 0;
{ ident = 0; typ = Tint; regname = None; regclass = 0;
adjlist = []; degree = 0; spillcost = 0.0;
movelist = []; alias = None; color = None;
nstate = state; nprev = empty; nnext = empty }
......@@ -363,7 +365,8 @@ let checkInvariants () =
let nodeOfReg r typenv spillcosts =
let ty = typenv r in
incr nextRegIdent;
{ ident = !nextRegIdent; typ = ty; regclass = class_of_type ty;
{ ident = !nextRegIdent; typ = ty;
regname = Some r; regclass = class_of_type ty;
spillcost = float(spillcosts r);
adjlist = []; degree = 0; movelist = []; alias = None;
color = None;
......@@ -373,7 +376,8 @@ let nodeOfReg r typenv spillcosts =
let nodeOfMreg mr =
let ty = mreg_type mr in
incr nextRegIdent;
{ ident = !nextRegIdent; typ = ty; regclass = class_of_type ty;
{ ident = !nextRegIdent; typ = ty;
regname = None; regclass = class_of_type ty;
spillcost = 0.0;
adjlist = []; degree = 0; movelist = []; alias = None;
color = Some (R mr);
......@@ -521,8 +525,10 @@ let canCoalesceBriggs u v =
try
iterAdjacent (consider v) u;
iterAdjacent (consider u) v;
(*i Printf.printf " Briggs: OK\n"; *)
true
with Exit ->
(*i Printf.printf " Briggs: no\n"; *)
false
(* George's conservative coalescing criterion: all high-degree neighbors
......@@ -537,8 +543,11 @@ let canCoalesceGeorge u v =
if t.degree < k || interfere t u then () else raise Exit
in
try
iterAdjacent isOK v; true
iterAdjacent isOK v;
(*i Printf.printf " George: OK\n"; *)
true
with Exit ->
(*i Printf.printf " George: no\n"; *)
false
(* The combined coalescing criterion. [u] can be precolored, but
......@@ -603,7 +612,7 @@ let coalesce () =
let m = DLinkMove.pick worklistMoves in
let x = getAlias m.src and y = getAlias m.dst in
let (u, v) = if y.nstate = Colored then (y, x) else (x, y) in
(*i Printf.printf "Attempt coalescing %s and %s\n" (name_of_node u) (name_of_node v);*)
(*i Printf.printf "Attempt coalescing %s and %s\n" (name_of_node u) (name_of_node v); *)
if u == v then begin
DLinkMove.insert m coalescedMoves;
addWorkList u
......
(* *********************************************************************)
(* *)
(* 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 GNU General Public License as published by *)
(* the Free Software Foundation, either version 2 of the License, or *)
(* (at your option) any later version. This file is also distributed *)
(* under the terms of the INRIA Non-Commercial License Agreement. *)
(* *)
(* *********************************************************************)
(** Pretty-printer for Cminor *)
open Format
open Camlcoq
open Datatypes
open BinPos
open Integers
open AST
open Cminor
(* Precedences and associativity -- like those of C *)
type associativity = LtoR | RtoL | NA
let rec precedence = function
| Evar _ -> (16, NA)
| Econst _ -> (16, NA)
| Eunop _ -> (15, RtoL)
| Ebinop((Omul|Odiv|Odivu|Omod|Omodu|Omulf|Odivf), _, _) -> (13, LtoR)
| Ebinop((Oadd|Osub|Oaddf|Osubf), _, _) -> (12, LtoR)
| Ebinop((Oshl|Oshr|Oshru), _, _) -> (11, LtoR)
| Ebinop((Ocmp _|Ocmpu _|Ocmpf _), _, _) -> (10, LtoR)
| Ebinop(Oand, _, _) -> (8, LtoR)
| Ebinop(Oxor, _, _) -> (7, LtoR)
| Ebinop(Oor, _, _) -> (6, LtoR)