@@ -901,12 +901,10 @@ struct
901901
902902 let find_first_after e set =
903903 find_first_opt (fun e' -> is_before_strict e e') set
904- [ @@ warning " -32 " ]
904+
905905end
906906
907- let map_loc_find loc m =
908- try U.LocEnv. find loc m
909- with Not_found -> []
907+ let map_loc_find loc m = U.LocEnv. safe_find [] loc m
910908
911909let match_reg_events add_eq es csn =
912910 let loc_loads_stores = U. collect_reg_loads_stores es in
@@ -1827,40 +1825,74 @@ let get_rf_value test read =
18271825 | _ ,_ -> k)
18281826 rfm E.EventRel. empty
18291827
1830- (* Reconstruct load/store atomic pairs *)
1828+ (*
1829+ * Reconstruct load/store atomic pairs,
1830+ * By definition such a pair exists when the
1831+ * store precedes the load in generalised program order
1832+ * (_i.e._ the union of program order and of iico), and
1833+ * that there is no atomic effect to the same location
1834+ * in-between (w.r.t generalised po) the load and the store.
1835+ * Computation proceeds as follows:
1836+ * First, atomic events are grouped first by thread
1837+ * and then by location. Then, to each atomic load, we
1838+ * associate the closest generalised po successor store,
1839+ * by using a set of stores ordered by generalised po.
1840+ * We additionally check that no atomic load exists
1841+ * between the load and store. Notice that it is not possible
1842+ * to use a set of all atomic events (by a given thread and
1843+ * with a given location) ordered by po because some atomic loads
1844+ * may be unrelated.
1845+ * Finally, such atomic pairs can be spurious, that is not performed
1846+ * by a specific thread. In that case, pairs are given
1847+ * simply by the intra causality data relation.
1848+ *)
18311849
18321850 let make_atomic_load_store es =
1833- let all = E. atomics_of es.E. events in
1834- let atms = U. collect_atomics es in
1835- U.LocEnv. fold
1836- (fun _loc atms k ->
1837- let atms =
1838- List. filter
1839- (fun e -> not (E. is_load e && E. is_store e))
1840- atms in (* get rid of C RMW *)
1841- let rs,ws = List. partition E. is_load atms in
1842- List. fold_left
1843- (fun k r ->
1844- let exp = E. is_explicit r in
1845- List. fold_left
1846- (fun k w ->
1847- if
1848- S. atomic_pair_allowed r w &&
1849- U. is_before_strict es r w &&
1850- E. is_explicit w = exp &&
1851- not
1852- (E.EventSet. exists
1853- (fun e ->
1854- E. is_explicit e = exp &&
1855- U. is_before_strict es r e &&
1856- U. is_before_strict es e w)
1857- all)
1858- then E.EventRel. add (r,w) k
1859- else k)
1860- k ws)
1861- k rs)
1862- atms E.EventRel. empty
1863-
1851+ let atms,spurious = U. collect_atomics es in
1852+ let module StoreSet = EvtSetByPo (struct let es = es end ) in
1853+ let make_atomic_pairs es k =
1854+ let rs,ws = List. partition E. is_load es in
1855+ let ws = StoreSet. of_list ws
1856+ and intervening_read er ew =
1857+ List. exists
1858+ (fun e ->
1859+ StoreSet. is_before_strict er e
1860+ && StoreSet. is_before_strict e ew)
1861+ rs in
1862+ List. fold_left
1863+ (fun k er ->
1864+ match StoreSet. find_first_after er ws with
1865+ | Some ew ->
1866+ if
1867+ S. atomic_pair_allowed er ew
1868+ && not (intervening_read er ew)
1869+ then
1870+ E.EventRel. add (er,ew) k
1871+ else k
1872+ | None -> k)
1873+ k rs in
1874+ let r1 =
1875+ List. map
1876+ (fun (_ ,m ) ->
1877+ U.LocEnv. fold
1878+ (fun _loc es k ->
1879+ let exps,nexps = List. partition E. is_explicit es in
1880+ make_atomic_pairs exps @@ make_atomic_pairs nexps k)
1881+ m E.EventRel. empty)
1882+ atms |> E.EventRel. unions
1883+ and r2 =
1884+ let iico = es.E. intra_causality_data in
1885+ List. map
1886+ (fun e ->
1887+ if E. is_load e then
1888+ match
1889+ E.EventRel. succs iico e |> E.EventSet. as_singleton
1890+ with
1891+ | None -> assert false (* spurious updates are by pairs *)
1892+ | Some w -> E.EventRel. singleton (e,w)
1893+ else E.EventRel. empty)
1894+ spurious |> E.EventRel. unions in
1895+ E.EventRel. union r1 r2
18641896
18651897(* Retrieve last store from rfmap *)
18661898 let get_max_store _test _es rfm loc =
@@ -1955,12 +1987,9 @@ let get_rf_value test read =
19551987 if C. debug.Debug_herd. mem then begin
19561988 eprintf " Observed locs: {%s}\n " (pp_locations observed_locs)
19571989 end ;
1958- U.LocEnv. fold
1959- (fun loc ws k ->
1960- if keep_observed_loc loc observed_locs then
1961- U.LocEnv. add loc ws k
1962- else k)
1963- loc_stores U.LocEnv. empty
1990+ U.LocEnv. filter
1991+ (fun loc _ -> keep_observed_loc loc observed_locs)
1992+ loc_stores
19641993 else loc_stores in
19651994
19661995 let possible_finals =
0 commit comments