-
-
-
-combineCaseValues
- :: AnalysisKind
- -> AbsVal -- Value of scrutinee
- -> [AbsVal] -- Value of branches (at least one)
- -> AbsVal -- Result
-
--- For strictness analysis, see if the scrutinee is bottom; if so
--- return bottom; otherwise, the lub of the branches.
-
-combineCaseValues StrAnal AbsBot branches = AbsBot
-combineCaseValues StrAnal other_scrutinee branches
- -- Scrutinee can only be AbsBot, AbsProd or AbsTop
- = ASSERT(ok_scrutinee)
- foldr1 lub branches
- where
- ok_scrutinee
- = case other_scrutinee of {
- AbsTop -> True; -- i.e., cool
- AbsProd _ -> True; -- ditto
- _ -> False -- party over
- }
-
--- For absence analysis, check if the scrutinee is all poison (isBot)
--- If so, return poison (AbsBot); otherwise, any nested poison will come
--- out from looking at the branches, so just glb together the branches
--- to get the worst one.
-
-combineCaseValues AbsAnal AbsBot branches = AbsBot
-combineCaseValues AbsAnal other_scrutinee branches
- -- Scrutinee can only be AbsBot, AbsProd or AbsTop
- = ASSERT(ok_scrutinee)
- let
- result = foldr1 glb branches
-
- tracer = if at_least_one_AbsFun && at_least_one_AbsTop
- && no_AbsBots then
- pprTrace "combineCase:" (ppr PprDebug branches)
- else
- id
- in
--- tracer (
- result
--- )
- where
- ok_scrutinee
- = case other_scrutinee of {
- AbsTop -> True; -- i.e., cool
- AbsProd _ -> True; -- ditto
- _ -> False -- party over
- }
-
- at_least_one_AbsFun = foldr ((||) . is_AbsFun) False branches
- at_least_one_AbsTop = foldr ((||) . is_AbsTop) False branches
- no_AbsBots = foldr ((&&) . is_not_AbsBot) True branches
-
- is_AbsFun x = case x of { AbsFun _ _ _ -> True; _ -> False }
- is_AbsTop x = case x of { AbsTop -> True; _ -> False }
- is_not_AbsBot x = case x of { AbsBot -> False; _ -> True }