95 lines
3.3 KiB
OCaml
95 lines
3.3 KiB
OCaml
(***********************************************************************)
|
|
(* *)
|
|
(* Objective Caml *)
|
|
(* *)
|
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
|
(* *)
|
|
(* Copyright 1998 Institut National de Recherche en Informatique et *)
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
(* under the terms of the Q Public License version 1.0. *)
|
|
(* *)
|
|
(***********************************************************************)
|
|
|
|
(* $Id$ *)
|
|
|
|
(* Auxiliaries for type-based optimizations, e.g. array kinds *)
|
|
|
|
open Misc
|
|
open Asttypes
|
|
open Primitive
|
|
open Path
|
|
open Types
|
|
open Typedtree
|
|
open Lambda
|
|
|
|
let has_base_type exp base_ty =
|
|
let exp_ty =
|
|
Ctype.expand_head exp.exp_env (Ctype.correct_levels exp.exp_type) in
|
|
match (Ctype.repr exp_ty, Ctype.repr base_ty) with
|
|
{desc = Tconstr(p1, _, _)}, {desc = Tconstr(p2, _, _)} -> Path.same p1 p2
|
|
| (_, _) -> false
|
|
|
|
let maybe_pointer exp =
|
|
let exp_ty =
|
|
Ctype.expand_head exp.exp_env (Ctype.correct_levels exp.exp_type) in
|
|
match (Ctype.repr exp_ty).desc with
|
|
Tconstr(p, args, abbrev) ->
|
|
not (Path.same p Predef.path_int) &&
|
|
not (Path.same p Predef.path_char) &&
|
|
begin try
|
|
match Env.find_type p exp.exp_env with
|
|
{type_kind = Type_variant cstrs} ->
|
|
List.exists (fun (name, args) -> args <> []) cstrs
|
|
| _ -> true
|
|
with Not_found -> true
|
|
(* This can happen due to e.g. missing -I options,
|
|
causing some .cmi files to be unavailable.
|
|
Maybe we should emit a warning. *)
|
|
end
|
|
| _ -> true
|
|
|
|
let array_element_kind env ty =
|
|
let ty = Ctype.repr (Ctype.expand_head env ty) in
|
|
match ty.desc with
|
|
Tvar ->
|
|
Pgenarray
|
|
| Tconstr(p, args, abbrev) ->
|
|
if Path.same p Predef.path_int || Path.same p Predef.path_char then
|
|
Pintarray
|
|
else if Path.same p Predef.path_float then
|
|
Pfloatarray
|
|
else if Path.same p Predef.path_string
|
|
|| Path.same p Predef.path_array then
|
|
Paddrarray
|
|
else begin
|
|
try
|
|
match Env.find_type p env with
|
|
{type_kind = Type_abstract} ->
|
|
Pgenarray
|
|
| {type_kind = Type_variant cstrs}
|
|
when List.for_all (fun (name, args) -> args = []) cstrs ->
|
|
Pintarray
|
|
| {type_kind = _} ->
|
|
Paddrarray
|
|
with Not_found ->
|
|
(* This can happen due to e.g. missing -I options,
|
|
causing some .cmi files to be unavailable.
|
|
Maybe we should emit a warning. *)
|
|
Pgenarray
|
|
end
|
|
| _ ->
|
|
Paddrarray
|
|
|
|
let array_kind_gen ty env =
|
|
let array_ty = Ctype.expand_head env (Ctype.correct_levels ty) in
|
|
match (Ctype.repr array_ty).desc with
|
|
Tconstr(p, [elt_ty], _) when Path.same p Predef.path_array ->
|
|
array_element_kind env elt_ty
|
|
| _ ->
|
|
(* This can happen with e.g. Obj.field *)
|
|
Pgenarray
|
|
|
|
let array_kind exp = array_kind_gen exp.exp_type exp.exp_env
|
|
|
|
let array_pattern_kind pat = array_kind_gen pat.pat_type pat.pat_env
|