aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--backend/Inliningaux.ml9
-rw-r--r--cfrontend/C2C.ml28
-rw-r--r--cparser/Elab.ml1
-rw-r--r--lib/JsonAST.ml2
4 files changed, 27 insertions, 13 deletions
diff --git a/backend/Inliningaux.ml b/backend/Inliningaux.ml
index 164773ae..842e0c93 100644
--- a/backend/Inliningaux.ml
+++ b/backend/Inliningaux.ml
@@ -86,7 +86,10 @@ let static_called_once id io =
(* To be considered: heuristics based on size of function? *)
let should_inline (io: inlining_info) (id: ident) (f: coq_function) =
- if !Clflags.option_finline then
- C2C.atom_is_inline id || static_called_once id io
- else
+ if !Clflags.option_finline then begin
+ match C2C.atom_inline id with
+ | C2C.Inline -> true
+ | C2C.Noinline -> false
+ | C2C.No_specifier -> static_called_once id io
+ end else
false
diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml
index 4c75c2f2..173764e3 100644
--- a/cfrontend/C2C.ml
+++ b/cfrontend/C2C.ml
@@ -26,13 +26,18 @@ open Csyntax
(** Record useful information about global variables and functions,
and associate it with the corresponding atoms. *)
+type inline_status =
+ | No_specifier (* No inline specifier and no noinline attribute *)
+ | Noinline (* The atom is declared with the noinline attribute *)
+ | Inline (* The atom is declared inline *)
+
type atom_info =
{ a_storage: C.storage; (* storage class *)
a_alignment: int option; (* alignment *)
a_sections: Sections.section_name list; (* in which section to put it *)
(* 1 section for data, 3 sections (code/lit/jumptbl) for functions *)
a_access: Sections.access_mode; (* access mode, e.g. small data area *)
- a_inline: bool; (* function declared inline? *)
+ a_inline: inline_status; (* function declared inline? *)
a_loc: location (* source location *)
}
@@ -74,11 +79,11 @@ let atom_is_rel_data a ofs =
with Not_found ->
false
-let atom_is_inline a =
+let atom_inline a =
try
(Hashtbl.find decl_atom a).a_inline
with Not_found ->
- false
+ No_specifier
(** Iso C99 defines inline definitions of functions as functions
with inline specifier and without extern. These functions do
@@ -89,7 +94,7 @@ let atom_is_iso_inline_definition a =
try
let i = Hashtbl.find decl_atom a in
match i.a_storage with
- | C.Storage_default -> i.a_inline
+ | C.Storage_default -> i.a_inline = Inline
| _ -> false
with Not_found ->
false
@@ -325,7 +330,7 @@ let name_for_string_literal s =
a_alignment = Some 1;
a_sections = [Sections.for_stringlit()];
a_access = Sections.Access_default;
- a_inline = false;
+ a_inline = No_specifier;
a_loc = Cutil.no_loc };
Hashtbl.add stringTable s id;
id
@@ -355,7 +360,7 @@ let name_for_wide_string_literal s =
a_alignment = Some Machine.((!config).sizeof_wchar);
a_sections = [Sections.for_stringlit()];
a_access = Sections.Access_default;
- a_inline = false;
+ a_inline = No_specifier;
a_loc = Cutil.no_loc };
Hashtbl.add wstringTable s id;
id
@@ -1148,13 +1153,20 @@ let convertFundef loc env fd =
fd.fd_locals in
let body' = convertStmt env fd.fd_body in
let id' = intern_string fd.fd_name.name in
+ let noinline = Cutil.find_custom_attributes ["noinline";"__noinline__"] fd.fd_attrib <> [] in
+ let inline = if noinline || fd.fd_vararg then (* PR#15 *)
+ Noinline
+ else if fd.fd_inline then
+ Inline
+ else
+ No_specifier in
Debug.atom_global fd.fd_name id';
Hashtbl.add decl_atom id'
{ a_storage = fd.fd_storage;
a_alignment = None;
a_sections = Sections.for_function env id' fd.fd_attrib;
a_access = Sections.Access_default;
- a_inline = fd.fd_inline && not fd.fd_vararg; (* PR#15 *)
+ a_inline = inline;
a_loc = loc };
(id', AST.Gfun(Ctypes.Internal
{fn_return = ret;
@@ -1240,7 +1252,7 @@ let convertGlobvar loc env (sto, id, ty, optinit) =
a_alignment = Some (Z.to_int al);
a_sections = [section];
a_access = access;
- a_inline = false;
+ a_inline = No_specifier;
a_loc = loc };
let volatile = List.mem C.AVolatile attr in
let readonly = List.mem C.AConst attr && not volatile in
diff --git a/cparser/Elab.ml b/cparser/Elab.ml
index 60772eec..e846e301 100644
--- a/cparser/Elab.ml
+++ b/cparser/Elab.ml
@@ -2365,7 +2365,6 @@ let elab_fundef env spec name defs body loc =
&& can_return then
warning loc Invalid_noreturn "function '%s' declared 'noreturn' should not return" s;
(* Build and emit function definition *)
- let inline = inline && find_custom_attributes ["noinline";"__noinline__"] attr = [] in
let fn =
{ fd_storage = sto1;
fd_inline = inline;
diff --git a/lib/JsonAST.ml b/lib/JsonAST.ml
index f3dd2dc6..73cac31e 100644
--- a/lib/JsonAST.ml
+++ b/lib/JsonAST.ml
@@ -59,7 +59,7 @@ let pp_int_opt pp = function
let pp_fundef pp_inst pp (name,fn) =
let alignment = atom_alignof name
- and inline = atom_is_inline name
+ and inline = atom_inline name = Inline
and static = atom_is_static name
and c_section,l_section,j_section = match (atom_sections name) with [a;b;c] -> a,b,c | _ -> assert false in
pp_jobject_start pp;