|
|
|
(*
|
|
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
|
|
|
*)
|
|
|
|
|
|
|
|
(** Types *)
|
|
|
|
|
|
|
|
type t = private
|
|
|
|
| Function of {return: t option; args: t iarray}
|
|
|
|
(** (Global) function names have type Pointer to Function. *)
|
|
|
|
| Integer of {bits: int; byts: int} (** Integer of given bitwidth. *)
|
|
|
|
| Float of {bits: int; byts: int; enc: [`IEEE | `Extended | `Pair]}
|
|
|
|
(** Floating-point numbers of given bitwidth and encoding. *)
|
|
|
|
| Pointer of {elt: t} (** Pointer to element type. *)
|
|
|
|
| Array of {elt: t; len: int; bits: int; byts: int}
|
|
|
|
(** Statically-sized array of [len] elements of type [elt]. *)
|
|
|
|
| Tuple of {elts: t iarray; bits: int; byts: int; packed: bool}
|
|
|
|
(** Anonymous aggregate of heterogeneous types. *)
|
|
|
|
| Struct of
|
|
|
|
{name: string; elts: t iarray; bits: int; byts: int; packed: bool}
|
|
|
|
(** Uniquely named aggregate of heterogeneous types. Every cycle of
|
|
|
|
recursive types contains a [Struct]. NOTE: recursive [Struct]
|
|
|
|
types are represented by cyclic values. *)
|
|
|
|
| Opaque of {name: string}
|
|
|
|
(** Uniquely named aggregate type whose definition is hidden. *)
|
|
|
|
[@@deriving compare, equal, hash, sexp]
|
|
|
|
|
|
|
|
val pp : t pp
|
|
|
|
val pp_defn : t pp
|
|
|
|
|
|
|
|
include Invariant.S with type t := t
|
|
|
|
|
|
|
|
(** Constructors *)
|
|
|
|
|
[sledge] Add typ of integer constants
Summary:
Types of integer constants, in particular their bit-width, are
necessary for:
- correctly interpreting bitwise operations (e.g. `-1 xor 1` at type
`i1` is `0` while without the type the result is `-2`), and;
- distinguishing between integers and booleans, which are one-bit
integers, since booleans admit stronger algebraic simplification.
Note that code does genuinely treat 1-bit integers interchangeably as
booleans and integers, e.g. with expressions such as `e + (b != 42)`.
Therefore a lighter-weight early syntactic distinction between boolean
and bitwise operations is nontrivial/impossible to make robust.
This patch:
- adds the type to the representation of Exp.Integer;
- adds checks that Integer values fit within their specified bit-width
- factors out code handling 1-bit integers as booleans into `Z`, as it
is easy to make mistakes when forgetting that `-1`, not `1`, is the
representation of `true`;
- corrects the treatment of Exp.Convert in some cases involving
treating negative integers as unsigned;
- corrects and strengthens Exp simplification based on the bit-width
information;
- removes the `e - e ==> 0` simplification, due to not having the type
for `0`.
Reviewed By: mbouaziz
Differential Revision: D10488407
fbshipit-source-id: ff4320a29
6 years ago
|
|
|
val bool : t
|
|
|
|
val byt : t
|
|
|
|
val int : t
|
[sledge] Add typ of integer constants
Summary:
Types of integer constants, in particular their bit-width, are
necessary for:
- correctly interpreting bitwise operations (e.g. `-1 xor 1` at type
`i1` is `0` while without the type the result is `-2`), and;
- distinguishing between integers and booleans, which are one-bit
integers, since booleans admit stronger algebraic simplification.
Note that code does genuinely treat 1-bit integers interchangeably as
booleans and integers, e.g. with expressions such as `e + (b != 42)`.
Therefore a lighter-weight early syntactic distinction between boolean
and bitwise operations is nontrivial/impossible to make robust.
This patch:
- adds the type to the representation of Exp.Integer;
- adds checks that Integer values fit within their specified bit-width
- factors out code handling 1-bit integers as booleans into `Z`, as it
is easy to make mistakes when forgetting that `-1`, not `1`, is the
representation of `true`;
- corrects the treatment of Exp.Convert in some cases involving
treating negative integers as unsigned;
- corrects and strengthens Exp simplification based on the bit-width
information;
- removes the `e - e ==> 0` simplification, due to not having the type
for `0`.
Reviewed By: mbouaziz
Differential Revision: D10488407
fbshipit-source-id: ff4320a29
6 years ago
|
|
|
val siz : t
|
|
|
|
val ptr : t
|
|
|
|
val function_ : return:t option -> args:t iarray -> t
|
|
|
|
val integer : bits:int -> byts:int -> t
|
|
|
|
val float : bits:int -> byts:int -> enc:[`Extended | `IEEE | `Pair] -> t
|
|
|
|
val pointer : elt:t -> t
|
|
|
|
val array : elt:t -> len:int -> bits:int -> byts:int -> t
|
|
|
|
val tuple : t iarray -> bits:int -> byts:int -> packed:bool -> t
|
|
|
|
|
|
|
|
val struct_ :
|
|
|
|
name:string -> bits:int -> byts:int -> packed:bool -> t lazy_t iarray -> t
|
|
|
|
|
|
|
|
val opaque : name:string -> t
|
|
|
|
|
|
|
|
(** Queries *)
|
|
|
|
|
|
|
|
val is_sized : t -> bool
|
|
|
|
(** Holds of types which are first-class and have a statically-known size. *)
|
|
|
|
|
|
|
|
val bit_size_of : t -> int
|
|
|
|
(** The number of bits required to hold a value of the given type. Raises
|
|
|
|
unless [is_sized] holds. *)
|
|
|
|
|
|
|
|
val size_of : t -> int
|
|
|
|
(** The number of bytes between adjacent values of the given type, including
|
|
|
|
alignment padding. Raises unless is_sized holds. *)
|
|
|
|
|
|
|
|
val equivalent : t -> t -> bool
|
|
|
|
(** Equivalent types are those that denote the same sets of values in the
|
|
|
|
semantic model. An equivalence relation. *)
|
|
|
|
|
|
|
|
val castable : t -> t -> bool
|
|
|
|
(** Castable types are those that can be cast between without loss of
|
|
|
|
information. An equivalence relation. *)
|
|
|
|
|
|
|
|
val convertible : t -> t -> bool
|
|
|
|
(** Convertible types are those that can be converted between, perhaps with
|
|
|
|
some loss of information. Not transitive: some admissible conversions
|
|
|
|
must be performed in multiple steps, such as from [Pointer] to [Integer]
|
|
|
|
to [Array]. *)
|