|
|
|
(*
|
|
|
|
* 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.
|
|
|
|
*)
|
|
|
|
|
|
|
|
(** Used-globals abstract domain *)
|
|
|
|
|
|
|
|
type t = Llair.Global.Set.t [@@deriving compare, equal, sexp]
|
|
|
|
|
|
|
|
let pp = Llair.Global.Set.pp
|
|
|
|
let empty = Llair.Global.Set.empty
|
|
|
|
|
|
|
|
let init globals =
|
|
|
|
[%Trace.info
|
|
|
|
" globals: {%a}" (IArray.pp ", " Llair.GlobalDefn.pp) globals] ;
|
|
|
|
empty
|
|
|
|
|
|
|
|
let join l r = Llair.Global.Set.union l r
|
|
|
|
let recursion_beyond_bound = `skip
|
|
|
|
let post _ _ state = state
|
|
|
|
let retn _ _ from_call post = Llair.Global.Set.union from_call post
|
|
|
|
let dnf t = [t]
|
|
|
|
|
|
|
|
let used_globals exp s =
|
|
|
|
Llair.Exp.fold_exps exp s ~f:(fun e s ->
|
|
|
|
match Llair.Global.of_exp e with
|
|
|
|
| Some g -> Llair.Global.Set.add g s
|
|
|
|
| None -> s )
|
|
|
|
|
|
|
|
let exec_assume st exp = Some (used_globals exp st)
|
|
|
|
let exec_kill _ st = st
|
|
|
|
|
|
|
|
let exec_move reg_exps st =
|
|
|
|
IArray.fold ~f:(fun (_, rhs) -> used_globals rhs) reg_exps st
|
|
|
|
|
|
|
|
let exec_inst inst st =
|
|
|
|
[%Trace.call fun {pf} -> pf "@ pre:{%a} %a" pp st Llair.Inst.pp inst]
|
|
|
|
;
|
|
|
|
Ok (Llair.Inst.fold_exps ~f:used_globals inst st)
|
|
|
|
|>
|
|
|
|
[%Trace.retn fun {pf} ->
|
|
|
|
Or_alarm.iter ~f:(fun uses -> pf "post:{%a}" pp uses)]
|
|
|
|
|
|
|
|
type from_call = t [@@deriving sexp]
|
|
|
|
|
|
|
|
(* Set abstract state to bottom (i.e. empty set) at function entry *)
|
|
|
|
let call ~summaries:_ ~globals:_ ~actuals ~areturn:_ ~formals:_ ~freturn:_
|
|
|
|
~locals:_ st =
|
[sledge] Represent function formal parameters and actual arguments in order
Summary:
Previously, when LLAIR was in SSA form, blocks took parameters just
like functions, and it was sometimes necessary to partially apply a
block to some of the parameters. For example, blocks to which function
calls return would need to accept the return value as an argument, and
sometimes immediately jump to another block passing the rest of the
arguments as well. These "trampoline" blocks were partial applications
of the eventual block to all but the final, return value,
argument.
This partial application mechanism meant that function parameters and
arguments were represented as a stack, with the first argument at the
bottom, that is, in reverse order.
Now that LLAIR is free of SSA, this confusion is no longer needed, and
this diff changes the representation of function formal parameters and
actual arguments to be in the natural order. This also brings Call
instructions in line with Intrinsic instructions, which will make
changing the handling of intrinsics from Calls to Intrinsic less
error-prone.
Reviewed By: jvillard
Differential Revision: D25146163
fbshipit-source-id: d3ed07a45
4 years ago
|
|
|
(empty, IArray.fold ~f:used_globals actuals st)
|
|
|
|
|
|
|
|
let resolve_callee _ _ _ = []
|
|
|
|
|
|
|
|
(* A function summary is the set of global registers accessed by that
|
|
|
|
function and its transitive callees *)
|
|
|
|
type summary = t
|
|
|
|
|
|
|
|
let pp_summary = pp
|
|
|
|
let create_summary ~locals:_ ~formals:_ state = (state, state)
|
|
|
|
let apply_summary st summ = Some (Llair.Global.Set.union st summ)
|
|
|
|
|
|
|
|
(** Query *)
|
|
|
|
|
|
|
|
type used_globals =
|
|
|
|
| Per_function of summary Llair.Function.Map.t
|
|
|
|
| Declared of summary
|
|
|
|
|
|
|
|
let by_function : used_globals -> Llair.Function.t -> t =
|
|
|
|
fun s fn ->
|
|
|
|
[%Trace.call fun {pf} -> pf "@ %a" Llair.Function.pp fn]
|
|
|
|
;
|
|
|
|
( match s with
|
|
|
|
| Declared set -> set
|
|
|
|
| Per_function map -> (
|
|
|
|
match Llair.Function.Map.find fn map with
|
|
|
|
| Some gs -> gs
|
|
|
|
| None ->
|
|
|
|
fail
|
|
|
|
"main analysis reached function %a that was not reached by \
|
|
|
|
used-globals pre-analysis "
|
|
|
|
Llair.Function.pp fn () ) )
|
|
|
|
|>
|
|
|
|
[%Trace.retn fun {pf} r -> pf "%a" Llair.Global.Set.pp r]
|