Skip to content

Commit d7e778b

Browse files
authored
Merge pull request #249 from ppedrot/even-leaner-symbol-table
More compact representation of compiled programs
2 parents 965f44f + f6e85a7 commit d7e778b

File tree

1 file changed

+41
-40
lines changed

1 file changed

+41
-40
lines changed

src/compiler.ml

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -105,27 +105,37 @@ type table = {
105105
uuid : Util.UUID.t;
106106
} [@@deriving show]
107107

108-
type pruned_table = {
109-
c2s0 : string D.Constants.Map.t;
110-
c2t0 : D.term D.Constants.Map.t;
111-
} [@@deriving show]
108+
type entry =
109+
| GlobalSymbol of D.constant * string
110+
| BoundVariable of D.constant * D.term
111+
[@@deriving show]
112+
113+
type pruned_table = entry array [@@deriving show]
112114

113115
let locked { locked } = locked
114116
let lock t = { t with locked = true }
115117
let uuid { uuid } = uuid
116118
let equal t1 t2 =
117119
locked t1 && locked t2 && uuid t1 = uuid t2
118120

119-
let size t = D.Constants.Map.cardinal t.c2t0
121+
let size t = Array.length t
120122

121-
let symbols { c2s0 } =
122-
List.map (fun (c,s) -> s ^ ":" ^ string_of_int c) (D.Constants.Map.bindings c2s0)
123+
let symbols table =
124+
let map = function
125+
| GlobalSymbol (c, s) -> Some (s ^ ":" ^ string_of_int c)
126+
| BoundVariable _ -> None
127+
in
128+
List.rev @@ List.filter_map map @@ Array.to_list table
123129

124130
let prune t ~alive =
125-
{
126-
c2s0 = D.Constants.Map.filter (fun k _ -> D.Constants.Set.mem k alive) t.c2s;
127-
c2t0 = D.Constants.Map.filter (fun k _ -> D.Constants.Set.mem k alive) t.c2t;
128-
}
131+
let c2s = t.c2s in
132+
let c2t0 = D.Constants.Map.filter (fun k _ -> D.Constants.Set.mem k alive) t.c2t in
133+
let map k t =
134+
if k < 0 then GlobalSymbol (k, D.Constants.Map.find k c2s)
135+
else BoundVariable (k, t)
136+
in
137+
let c2t0 = D.Constants.Map.mapi map c2t0 in
138+
Array.of_list @@ List.rev_map snd @@ D.Constants.Map.bindings c2t0
129139

130140
let table = D.State.declare
131141
~descriptor:D.elpi_state_descriptor
@@ -247,10 +257,10 @@ let build_shift ?(lock_base=false) ~flags:{ print_units } ~base symbols =
247257
(* We try hard to respect the same order if possible, since some tests
248258
(grundlagen) depend on this order (for performance, the constant-timestamp
249259
heuristic in unfolding) *)
250-
List.fold_left (fun (base,shift as acc) (v, t) ->
251-
if v < 0 then
252-
let name = Map.find v symbols.c2s0 in
253-
try
260+
Array.fold_left (fun (base,shift as acc) e ->
261+
match e with
262+
| GlobalSymbol (v, name) ->
263+
begin try
254264
let c, _ = F.Map.find (F.from_string name) base.ast2ct in
255265
if c == v then acc
256266
else begin
@@ -262,13 +272,14 @@ let build_shift ?(lock_base=false) ~flags:{ print_units } ~base symbols =
262272
| Not_found ->
263273
let base, (c,_) = allocate_global_symbol_aux (Ast.Func.from_string name) base in
264274
base, Map.add v c shift
265-
else
275+
end
276+
| BoundVariable (v, t) ->
266277
if Map.mem v base.c2t then acc
267278
else
268279
let base = { base with c2t = Map.add v t base.c2t } in
269280
base, shift
270281
)
271-
(base,Map.empty) (List.rev (Map.bindings symbols.c2t0)))
282+
(base, Map.empty) symbols)
272283

273284
let build_shift ?lock_base ~flags ~base symbols =
274285
try Stdlib.Result.Ok (build_shift ?lock_base ~flags ~base symbols)
@@ -533,9 +544,6 @@ type program = {
533544
clauses : (preterm,Ast.Structured.attribute) Ast.Clause.t list;
534545
chr : (constant list * prechr_rule list) list;
535546
local_names : int;
536-
symbols : C.Set.t;
537-
538-
toplevel_macros : macro_declaration;
539547
}
540548
[@@deriving show]
541549

@@ -579,7 +587,7 @@ type compilation_unit = {
579587

580588
type builtins = string * Data.BuiltInPredicate.declaration list
581589

582-
type header = State.t * compilation_unit
590+
type header = State.t * compilation_unit * macro_declaration
583591
type program = State.t * Assembled.program
584592

585593

@@ -1497,7 +1505,7 @@ module Flatten : sig
14971505

14981506
(* Eliminating the structure (name spaces) *)
14991507

1500-
val run : State.t -> Structured.program -> Flat.program
1508+
val run : State.t -> Structured.program -> C.Set.t * macro_declaration * Flat.program
15011509

15021510
val relocate : State.t -> D.constant D.Constants.Map.t -> Flat.program -> Flat.program
15031511
val relocate_term : State.t -> D.constant D.Constants.Map.t -> term -> term
@@ -1696,14 +1704,12 @@ let subst_amap state f { nargs; c2i; i2n; n2t; n2i } =
16961704
let modes = apply_subst_modes ~live_symbols empty_subst modes in
16971705
let types, type_abbrevs, modes, clauses, chr =
16981706
compile_body live_symbols state local_names types type_abbrevs modes [] [] empty_subst body in
1699-
{ Flat.types;
1707+
!live_symbols, toplevel_macros, { Flat.types;
17001708
type_abbrevs;
17011709
modes;
17021710
clauses;
17031711
chr = List.rev chr;
17041712
local_names;
1705-
toplevel_macros;
1706-
symbols = !live_symbols
17071713
}
17081714
let relocate_term state s t =
17091715
let ksub = apply_subst_constant ([],s) in
@@ -1716,8 +1722,6 @@ let subst_amap state f { nargs; c2i; i2n; n2t; n2i } =
17161722
clauses;
17171723
chr;
17181724
local_names;
1719-
toplevel_macros;
1720-
symbols;
17211725
} =
17221726
let f = [], f in
17231727
{
@@ -1727,8 +1731,6 @@ let subst_amap state f { nargs; c2i; i2n; n2t; n2i } =
17271731
clauses = apply_subst_clauses state f clauses;
17281732
chr = smart_map (apply_subst_chr state f) chr;
17291733
local_names;
1730-
toplevel_macros;
1731-
symbols;
17321734
}
17331735

17341736

@@ -2073,7 +2075,7 @@ let assemble flags state code (ul : compilation_unit list) =
20732075

20742076
let state, clauses_rev, types, type_abbrevs, modes, chr_rev =
20752077
List.fold_left (fun (state, cl1, t1, ta1, m1, c1) ({ symbol_table; code } as _u) ->
2076-
let state, { Flat.clauses = cl2; types = t2; type_abbrevs = ta2; modes = m2; chr = c2; toplevel_macros = _ } =
2078+
let state, { Flat.clauses = cl2; types = t2; type_abbrevs = ta2; modes = m2; chr = c2; } =
20772079
let state, shift = Stdlib.Result.get_ok @@ Symbols.build_shift ~flags ~base:state symbol_table in
20782080
let code =
20792081
if C.Map.is_empty shift then code
@@ -2146,7 +2148,7 @@ let unit_or_header_of_ast { print_passes } s ?(toplevel_macros=F.Map.empty) p =
21462148
Format.eprintf "== Structured ================@\n@[<v 0>%a@]@\n"
21472149
(w_symbol_table s Structured.pp_program) p;
21482150

2149-
let p = Flatten.run s p in
2151+
let alive, toplevel_macros, p = Flatten.run s p in
21502152

21512153
if print_passes then
21522154
Format.eprintf "== Flat ================@\n@[<v 0>%a@]@\n"
@@ -2155,8 +2157,8 @@ let unit_or_header_of_ast { print_passes } s ?(toplevel_macros=F.Map.empty) p =
21552157
s, {
21562158
version = "%%VERSION_NUM%%";
21572159
code = p;
2158-
symbol_table = Symbols.prune (State.get Symbols.table s) ~alive:p.Flat.symbols
2159-
}
2160+
symbol_table = Symbols.prune (State.get Symbols.table s) ~alive
2161+
}, toplevel_macros
21602162
;;
21612163

21622164
let print_unit { print_units } x =
@@ -2199,25 +2201,24 @@ let header_of_ast ~flags ~parser:p state_descriptor quotation_descriptor hoas_de
21992201
| Data.BuiltInPredicate.MLDataC _ -> state
22002202
| Data.BuiltInPredicate.LPCode _ -> state
22012203
| Data.BuiltInPredicate.LPDoc _ -> state) state decls) state builtins in
2202-
let state, u = unit_or_header_of_ast flags state ast in
2204+
let state, u, toplevel_macros = unit_or_header_of_ast flags state ast in
22032205
print_unit flags u;
2204-
state, u
2206+
state, u, toplevel_macros
22052207

2206-
let unit_of_ast ~flags ~header:(s, (header : compilation_unit)) p : compilation_unit =
2207-
let toplevel_macros = header.code.Flat.toplevel_macros in
2208-
let _, u = unit_or_header_of_ast flags s ~toplevel_macros p in
2208+
let unit_of_ast ~flags ~header:(s, (header : compilation_unit), toplevel_macros) p : compilation_unit =
2209+
let _, u, _ = unit_or_header_of_ast flags s ~toplevel_macros p in
22092210
print_unit flags u;
22102211
u
22112212

2212-
let assemble_units ~flags ~header:(s,h) units : program =
2213+
let assemble_units ~flags ~header:(s,h,toplevel_macros) units : program =
22132214

22142215
let nunits_with_locals =
22152216
(h :: units) |> List.filter (fun {code = { Flat.local_names = x }} -> x > 0) |> List.length in
22162217

22172218
if nunits_with_locals > 0 then
22182219
error "Only 1 compilation unit is supported when local directives are used";
22192220

2220-
let init = { Assembled.empty with toplevel_macros = h.code.toplevel_macros; local_names = h.code.local_names } in
2221+
let init = { Assembled.empty with toplevel_macros; local_names = h.code.local_names } in
22212222

22222223
let s, p = Assemble.assemble flags s init (h :: units) in
22232224

0 commit comments

Comments
 (0)