aboutsummaryrefslogtreecommitdiffstats
path: root/cparser/StructByValue.ml
diff options
context:
space:
mode:
authorxleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2012-02-04 19:14:14 +0000
committerxleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2012-02-04 19:14:14 +0000
commit25b9b003178002360d666919f2e49e7f5f4a36e2 (patch)
treed5f7fb317f34f3a7ac9383c21b0eb143317c30f8 /cparser/StructByValue.ml
parent145b32ec504541e98f73b2c87ff2d8181b5e7968 (diff)
downloadcompcert-25b9b003178002360d666919f2e49e7f5f4a36e2.tar.gz
compcert-25b9b003178002360d666919f2e49e7f5f4a36e2.zip
Merge of the "volatile" branch:
- native treatment of volatile accesses in CompCert C's semantics - translation of volatile accesses to built-ins in SimplExpr - native treatment of struct assignment and passing struct parameter by value - only passing struct result by value remains emulated - in cparser, remove emulations that are no longer used - added C99's type _Bool and used it to express || and && more efficiently. git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1814 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'cparser/StructByValue.ml')
-rw-r--r--cparser/StructByValue.ml298
1 files changed, 0 insertions, 298 deletions
diff --git a/cparser/StructByValue.ml b/cparser/StructByValue.ml
deleted file mode 100644
index 1b74ec52..00000000
--- a/cparser/StructByValue.ml
+++ /dev/null
@@ -1,298 +0,0 @@
-(* *********************************************************************)
-(* *)
-(* 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. *)
-(* *)
-(* *********************************************************************)
-
-(* Eliminate by-value passing of structs and unions. *)
-
-(* Assumes: nothing.
- Preserves: unblocked code *)
-
-open C
-open Cutil
-open Transform
-
-(* In function argument types, struct s -> const struct s *
- In function result types, struct s -> void + add 1st parameter struct s *
- Try to preserve original typedef names when no change.
-*)
-
-let rec transf_type env t =
- match unroll env t with
- | TFun(tres, None, vararg, attr) ->
- let tres' = transf_type env tres in
- TFun((if is_composite_type env tres then TVoid [] else tres'),
- None, vararg, attr)
- | TFun(tres, Some args, vararg, attr) ->
- let args' = List.map (transf_funarg env) args in
- let tres' = transf_type env tres in
- if is_composite_type env tres then begin
- let res = Env.fresh_ident "_res" in
- TFun(TVoid [], Some((res, TPtr(tres', [])) :: args'), vararg, attr)
- end else
- TFun(tres', Some args', vararg, attr)
- | TPtr(t1, attr) ->
- let t1' = transf_type env t1 in
- if t1' = t1 then t else TPtr(transf_type env t1, attr)
- | TArray(t1, sz, attr) ->
- let t1' = transf_type env t1 in
- if t1' = t1 then t else TArray(transf_type env t1, sz, attr)
- | _ -> t
-
-and transf_funarg env (id, t) =
- let t = transf_type env t in
- if is_composite_type env t
- then (id, TPtr(add_attributes_type [AConst] t, []))
- else (id, t)
-
-(* Expressions: transform calls + rewrite the types *)
-
-let rec transf_expr env ctx e =
- let newty = transf_type env e.etyp in
- match e.edesc with
- | EConst c ->
- {edesc = EConst c; etyp = newty}
- | ESizeof ty ->
- {edesc = ESizeof (transf_type env ty); etyp = newty}
- | EVar x ->
- {edesc = EVar x; etyp = newty}
- | EUnop(op, e1) ->
- {edesc = EUnop(op, transf_expr env Val e1); etyp = newty}
- | EBinop(Oassign, lhs, {edesc = ECall(fn, args)}, ty)
- when is_composite_type env ty ->
- transf_composite_call env ctx (Some lhs) fn args ty
- | EBinop(Ocomma, e1, e2, ty) ->
- {edesc = EBinop(Ocomma, transf_expr env Effects e1,
- transf_expr env ctx e2,
- transf_type env ty);
- etyp = newty}
- | EBinop(op, e1, e2, ty) ->
- {edesc = EBinop(op, transf_expr env Val e1,
- transf_expr env Val e2,
- transf_type env ty);
- etyp = newty}
- | EConditional(e1, e2, e3) ->
- {edesc = EConditional(transf_expr env Val e1,
- transf_expr env ctx e2,
- transf_expr env ctx e3);
- etyp = newty}
- | ECast(ty, e1) ->
- {edesc = ECast(transf_type env ty, transf_expr env Val e1); etyp = newty}
- | ECall(fn, args) ->
- if is_composite_type env e.etyp then
- transf_composite_call env ctx None fn args e.etyp
- else
- {edesc = ECall(transf_expr env Val fn, List.map (transf_arg env) args);
- etyp = newty}
-
-(* Function arguments: pass by reference those having composite type *)
-
-and transf_arg env e =
- let e' = transf_expr env Val e in
- if is_composite_type env e'.etyp then eaddrof e' else e'
-
-(* Function calls returning a composite: add first argument.
- ctx = Effects: lv = f(...) -> f(&lv, ...)
- f(...) -> f(&newtemp, ...)
- ctx = Val: lv = f(...) -> f(&newtemp, ...), lv = newtemp, newtemp
- f(...) -> f(&newtemp, ...), newtemp
-*)
-
-and transf_composite_call env ctx opt_lhs fn args ty =
- let ty = transf_type env ty in
- let fn = transf_expr env Val fn in
- let args = List.map (transf_arg env) args in
- match ctx, opt_lhs with
- | Effects, None ->
- let tmp = new_temp ~name:"_res" ty in
- {edesc = ECall(fn, eaddrof tmp :: args); etyp = TVoid []}
- | Effects, Some lhs ->
- let lhs = transf_expr env Val lhs in
- {edesc = ECall(fn, eaddrof lhs :: args); etyp = TVoid []}
- | Val, None ->
- let tmp = new_temp ~name:"_res" ty in
- ecomma {edesc = ECall(fn, eaddrof tmp :: args); etyp = TVoid []} tmp
- | Val, Some lhs ->
- let lhs = transf_expr env Val lhs in
- let tmp = new_temp ~name:"_res" ty in
- ecomma (ecomma {edesc = ECall(fn, eaddrof tmp :: args); etyp = TVoid []}
- (eassign lhs tmp))
- tmp
-
-(* The transformation above can create ill-formed lhs containing ",", as in
- f().x = y ---> (f(&tmp), tmp).x = y
- f(g(x)); ---> f(&(g(&tmp),tmp))
- We fix this by floating the "," above the lhs, up to the nearest enclosing
- rhs:
- f().x = y ---> (f(&tmp), tmp).x = y --> f(&tmp), tmp.x = y
- f(g(x)); ---> f(&(g(&tmp),tmp)) --> f((g(&tmp), &tmp))
-*)
-
-let rec float_comma e =
- match e.edesc with
- | EConst c -> e
- | ESizeof ty -> e
- | EVar x -> e
- (* lvalue-consuming unops *)
- | EUnop((Oaddrof|Opreincr|Opredecr|Opostincr|Opostdecr|Odot _) as op,
- {edesc = EBinop(Ocomma, e1, e2, _)}) ->
- ecomma (float_comma e1)
- (float_comma {edesc = EUnop(op, e2); etyp = e.etyp})
- (* lvalue-consuming binops *)
- | EBinop((Oassign|Oadd_assign|Osub_assign|Omul_assign|Odiv_assign
- |Omod_assign|Oand_assign|Oor_assign|Oxor_assign
- |Oshl_assign|Oshr_assign) as op,
- {edesc = EBinop(Ocomma, e1, e2, _)}, e3, tyres) ->
- ecomma (float_comma e1)
- (float_comma {edesc = EBinop(op, e2, e3, tyres); etyp = e.etyp})
- (* other expressions *)
- | EUnop(op, e1) ->
- {edesc = EUnop(op, float_comma e1); etyp = e.etyp}
- | EBinop(op, e1, e2, tyres) ->
- {edesc = EBinop(op, float_comma e1, float_comma e2, tyres); etyp = e.etyp}
- | EConditional(e1, e2, e3) ->
- {edesc = EConditional(float_comma e1, float_comma e2, float_comma e3);
- etyp = e.etyp}
- | ECast(ty, e1) ->
- {edesc = ECast(ty, float_comma e1); etyp = e.etyp}
- | ECall(e1, el) ->
- {edesc = ECall(float_comma e1, List.map float_comma el); etyp = e.etyp}
-
-(* Initializers *)
-
-let rec transf_init env = function
- | Init_single e ->
- Init_single (float_comma(transf_expr env Val e))
- | Init_array il ->
- Init_array (List.map (transf_init env) il)
- | Init_struct(id, fil) ->
- Init_struct (id, List.map (fun (fld, i) -> (fld, transf_init env i)) fil)
- | Init_union(id, fld, i) ->
- Init_union(id, fld, transf_init env i)
-
-(* Declarations *)
-
-let transf_decl env (sto, id, ty, init) =
- (sto, id, transf_type env ty,
- match init with None -> None | Some i -> Some (transf_init env i))
-
-(* Transformation of statements and function bodies *)
-
-let transf_funbody env body optres =
-
-let transf_expr ctx e = float_comma(transf_expr env ctx e) in
-
-(* Function returns: if return type is struct or union,
- return x -> _res = x; return
-*)
-
-let rec transf_stmt s =
- match s.sdesc with
- | Sskip -> s
- | Sdo e ->
- {s with sdesc = Sdo(transf_expr Effects e)}
- | Sseq(s1, s2) ->
- {s with sdesc = Sseq(transf_stmt s1, transf_stmt s2)}
- | Sif(e, s1, s2) ->
- {s with sdesc = Sif(transf_expr Val e,
- transf_stmt s1, transf_stmt s2)}
- | Swhile(e, s1) ->
- {s with sdesc = Swhile(transf_expr Val e, transf_stmt s1)}
- | Sdowhile(s1, e) ->
- {s with sdesc = Sdowhile(transf_stmt s1, transf_expr Val e)}
- | Sfor(s1, e, s2, s3) ->
- {s with sdesc = Sfor(transf_stmt s1, transf_expr Val e,
- transf_stmt s2, transf_stmt s3)}
- | Sbreak -> s
- | Scontinue -> s
- | Sswitch(e, s1) ->
- {s with sdesc = Sswitch(transf_expr Val e, transf_stmt s1)}
- | Slabeled(lbl, s1) ->
- {s with sdesc = Slabeled(lbl, transf_stmt s1)}
- | Sgoto lbl -> s
- | Sreturn None -> s
- | Sreturn(Some e) ->
- let e = transf_expr Val e in
- begin match optres with
- | None ->
- {s with sdesc = Sreturn(Some e)}
- | Some dst ->
- sseq s.sloc
- (sassign s.sloc dst e)
- {sdesc = Sreturn None; sloc = s.sloc}
- end
- | Sblock sl ->
- {s with sdesc = Sblock(List.map transf_stmt sl)}
- | Sdecl d ->
- {s with sdesc = Sdecl(transf_decl env d)}
-
-in
- transf_stmt body
-
-let transf_params loc env params =
- let rec transf_prm = function
- | [] ->
- ([], [], sskip)
- | (id, ty) :: params ->
- let ty = transf_type env ty in
- if is_composite_type env ty then begin
- let id' = Env.fresh_ident id.name in
- let ty' = TPtr(add_attributes_type [AConst] ty, []) in
- let (params', decls, init) = transf_prm params in
- ((id', ty') :: params',
- (Storage_default, id, ty, None) :: decls,
- sseq loc
- (sassign loc {edesc = EVar id; etyp = ty}
- {edesc = EUnop(Oderef, {edesc = EVar id'; etyp = ty'});
- etyp = ty})
- init)
- end else begin
- let (params', decls, init) = transf_prm params in
- ((id, ty) :: params', decls, init)
- end
- in transf_prm params
-
-let transf_fundef env f =
- reset_temps();
- let ret = transf_type env f.fd_ret in
- let (params, newdecls, init) = transf_params f.fd_body.sloc env f.fd_params in
- let (ret1, params1, body1) =
- if is_composite_type env ret then begin
- let vres = Env.fresh_ident "_res" in
- let tres = TPtr(ret, []) in
- let eres = {edesc = EVar vres; etyp = tres} in
- let eeres = {edesc = EUnop(Oderef, eres); etyp = ret} in
- (TVoid [],
- (vres, tres) :: params,
- transf_funbody env f.fd_body (Some eeres))
- end else
- (ret, params, transf_funbody env f.fd_body None) in
- let body2 = sseq body1.sloc init body1 in
- let temps = get_temps() in
- {f with fd_ret = ret1; fd_params = params1;
- fd_locals = newdecls @ f.fd_locals @ temps; fd_body = body2}
-
-(* Composites *)
-
-let transf_composite env su id attr fl =
- (attr, List.map (fun f -> {f with fld_typ = transf_type env f.fld_typ}) fl)
-
-(* Entry point *)
-
-let program p =
- Transform.program
- ~decl:transf_decl
- ~fundef:transf_fundef
- ~composite:transf_composite
- ~typedef:(fun env id ty -> transf_type env ty)
- p