[m-rev.] diff: [CTGC] avoid some re-verification of indirect reuses

Peter Wang novalazy at gmail.com
Thu Jun 5 13:29:55 AEST 2008


Branches: main

Avoid some unnecessary re-verification of indirect reuse calls when we know
that a result can't change.

compiler/hlds_goal.m:
	Add `no_possible_reuse' option to goal reuse descriptions.

compiler/structure_reuse.indirect.m:
	Annotate goals with `no_possible_reuse' when we know there is no reuse
	opportunity and reanalysis (in this compiler run) won't help.

	Skip verification of an indirect reuse call if the goal annotatation
	allows us to.

compiler/hlds_out.m:
compiler/structure_reuse.versions.m:
	Conform to the change to goal reuse descriptions.

Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.191
diff -u -r1.191 hlds_goal.m
--- compiler/hlds_goal.m	28 May 2008 00:52:27 -0000	1.191
+++ compiler/hlds_goal.m	5 Jun 2008 02:58:36 -0000
@@ -1000,33 +1000,45 @@
             ).
 
     % Information describing possible kinds of reuse on a per goal basis.
+    %
     % - 'no_reuse_info': before CTGC analysis, every goal is annotated with
     % the reuse description 'no_reuse_info', i.e. no information about any
     % reuse.
+    %
+    % - 'no_possible_reuse': the goal has been analysed and determined to have
+    % no reuse opportunity and reanalysis in light of further information
+    % within the same module is unnecessary.
+    %
     % - 'potential_reuse': the value 'potential_reuse' states that in a reuse
     % version of the procedure to which the goal belongs, this goal may safely
     % be replaced by a goal implementing structure reuse.
+    %
     % - 'reuse': the value 'reuse' states that in the current procedure (either
     % the specialised reuse version of a procedure, or the original procedure
     % itself) the current goal can safely be replaced by a goal performing
     % structure reuse.
+    %
     % - 'missed_reuse': the value 'missed_reuse' gives some feedback when an
     % opportunity for reuse was missed for some reason (only used for calls).
     %
 :- type reuse_description
     --->    no_reuse_info
+    ;       no_possible_reuse
     ;       missed_reuse(list(missed_message))
     ;       potential_reuse(short_reuse_description)
     ;       reuse(short_reuse_description).
 
     % A short description of the kind of reuse allowed in the associated
     % goal:
+    %
     % - 'cell_died' (only relevant for deconstructions): states that the cell
     % of the deconstruction becomes dead after that deconstruction.
+    %
     % - 'cell_reused' (only relevant for constructions): states that it is
     % allowed to reuse a previously discovered dead term for constructing a
     % new term in the given construction. Details of which term is reused are
     % recorded.
+    %
     % - 'reuse_call' (only applicable to procedure calls): the called
     % procedure is an optimised procedure w.r.t. CTGC. Records whether the
     % call is conditional or not.
@@ -2442,6 +2454,7 @@
         rename_vars_in_var_set(Must, Subn, BackwardUse0, BackwardUse),
         (
             ( ReuseDesc0 = no_reuse_info
+            ; ReuseDesc0 = no_possible_reuse
             ; ReuseDesc0 = missed_reuse(_)
             ),
             ReuseDesc = ReuseDesc0
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.451
diff -u -r1.451 hlds_out.m
--- compiler/hlds_out.m	28 May 2008 00:52:27 -0000	1.451
+++ compiler/hlds_out.m	5 Jun 2008 02:58:36 -0000
@@ -1517,7 +1517,10 @@
             write_string("% Reuse: ", !IO),
             (
                 ReuseDescription = no_reuse_info,
-                io.write_string("no", !IO)
+                io.write_string("no reuse info", !IO)
+            ;
+                ReuseDescription = no_possible_reuse,
+                io.write_string("no possible reuse", !IO)
             ;
                 ReuseDescription = missed_reuse(Messages),
                 io.write_string("missed (", !IO), 

Index: compiler/structure_reuse.indirect.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/structure_reuse.indirect.m,v
retrieving revision 1.25
diff -u -r1.25 structure_reuse.indirect.m
--- compiler/structure_reuse.indirect.m	28 May 2008 00:52:29 -0000	1.25
+++ compiler/structure_reuse.indirect.m	5 Jun 2008 02:58:39 -0000
@@ -182,10 +182,6 @@
 :- pred extend_scc_with_reuse_procs(reuse_as_table::in, list(pred_proc_id)::in,
     list(pred_proc_id)::out) is det.
 
-% extend_scc_with_reuse_procs(_, SCC, SCC).
-
-% temporarily commented out to narrow down --structure-reuse-repeat bug
-
 extend_scc_with_reuse_procs(ReuseTable, SCC, ExtendedSCC) :-
     ReuseVersionMap = ReuseTable ^ reuse_version_map,
     solutions(
@@ -461,14 +457,27 @@
     ;
         GoalExpr0 = plain_call(CalleePredId, CalleeProcId, CalleeArgs,
             _Builtin, _Context, _Sym),
-        NoClobbers = [],
-        verify_indirect_reuse(BaseInfo, proc(CalleePredId, CalleeProcId),
-            NoClobbers, CalleeArgs, GoalInfo0, GoalInfo, !IrInfo),
+        Reuse0 = goal_info_get_reuse(GoalInfo0),
+        (
+            ( Reuse0 = no_reuse_info
+            ; Reuse0 = missed_reuse(_)
+            ; Reuse0 = potential_reuse(_)
+                % Might be able to improve the result with reanalysis. 
+            ),
+            NoClobbers = [],
+            verify_indirect_reuse(BaseInfo, proc(CalleePredId, CalleeProcId),
+                NoClobbers, CalleeArgs, GoalInfo0, GoalInfo, !IrInfo),
+            !:Goal = hlds_goal(GoalExpr0, GoalInfo)
+        ;
+            ( Reuse0 = no_possible_reuse
+            ; Reuse0 = reuse(_)
+            )
+            % Don't need to verify these calls again.
+        ),
         OldSharing = !.IrInfo ^ sharing_as,
         lookup_sharing_and_comb(ModuleInfo, PredInfo, ProcInfo, SharingTable,
             CalleePredId, CalleeProcId, CalleeArgs, OldSharing, NewSharing),
-        update_sharing_as(BaseInfo, OldSharing, NewSharing, !IrInfo),
-        !:Goal = hlds_goal(GoalExpr0, GoalInfo)
+        update_sharing_as(BaseInfo, OldSharing, NewSharing, !IrInfo)
     ;
         GoalExpr0 = generic_call(_GenDetails, _, _, _),
         Context = goal_info_get_context(GoalInfo0),
@@ -648,12 +657,14 @@
     % XXX if we can't find an exact match for NoClobbers, we could try
     % procedures which have no-clobber sets which are supersets of NoClobbers.
     lookup_reuse_as(BaseInfo, CalleePPId, NoClobbers, !IrInfo, FormalReuseAs),
-
     (
         % If there is no reuse, then nothing can be done.
         reuse_as_no_reuses(FormalReuseAs)
     ->
         Reason = callee_has_no_reuses,
+        % Setting `no_possible_reuse' here would have adverse effects because
+        % the reuse_as from `lookup_reuse_as' is not definitive.  It may
+        % return something else later.
         trace [io(!IO)] (
             maybe_write_verify_indirect_reuse_reason(BaseInfo, CalleePPId,
                 NoClobbers, !.GoalInfo, Reason, !IO)
@@ -685,7 +696,7 @@
             % pairs. In this case, reuse is not allowed.
             sharing_as_is_top(!.IrInfo ^ sharing_as)
         ->
-            % No need to update anything.
+            goal_info_set_reuse(no_possible_reuse, !GoalInfo),
             trace [io(!IO)] (
                 maybe_write_verify_indirect_reuse_reason(BaseInfo, CalleePPId,
                     NoClobbers, !.GoalInfo, current_sharing_is_top, !IO)
@@ -715,6 +726,7 @@
             NotDeadArgNums = NoClobbers
         ->
             % Don't do anything.  Don't even request a new version.
+            goal_info_set_reuse(no_possible_reuse, !GoalInfo),
             trace [io(!IO)] (
                 maybe_write_verify_indirect_reuse_reason(BaseInfo, CalleePPId,
                     NoClobbers, !.GoalInfo, reuse_is_unsafe(NotDeadVars), !IO)
@@ -731,7 +743,14 @@
                 CalleeArgs, !GoalInfo, !IrInfo)
         ;
             % Request another version of the procedure.
-            maybe_add_request(BaseInfo, CalleePPId, NotDeadArgNums, !IrInfo),
+            add_request(BaseInfo, CalleePPId, NotDeadArgNums, IntraModule,
+                !IrInfo),
+            (
+                IntraModule = yes
+            ;
+                IntraModule = no,
+                goal_info_set_reuse(no_possible_reuse, !GoalInfo)
+            ),
             trace [io(!IO)] (
                 maybe_write_verify_indirect_reuse_reason(BaseInfo, CalleePPId,
                     NoClobbers, !.GoalInfo, reuse_is_unsafe(NotDeadVars), !IO)
@@ -834,16 +853,24 @@
 lookup_reuse_as(BaseInfo, OrigPPId, NoClobbers, !IrInfo, ReuseAs) :-
     (
         reuse_as_table_search_reuse_version_proc(BaseInfo ^ reuse_table,
-            OrigPPId, NoClobbers, PPId0)
+            OrigPPId, NoClobbers, PPId)
     ->
-        PPId = PPId0
+        lookup_reuse_as_2(BaseInfo, OrigPPId, PPId, NoClobbers, !IrInfo,
+            ReuseAs)
     ;
         NoClobbers = []
     ->
-        PPId = OrigPPId
+        lookup_reuse_as_2(BaseInfo, OrigPPId, OrigPPId, NoClobbers, !IrInfo,
+            ReuseAs)
     ;
         unexpected(this_file, "lookup_reuse_as")
-    ),
+    ).
+
+:- pred lookup_reuse_as_2(ir_background_info::in, pred_proc_id::in,
+    pred_proc_id::in, list(int)::in, ir_analysis_info::in,
+    ir_analysis_info::out, reuse_as::out) is det.
+
+lookup_reuse_as_2(BaseInfo, OrigPPId, PPId, NoClobbers, !IrInfo, ReuseAs) :-
     (
         % Check in the fixpoint table
         sr_fixpoint_table_get_as(PPId, ReuseAs_Status0, !.IrInfo ^ fptable,
@@ -942,18 +969,26 @@
         Indices = Indices0
     ).
 
-:- pred maybe_add_request(ir_background_info::in, pred_proc_id::in,
-    list(int)::in, ir_analysis_info::in, ir_analysis_info::out) is det.
+    % Add an intra- or inter-module request for the called procedure.
+    %
+:- pred add_request(ir_background_info::in, pred_proc_id::in, list(int)::in,
+    bool::out, ir_analysis_info::in, ir_analysis_info::out) is det.
 
-maybe_add_request(BaseInfo, CalleePPId, NotDeadArgNums, !IrInfo) :-
+add_request(BaseInfo, CalleePPId, NotDeadArgNums, IntraModule, !IrInfo) :-
     CalleePPId = proc(CalleePredId, _),
     ModuleInfo = BaseInfo ^ module_info,
     module_info_pred_info(ModuleInfo, CalleePredId, PredInfo),
     pred_info_get_import_status(PredInfo, ImportStatus),
-    ( status_defined_in_this_module(ImportStatus) = yes ->
+    (
+        ( status_defined_in_this_module(ImportStatus) = yes
+        ; ImportStatus = status_opt_imported
+        )
+    ->
+        IntraModule = yes,
         Request = sr_request(CalleePPId, NotDeadArgNums),
         !IrInfo ^ requests := set.insert(!.IrInfo ^ requests, Request)
     ;
+        IntraModule = no,
         module_info_get_globals(ModuleInfo, Globals),
         globals.lookup_bool_option(Globals, intermodule_analysis,
             IntermoduleAnalysis),
Index: compiler/structure_reuse.versions.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/structure_reuse.versions.m,v
retrieving revision 1.16
diff -u -r1.16 structure_reuse.versions.m
--- compiler/structure_reuse.versions.m	28 May 2008 00:52:29 -0000	1.16
+++ compiler/structure_reuse.versions.m	5 Jun 2008 02:58:39 -0000
@@ -346,6 +346,8 @@
         ;
             ReuseDescription0 = no_reuse_info
         ;
+            ReuseDescription0 = no_possible_reuse
+        ;
             ReuseDescription0 = missed_reuse(_)
         )
     ;



--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list