diff: fix for bug in switch detection
Fergus Henderson
fjh at cs.mu.oz.au
Sun May 11 02:20:46 AEST 1997
compiler/switch_detection.m:
Fix a bug. It was preferring incomplete switches to
complete one-case switches, which lead to spurious determinism
errors in some cases.
Index: switch_detection.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/switch_detection.m,v
retrieving revision 1.69
diff -u -r1.69 switch_detection.m
--- switch_detection.m 1997/05/08 06:46:56 1.69
+++ switch_detection.m 1997/05/10 16:16:19
@@ -214,16 +214,44 @@
inst_is_bound(ModuleInfo, VarInst0),
partition_disj(Goals0, Var, GoalInfo, Left, CasesList)
->
- % are there any disjuncts that are not part of the switch?
+ %
+ % A switch needs to have at least two cases.
+ %
+ % But, if there is a complete one-case switch
+ % for a goal, we must leave it as a disjunction
+ % rather than doing an incomplete switch on a
+ % different variable, because otherwise we might
+ % get determinism analysis wrong. (The complete
+ % one-case switch may be decomposable into other
+ % complete sub-switches on the functor's arguments)
+ %
(
+ % are there any disjuncts that are not part of the
+ % switch?
Left = []
->
- cases_to_switch(CasesList, Var, VarTypes, GoalInfo,
- SM, InstMap, ModuleInfo, Goal)
+ ( CasesList = [_, _ | _] ->
+ cases_to_switch(CasesList, Var, VarTypes,
+ GoalInfo, SM, InstMap, ModuleInfo,
+ Goal)
+ ;
+ detect_sub_switches_in_disj(Goals0, InstMap,
+ VarTypes, ModuleInfo, Goals),
+ Goal = disj(Goals, SM)
+ )
;
+ % insert this switch into the list of incomplete
+ % switches only if it has at least two cases
+ %
+ ( CasesList = [_, _ | _] ->
+ Again1 = [again(Var, Left, CasesList) | Again0]
+ ;
+ Again1 = Again0
+ ),
+ % try to find a switch
detect_switches_in_disj(Vars, Goals0, GoalInfo,
SM, InstMap, VarTypes, AllVars, ModuleInfo,
- [again(Var, Left, CasesList) | Again0], Goal)
+ Again1, Goal)
)
;
detect_switches_in_disj(Vars, Goals0, GoalInfo, SM, InstMap,
@@ -322,8 +350,8 @@
map__init(Cases0),
partition_disj_trial(Goals0, Var, [], Left, Cases0, Cases),
map__to_assoc_list(Cases, CasesAssocList),
- fix_case_list(CasesAssocList, GoalInfo, CasesList),
- CasesList = [_, _ | _]. % there must be more than one case
+ CasesAssocList \= [],
+ fix_case_list(CasesAssocList, GoalInfo, CasesList).
:- pred partition_disj_trial(list(hlds_goal), var,
list(hlds_goal), list(hlds_goal), cases, cases).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list