Skip to content

Commit 9f1336c

Browse files
committed
Implement Promise-First optimization
1 parent dfe8ec8 commit 9f1336c

File tree

5 files changed

+372
-181
lines changed

5 files changed

+372
-181
lines changed

ArchSem/GenPromising.v

Lines changed: 102 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Require Import ASCommon.Common.
5353
Require Import ASCommon.Exec.
5454
Require Import ASCommon.Effects.
5555
Require Import ASCommon.FMon.
56+
Require Import ASCommon.HVec.
5657
Require Import ASCommon.StateT.
5758

5859
Require Import Relations.
@@ -182,27 +183,38 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
182183
it generic *)
183184
Structure BasicExecutablePM := {
184185
pModel :> PromisingModel;
185-
(** try to compute ALL allowed promises, if that is not possible (not
186-
enough fuel) then fail with error message.
187186

188-
Soundness and completeness proofs are required to show that when not
189-
failing, promise_select effectively computes the allowed_promises
190-
set.*)
191-
promise_select :
187+
enumerate_promises_and_terminal_states :
192188
(* fuel *) nat → (* tid *) nat →
193189
(* termination condition *) (registerMap → bool) →
194190
memoryMap → pModel.(tState) → PromMemory.t pModel.(mEvent) →
195-
Exec.res string pModel.(mEvent);
191+
result string (list pModel.(mEvent) * list pModel.(tState));
196192

197193
promise_select_sound :
198-
∀ fuel tid term initMem ts mem,
199-
∀ ev ∈ (promise_select fuel tid term initMem ts mem),
200-
ev ∈ pModel.(allowed_promises) tid initMem ts mem;
194+
∀ fuel tid term initMem ts mem promises tstates,
195+
Ok (promises, tstates) =
196+
enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
197+
∀ ev ∈ promises, ev ∈ pModel.(allowed_promises) tid initMem ts mem;
198+
201199
promise_select_complete :
202-
∀ fuel tid term initMem ts mem,
203-
¬ Exec.has_error (promise_select fuel tid term initMem ts mem) →
204-
∀ ev ∈ pModel.(allowed_promises) tid initMem ts mem,
205-
ev ∈ promise_select fuel tid term initMem ts mem
200+
∀ fuel tid term initMem ts mem promises tstates,
201+
Ok (promises, tstates) =
202+
enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
203+
∀ ev ∈ pModel.(allowed_promises) tid initMem ts mem, ev ∈ promises;
204+
205+
terminal_state_no_outstanding_promise :
206+
∀ fuel tid term initMem ts mem promises tstates,
207+
Ok (promises, tstates) =
208+
enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
209+
∀ tts ∈ tstates, pModel.(tState_nopromises) tts;
210+
211+
terminal_state_is_terminated :
212+
∀ fuel tid term initMem ts mem promises tstates,
213+
Ok (promises, tstates) =
214+
enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
215+
∀ tts ∈ tstates, term (pModel.(tState_regs) tts);
216+
217+
(* TODO: add terminal_state_is_reachable *)
206218
}.
207219
Arguments BasicExecutablePM : clear implicits.
208220

@@ -340,10 +352,24 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
340352
Local Notation mEvent := (mEvent prom).
341353
Local Notation t := (t tState mEvent n).
342354

355+
(** The type of final promising state return by run *)
356+
Definition final := { x : t | terminated prom term x }.
357+
358+
Definition make_final (p : t) := exist (terminated prom term) p.
359+
360+
(** Convert a final promising state to a generic final state *)
361+
Program Definition to_final_archState (f : final) :
362+
{s & archState.is_terminated term s} :=
363+
existT (to_archState prom f) _.
364+
Solve All Obligations with
365+
hauto unfold:terminated unfold:archState.is_terminated l:on db:vec, brefl.
366+
343367
(** Get a list of possible promises for a thread by tid *)
344368
Definition promise_select_tid (fuel : nat) (st : t)
345369
(tid : fin n) : Exec.res string mEvent :=
346-
prom.(promise_select) fuel tid (term tid) (initmem st) (tstate tid st) (events st).
370+
'(promises, _) ← mlift $ prom.(enumerate_promises_and_terminal_states)
371+
fuel tid (term tid) (initmem st) (tstate tid st) (events st);
372+
mchoosel promises.
347373

348374
(** Take any promising step for that tid and promise it *)
349375
Definition cpromise_tid (fuel : nat) (tid : fin n)
@@ -367,19 +393,6 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
367393
promise ← mchoosel (enum bool);
368394
if (promise : bool) then cpromise_tid fuel tid else run_tid isem prom tid.
369395

370-
(** The type of final promising state return by run *)
371-
Definition final := { x : t | terminated prom term x }.
372-
373-
Definition make_final (p : t) := exist (terminated prom term) p.
374-
375-
376-
(** Convert a final promising state to a generic final state *)
377-
Program Definition to_final_archState (f : final) :
378-
{s & archState.is_terminated term s} :=
379-
existT (to_archState prom f) _.
380-
Solve All Obligations with
381-
hauto unfold:terminated unfold:archState.is_terminated l:on db:vec, brefl.
382-
383396
(** Computational evaluate all the possible allowed final states according
384397
to the promising model prom starting from st *)
385398
Fixpoint run (fuel : nat) : Exec.t t string final :=
@@ -390,19 +403,79 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
390403
run_step (S fuel);;
391404
run fuel
392405
else mthrow "Could not finish running within the size of the fuel".
406+
407+
(** Explore all possible promise-based executions across all threads. *)
408+
Fixpoint prune_promises_and_states (fuel_per_tid fuel : nat)
409+
(finals : list final) : Exec.t t string (list final) :=
410+
if fuel is S fuel then
411+
st ← mGet;
412+
(* Find out next possible promises or terminating states at the current thread *)
413+
executions ←
414+
for (tid : fin n) in enum (fin n) do
415+
'(promises_per_tid, tstates_per_tid) ←
416+
mlift $ prom.(enumerate_promises_and_terminal_states)
417+
fuel_per_tid tid (term tid) (initmem st) (tstate tid st) (events st);
418+
mret (map (λ ev, (ev, tid)) promises_per_tid, tstates_per_tid)
419+
end;
420+
421+
(* Compute cartesian products of the possible thread states *)
422+
let tstates_sys :=
423+
fold_left (λ partial_sts tstates_tid,
424+
List.flat_map (λ tstate,
425+
if is_emptyb partial_sts then [[tstate]]
426+
else map (λ partial_st, partial_st ++ [tstate]) partial_sts
427+
) tstates_tid
428+
) (map snd executions) [] in
429+
let new_finals :=
430+
omap (λ tstates,
431+
if (list_to_vec_n n tstates) is Some tstates_vec then
432+
let st := Make tstates_vec st.(PState.initmem) st.(PState.events) in
433+
if decide $ terminated prom term st is left pt
434+
then Some (make_final st pt)
435+
else None
436+
else None
437+
) tstates_sys in
438+
439+
(* Non-deterministically choose the next promise and the tid for pruning *)
440+
let promises_all := List.concat (map fst executions) in
441+
if is_emptyb promises_all then
442+
mret (new_finals ++ finals)
443+
else
444+
'(next_ev, tid) ← mchoosel promises_all;
445+
mSet (λ st, promise_tid prom st tid next_ev);;
446+
prune_promises_and_states fuel_per_tid fuel (new_finals ++ finals)
447+
else mret finals.
448+
449+
(** Computational evaluate all the possible allowed final states according
450+
to the promising model prom starting from st
451+
with promise-first optimization *)
452+
Definition run_promise_first (fuel : nat) : Exec.t t string final :=
453+
finals ← prune_promises_and_states fuel fuel [];
454+
mchoosel finals.
455+
393456
End CPS.
394457
Arguments to_final_archState {_ _ _}.
395458
End CPState.
396459

397460
(** Create a computational model from an ISA model and promising model *)
398461
Definition Promising_to_Modelc (isem : iMon ()) (prom : BasicExecutablePM)
399462
(fuel : nat) : archModel.c ∅ :=
400-
fun n term (initMs : archState n) =>
463+
λ n term (initMs : archState n),
401464
PState.from_archState prom initMs |>
402465
archModel.Res.from_exec
403466
$ CPState.to_final_archState
404467
<$> CPState.run isem prom term fuel.
405468

469+
(** Create a computational model from an ISA model and promising model
470+
with promise-free optimization *)
471+
Definition Promising_to_Modelc_pf (isem : iMon ()) (prom : BasicExecutablePM)
472+
(fuel : nat) : archModel.c ∅ :=
473+
λ n term (initMs : archState n),
474+
PState.from_archState prom initMs |>
475+
archModel.Res.from_exec
476+
$ CPState.to_final_archState
477+
<$> CPState.run_promise_first prom term fuel.
478+
406479
(* TODO state some soundness lemma between Promising_to_Modelnc and
407480
Promising_Modelc *)
408481

0 commit comments

Comments
 (0)