[m-rev.] For review: Include the name of futures in ThreadScope profiles.

Paul Bone pbone at csse.unimelb.edu.au
Mon May 30 14:36:06 AEST 2011


For review by anyone.  In particular, I'm not sure that my changes to
global_data.m and mercury_compile_llds_back_end.m are the correct way of
passing global data from the HLDS to LLDS stages.

Thanks.

---

Include the name of futures in ThreadScope profiles.

runtime/mercury_threadscope.h:
runtime/mercury_threadscope.c:
    Add a second parameter for the NEW_FUTURE event. The parameter is the id of
    the string that holds the future's name.

runtime/mercury_par_builtin.h:
    In threadscope grades use a two-args version of the new_future macro.

library/par_builtin.m:
    Conform to changes in mercury_par_builtin.h, new_future now takes two
    arguments.

compiler/dep_par_conj.m:
    Create a name variable for each future and pass it as a second parameter to
    calls to new_future.

    Thread a threadscope string table throughout this transformation so that
    strings for variables can be collected.

compiler/hlds_module.m:
    Add a threadscope string table to the module_info structure.

compiler/global_data.m:
    global_data_init now takes the threadscope string table and its size as
    parameters.  This is necessary because the table may be non-empty before
    the LLDS transformation begins.

compiler/mercury_compile_llds_back_end.m:
    Conform to changes in global_data.m

mdbcomp/program_representation.m:
    Disable the polymorphism transformation for new_future/2.

Index: compiler/dep_par_conj.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dep_par_conj.m,v
retrieving revision 1.53
diff -u -p -b -r1.53 dep_par_conj.m
--- compiler/dep_par_conj.m	23 May 2011 05:08:01 -0000	1.53
+++ compiler/dep_par_conj.m	30 May 2011 04:29:49 -0000
@@ -180,8 +180,10 @@ impl_dep_par_conjs_in_module(!ModuleInfo
     % Phase one: insert synchronization code into all parallel conjunctions
     % in the module.
     module_info_get_valid_predids(PredIds, !ModuleInfo),
-    list.foldl2(maybe_sync_dep_par_conjs_in_pred, PredIds,
-        !ModuleInfo, [], ProcsToScan),
+    module_info_get_ts_rev_string_table(!.ModuleInfo, _, RevTable0),
+    make_ts_string_table(RevTable0, TSStringTable0),
+    list.foldl3(maybe_sync_dep_par_conjs_in_pred, PredIds,
+        !ModuleInfo, [], ProcsToScan, TSStringTable0, TSStringTable1),
 
     % Phase two: attempt to push the synchronization code inside procedures
     % as far as we can. We do this by creating specialized versions of
@@ -198,7 +200,10 @@ impl_dep_par_conjs_in_module(!ModuleInfo
         ProcsToScan, !ModuleInfo, PendingParProcs0, PendingParProcs,
         Pushability0, Pushability, RevProcMap0, RevProcMap),
     add_requested_specialized_par_procs(PendingParProcs, Pushability,
-        DoneParProcs0, InitialModuleInfo, !ModuleInfo, RevProcMap, _).
+        DoneParProcs0, InitialModuleInfo, !ModuleInfo, RevProcMap, _,
+        TSStringTable1, TSStringTable),
+    module_info_set_ts_rev_string_table(TSStringTable ^ st_size,
+        TSStringTable ^ st_rev_table, !ModuleInfo).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -230,24 +235,31 @@ impl_dep_par_conjs_in_module(!ModuleInfo
                 sync_vartypes               :: vartypes,
 
                 % The current procedure.
-                sync_this_proc              :: pred_proc_id
+                sync_this_proc              :: pred_proc_id,
+
+                % The current threadscope string table.
+                sync_ts_string_table        :: ts_string_table
             ).
 
 :- pred maybe_sync_dep_par_conjs_in_pred(pred_id::in,
     module_info::in, module_info::out,
-    list(pred_proc_id)::in, list(pred_proc_id)::out) is det.
+    list(pred_proc_id)::in, list(pred_proc_id)::out,
+    ts_string_table::in, ts_string_table::out) is det.
 
-maybe_sync_dep_par_conjs_in_pred(PredId, !ModuleInfo, !ProcsToScan) :-
+maybe_sync_dep_par_conjs_in_pred(PredId, !ModuleInfo, !ProcsToScan,
+        !TSStringTable) :-
     module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
     ProcIds = pred_info_non_imported_procids(PredInfo),
-    list.foldl2(maybe_sync_dep_par_conjs_in_proc(PredId), ProcIds,
-        !ModuleInfo, !ProcsToScan).
+    list.foldl3(maybe_sync_dep_par_conjs_in_proc(PredId), ProcIds,
+        !ModuleInfo, !ProcsToScan, !TSStringTable).
 
 :- pred maybe_sync_dep_par_conjs_in_proc(pred_id::in, proc_id::in,
     module_info::in, module_info::out,
-    list(pred_proc_id)::in, list(pred_proc_id)::out) is det.
+    list(pred_proc_id)::in, list(pred_proc_id)::out,
+    ts_string_table::in, ts_string_table::out) is det.
 
-maybe_sync_dep_par_conjs_in_proc(PredId, ProcId, !ModuleInfo, !ProcsToScan) :-
+maybe_sync_dep_par_conjs_in_proc(PredId, ProcId, !ModuleInfo, !ProcsToScan,
+        !TSStringTable) :-
     module_info_proc_info(!.ModuleInfo, PredId, ProcId, ProcInfo),
     proc_info_get_has_parallel_conj(ProcInfo, HasParallelConj),
     (
@@ -255,15 +267,16 @@ maybe_sync_dep_par_conjs_in_proc(PredId,
     ;
         HasParallelConj = yes,
         sync_dep_par_conjs_in_proc(PredId, ProcId, set.init,
-            !ModuleInfo, !ProcsToScan)
+            !ModuleInfo, !ProcsToScan, !TSStringTable)
     ).
 
 :- pred sync_dep_par_conjs_in_proc(pred_id::in, proc_id::in, set(prog_var)::in,
     module_info::in, module_info::out,
-    list(pred_proc_id)::in, list(pred_proc_id)::out) is det.
+    list(pred_proc_id)::in, list(pred_proc_id)::out,
+    ts_string_table::in, ts_string_table::out) is det.
 
 sync_dep_par_conjs_in_proc(PredId, ProcId, IgnoreVars, !ModuleInfo,
-        !ProcsToScan) :-
+        !ProcsToScan, !TSStringTable) :-
     some [!PredInfo, !ProcInfo, !Goal, !VarSet, !VarTypes, !SyncInfo] (
         module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId,
             !:PredInfo, !:ProcInfo),
@@ -282,9 +295,10 @@ sync_dep_par_conjs_in_proc(PredId, ProcI
 
         GoalBeforeDepParConj = !.Goal,
         !:SyncInfo = sync_info(!.ModuleInfo, IgnoreVars, AllowSomePathsOnly,
-            !.VarSet, !.VarTypes, proc(PredId, ProcId)),
+            !.VarSet, !.VarTypes, proc(PredId, ProcId), !.TSStringTable),
         sync_dep_par_conjs_in_goal(!Goal, InstMap0, _, !SyncInfo),
-        !.SyncInfo = sync_info(_, _, _, !:VarSet, !:VarTypes, _),
+        !.SyncInfo = sync_info(_, _, _, !:VarSet, !:VarTypes, _,
+            !:TSStringTable),
         % XXX RTTI varmaps may need to be updated
 
         trace [compile_time(flag("debug-dep-par-conj")), io(!IO)] (
@@ -448,7 +462,7 @@ sync_dep_par_conjs_in_cases([Case0 | Cas
 
 maybe_sync_dep_par_conj(Conjuncts, GoalInfo, NewGoal, InstMap, !SyncInfo) :-
     !.SyncInfo = sync_info(ModuleInfo0, IgnoreVars, AllowSomePathsOnly,
-        VarSet0, VarTypes0, PredProcId),
+        VarSet0, VarTypes0, PredProcId, TSStringTable0),
     % Find the variables that are shared between conjuncts.
     SharedVars0 = find_shared_variables(ModuleInfo0, InstMap, Conjuncts),
 
@@ -463,13 +477,14 @@ maybe_sync_dep_par_conj(Conjuncts, GoalI
         reorder_indep_par_conj(PredProcId, VarTypes0, InstMap, Conjuncts,
             GoalInfo, NewGoal, ModuleInfo0, ModuleInfo),
         !:SyncInfo = sync_info(ModuleInfo, IgnoreVars, AllowSomePathsOnly,
-            VarSet0, VarTypes0, PredProcId)
+            VarSet0, VarTypes0, PredProcId, TSStringTable0)
     ;
         sync_dep_par_conj(ModuleInfo0, AllowSomePathsOnly, SharedVars,
             Conjuncts, GoalInfo, NewGoal, InstMap,
-            VarSet0, VarSet, VarTypes0, VarTypes),
+            VarSet0, VarSet, VarTypes0, VarTypes, TSStringTable0,
+            TSStringTable),
         !:SyncInfo = sync_info(ModuleInfo0, IgnoreVars, AllowSomePathsOnly,
-            VarSet, VarTypes, PredProcId)
+            VarSet, VarTypes, PredProcId, TSStringTable)
     ).
 
     % Transforming the parallel conjunction.
@@ -498,13 +513,16 @@ maybe_sync_dep_par_conj(Conjuncts, GoalI
     %
 :- pred sync_dep_par_conj(module_info::in, bool::in, set(prog_var)::in,
     list(hlds_goal)::in, hlds_goal_info::in, hlds_goal::out, instmap::in,
-    prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
+    prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
+    ts_string_table::in, ts_string_table::out) is det.
 
 sync_dep_par_conj(ModuleInfo, AllowSomePathsOnly, SharedVars, Goals, GoalInfo,
-        NewGoal, InstMap, !VarSet, !VarTypes) :-
+        NewGoal, InstMap, !VarSet, !VarTypes, !TSStringTable) :-
     SharedVarsList = set.to_sorted_list(SharedVars),
-    list.map_foldl3(allocate_future(ModuleInfo), SharedVarsList,
-        AllocateFutures, !VarSet, !VarTypes, map.init, FutureMap),
+    list.map_foldl4(allocate_future(ModuleInfo), SharedVarsList,
+        AllocateFuturesGoals, !VarSet, !VarTypes, map.init, FutureMap,
+        !TSStringTable),
+    list.condense(AllocateFuturesGoals, AllocateFutures),
     list.map_foldl3(
         sync_dep_par_conjunct(ModuleInfo, AllowSomePathsOnly,
             par_conjunct_is_in_conjunction, SharedVars, FutureMap),
@@ -1521,11 +1539,12 @@ find_specialization_requests_in_proc(Don
 
 :- pred add_requested_specialized_par_procs(pending_par_procs::in,
     pushable_args_map::in, done_par_procs::in, module_info::in,
-    module_info::in, module_info::out, rev_proc_map::in, rev_proc_map::out)
-    is det.
+    module_info::in, module_info::out, rev_proc_map::in, rev_proc_map::out,
+    ts_string_table::in, ts_string_table::out) is det.
 
 add_requested_specialized_par_procs(!.PendingParProcs, !.Pushability,
-        !.DoneParProcs, InitialModuleInfo, !ModuleInfo, !RevProcMap) :-
+        !.DoneParProcs, InitialModuleInfo, !ModuleInfo, !RevProcMap,
+        !TSStringTable) :-
     (
         !.PendingParProcs = []
     ;
@@ -1535,20 +1554,22 @@ add_requested_specialized_par_procs(!.Pe
         map.det_insert(CallPattern, NewProc, !DoneParProcs),
         add_requested_specialized_par_proc(CallPattern, NewProc,
             !PendingParProcs, !Pushability, !.DoneParProcs, InitialModuleInfo,
-            !ModuleInfo, !RevProcMap),
+            !ModuleInfo, !RevProcMap, !TSStringTable),
         add_requested_specialized_par_procs(!.PendingParProcs, !.Pushability,
-            !.DoneParProcs, InitialModuleInfo, !ModuleInfo, !RevProcMap)
+            !.DoneParProcs, InitialModuleInfo, !ModuleInfo, !RevProcMap,
+            !TSStringTable)
     ).
 
 :- pred add_requested_specialized_par_proc(par_proc_call_pattern::in,
     new_par_proc::in, pending_par_procs::in, pending_par_procs::out,
     pushable_args_map::in, pushable_args_map::out, done_par_procs::in,
     module_info::in, module_info::in, module_info::out,
-    rev_proc_map::in, rev_proc_map::out) is det.
+    rev_proc_map::in, rev_proc_map::out,
+    ts_string_table::in, ts_string_table::out) is det.
 
 add_requested_specialized_par_proc(CallPattern, NewProc, !PendingParProcs,
         !Pushability, DoneParProcs, InitialModuleInfo, !ModuleInfo,
-        !RevProcMap) :-
+        !RevProcMap, !TSStringTable) :-
     CallPattern = par_proc_call_pattern(OldPredProcId, FutureArgs),
     NewProc = new_par_proc(NewPredProcId, _Name),
     OldPredProcId = proc(OldPredId, OldProcId),
@@ -1614,7 +1635,7 @@ add_requested_specialized_par_proc(CallP
         % placeholder) specialized procedure.
         IgnoreVars = set.from_list(map.keys(FutureMap)),
         sync_dep_par_conjs_in_proc(NewPredId, NewProcId, IgnoreVars,
-            !ModuleInfo, [], _ProcsToScan),
+            !ModuleInfo, [], _ProcsToScan, !TSStringTable),
         find_specialization_requests_in_proc(DoneParProcs, InitialModuleInfo,
             NewPredProcId, !ModuleInfo, !PendingParProcs, !Pushability,
             !RevProcMap)
@@ -1627,8 +1648,9 @@ add_requested_specialized_par_proc(CallP
 map_arg_to_new_future(HeadVars, FutureArg, !FutureMap, !VarSet, !VarTypes) :-
     HeadVar = list.det_index1(HeadVars, FutureArg),
     map.lookup(!.VarTypes, HeadVar, VarType),
-    make_future_var(HeadVar, VarType, !VarSet, !VarTypes, FutureVar,
-        _FutureVarType),
+    varset.lookup_name(!.VarSet, HeadVar, HeadVarName),
+    make_future_var(HeadVarName, VarType, FutureVar, _FutureVarType, !VarSet,
+        !VarTypes),
     map.det_insert(HeadVar, FutureVar, !FutureMap).
 
 :- pred replace_head_vars(module_info::in, future_map::in,
@@ -2990,15 +3012,19 @@ seen_more_signal_2(seen_signal_non_negli
     % to FutureVar to FutureMap, and generate the goal AllocGoal that calls
     % `par_builtin.new_future/1' to allocate FutureVar.
     %
-:- pred allocate_future(module_info::in, prog_var::in, hlds_goal::out,
+:- pred allocate_future(module_info::in, prog_var::in, hlds_goals::out,
     prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
-    future_map::in, future_map::out) is det.
+    future_map::in, future_map::out, ts_string_table::in, ts_string_table::out)
+    is det.
 
-allocate_future(ModuleInfo, SharedVar, AllocGoal, !VarSet, !VarTypes,
-        !FutureMap) :-
+allocate_future(ModuleInfo, SharedVar, Goals, !VarSet, !VarTypes,
+        !FutureMap, !TSStringTable) :-
     map.lookup(!.VarTypes, SharedVar, SharedVarType),
-    make_future_var(SharedVar, SharedVarType, !VarSet, !VarTypes,
-        FutureVar, FutureVarType),
+    varset.lookup_name(!.VarSet, SharedVar, SharedVarName),
+    make_future_var(SharedVarName, SharedVarType, FutureVar, FutureVarType,
+        !VarSet, !VarTypes),
+    make_future_name_var_and_goal(SharedVarName, FutureNameVar, SetNameGoal,
+        !VarSet, !VarTypes, !TSStringTable),
     map.det_insert(SharedVar, FutureVar, !FutureMap),
 
     ModuleName = mercury_par_builtin_module,
@@ -3009,37 +3035,59 @@ allocate_future(ModuleInfo, SharedVar, A
     ShouldInline = should_inline_par_builtin_calls(ModuleInfo),
     (
         ShouldInline = no,
-        ArgVars = [FutureVar],
+        ArgVars = [FutureNameVar, FutureVar],
         generate_simple_call(ModuleName, PredName, pf_predicate,
             only_mode, detism_det, purity_pure, ArgVars, Features,
             InstMapDelta, ModuleInfo, Context, AllocGoal)
     ;
         ShouldInline = yes,
         ForeignAttrs = par_builtin_foreign_proc_attributes(purity_pure, no),
-        Arg1 = foreign_arg(FutureVar, yes("Future" - out_mode),
+        ArgName = foreign_arg(FutureNameVar, yes("Name" - in_mode),
+            builtin_type(builtin_type_int), native_if_possible),
+        ArgFuture = foreign_arg(FutureVar, yes("Future" - out_mode),
             FutureVarType, native_if_possible),
-        Args = [Arg1],
+        Args = [ArgName, ArgFuture],
         ExtraArgs = [],
-        Code = "MR_par_builtin_new_future(Future);",
+        Code = new_future_code,
         generate_foreign_proc(ModuleName, PredName, pf_predicate,
             only_mode, detism_det, purity_pure, ForeignAttrs, Args, ExtraArgs,
             no, Code, Features, InstMapDelta, ModuleInfo, Context, AllocGoal)
-    ).
+    ),
+    Goals = [SetNameGoal, AllocGoal].
 
     % Given a variable SharedVar of type SharedVarType, add a new variable
     % FutureVar of type future(SharedVarType).
     %
-:- pred make_future_var(prog_var::in, mer_type::in,
-    prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
-    prog_var::out, mer_type::out) is det.
+:- pred make_future_var(string::in, mer_type::in,
+    prog_var::out, mer_type::out, prog_varset::in, prog_varset::out,
+    vartypes::in, vartypes::out) is det.
 
-make_future_var(SharedVar, SharedVarType, !VarSet, !VarTypes,
-        FutureVar, FutureVarType) :-
+make_future_var(SharedVarName, SharedVarType, FutureVar, FutureVarType,
+        !VarSet, !VarTypes) :-
     FutureVarType = future_type(SharedVarType),
-    varset.lookup_name(!.VarSet, SharedVar, SharedVarName),
     varset.new_named_var("Future" ++ SharedVarName, FutureVar, !VarSet),
     map.det_insert(FutureVar, FutureVarType, !VarTypes).
 
+:- pred make_future_name_var_and_goal(string::in, prog_var::out, hlds_goal::out,
+    prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
+    ts_string_table::in, ts_string_table::out) is det.
+
+make_future_name_var_and_goal(Name, FutureNameVar, Goal, !VarSet, !VarTypes, !TSStringTable) :-
+    varset.new_named_var("FutureName" ++ Name, FutureNameVar, !VarSet),
+    IntType = builtin_type(builtin_type_int),
+    map.det_insert(FutureNameVar, IntType, !VarTypes),
+    allocate_ts_string(Name, NameId, !TSStringTable),
+    Ground = ground(unique, none),
+    GoalExpr = unify(FutureNameVar, rhs_functor(int_const(NameId), no, []),
+        (free(IntType) -> Ground) - (Ground -> Ground),
+        construct(FutureNameVar, int_const(NameId), [], [],
+            construct_statically, cell_is_unique, no_construct_sub_info),
+        unify_context(umc_implicit("dep_par_conj transformation"), [])),
+    InstmapDelta = instmap_delta_from_assoc_list([FutureNameVar - Ground]),
+    goal_info_init(set([FutureNameVar]), InstmapDelta, detism_det, purity_pure,
+        GoalInfo),
+    Goal = hlds_goal(GoalExpr, GoalInfo).
+
 :- pred make_wait_goal(module_info::in, vartypes::in,
     prog_var::in, prog_var::in, hlds_goal::out) is det.
 
@@ -3152,6 +3200,16 @@ wait_future_pred_name = "wait_future".
 get_future_pred_name = "get_future".
 signal_future_pred_name = "signal_future".
 
+:- func new_future_code = string.
+
+new_future_code = "
+    #ifdef MR_THREADSCOPE
+        MR_par_builtin_new_future(Name, Future);
+    #else
+        MR_par_builtin_new_future(Future);
+    #endif
+".
+
 :- func should_inline_par_builtin_calls(module_info) = bool.
 
 should_inline_par_builtin_calls(ModuleInfo) = ShouldInline :-
@@ -3311,5 +3369,46 @@ var_not_in_nonlocals(Var, Goal) :-
     not var_in_nonlocals(Var, Goal).
 
 %-----------------------------------------------------------------------------%
+%
+% Threadscope support used in this module.
+%
+
+:- type ts_string_table
+    --->    ts_string_table(
+                st_lookup_map       :: map(string, int),
+                st_rev_table        :: list(string),
+                st_size             :: int
+            ).
+
+:- pred allocate_ts_string(string::in, int::out,
+    ts_string_table::in, ts_string_table::out) is det.
+
+allocate_ts_string(String, Id, !Table) :-
+    !.Table = ts_string_table(Map0, RevTable0, Size0),
+    ( map.search(Map0, String, ExistingId) ->
+        Id = ExistingId
+    ;
+        Id = Size0,
+        Size = Size0 + 1,
+        RevTable = [String | RevTable0],
+        map.det_insert(String, Id, Map0, Map),
+        !:Table = ts_string_table(Map, RevTable, Size)
+    ).
+
+:- pred make_ts_string_table(list(string)::in, ts_string_table::out) is det.
+
+make_ts_string_table(RevTable, ts_string_table(Map, RevTable, Size)) :-
+    make_ts_string_table_2(RevTable, Size, map.init, Map).
+
+:- pred make_ts_string_table_2(list(string)::in, int::out,
+    map(string, int)::in, map(string, int)::out) is det.
+
+make_ts_string_table_2([], 0, !Map).
+make_ts_string_table_2([Str | Strs], Size, !Map) :-
+    make_ts_string_table_2(Strs, Size0, !Map),
+    Size = Size0 + 1,
+    map.det_insert(Str, Size0, !Map).
+
+%-----------------------------------------------------------------------------%
 :- end_module transform_hlds.dep_par_conj.
 %-----------------------------------------------------------------------------%
Index: compiler/global_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/global_data.m,v
retrieving revision 1.49
diff -u -p -b -r1.49 global_data.m
--- compiler/global_data.m	23 May 2011 05:08:02 -0000	1.49
+++ compiler/global_data.m	30 May 2011 04:30:02 -0000
@@ -34,7 +34,8 @@
 
 :- type global_data.
 
-:- pred global_data_init(static_cell_info::in, global_data::out) is det.
+:- pred global_data_init(static_cell_info::in, int::in, list(string)::in,
+    global_data::out) is det.
 
 :- pred global_data_add_new_proc_var(pred_proc_id::in, tabling_info_struct::in,
     global_data::in, global_data::out) is det.
@@ -200,11 +201,13 @@
                 gd_alloc_sites              :: set_tree234(alloc_site_info)
             ).
 
-global_data_init(StaticCellInfo, GlobalData) :-
+global_data_init(StaticCellInfo, TSStringTableSize, TSRevStringTable,
+        GlobalData) :-
     map.init(EmptyDataMap),
     map.init(EmptyLayoutMap),
     GlobalData = global_data(EmptyDataMap, EmptyLayoutMap, [],
-        0, [], StaticCellInfo, set_tree234.init).
+        TSStringTableSize, TSRevStringTable, StaticCellInfo,
+        set_tree234.init).
 
 global_data_add_new_proc_var(PredProcId, ProcVar, !GlobalData) :-
     ProcVarMap0 = !.GlobalData ^ gd_proc_var_map,
Index: compiler/hlds_module.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_module.m,v
retrieving revision 1.172
diff -u -p -b -r1.172 hlds_module.m
--- compiler/hlds_module.m	23 May 2011 05:08:03 -0000	1.172
+++ compiler/hlds_module.m	30 May 2011 04:29:49 -0000
@@ -525,6 +525,12 @@
 :- pred module_info_set_event_set(event_set::in,
     module_info::in, module_info::out) is det.
 
+:- pred module_info_get_ts_rev_string_table(module_info::in, int::out,
+    list(string)::out) is det.
+
+:- pred module_info_set_ts_rev_string_table(int::in, list(string)::in,
+    module_info::in, module_info::out) is det.
+
 %-----------------------------------------------------------------------------%
 
 :- pred module_info_get_preds(module_info::in, pred_table::out) is det.
@@ -827,7 +833,16 @@
                 % language.
                 msi_exported_enums              :: list(exported_enum_info),
 
-                msi_event_set                   :: event_set
+                msi_event_set                   :: event_set,
+
+                % A table of strings used by some threadscope events.
+                % Currently threadscope events are introduced for each future
+                % in dep_par_conj.m which is why we need to record the table
+                % within the HLDS.  The LLDS also uses threadscope string
+                % tables, see global_data.m, the LLDS introduces strings during
+                % the HLDS->LLDS transformation of parallel conjunctions.
+                msi_ts_string_table_size        :: int,
+                msi_ts_rev_string_table         :: list(string)
             ).
 
 module_info_init(Name, DumpBaseFileName, Items, Globals, QualifierInfo,
@@ -881,6 +896,8 @@ module_info_init(Name, DumpBaseFileName,
     set.init(InterfaceModuleSpecs),
     ExportedEnums = [],
     EventSet = event_set("", map.init),
+    TSStringTableSize = 0,
+    TSRevStringTable = [],
 
     ModuleSubInfo = module_sub_info(Name, DumpBaseFileName, Globals,
         ContainsParConj, ContainsUserEvent, ContainsForeignType,
@@ -894,7 +911,7 @@ module_info_init(Name, DumpBaseFileName,
         MaybeComplexityMap, ComplexityProcInfos,
         AnalysisInfo, UserInitPredCNames, UserFinalPredCNames,
         StructureReusePredIds, UsedModules, InterfaceModuleSpecs,
-        ExportedEnums, EventSet),
+        ExportedEnums, EventSet, TSStringTableSize, TSRevStringTable),
 
     predicate_table_init(PredicateTable),
     unify_proc.init_requests(Requests),
@@ -1027,6 +1044,9 @@ module_info_get_interface_module_specifi
     MI ^ mi_sub_info ^ msi_interface_module_specifiers).
 module_info_get_exported_enums(MI, MI ^ mi_sub_info ^ msi_exported_enums).
 module_info_get_event_set(MI, MI ^ mi_sub_info ^ msi_event_set).
+module_info_get_ts_rev_string_table(MI,
+    MI ^ mi_sub_info ^ msi_ts_string_table_size,
+    MI ^ mi_sub_info ^ msi_ts_rev_string_table).
 
     % XXX There is some debate as to whether duplicate initialise directives
     % in the same module should constitute an error. Currently it is not, but
@@ -1184,6 +1204,9 @@ module_info_set_used_modules(UsedModules
     !MI ^ mi_sub_info ^ msi_used_modules := UsedModules.
 module_info_set_event_set(EventSet, !MI) :-
     !MI ^ mi_sub_info ^ msi_event_set := EventSet.
+module_info_set_ts_rev_string_table(Size, RevTable, !MI) :-
+    !MI ^ mi_sub_info ^ msi_ts_string_table_size := Size,
+    !MI ^ mi_sub_info ^ msi_ts_rev_string_table := RevTable.
 
 module_info_add_parents_to_used_modules(Modules, !MI) :-
     module_info_get_used_modules(!.MI, UsedModules0),
Index: compiler/mercury_compile_llds_back_end.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile_llds_back_end.m,v
retrieving revision 1.14
diff -u -p -b -r1.14 mercury_compile_llds_back_end.m
--- compiler/mercury_compile_llds_back_end.m	23 May 2011 05:08:05 -0000	1.14
+++ compiler/mercury_compile_llds_back_end.m	30 May 2011 04:30:02 -0000
@@ -110,7 +110,10 @@ llds_backend_pass(!HLDS, !:GlobalData, L
     ),
     StaticCellInfo0 = init_static_cell_info(ModuleName, UnboxFloats,
         DoCommonData),
-    global_data_init(StaticCellInfo0, !:GlobalData),
+    module_info_get_ts_rev_string_table(!.HLDS, TSStringTableSize,
+        TSRevStringTable),
+    global_data_init(StaticCellInfo0, TSStringTableSize, TSRevStringTable,
+        !:GlobalData),
 
     globals.lookup_bool_option(Globals, verbose, Verbose),
     globals.lookup_bool_option(Globals, statistics, Stats),
Index: library/par_builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/par_builtin.m,v
retrieving revision 1.24
diff -u -p -b -r1.24 par_builtin.m
--- library/par_builtin.m	8 Feb 2011 03:48:10 -0000	1.24
+++ library/par_builtin.m	30 May 2011 02:08:16 -0000
@@ -33,7 +33,10 @@
     % shared variable between parallel conjuncts, when one conjunct produces
     % the value for other conjuncts.
     %
-:- pred new_future(future(T)::uo) is det.
+    % The first argument is an integer that refers to a string (via a table) of
+    % the future's name. It is used in threadscope grades.
+    %
+:- pred new_future(int::in, future(T)::uo) is det.
 
     % wait_future(Future, Var):
     %
@@ -113,11 +116,15 @@
 %-----------------------------------------------------------------------------%
 
 :- pragma foreign_proc("C",
-    new_future(Future::uo),
+    new_future(Name::in, Future::uo),
     [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
         may_not_duplicate],
 "
+    #ifdef MR_THREADSCOPE
+        MR_par_builtin_new_future(Future, Name);
+    #else
     MR_par_builtin_new_future(Future);
+    #endif
 ").
 
 :- pragma foreign_proc("C",
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.61
diff -u -p -b -r1.61 program_representation.m
--- mdbcomp/program_representation.m	20 May 2011 04:16:53 -0000	1.61
+++ mdbcomp/program_representation.m	30 May 2011 04:29:50 -0000
@@ -1548,7 +1548,7 @@ no_type_info_builtin_2(table_builtin, "t
 no_type_info_builtin_2(table_builtin, "table_lookup_insert_typeinfo", 3).
 no_type_info_builtin_2(table_builtin, "table_lookup_insert_typeclassinfo", 3).
 no_type_info_builtin_2(term_size_prof_builtin, "increment_size", 2).
-no_type_info_builtin_2(par_builtin, "new_future", 1).
+no_type_info_builtin_2(par_builtin, "new_future", 2).
 no_type_info_builtin_2(par_builtin, "wait_future", 2).
 no_type_info_builtin_2(par_builtin, "get_future", 2).
 no_type_info_builtin_2(par_builtin, "signal_future", 2).
Index: runtime/mercury_par_builtin.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_par_builtin.h,v
retrieving revision 1.5
diff -u -p -b -r1.5 mercury_par_builtin.h
--- runtime/mercury_par_builtin.h	10 May 2011 00:28:15 -0000	1.5
+++ runtime/mercury_par_builtin.h	30 May 2011 01:45:24 -0000
@@ -73,7 +73,7 @@ vim: ft=c ts=4 sw=4 et
 
 #ifdef MR_LL_PARALLEL_CONJ
 
-    #define MR_par_builtin_new_future(Future)                               \
+    #define MR_par_builtin_new_future_2(Future)                             \
         do {                                                                \
             MR_Word fut_addr;                                               \
                                                                             \
@@ -86,9 +86,28 @@ vim: ft=c ts=4 sw=4 et
                                                                             \
             Future->MR_fut_signalled = MR_FALSE;                            \
             Future->MR_fut_suspended = NULL;                                \
-            MR_maybe_post_new_future(Future);                               \
         } while (0)
 
+  #ifdef MR_THREADSCOPE
+    /*
+    ** In threadscope grades we need to pass the name of the future to the
+    ** threadscope event.
+    */
+    #define MR_par_builtin_new_future(Future, Name)                         \
+        do {                                                                \
+            MR_par_builtin_new_future_2(Future);                            \
+            MR_threadscope_post_new_future(Future, Name);                   \
+        } while (0)
+
+  #else /* ! MR_THREADSCOPE */
+
+    #define MR_par_builtin_new_future(Future)                               \
+        do {                                                                \
+            MR_par_builtin_new_future_2(Future);                            \
+        } while (0)
+
+  #endif /* ! MR_THREADSCOPE */
+
     /*
     ** If MR_fut_signalled is true then we guarantee that reading MR_fut_value
     ** is safe, even without a lock, see the corresponding code in
@@ -202,11 +221,6 @@ vim: ft=c ts=4 sw=4 et
             MR_threadscope_post_stop_context(MR_TS_STOP_REASON_BLOCKED);    \
         } while (0)
 
-    #define MR_maybe_post_new_future(future)                                \
-        do {                                                                \
-            MR_threadscope_post_new_future(future);                         \
-        } while (0)
-
     #define MR_maybe_post_wait_future_nosuspend(future)                     \
         do {                                                                \
             MR_threadscope_post_wait_future_nosuspend(future);              \
@@ -227,7 +241,6 @@ vim: ft=c ts=4 sw=4 et
         do {                                                                \
         } while (0)
     #define MR_maybe_post_stop_context MR_noop
-    #define MR_maybe_post_new_future(future) MR_noop
     #define MR_maybe_post_wait_future_nosuspend(future) MR_noop
     #define MR_maybe_post_wait_future_suspended(future) MR_noop
     #define MR_maybe_post_signal_future(future) MR_noop
Index: runtime/mercury_threadscope.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_threadscope.c,v
retrieving revision 1.13
diff -u -p -b -r1.13 mercury_threadscope.c
--- runtime/mercury_threadscope.c	24 May 2011 04:16:48 -0000	1.13
+++ runtime/mercury_threadscope.c	24 May 2011 07:44:46 -0000
@@ -169,7 +169,7 @@
 */
 #define MR_TS_MER_EVENT_SPARKING            103 /* (int id, spark id) */
 
-#define MR_TS_MER_EVENT_FUT_CREATE          104 /* (fut id) */
+#define MR_TS_MER_EVENT_FUT_CREATE          104 /* (fut id, memo'd name id) */
 #define MR_TS_MER_EVENT_FUT_WAIT_NOSUSPEND  105 /* (fut id) */
 #define MR_TS_MER_EVENT_FUT_WAIT_SUSPENDED  106 /* (fut id) */
 #define MR_TS_MER_EVENT_FUT_SIGNAL          107 /* (fut id) */
@@ -262,7 +262,9 @@ typedef struct {
 #define SZ_ENGINE_ID            2
 #define SZ_PID                  4
 #define SZ_SPARK_ID             4
-#define SZ_STATIC_CONJ_ID       4
+#define SZ_STRING_ID            4
+#define SZ_STATIC_CONJ_ID       (SZ_STRING_ID)
+#define SZ_VAR_NAME_ID          (SZ_STRING_ID)
 #define SZ_TIME                 8
 #define SZ_FUTURE_ID            8
 
@@ -464,7 +466,7 @@ static EventTypeDesc event_type_descs[] 
         */
         MR_TS_MER_EVENT_FUT_CREATE,
         "Create a future (future id)",
-        SZ_FUTURE_ID
+        SZ_FUTURE_ID + SZ_VAR_NAME_ID
     },
     {
         MR_TS_MER_EVENT_FUT_WAIT_NOSUSPEND,
@@ -1582,7 +1584,7 @@ MR_threadscope_post_runtime_identifier(M
 }
 
 void
-MR_threadscope_post_new_future(MR_Future *future_id)
+MR_threadscope_post_new_future(MR_Future *future_id, MR_TS_StringId name)
 {
     struct MR_threadscope_event_buffer *buffer = MR_ENGINE(MR_eng_ts_buffer);
 
@@ -1597,6 +1599,7 @@ MR_threadscope_post_new_future(MR_Future
     put_event_header(buffer, MR_TS_MER_EVENT_FUT_CREATE,
         get_current_time_nanosecs());
     put_future_id(buffer, future_id);
+    put_string_id(buffer, name);
 
     MR_US_UNLOCK(&(buffer->MR_tsbuffer_lock));
 }
Index: runtime/mercury_threadscope.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_threadscope.h,v
retrieving revision 1.10
diff -u -p -b -r1.10 mercury_threadscope.h
--- runtime/mercury_threadscope.h	24 May 2011 04:16:48 -0000	1.10
+++ runtime/mercury_threadscope.h	24 May 2011 07:46:14 -0000
@@ -174,8 +174,9 @@ extern void MR_threadscope_post_end_par_
 /*
 ** Post this message when a future is created, this establishes the conjuction
 ** id to future id mapping.  The conjunction id is inferred by context.
+** The name of the future within the conjunction is given by 'name'.
 */
-extern void MR_threadscope_post_new_future(MR_Future* future_id);
+extern void MR_threadscope_post_new_future(MR_Future* future_id, MR_TS_StringId name);
 
 /*
 ** Post either of these messages when waiting on a future.  THe first if the
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 489 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20110530/6e52353a/attachment.sig>


More information about the reviews mailing list