Files
mercury/compiler/rbmm.add_rbmm_goal_infos.m
Zoltan Somogyi d8a31e574e Move six utility modules from check_hlds to hlds.
compiler/inst_lookup.m:
compiler/inst_mode_type_prop.m:
compiler/inst_test.m:
compiler/inst_util.m:
compiler/mode_util.m:
compiler/type_util.m:
    Move these modules from the check_hlds package to the hlds package.
    The reason is that all the content of five of these modules, and
    most of the content of one module (inst_util.m) is not used
    exclusively during semantic checking passes. (A later diff
    should deal with the exception.) Some are used by the pass that
    builds the initial HLDS, and all are used by middle-end and backend
    passes. The move therefore reduces the number of inappropriate imports
    of the check_hlds package.

compiler/check_hlds.m:
compiler/hlds.m:
    Effect the transfer.

compiler/*.m:
    Conform to the changes above.
2025-10-08 23:07:13 +11:00

562 lines
25 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2007-2012 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
%
% File rbmm.add_rbmm_goal_infos.m.
% Main author: Quan Phan.
%
% This module fills in rbmm_goal_info field in hlds_goal_extra_info data
% structure. The details of this information can be read in hlds_goal.m.
%
% This information is used by the code generator to optimize the runtime
% region support for backtracking in region-based memory management.
%
% To support programs with backtracking in region-based memory management we
% have to deal with region resurrection (i.e. a region is dead during forward
% execution but is still needed when the program backtracks) and we may also
% want to do instant reclaiming when backtracking happens. In Mercury, the
% support is needed for if-then-else, nondet disjunction and commit context.
% This runtime support certainly incurs runtime overhead to programs therefore
% we would like to pay for it only when we actually need it. For example, if
% we know that the condition of an if-then-else does not allocate memory into
% any existing regions, does not create any regions nor destroy any regions,
% then we do not need to provide support for the if-then-else. This situation
% is very often the case with if-then-elses therefore if we can exploit it we
% will hopefully boost the performance of region-based memory management. The
% rbmm_goal_info gives the code generator the information which is needed to
% fulfill this optimization.
%
% XXX More information about the advanced runtime support for backtracking
% should be documented or found somewhere but it is not avaiable yet because
% it is still in experimental state. We should fix this when it is more
% stable.
%
%---------------------------------------------------------------------------%
:- module transform_hlds.rbmm.add_rbmm_goal_infos.
:- interface.
:- import_module hlds.
:- import_module hlds.hlds_module.
:- import_module transform_hlds.rbmm.points_to_info.
:- import_module transform_hlds.rbmm.region_arguments.
:- import_module transform_hlds.rbmm.region_resurrection_renaming.
:- import_module transform_hlds.rbmm.region_transformation.
:- pred collect_rbmm_goal_info(rpta_info_table::in,
proc_pp_actual_region_args_table::in,
rbmm_renaming_table::in, rbmm_renaming_table::in,
name_to_prog_var_table::in, module_info::in, module_info::out) is det.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module hlds.hlds_goal.
:- import_module hlds.hlds_pred.
:- import_module hlds.type_util.
:- import_module libs.
:- import_module libs.globals.
:- import_module libs.options.
:- import_module mdbcomp.
:- import_module mdbcomp.builtin_modules.
:- import_module parse_tree.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.set_of_var.
:- import_module transform_hlds.rbmm.points_to_graph.
:- import_module transform_hlds.smm_common.
:- import_module bool.
:- import_module list.
:- import_module map.
:- import_module maybe.
:- import_module require.
:- import_module set.
%---------------------------------------------------------------------------%
%
% Collect rbmm_goal_info.
%
% It only makes sense to collect rbmm_goal_info for the procedures
% which have been region-analyzed. To find such procedures we can use one
% of the result tables of any previous region analyses.
% Note: The use of ActualRegionArgumentTable here is convenient because
% apart from the procedure id, we also need the information about actual
% region arguments in this pass.
%
collect_rbmm_goal_info(RptaInfoTable, ActualRegionArgumentTable,
ResurRenamingTable, IteRenamingTable, NameToRegionVarTable,
!ModuleInfo) :-
map.foldl(collect_rbmm_goal_info_proc(RptaInfoTable, ResurRenamingTable,
IteRenamingTable, NameToRegionVarTable), ActualRegionArgumentTable,
!ModuleInfo).
:- pred collect_rbmm_goal_info_proc(rpta_info_table::in,
rbmm_renaming_table::in, rbmm_renaming_table::in,
name_to_prog_var_table::in, pred_proc_id::in,
pp_actual_region_args_table::in,
module_info::in, module_info::out) is det.
collect_rbmm_goal_info_proc(RptaInfoTable, ResurRenamingTable,
IteRenamingTable, NameToRegionVarTable, PPId, ActualRegionsArgsProc,
!ModuleInfo) :-
module_info_pred_proc_info(!.ModuleInfo, PPId, PredInfo, ProcInfo0),
proc_info_get_goal(ProcInfo0, Body0),
map.lookup(RptaInfoTable, PPId, RptaInfo),
RptaInfo = rpta_info(Graph, _),
( if map.search(ResurRenamingTable, PPId, ResurRenamingProc0) then
ResurRenamingProc = ResurRenamingProc0
else
ResurRenamingProc = map.init
),
( if map.search(IteRenamingTable, PPId, IteRenamingProc0) then
IteRenamingProc = IteRenamingProc0
else
IteRenamingProc = map.init
),
map.lookup(NameToRegionVarTable, PPId, NameToRegionVar),
collect_rbmm_goal_info_goal(!.ModuleInfo, ProcInfo0, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, Body0, Body),
proc_info_set_goal(Body, ProcInfo0, ProcInfo),
module_info_set_pred_proc_info(PPId, PredInfo, ProcInfo, !ModuleInfo).
:- pred collect_rbmm_goal_info_goal(module_info::in, proc_info::in,
rpt_graph::in, pp_actual_region_args_table::in,
rbmm_renaming_proc::in, rbmm_renaming_proc::in, name_to_prog_var::in,
hlds_goal::in, hlds_goal::out) is det.
collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, !Goal) :-
!.Goal = hlds_goal(Expr0, Info0),
collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, Expr0, Expr, Info0, Info),
!:Goal = hlds_goal(Expr, Info).
:- pred collect_rbmm_goal_info_goal_expr(module_info::in, proc_info::in,
rpt_graph::in, pp_actual_region_args_table::in,
rbmm_renaming_proc::in, rbmm_renaming_proc::in, name_to_prog_var::in,
hlds_goal_expr::in, hlds_goal_expr::out,
hlds_goal_info::in, hlds_goal_info::out) is det.
collect_rbmm_goal_info_goal_expr(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, !Expr, !Info) :-
(
!.Expr = unify(_, _, _, Unification, _),
ProgPoint = program_point_init(!.Info),
( if map.search(ResurRenamingProc, ProgPoint, ResurRenaming0) then
ResurRenaming = ResurRenaming0
else
ResurRenaming = map.init
),
( if map.search(IteRenamingProc, ProgPoint, IteRenaming0) then
IteRenaming = IteRenaming0
else
IteRenaming = map.init
),
collect_rbmm_goal_info_unification(Unification, ModuleInfo, Graph,
ResurRenaming, IteRenaming, NameToRegionVar, !Info)
;
!.Expr = plain_call(PredId, ProcId, Args, _, _, _),
CalleePPId = proc(PredId, ProcId),
( if
is_create_region_call(!.Expr, ModuleInfo, CreatedRegion)
then
RbmmGoalInfo = rbmm_goal_info(
set.make_singleton_set(CreatedRegion),
set.init, set.init, set.init, set.init),
goal_info_set_maybe_rbmm(yes(RbmmGoalInfo), !Info)
else if
is_remove_region_call(!.Expr, ModuleInfo, RemovedRegion)
then
RbmmGoalInfo = rbmm_goal_info(set.init,
set.make_singleton_set(RemovedRegion), set.init, set.init,
set.init),
goal_info_set_maybe_rbmm(yes(RbmmGoalInfo), !Info)
else if
some_are_special_preds([CalleePPId], ModuleInfo)
then
goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
else
CallSite = program_point_init(!.Info),
proc_info_get_var_table(ProcInfo, VarTable),
RegionArgs = list.filter(is_region_var(VarTable), Args),
map.lookup(ActualRegionsArgsProc, CallSite, ActualRegionArgs),
ActualRegionArgs = region_args(Constants, Inputs, _Outputs),
list.det_split_list(list.length(Constants), RegionArgs,
CarriedRegions, RemovedAndCreated),
list.det_split_list(list.length(Inputs), RemovedAndCreated,
RemovedRegions, CreatedRegions),
% XXX We safely approximate that RemovedRegions and CarriedRegions
% are allocated into and read from in this call.
AllocatedIntoAndReadFrom =
set.list_to_set(RemovedRegions ++ CarriedRegions),
module_info_get_globals(ModuleInfo, Globals),
globals.lookup_bool_option(Globals, use_alloc_regions,
UseAllocRegions),
(
UseAllocRegions = yes,
% Keep only the regions that are removed but
% also allocated into.
keep_allocated_regions(Inputs, RemovedRegions, Graph,
RemovedAndAllocRegions),
% Allocated regions are the above plus the carried ones.
% The carried here are those that are also allocated into.
AllocatedIntoRegions =
set.list_to_set(RemovedAndAllocRegions ++ CarriedRegions)
;
UseAllocRegions = no,
AllocatedIntoRegions = AllocatedIntoAndReadFrom
),
% The read-from set is not very important so we are not precise
% in estimating it.
RbmmGoalInfo = rbmm_goal_info(set.list_to_set(CreatedRegions),
set.list_to_set(RemovedRegions),
set.list_to_set(CarriedRegions),
AllocatedIntoRegions, AllocatedIntoAndReadFrom),
goal_info_set_maybe_rbmm(yes(RbmmGoalInfo), !Info)
)
;
!.Expr = conj(ConjType, Conjs0),
list.map(
collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar),
Conjs0, Conjs),
!:Expr = conj(ConjType, Conjs),
% Calculate created, removed, allocated into, used regions.
compute_rbmm_info_conjunction(Conjs, rbmm_info_init, RbmmInfo0),
% Calculate carried regions.
% The carried regions are those that are NOT removed, NOT created
% by all the conjuncts.
RbmmInfo0 = rbmm_goal_info(Created, Removed, _, AllocatedInto, Used),
NonLocals = goal_info_get_nonlocals(!.Info),
proc_info_get_var_table(ProcInfo, VarTable),
NonLocalRegionsSet =
set_of_var.filter(is_region_var(VarTable), NonLocals),
NonLocalRegions = set_of_var.bitset_to_set(NonLocalRegionsSet),
set.difference(NonLocalRegions, set.union(Created, Removed), Carried),
RbmmInfo =
rbmm_goal_info(Created, Removed, Carried, AllocatedInto, Used),
goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
;
!.Expr = disj(Disjs0),
list.map(collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar), Disjs0, Disjs),
!:Expr = disj(Disjs),
(
Disjs = [],
goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
;
% Well-modedness requires that each disjunct creates, removes and
% carries the same regions, which are also created, removed,
% carried by the disjunction.
Disjs = [hlds_goal(_, DInfo) | _],
DRbmmInfo = goal_info_get_rbmm(DInfo),
DRbmmInfo = rbmm_goal_info(Created, Removed, Carried, _, _),
RbmmInfo0 = rbmm_goal_info(Created, Removed, Carried, set.init,
set.init),
% Calculate allocated-into and used regions.
compute_rbmm_info_goals(Disjs, RbmmInfo0, RbmmInfo),
goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
)
;
!.Expr = switch(A, B, Cases0),
list.map(collect_rbmm_goal_info_case(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar), Cases0, Cases),
!:Expr = switch(A, B, Cases),
(
Cases = [],
unexpected($pred, "empty switch")
;
% The process here is similar to the above code for disjunctions.
Cases = [Case | _],
Case = case(_, _, Goal),
Goal = hlds_goal(_, CaseInfo),
CaseRbmmInfo = goal_info_get_rbmm(CaseInfo),
CaseRbmmInfo = rbmm_goal_info(Created, Removed, Carried, _, _),
SwitchRbmmInfo0 =
rbmm_goal_info(Created, Removed, Carried, set.init, set.init),
list.foldl(
( pred(C::in, Gs0::in, Gs::out) is det :-
C = case(_, _, G),
Gs = [G | Gs0]
), Cases, [], Goals),
compute_rbmm_info_goals(Goals, SwitchRbmmInfo0, SwitchRbmmInfo),
goal_info_set_maybe_rbmm(yes(SwitchRbmmInfo), !Info)
)
;
!.Expr = negation(Goal0),
collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, Goal0, Goal),
!:Expr = negation(Goal),
Goal = hlds_goal(_, Info),
RbmmInfo = goal_info_get_rbmm(Info),
goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
;
!.Expr = scope(Reason, Goal0),
% XXX We should special-case the handling of from_ground_term_construct
% scopes.
collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, Goal0, Goal),
!:Expr = scope(Reason, Goal),
Goal = hlds_goal(_, Info),
RbmmInfo = goal_info_get_rbmm(Info),
goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
;
!.Expr = if_then_else(Vars, Cond0, Then0, Else0),
collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, Cond0, Cond),
collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, Then0, Then),
collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, Else0, Else),
!:Expr = if_then_else(Vars, Cond, Then, Else),
% Well-modedness requires that the (cond, then) and the else parts
% create, remove and carry the same regions, which are also created,
% removed, carried by the if-then-else.
Else = hlds_goal(_, ElseInfo),
ElseRbmmInfo = goal_info_get_rbmm(ElseInfo),
ElseRbmmInfo = rbmm_goal_info(Created, Removed, Carried, _, _),
IteRbmmInfo0 = rbmm_goal_info(Created, Removed, Carried, set.init,
set.init),
compute_rbmm_info_goals([Cond, Then, Else], IteRbmmInfo0, IteRbmmInfo),
goal_info_set_maybe_rbmm(yes(IteRbmmInfo), !Info)
;
% We do not handle generic calls and calls to foreign procs
% in RBMM yet, so if a program has any of them, the RBMM compilation
% will fail before reaching here. We just call sorry now so that
% they are not forgotten when we deal with these explicitly
% in the future.
(
!.Expr = generic_call(_, _, _, _, _),
sorry($pred, "generic call not handled")
;
!.Expr = call_foreign_proc(_, _, _, _, _, _, _),
sorry($pred, "call to foreign proc not handled")
)
;
!.Expr = shorthand(_),
% These should have been expanded out by now.
unexpected($pred, "shorthand")
).
% The elements in the first and second lists are corresponding.
% Ones in the first list are the nodes in rpt graph therefore we can
% check their allocated property, ones in the second list are prog_vars
% (after renaming) that represent those in the first.
%
:- pred keep_allocated_regions(list(rptg_node)::in, list(prog_var)::in,
rpt_graph::in, list(prog_var)::out) is det.
keep_allocated_regions([], [], _, []).
keep_allocated_regions([], [_ | _], _, []) :-
unexpected($pred, "length mismatch").
keep_allocated_regions([_ | _], [], _, []) :-
unexpected($pred, "length mismatch").
keep_allocated_regions([Input | Inputs], [RemovedRegion | RemovedRegions],
Graph, RemovedAndAllocRegions) :-
keep_allocated_regions(Inputs, RemovedRegions, Graph,
RemovedAndAllocRegions0),
( if rptg_is_allocated_node(Graph, Input) then
RemovedAndAllocRegions = [RemovedRegion | RemovedAndAllocRegions0]
else
RemovedAndAllocRegions = RemovedAndAllocRegions0
).
% The regions that are created inside this conjunction are all that are
% created inside each conjunct.
% The regions that are removed inside this conjunction are all that are
% removed inside each conjunct AND EXIST before the conjunction,
% i.e. not being created in the condition.
% The regions that are allocated into inside this conjunction are those
% allocated into by any conjuncts AND EXIST ...
% The regions that are read from inside this conjunction are those that
% are read from by any conjuncts AND EXIST ...
%
:- pred compute_rbmm_info_conjunction(list(hlds_goal)::in,
rbmm_goal_info::in, rbmm_goal_info::out) is det.
compute_rbmm_info_conjunction([], !RbmmInfo).
compute_rbmm_info_conjunction([Conj | Conjs], !RbmmInfo) :-
Conj = hlds_goal(_, CInfo),
CRbmmInfo = goal_info_get_rbmm(CInfo),
CRbmmInfo = rbmm_goal_info(CCreated, CRemoved, _, CAllocatedInto, CUsed),
!.RbmmInfo = rbmm_goal_info(Created0, Removed0, Carried, AllocatedInto0,
Used0),
set.union(CCreated, Created0, Created),
set.difference(set.union(CRemoved, Removed0), Created, Removed),
set.difference(set.union(CAllocatedInto, AllocatedInto0), Created,
AllocatedInto),
set.difference(set.union(CUsed, Used0), Created, Used),
!:RbmmInfo = rbmm_goal_info(Created, Removed, Carried, AllocatedInto,
Used),
compute_rbmm_info_conjunction(Conjs, !RbmmInfo).
% The regions that are allocated into inside this list of goals are those
% allocated into by any goals AND EXIST ...
% The regions that are read from inside this list of goals are those that
% are read from by any goals AND EXIST ...
%
% This predicate are used to compute the above information for the goals
% in disjunction, cases, and if-then-else.
%
:- pred compute_rbmm_info_goals(list(hlds_goal)::in,
rbmm_goal_info::in, rbmm_goal_info::out) is det.
compute_rbmm_info_goals([], !RbmmInfo).
compute_rbmm_info_goals([Goal | Goals], !RbmmInfo) :-
Goal = hlds_goal(_, Info),
GoalRbmmInfo = goal_info_get_rbmm(Info),
GoalRbmmInfo = rbmm_goal_info(_, _, _, GoalAllocatedInto, GoalUsed),
!.RbmmInfo = rbmm_goal_info(Created, Removed, Carried, AllocatedInto0,
Used0),
set.difference(set.union(GoalAllocatedInto, AllocatedInto0), Created,
AllocatedInto),
set.difference(set.union(GoalUsed, Used0), Created, Used),
!:RbmmInfo = rbmm_goal_info(Created, Removed, Carried, AllocatedInto,
Used),
compute_rbmm_info_goals(Goals, !RbmmInfo).
:- pred collect_rbmm_goal_info_unification(unification::in, module_info::in,
rpt_graph::in, rbmm_renaming::in, rbmm_renaming::in, name_to_prog_var::in,
hlds_goal_info::in, hlds_goal_info::out) is det.
collect_rbmm_goal_info_unification(Unification, ModuleInfo, Graph,
ResurRenaming, IteRenaming, RegionNameToVar, !Info) :-
(
Unification = construct(_, _, _, _, HowToConstruct, _, _),
(
HowToConstruct = construct_in_region(AllocatedIntoRegion),
RbmmInfo = rbmm_goal_info(set.init, set.init,
set.make_singleton_set(AllocatedIntoRegion),
set.make_singleton_set(AllocatedIntoRegion), set.init),
goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
;
( HowToConstruct = construct_statically(_)
; HowToConstruct = construct_dynamically
; HowToConstruct = reuse_cell(_)
),
goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
)
;
Unification = deconstruct(DeconsCellVar, _, _, _, _, _),
rptg_get_node_by_variable(Graph, DeconsCellVar, Node),
NodeType = rptg_lookup_node_type(Graph, Node),
( if type_not_stored_in_region(NodeType, ModuleInfo) then
goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
else
% We need to try to apply renaming here because the
% region name in the Graph may need to be changed.
OriginalName = rptg_lookup_region_name(Graph, Node),
( if map.search(ResurRenaming, OriginalName, ResurNameList) then
Name = list.det_last(ResurNameList)
else if map.search(IteRenaming, OriginalName, IteNameList) then
Name = list.det_last(IteNameList)
else
Name = OriginalName
),
% This region may only be read from in the procedure containing
% this deconstruction therefore there might be no entry for it
% in RegionNameToVar.
( if map.search(RegionNameToVar, Name, RegionVar) then
RbmmInfo = rbmm_goal_info(set.init, set.init,
set.make_singleton_set(RegionVar),
set.init, set.make_singleton_set(RegionVar))
else
RbmmInfo = rbmm_info_init
),
goal_info_set_maybe_rbmm(yes(RbmmInfo), !Info)
)
;
% XXX We do have assignments between two region variables.
% But we do not consider either of them created or removed because
% the region they are bound to is still there, i.e. it has been
% created and will not be removed.
( Unification = assign(_, _)
; Unification = simple_test(_, _)
),
goal_info_set_maybe_rbmm(yes(rbmm_info_init), !Info)
;
Unification = complicated_unify(_, _, _),
unexpected($pred, "complicated unification")
).
:- pred is_remove_region_call(hlds_goal_expr::in, module_info::in,
prog_var::out) is semidet.
is_remove_region_call(plain_call(PredId, _ProcId, Args, _, _, _),
ModuleInfo, RemovedRegion) :-
module_info_pred_info(ModuleInfo, PredId, PredInfo),
pred_info_module(PredInfo) = mercury_region_builtin_module,
pred_info_name(PredInfo) = remove_region_pred_name,
Args = [RemovedRegion].
:- pred is_create_region_call(hlds_goal_expr::in, module_info::in,
prog_var::out) is semidet.
is_create_region_call(plain_call(PredId, _ProcId, Args, _, _, _),
ModuleInfo, CreatedRegion) :-
module_info_pred_info(ModuleInfo, PredId, PredInfo),
pred_info_module(PredInfo) = mercury_region_builtin_module,
pred_info_name(PredInfo) = create_region_pred_name,
Args = [CreatedRegion].
:- pred collect_rbmm_goal_info_case(module_info::in, proc_info::in,
rpt_graph::in, pp_actual_region_args_table::in,
rbmm_renaming_proc::in, rbmm_renaming_proc::in, name_to_prog_var::in,
case::in, case::out) is det.
collect_rbmm_goal_info_case(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, !Case) :-
!.Case = case(MainConsId, OtherConsIds, Goal0),
collect_rbmm_goal_info_goal(ModuleInfo, ProcInfo, Graph,
ActualRegionsArgsProc, ResurRenamingProc, IteRenamingProc,
NameToRegionVar, Goal0, Goal),
!:Case = case(MainConsId, OtherConsIds, Goal).
%---------------------------------------------------------------------------%
% The following functions produce an 'unexpected' error when the
% requested values have not been set.
%
:- func goal_info_get_rbmm(hlds_goal_info) = rbmm_goal_info.
goal_info_get_rbmm(GoalInfo) = RBMM :-
MaybeRBMM = goal_info_get_maybe_rbmm(GoalInfo),
(
MaybeRBMM = yes(RBMM)
;
MaybeRBMM = no,
unexpected($pred, "Requesting unavailable RBMM information.")
).
%---------------------------------------------------------------------------%
:- end_module transform_hlds.rbmm.add_rbmm_goal_infos.
%---------------------------------------------------------------------------%