Library AST


This file defines a number of data types and operations used in the abstract syntax trees of many of the intermediate languages.

Require Import Coqlib.
Require Import Errors.
Require Import Integers.

Set Implicit Arguments.

Syntactic elements

Identifiers (names of local variables, of global symbols and functions, etc) are represented by the type positive of positive integers.

Definition ident := positive.

Definition ident_eq := peq.

The intermediate languages are weakly typed, using only two types: Tint for integers and pointers, and Tfloat for floating-point numbers.

Inductive typ : Set :=
  | Tint : typ
.

Definition typesize (ty: typ) : Z :=
  match ty with Tint => 4 end.

Lemma typesize_pos: forall ty, typesize ty > 0.
Proof. destruct ty; simpl; omega. Qed.

Lemma typ_eq: forall (t1 t2: typ), {t1=t2} + {t1<>t2}.
Proof. decide equality. Qed.

Lemma opt_typ_eq: forall (t1 t2: option typ), {t1=t2} + {t1<>t2}.
Proof.
  destruct t1; destruct t2; eauto; try (right; discriminate).
  destruct (typ_eq t t0).
   left. congruence.
  right. congruence.
Qed.

Additionally, function definitions and function calls are annotated by function signatures indicating the number and types of arguments, as well as the type of the returned value if any. These signatures are used in particular to determine appropriate calling conventions for the function.

Record signature : Type := mksignature {
  sig_args: list typ;
  sig_res: option typ
}.

Definition proj_sig_res (s: signature) : typ :=
  match s.(sig_res) with
  | None => Tint
  | Some t => t
  end.

Memory accesses (load and store instructions) are annotated by a ``memory chunk'' indicating the type, size and signedness of the chunk of memory being accessed.

Inductive memory_chunk : Type :=
  | Mint8signed : memory_chunk
  | Mint8unsigned : memory_chunk
  | Mint16signed : memory_chunk
  | Mint16unsigned : memory_chunk
  | Mint32 : memory_chunk

.

The type (integer/pointer or float) of a chunk.

Definition type_of_chunk (c: memory_chunk) : typ :=
  match c with
  | Mint8signed => Tint
  | Mint8unsigned => Tint
  | Mint16signed => Tint
  | Mint16unsigned => Tint
  | Mint32 => Tint

  end.

Initialization data for global variables.

Inductive init_data: Type :=
  | Init_int8: int -> init_data
  | Init_int16: int -> init_data
  | Init_int32: int -> init_data

  | Init_space: Z -> init_data
  | Init_addrof: ident -> int -> init_data.
Information attached to global variables.

Record globvar (V: Type) : Type := mkglobvar {
  gvar_info: V;
  gvar_init: list init_data;
  gvar_readonly: bool;
  gvar_volatile: bool
}.

Whole programs consist of:
  • a collection of global definitions (name and description);
  • the name of the ``main'' function that serves as entry point in the program.
A global definition is either a global function or a global variable. The type of function descriptions and that of additional information for variables vary among the various intermediate languages and are taken as parameters to the program type. The other parts of whole programs are common to all languages.

Inductive globdef (F V: Type) : Type :=
  | Gfun (f: F)
  | Gvar (v: globvar V).

Implicit Arguments Gfun [F V].
Implicit Arguments Gvar [F V].

Generic transformations over programs

We now define a general iterator over programs that applies a given code transformation function to all function descriptions and leaves the other parts of the program unchanged.

Section TRANSF_PROGRAM.

Variable A B V: Type.
Variable transf: A -> B.

Definition transform_program_globdef (idg: ident * globdef A V) : ident * globdef B V :=
  match idg with
  | (id, Gfun f) => (id, Gfun (transf f))
  | (id, Gvar v) => (id, Gvar v)
  end.

End TRANSF_PROGRAM.

The following is a more general presentation of transform_program where global variable information can be transformed, in addition to function definitions. Moreover, the transformation functions can fail and return an error message.

Open Local Scope error_monad_scope.
Open Local Scope string_scope.

Section TRANSF_PROGRAM_GEN.

Variables A B V W: Type.
Variable transf_fun: A -> res B.
Variable transf_var: V -> res W.

Definition transf_globvar (g: globvar V) : res (globvar W) :=
  do info' <- transf_var g.(gvar_info);
  OK (mkglobvar info' g.(gvar_init) g.(gvar_readonly) g.(gvar_volatile)).

Fixpoint transf_globdefs (l: list (ident * globdef A V)) : res (list (ident * globdef B W)) :=
  match l with
  | nil => OK nil
  | (id, Gfun f) :: l' =>
      match transf_fun f with
      | Error msg => Error (MSG "In function " :: CTX id :: MSG ": " :: msg)
      | OK tf =>
          do tl' <- transf_globdefs l'; OK ((id, Gfun tf) :: tl')
      end
  | (id, Gvar v) :: l' =>
      match transf_globvar v with
      | Error msg => Error (MSG "In variable " :: CTX id :: MSG ": " :: msg)
      | OK tv =>
          do tl' <- transf_globdefs l'; OK ((id, Gvar tv) :: tl')
      end
  end.

End TRANSF_PROGRAM_GEN.

The following is a relational presentation of transform_partial_augment_preogram. Given relations between function definitions and between variable information, it defines a relation between programs stating that the two programs have appropriately related shapes (global names are preserved and possibly augmented, etc) and that identically-named function definitions and variable information are related.

Section MATCH_PROGRAM.

Variable A B V W: Type.
Variable match_fundef: A -> B -> Prop.
Variable match_varinfo: V -> W -> Prop.

Inductive match_globdef: ident * globdef A V -> ident * globdef B W -> Prop :=
  | match_glob_fun: forall id f1 f2,
      match_fundef f1 f2 ->
      match_globdef (id, Gfun f1) (id, Gfun f2)
  | match_glob_var: forall id init ro vo info1 info2,
      match_varinfo info1 info2 ->
      match_globdef (id, Gvar (mkglobvar info1 init ro vo)) (id, Gvar (mkglobvar info2 init ro vo)).

End MATCH_PROGRAM.

Function definitions are the union of internal and external functions.

Inductive fundef (G F: Type): Type :=
  | Internal: F -> fundef G F
  | External: G -> fundef G F.

Implicit Arguments Internal [F G].
Implicit Arguments External [F G].

Section TRANSF_FUNDEF.

Variable G A B: Type.
Variable transf: A -> B.

Definition transf_fundef (fd: fundef G A): fundef G B :=
  match fd with
  | Internal f => Internal (transf f)
  | External ef => External ef
  end.

End TRANSF_FUNDEF.

Section TRANSF_PARTIAL_FUNDEF.

Variable G A B: Type.
Variable transf_partial: A -> res B.

Definition transf_partial_fundef (fd: fundef G A): res (fundef G B) :=
  match fd with
  | Internal f => do f' <- transf_partial f; OK (Internal f')
  | External ef => OK (External ef)
  end.

End TRANSF_PARTIAL_FUNDEF.