diff options
author | diederik | 2002-07-25 14:56:04 +0000 |
---|---|---|
committer | diederik | 2002-07-25 14:56:04 +0000 |
commit | 04dee0631e984781485d6c23e0bdcb67fab13ffd (patch) | |
tree | 22312730547f20664b3ba7ceead31d70ee9b74e9 /frontend/classify.icl | |
parent | make args for which specials exist active (diff) |
extend for reclassify
improve refcounts for case
git-svn-id: https://svn.cs.ru.nl/repos/clean-compiler/trunk@1173 1f8540f1-abd5-4d5b-9d24-4c5ce8603e2d
Diffstat (limited to 'frontend/classify.icl')
-rw-r--r-- | frontend/classify.icl | 781 |
1 files changed, 671 insertions, 110 deletions
diff --git a/frontend/classify.icl b/frontend/classify.icl index 2b86b72..0b1966f 100644 --- a/frontend/classify.icl +++ b/frontend/classify.icl @@ -87,7 +87,7 @@ where = (inc length, [x : xs]) mapAndLength f [] = (0, []) - + skip_indirections subst cc | IsAVariable cc = skip_indirections subst subst.[cc] @@ -99,12 +99,14 @@ where :: *AnalyseInfo = { ai_var_heap :: !*VarHeap - , ai_cons_class :: !*{! ConsClasses} + , ai_cons_class :: !*{!ConsClasses} , ai_cur_ref_counts :: !*RefCounts // for each variable 0,1 or 2 - , ai_class_subst :: !* ConsClassSubst + , ai_class_subst :: !*ConsClassSubst , ai_next_var :: !Int , ai_next_var_of_fun :: !Int , ai_cases_of_vars_for_function :: ![Case] + , ai_fun_heap :: !*FunctionHeap + , ai_def_ref_counts :: !RefCounts } /* defined in syntax.dcl: @@ -267,7 +269,7 @@ where = ai instance consumerRequirements App where - consumerRequirements {app_symb={symb_kind = SK_Function {glob_module,glob_object}, symb_name}, app_args} + consumerRequirements {app_symb={symb_kind = SK_Function {glob_module,glob_object},symb_name}, app_args} common_defs=:(ConsumerAnalysisRO {main_dcl_module_n,stdStrictLists_module_n,imported_funs}) ai=:{ai_cons_class} @@ -277,7 +279,7 @@ instance consumerRequirements App where = reqs_of_args fun_class.cc_args app_args CPassive common_defs ai = consumerRequirements app_args common_defs ai - | glob_module==stdStrictLists_module_n && (not (isEmpty app_args)) + | glob_module == stdStrictLists_module_n && (not (isEmpty app_args)) && is_nil_cons_or_decons_of_UList_or_UTSList glob_object glob_module imported_funs # [app_arg:app_args]=app_args; # (cc, _, ai) = consumerRequirements app_arg common_defs ai @@ -298,17 +300,27 @@ instance consumerRequirements App where = activeArgs (n-1) app_args common_defs ai // ...SPECIAL = consumerRequirements app_args common_defs ai - consumerRequirements {app_symb={symb_kind = SK_LocalMacroFunction glob_object, symb_name}, app_args} + consumerRequirements {app_symb={symb_kind = SK_LocalMacroFunction glob_object,symb_name}, app_args} common_defs=:(ConsumerAnalysisRO {main_dcl_module_n}) ai=:{ai_cons_class} | glob_object < size ai_cons_class #! fun_class = ai_cons_class.[glob_object] = reqs_of_args fun_class.cc_args app_args CPassive common_defs ai = consumerRequirements app_args common_defs ai + + // new alternative for generated function + reanalysis... + consumerRequirements {app_symb={symb_kind = SK_GeneratedFunction fun_info_ptr index,symb_name}, app_args} + common_defs + ai + # (FI_Function {gf_cons_args={cc_args,cc_linear_bits}}, ai_fun_heap) + = readPtr fun_info_ptr ai.ai_fun_heap + = reqs_of_args cc_args app_args CPassive common_defs {ai & ai_fun_heap = ai_fun_heap} + consumerRequirements {app_args} common_defs ai = not_an_unsafe_pattern (consumerRequirements app_args common_defs ai) -reqs_of_args :: [.Int] !.[Expression] Int ConsumerAnalysisRO !*AnalyseInfo -> *(!Int,!.Bool,!*AnalyseInfo) + +reqs_of_args :: ![ConsClass] !.[Expression] ConsClass ConsumerAnalysisRO !*AnalyseInfo -> *(!ConsClass,!.Bool,!*AnalyseInfo) reqs_of_args _ [] cumm_arg_class _ ai = (cumm_arg_class, False, ai) reqs_of_args [] _ cumm_arg_class _ ai @@ -317,18 +329,48 @@ reqs_of_args [form_cc : ccs] [arg : args] cumm_arg_class common_defs ai # (act_cc, _, ai) = consumerRequirements arg common_defs ai ai = aiUnifyClassifications form_cc act_cc ai = reqs_of_args ccs args (combineClasses act_cc cumm_arg_class) common_defs ai +reqs_of_args cc xp _ _ _ = abort "classify:reqs_of_args doesn't match" ---> (cc,xp) + +showRefCount msg ai + :== ai ---> (msg,rc) +where + {ai_cur_ref_counts} = ai + + rc :: String + rc = {show c \\ c <-: ai_cur_ref_counts} + + show 0 = '0' + show 1 = '1' + show 2 = '2' + show _ = '?' instance consumerRequirements Case where - consumerRequirements kees=:{case_expr,case_guards,case_default,case_info_ptr} common_defs=:(ConsumerAnalysisRO {common_defs=common_defs_parameter}) ai - # (cce, _, ai) = consumerRequirements case_expr common_defs ai - (ccgs, unsafe_bits, ai) = consumer_requirements_of_guards case_guards common_defs ai - has_default = case case_default of - Yes _ -> True - _ -> False - (ccd, default_is_unsafe, ai) = consumerRequirements case_default common_defs ai - (every_constructor_appears_in_safe_pattern, may_be_active) = inspect_patterns common_defs_parameter has_default case_guards unsafe_bits - safe = (has_default && not default_is_unsafe) || every_constructor_appears_in_safe_pattern - ai = aiUnifyClassifications (if may_be_active CActive CVarOfMultimatchCase) cce ai + consumerRequirements kees=:{case_expr,case_guards,case_default,case_info_ptr,case_explicit} + common_defs=:(ConsumerAnalysisRO {common_defs=common_defs_parameter}) ai + # (cce, _, ai) = consumerRequirements case_expr common_defs ai + #! env_counts = ai.ai_cur_ref_counts + (s,env_counts) = usize env_counts + zero_array = createArray s 0 + ai = {ai & ai_cur_ref_counts = zero_array} + (ccd, default_is_unsafe, ai) = consumerRequirements case_default common_defs ai + #! (context_counts,ai) = case use_context_default of + True + -> ({},{ai & ai_cur_ref_counts = env_counts}) + False + -> (ai.ai_def_ref_counts,{ai & ai_def_ref_counts = ai.ai_cur_ref_counts, ai_cur_ref_counts = env_counts}) + # (ccgs, unsafe_bits, ai) = consumer_requirements_of_guards case_guards common_defs ai + # ai = case use_context_default of + True + -> ai + False + -> {ai & ai_def_ref_counts = context_counts} + # (every_constructor_appears_in_safe_pattern, may_be_active) + = inspect_patterns common_defs_parameter has_default case_guards unsafe_bits + safe = case_explicit || (has_default && not default_is_unsafe) || every_constructor_appears_in_safe_pattern + ai = aiUnifyClassifications (SwitchMultimatchClassification + (if may_be_active CActive CVarOfMultimatchCase) + CActive) + cce ai ai = case case_expr of Var {var_info_ptr} | may_be_active @@ -348,19 +390,28 @@ instance consumerRequirements Case where -> ai = (combineClasses ccgs ccd, not safe, ai) where + has_default = case case_default of + Yes _ -> True + _ -> False + use_context_default = not (case_explicit || has_default) + inspect_patterns common_defs has_default (AlgebraicPatterns {glob_object, glob_module} algebraic_patterns) unsafe_bits - # type_def = common_defs.[glob_module].com_type_defs.[glob_object] - defined_symbols = case type_def.td_rhs of - AlgType defined_symbols -> defined_symbols - RecordType {rt_constructor} -> [rt_constructor] - all_constructors = [ ds_index \\ {ds_index}<-defined_symbols ] - pattern_constructors = [ glob_object.ds_index \\ {ap_symbol={glob_object}}<-algebraic_patterns] - sorted_pattern_constructors = sort pattern_constructors unsafe_bits - all_sorted_constructors = if (is_sorted all_constructors) all_constructors (sortBy (<) all_constructors) - = (appearance_loop all_sorted_constructors sorted_pattern_constructors, not (multimatch_loop has_default sorted_pattern_constructors)) + # type_def = common_defs.[glob_module].com_type_defs.[glob_object] + defined_symbols = case type_def.td_rhs of + AlgType defined_symbols -> defined_symbols + RecordType {rt_constructor} -> [rt_constructor] + all_constructors = [ ds_index \\ {ds_index}<-defined_symbols ] + pattern_constructors = [ glob_object.ds_index \\ {ap_symbol={glob_object}}<-algebraic_patterns] + sorted_pattern_constructors = sort pattern_constructors unsafe_bits + all_sorted_constructors = if (is_sorted all_constructors) + all_constructors + (sortBy (<) all_constructors) + = ( appearance_loop all_sorted_constructors sorted_pattern_constructors + , not (multimatch_loop has_default sorted_pattern_constructors) + ) inspect_patterns common_defs has_default (BasicPatterns BT_Bool basic_patterns) unsafe_bits - # bools_indices = [ if bool 1 0 \\ {bp_value=BVB bool}<-basic_patterns ] - sorted_pattern_constructors = sort bools_indices unsafe_bits + # bools_indices = [ if bool 1 0 \\ {bp_value=BVB bool}<-basic_patterns ] + sorted_pattern_constructors = sort bools_indices unsafe_bits = (appearance_loop [0,1] sorted_pattern_constructors, not (multimatch_loop has_default sorted_pattern_constructors)) // inspect_patterns common_defs has_default (OverloadedListPatterns {glob_object, glob_module} algebraic_patterns) unsafe_bits @@ -432,20 +483,29 @@ instance consumerRequirements Case where consumer_requirements_of_guards :: !CasePatterns ConsumerAnalysisRO !*AnalyseInfo -> (!Int,.[Bool],!*AnalyseInfo) consumer_requirements_of_guards (AlgebraicPatterns type patterns) common_defs ai - # pattern_exprs = [ ap_expr \\ {ap_expr}<-patterns] - pattern_vars = flatten [ ap_vars \\ {ap_vars}<-patterns] - (ai_next_var, ai_next_var_of_fun, ai_var_heap) = bindPatternVars pattern_vars ai.ai_next_var ai.ai_next_var_of_fun ai.ai_var_heap - ai = { ai & ai_var_heap=ai_var_heap, ai_next_var=ai_next_var, ai_next_var_of_fun = ai_next_var_of_fun } + # pattern_exprs + = [ ap_expr \\ {ap_expr}<-patterns] + pattern_vars + = flatten [ ap_vars \\ {ap_vars}<-patterns] + (ai_next_var, ai_next_var_of_fun, ai_var_heap) + = bindPatternVars pattern_vars ai.ai_next_var ai.ai_next_var_of_fun ai.ai_var_heap + ai = { ai & ai_var_heap=ai_var_heap, ai_next_var=ai_next_var, ai_next_var_of_fun = ai_next_var_of_fun } = independentConsumerRequirements pattern_exprs common_defs ai consumer_requirements_of_guards (BasicPatterns type patterns) common_defs ai - # pattern_exprs = [ bp_expr \\ {bp_expr}<-patterns] + # pattern_exprs + = [ bp_expr \\ {bp_expr}<-patterns] = independentConsumerRequirements pattern_exprs common_defs ai consumer_requirements_of_guards (OverloadedListPatterns type _ patterns) common_defs ai - # pattern_exprs = [ ap_expr \\ {ap_expr}<-patterns] - pattern_vars = flatten [ ap_vars \\ {ap_vars}<-patterns] - (ai_next_var, ai_next_var_of_fun, ai_var_heap) = bindPatternVars pattern_vars ai.ai_next_var ai.ai_next_var_of_fun ai.ai_var_heap - ai = { ai & ai_var_heap=ai_var_heap, ai_next_var=ai_next_var, ai_next_var_of_fun = ai_next_var_of_fun } + # pattern_exprs + = [ ap_expr \\ {ap_expr}<-patterns] + pattern_vars + = flatten [ ap_vars \\ {ap_vars}<-patterns] + (ai_next_var, ai_next_var_of_fun, ai_var_heap) + = bindPatternVars pattern_vars ai.ai_next_var ai.ai_next_var_of_fun ai.ai_var_heap + ai = { ai & ai_var_heap=ai_var_heap, ai_next_var=ai_next_var, ai_next_var_of_fun = ai_next_var_of_fun } = independentConsumerRequirements pattern_exprs common_defs ai +consumer_requirements_of_guards NoPattern common_defs ai + = independentConsumerRequirements [] common_defs ai bindPatternVars :: !.[FreeVar] !Int !Int !*VarHeap -> (!Int,!Int,!*VarHeap) bindPatternVars [fv=:{fv_info_ptr,fv_count} : vars] next_var next_var_of_fun var_heap @@ -459,26 +519,150 @@ bindPatternVars [] next_var next_var_of_fun var_heap = (next_var, next_var_of_fun, var_heap) independentConsumerRequirements :: !.[Expression] ConsumerAnalysisRO !*AnalyseInfo -> (!Int,.[Bool],!*AnalyseInfo) +independentConsumerRequirements [] common_defs ai=:{ai_cur_ref_counts,ai_def_ref_counts} + #! s = size ai_cur_ref_counts + unified_ref_counts = unify_with_default` s ai_cur_ref_counts ai_def_ref_counts + ai = {ai & ai_cur_ref_counts = unified_ref_counts} + = (CPassive,[],ai) +where + unify_with_default` 0 accu env + = accu + unify_with_default` i accu env + #! i1 = dec i + rca = accu.[i1] + rce = env.[i1] + accu = { accu & [i1] = unify_counts rca rce } + = unify_with_default` i1 accu env + where + unify_counts 0 x = x + unify_counts 1 x = if (x==2) 2 (inc x) + unify_counts 2 x = 2 + +independentConsumerRequirements [expr:exprs] common_defs ai=:{ai_cur_ref_counts,ai_def_ref_counts} + #! s = size ai_cur_ref_counts + zero_array = createArray s 0 + ai = { ai & ai_cur_ref_counts=zero_array } + + (cce, is_unsafe_case, ai) = consumerRequirements expr common_defs ai + cc = combineClasses cce CPassive + r_unsafe_bits = [is_unsafe_case] + + pat_counts = case is_unsafe_case of + True -> combine_with_default s ai.ai_cur_ref_counts ai_def_ref_counts + False -> ai.ai_cur_ref_counts + = case exprs of + [] //| size ai.ai_cur_ref_counts <> s || size ai_def_ref_counts <> s -> abort ("("+++toString s+++","+++ toString (size ai.ai_cur_ref_counts) +++","+++toString (size ai_def_ref_counts) +++")") + #! unified_pat_counts = unify_with_default s ai.ai_cur_ref_counts ai_def_ref_counts + unified_ref_counts = unify_pattern_accu_with_env s unified_pat_counts ai_cur_ref_counts + ai = { ai & ai_cur_ref_counts=unified_ref_counts } + -> (cc, r_unsafe_bits, ai) + _ #! zero_array = createArray s 0 + accu = ai.ai_cur_ref_counts + ai = { ai & ai_cur_ref_counts=zero_array } + (accu,cc,r_unsafe_bits,ai) = foldSt (build_pattern_accu common_defs) exprs (accu,cc,r_unsafe_bits,ai) + //| size ai.ai_cur_ref_counts <> s || size ai_def_ref_counts <> s -> abort "222" + #! unified_pat_counts = unify_with_default s accu ai_def_ref_counts + unified_ref_counts = unify_pattern_accu_with_env s unified_pat_counts ai_cur_ref_counts + ai = { ai & ai_cur_ref_counts=unified_ref_counts } + -> (cc, reverse r_unsafe_bits, ai) +where + build_pattern_accu common_defs expr (ref_counts_accu,cc,unsafe_bits_accu,ai) + # (s,ai) = getSize ai + #! (cce, is_unsafe_case, ai) = consumerRequirements expr common_defs ai + cc = combineClasses cce cc + unsafe_bits_accu = [is_unsafe_case:unsafe_bits_accu] + + #! ai_cur_ref_counts` = ai.ai_cur_ref_counts + pat_counts = case is_unsafe_case of + True -> combine_with_default s ai_cur_ref_counts` ai_def_ref_counts + False -> ai_cur_ref_counts` + + (ref_counts_accu,zero_array) = unify_pattern_accu_with_pat s ref_counts_accu pat_counts + ai = { ai & ai_cur_ref_counts=zero_array } + = (ref_counts_accu,cc,unsafe_bits_accu,ai) + where + getSize :: !*AnalyseInfo -> (!Int,!*AnalyseInfo) + getSize ai=:{ai_cur_ref_counts} + # (s,ai_cur_ref_counts) = usize ai_cur_ref_counts + = (s,{ ai & ai_cur_ref_counts = ai_cur_ref_counts}) + + + unify_with_default :: !Int !*RefCounts !RefCounts -> *RefCounts + unify_with_default 0 accu env + = accu + unify_with_default i accu env + #! i1 = dec i + rca = accu.[i1] + rce = env.[i1] + accu = { accu & [i1] = unify_counts rce rca } + = unify_with_default i1 accu env + where + unify_counts 0 x = x + unify_counts 1 x = if (x==0) 1 x + unify_counts 2 x = 2 + + combine_with_default 0 accu env + = accu + combine_with_default i accu env + #! i1 = dec i + rca = accu.[i1] + rce = env.[i1] + accu = { accu & [i1] = unify_counts rca rce } + = combine_with_default i1 accu env + where + unify_counts 0 x = x + unify_counts 1 x = if (x==2) 2 (inc x) + unify_counts 2 x = 2 + + unify_pattern_accu_with_env 0 accu env + = env + unify_pattern_accu_with_env i accu env + #! i1 = dec i + rca = accu.[i1] + rce = env.[i1] + env = { env & [i1] = unify_counts rca rce } + = unify_pattern_accu_with_env i1 accu env + where + unify_counts 0 x = x + unify_counts 1 x = if (x==2) 2 (inc x) + unify_counts 2 x = 2 + + unify_pattern_accu_with_pat :: !Int !*RefCounts !*RefCounts -> (!*RefCounts,!*RefCounts) + unify_pattern_accu_with_pat 0 accu pat + = (accu,pat) + unify_pattern_accu_with_pat i accu pat + #! i1 = dec i + rca = accu.[i1] + rcp = pat.[i1] + accu = { accu & [i1] = unify_counts rcp rca } + pat = { pat & [i1] = 0 } + = unify_pattern_accu_with_pat i1 accu pat + where + unify_counts 0 x = x + unify_counts 1 x = if (x==0) 1 x + unify_counts 2 x = 2 + +/* old WRONG version... independentConsumerRequirements exprs common_defs ai=:{ai_cur_ref_counts} // reference counting happens independently for each pattern expression - #! s = size ai_cur_ref_counts - zero_array = createArray s 0 - (_, cc, r_unsafe_bits ,ai) = foldSt (independent_consumer_requirements common_defs) exprs (zero_array, CPassive, [], ai) + #! s = size ai_cur_ref_counts + zero_array = createArray s 0 + (_, cc, r_unsafe_bits ,ai) = foldSt (independent_consumer_requirements common_defs) exprs (zero_array, CPassive, [], ai) = (cc, reverse r_unsafe_bits, ai) - where +where independent_consumer_requirements common_defs expr (zero_array, cc, unsafe_bits_accu, ai=:{ai_cur_ref_counts}) - #! s = size ai_cur_ref_counts - ai = { ai & ai_cur_ref_counts=zero_array } - (cce, is_unsafe_case, ai) = consumerRequirements expr common_defs ai - (unused, unified_ref_counts) = unify_ref_count_arrays s ai_cur_ref_counts ai.ai_cur_ref_counts - ai = { ai & ai_cur_ref_counts=unified_ref_counts } + #! s = size ai_cur_ref_counts + ai = { ai & ai_cur_ref_counts=zero_array } + (cce, is_unsafe_case, ai) = consumerRequirements expr common_defs ai + (unused, unified_ref_counts) = unify_ref_count_arrays s ai_cur_ref_counts ai.ai_cur_ref_counts + ai = { ai & ai_cur_ref_counts=unified_ref_counts } = ({ unused & [i]=0 \\ i<-[0..s-1]}, combineClasses cce cc, [is_unsafe_case:unsafe_bits_accu], ai) unify_ref_count_arrays 0 src1 src2_dest = (src1, src2_dest) unify_ref_count_arrays i src1 src2_dest - #! i1 = dec i - rc1 = src1.[i1] - rc2 = src2_dest.[i1] + #! i1 = dec i + rc1 = src1.[i1] + rc2 = src2_dest.[i1] src2_dest = { src2_dest & [i1] = unify_ref_counts rc1 rc2 } = unify_ref_count_arrays i1 src1 src2_dest @@ -486,7 +670,7 @@ independentConsumerRequirements exprs common_defs ai=:{ai_cur_ref_counts} unify_ref_counts 0 x = if (x==2) 2 0 unify_ref_counts 1 x = if (x==0) 1 2 unify_ref_counts 2 _ = 2 - +*/ instance consumerRequirements DynamicExpr where consumerRequirements {dyn_expr} common_defs ai = consumerRequirements dyn_expr common_defs ai @@ -509,7 +693,7 @@ instance consumerRequirements (!a,!b) | consumerRequirements a & consumerRequire instance consumerRequirements [a] | consumerRequirements a where consumerRequirements [x : xs] common_defs ai - # (ccx, _, ai) = consumerRequirements x common_defs ai + # (ccx, _, ai) = consumerRequirements x common_defs ai (ccxs, _, ai) = consumerRequirements xs common_defs ai = (combineClasses ccx ccxs, False, ai) consumerRequirements [] _ ai @@ -525,8 +709,8 @@ instance consumerRequirements (Bind a b) | consumerRequirements a where analyseGroups :: !{# CommonDefs} !{#{#FunType}} !IndexRange !Int !Int !*{! Group} !*{#FunDef} !*VarHeap !*ExpressionHeap -> (!CleanupInfo, !*{! ConsClasses}, !*{! Group}, !*{#FunDef}, !*VarHeap, !*ExpressionHeap) analyseGroups common_defs imported_funs {ir_from, ir_to} main_dcl_module_n stdStrictLists_module_n groups fun_defs var_heap expr_heap - #! nr_of_funs = size fun_defs + ir_from - ir_to /* Sjaak */ - nr_of_groups = size groups + #! nr_of_funs = size fun_defs + ir_from - ir_to /* Sjaak */ + nr_of_groups = size groups # consumerAnalysisRO=ConsumerAnalysisRO { common_defs = common_defs , imported_funs = imported_funs @@ -538,69 +722,101 @@ analyseGroups common_defs imported_funs {ir_from, ir_to} main_dcl_module_n stdSt ([], class_env, groups, fun_defs, var_heap, expr_heap) where analyse_group common_defs group_nr (cleanup_info, class_env, groups, fun_defs, var_heap, expr_heap) - # ({group_members}, groups) = groups![group_nr] - # (nr_of_vars, nr_of_local_vars, var_heap, class_env, fun_defs) = initial_cons_class group_members 0 0 var_heap class_env fun_defs - initial_subst = createArray (nr_of_vars + nr_of_local_vars) CPassive - (ai_cases_of_vars_for_group, ai, fun_defs) - = analyse_functions common_defs group_members [] - { ai_var_heap = var_heap, - ai_cons_class = class_env, - ai_cur_ref_counts = {}, ai_class_subst = initial_subst, - ai_next_var = nr_of_vars, - ai_next_var_of_fun = 0, - ai_cases_of_vars_for_function = [] //, -// ai_main_dcl_module_n=main_dcl_module_n - } fun_defs - class_env = collect_classifications group_members ai.ai_cons_class ai.ai_class_subst + # ({group_members}, groups) + = groups![group_nr] + + # (next_var, nr_of_local_vars, var_heap, class_env, fun_defs) + = foldSt initial_cons_class group_members (0, 0, var_heap, class_env, fun_defs) + + # ai = + { ai_var_heap = var_heap + , ai_cons_class = class_env + , ai_cur_ref_counts = {} + , ai_class_subst = createArray (next_var + nr_of_local_vars) CPassive + , ai_next_var = next_var + , ai_next_var_of_fun = 0 + , ai_cases_of_vars_for_function = [] + , ai_fun_heap = newHeap + , ai_def_ref_counts = {} + } + + # (ai_cases_of_vars_for_group, ai, fun_defs) + = foldSt (analyse_functions common_defs) group_members ([], ai, fun_defs) + + class_env + = ai.ai_cons_class + class_env + = foldSt (collect_classifications ai.ai_class_subst) group_members class_env (cleanup_info, class_env, fun_defs, var_heap, expr_heap) - = foldSt set_case_expr_info (flatten ai_cases_of_vars_for_group) (cleanup_info,class_env, fun_defs, ai.ai_var_heap, expr_heap) + = foldSt set_case_expr_info (flatten ai_cases_of_vars_for_group) + (cleanup_info, class_env, fun_defs, ai.ai_var_heap, expr_heap) = (cleanup_info, class_env, groups, fun_defs, var_heap, expr_heap) where //initial classification... - initial_cons_class [fun : funs] next_var_number nr_of_local_vars var_heap class_env fun_defs - # (fun_def, fun_defs) = fun_defs![fun] - # (TransformedBody {tb_args}) = fun_def.fun_body - (fresh_vars, next_var_number, var_heap) = fresh_variables tb_args 0 next_var_number var_heap - = initial_cons_class funs next_var_number (length fun_def.fun_info.fi_local_vars + nr_of_local_vars) var_heap - { class_env & [fun] = { cc_size = 0, cc_args = fresh_vars, cc_linear_bits=[], cc_producer=False}} fun_defs - initial_cons_class [] next_var_number nr_of_local_vars var_heap class_env fun_defs - = (next_var_number, nr_of_local_vars, var_heap, class_env, fun_defs) + initial_cons_class fun (next_var, nr_of_local_vars, var_heap, class_env, fun_defs) + # (fun_def, fun_defs) = fun_defs![fun] + (TransformedBody {tb_args}) = fun_def.fun_body + + nr_of_locals = length fun_def.fun_info.fi_local_vars + nr_of_local_vars = nr_of_local_vars + nr_of_locals + + # (fresh_vars, next_var, var_heap) + = fresh_variables tb_args 0 next_var var_heap + # fun_class = { cc_size = 0, cc_args = fresh_vars, cc_linear_bits=[], cc_producer=False} + class_env = { class_env & [fun] = fun_class} + = (next_var, nr_of_local_vars, var_heap, class_env, fun_defs) //determine classification... - analyse_functions common_defs [fun : funs] cfvog_accu ai fun_defs - # (fun_def, fun_defs) = fun_defs![fun] - (TransformedBody {tb_args, tb_rhs}) = fun_def.fun_body - nr_of_args = length tb_args - ai = { ai & ai_cur_ref_counts = createArray (nr_of_args + length fun_def.fun_info.fi_local_vars) 0, - ai_next_var_of_fun = nr_of_args } - (_, _, ai) = consumerRequirements tb_rhs common_defs ai - ai_cur_ref_counts = ai.ai_cur_ref_counts - ai = { ai & ai_cur_ref_counts={} } - ai_cons_class = update_array_element ai.ai_cons_class fun - (\cc->{ cc & cc_linear_bits=[ ref_count<2 \\ ref_count<-:ai_cur_ref_counts] }) - cases_of_vars_for_function = [(a,fun) \\ a<-ai.ai_cases_of_vars_for_function ] - ai = { ai & ai_cons_class=ai_cons_class, ai_cases_of_vars_for_function=[] } - = analyse_functions common_defs funs [cases_of_vars_for_function:cfvog_accu] ai fun_defs - where - update_array_element array index transition - # (before, array) = array![index] - = { array & [index]=transition before } - analyse_functions common_defs [] cfvog_accu ai fun_defs + analyse_functions common_defs fun (cfvog_accu, ai, fun_defs) + # (fun_def, fun_defs) = fun_defs![fun] + (TransformedBody {tb_args, tb_rhs}) = fun_def.fun_body + + nr_of_locals = length fun_def.fun_info.fi_local_vars + nr_of_args = length tb_args + + ai = { ai + & ai_cur_ref_counts = createArray (nr_of_args + nr_of_locals) 0 + , ai_def_ref_counts = createArray (nr_of_args + nr_of_locals) 0 + , ai_next_var_of_fun = nr_of_args + } + // classify + (_, _, ai) = consumerRequirements tb_rhs common_defs ai + // set linearity info based on cur_ref_counts + # ai_cur_ref_counts = ai.ai_cur_ref_counts + ai_cons_class = ai.ai_cons_class + (fun_cons_class,ai_cons_class) = ai_cons_class![fun] + linear_bits = [ ref_count<2 \\ ref_count <-: ai_cur_ref_counts ] + fun_cons_class = { fun_cons_class & cc_linear_bits=linear_bits } + cc_args = add_unused_args fun_cons_class.cc_args ai_cur_ref_counts + fun_cons_class = { fun_cons_class & cc_args = cc_args } + ai_cons_class = {ai_cons_class & [fun] = fun_cons_class} + cases_of_vars_for_function = [(a,fun) \\ a <- ai.ai_cases_of_vars_for_function ] + cfvog_accu = [cases_of_vars_for_function:cfvog_accu] + + ai = { ai + & ai_cons_class = ai_cons_class + , ai_cases_of_vars_for_function = [] + , ai_cur_ref_counts = {} + } = (cfvog_accu, ai, fun_defs) //final classification... - collect_classifications [] class_env class_subst - = class_env - collect_classifications [fun : funs] class_env class_subst - # (fun_class, class_env) = class_env![fun] - # fun_class = determine_classification fun_class class_subst - = collect_classifications funs { class_env & [fun] = fun_class /*---> (fun, fun_class)*/} class_subst - - set_case_expr_info ({case_expr=case_expr=:(Var {var_info_ptr}), case_guards, case_info_ptr},fun_index) (cleanup_acc, class_env, fun_defs, var_heap, expr_heap) - # (VI_AccVar _ arg_position, var_heap) = readPtr var_info_ptr var_heap - ({cc_size, cc_args, cc_linear_bits},class_env) = class_env![fun_index] - (aci_linearity_of_patterns, var_heap) = get_linearity_info cc_linear_bits case_guards var_heap + collect_classifications class_subst fun class_env + # (fun_class, class_env) = class_env![fun] + fun_class = determine_classification fun_class class_subst + = { class_env & [fun] = fun_class + + set_case_expr_info ({case_expr=case_expr=:(Var {var_info_ptr}), case_guards, case_info_ptr},fun_index) + (cleanup_acc, class_env, fun_defs, var_heap, expr_heap) + # (VI_AccVar _ arg_position, var_heap) = readPtr var_info_ptr var_heap + ({cc_size, cc_args, cc_linear_bits},class_env) = class_env![fun_index] + (aci_linearity_of_patterns, var_heap) = get_linearity_info cc_linear_bits case_guards var_heap | arg_position<cc_size && (arg_position>=cc_size || cc_args!!arg_position==CActive) && cc_linear_bits!!arg_position // mark non multimatch cases whose case_expr is an active linear function argument - # aci = { aci_params = [], aci_opt_unfolder = No, aci_free_vars=No, aci_linearity_of_patterns = aci_linearity_of_patterns } + # aci = + { aci_params = [] + , aci_opt_unfolder = No + , aci_free_vars = No + , aci_linearity_of_patterns = aci_linearity_of_patterns + } = ([case_info_ptr:cleanup_acc], class_env, fun_defs, var_heap, setExtendedExprInfo case_info_ptr (EEI_ActiveCase aci) expr_heap) = (cleanup_acc, class_env, fun_defs, var_heap, expr_heap) @@ -615,6 +831,182 @@ where get_linearity_info_of_pattern cc_linear_bits {ap_vars} var_heap # (var_indices, var_heap) = mapSt get_var_index ap_vars var_heap = ([if (index==cNope) True (cc_linear_bits!!index) \\ index<-var_indices], var_heap) + + get_var_index {fv_info_ptr} var_heap + # (vi, var_heap) = readPtr fv_info_ptr var_heap + index = case vi of + VI_AccVar _ index -> index + VI_Count 0 False -> cNope + = (index, var_heap) + +reanalyseGroups :: !{# CommonDefs} !{#{#FunType}} !Int !Int ![FunctionInfoPtr] ![Group] !*{#FunDef} !*VarHeap !*ExpressionHeap !*FunctionHeap !*{!ConsClasses} + -> (!CleanupInfo, !*{#FunDef}, !*VarHeap, !*ExpressionHeap, !*FunctionHeap, !*{!ConsClasses}) +reanalyseGroups common_defs imported_funs main_dcl_module_n stdStrictLists_module_n new_functions + groups fun_defs var_heap expr_heap fun_heap class_env + #! nr_of_groups = size groups + # consumerAnalysisRO=ConsumerAnalysisRO + { common_defs = common_defs + , imported_funs = imported_funs + , main_dcl_module_n = main_dcl_module_n + , stdStrictLists_module_n = stdStrictLists_module_n + } + = foldSt (analyse_group consumerAnalysisRO) groups + ([], fun_defs, var_heap, expr_heap, fun_heap, class_env) +where + analyse_group common_defs group (cleanup_info, fun_defs, var_heap, expr_heap, fun_heap, class_env) + # {group_members} = group + + # (next_var, nr_of_local_vars, var_heap, class_env, fun_defs, fun_heap) + = foldSt initial_cons_class group_members (0, 0, var_heap, class_env, fun_defs, fun_heap) + + # ai = + { ai_var_heap = var_heap + , ai_cons_class = class_env + , ai_cur_ref_counts = {} + , ai_class_subst = createArray (next_var + nr_of_local_vars) CPassive + , ai_next_var = next_var + , ai_next_var_of_fun = 0 + , ai_cases_of_vars_for_function = [] + , ai_fun_heap = fun_heap + , ai_def_ref_counts = {} + } + + # (ai_cases_of_vars_for_group, ai, fun_defs) + = foldSt (analyse_functions common_defs) group_members ([], ai, fun_defs) + + class_env + = ai.ai_cons_class + fun_heap + = ai.ai_fun_heap + (class_env,fun_heap) + = foldSt (collect_classifications ai.ai_class_subst) group_members (class_env,fun_heap) + (cleanup_info, class_env, fun_defs, var_heap, expr_heap, fun_heap) + = foldSt set_case_expr_info (flatten ai_cases_of_vars_for_group) + (cleanup_info, class_env, fun_defs, ai.ai_var_heap, expr_heap, fun_heap) + = (cleanup_info, fun_defs, var_heap, expr_heap, fun_heap, class_env) + where +//initial classification... + initial_cons_class fun (next_var, nr_of_local_vars, var_heap, class_env, fun_defs, fun_heap) + # (fun_def, fun_defs, fun_heap) = get_fun_def fun fun_defs fun_heap + # (TransformedBody {tb_args,tb_rhs}) = fun_def.fun_body + + nr_of_locals = count_locals tb_rhs 0 + nr_of_local_vars = nr_of_local_vars + nr_of_locals + + # (fresh_vars, next_var, var_heap) + = fresh_variables tb_args 0 next_var var_heap + # fun_class = { cc_size = 0, cc_args = fresh_vars, cc_linear_bits=[], cc_producer=False} + # (fun_heap,class_env) = set_fun_class fun fun_class fun_heap class_env + = (next_var, nr_of_local_vars, var_heap, class_env, fun_defs, fun_heap) + + + set_fun_class fun fun_class fun_heap class_env + | fun < size class_env + # class_env = { class_env & [fun] = fun_class} + = (fun_heap,class_env) + + # (fun_def_ptr,fun_heap) = lookup_ptr fun new_functions fun_heap + with + lookup_ptr fun [] ti_fun_heap = abort "drat" + lookup_ptr fun [fun_def_ptr:new_functions] ti_fun_heap + # (FI_Function {gf_fun_index}, ti_fun_heap) + = readPtr fun_def_ptr ti_fun_heap + | gf_fun_index == fun + = (fun_def_ptr, ti_fun_heap) + = lookup_ptr fun new_functions ti_fun_heap + # (FI_Function gf, fun_heap) = readPtr fun_def_ptr fun_heap + # fun_heap = writePtr fun_def_ptr (FI_Function {gf & gf_cons_args = fun_class}) fun_heap + = (fun_heap,class_env) + +//determine classification... + analyse_functions common_defs fun (cfvog_accu, ai, fun_defs) + # (fun_def, fun_defs, fun_heap) = get_fun_def fun fun_defs ai.ai_fun_heap + ai = {ai & ai_fun_heap = fun_heap} + (TransformedBody {tb_args, tb_rhs}) = fun_def.fun_body + + nr_of_locals = count_locals tb_rhs 0 + nr_of_args = length tb_args + + ai = { ai + & ai_cur_ref_counts = createArray (nr_of_args + nr_of_locals) 0 + , ai_def_ref_counts = createArray (nr_of_args + nr_of_locals) 0 + , ai_next_var_of_fun = nr_of_args + } + // classify + (_, _, ai) = consumerRequirements tb_rhs common_defs ai + // set linearity info based on cur_ref_counts + # ai_cur_ref_counts = ai.ai_cur_ref_counts + ai_cons_class = ai.ai_cons_class + + # fun_heap = ai.ai_fun_heap + # (fun_cons_class,fun_heap,ai_cons_class) = get_fun_class fun fun_heap ai_cons_class + + linear_bits = [ ref_count<2 \\ ref_count <-: ai_cur_ref_counts ] + fun_cons_class = { fun_cons_class & cc_linear_bits=linear_bits } + cc_args = add_unused_args fun_cons_class.cc_args ai_cur_ref_counts + fun_cons_class = { fun_cons_class & cc_args = cc_args } + # (fun_heap,ai_cons_class) = set_fun_class fun fun_cons_class fun_heap ai_cons_class + cases_of_vars_for_function = [(a,fun) \\ a <- ai.ai_cases_of_vars_for_function ] + cfvog_accu = [cases_of_vars_for_function:cfvog_accu] + + ai = { ai + & ai_cons_class = ai_cons_class + , ai_cases_of_vars_for_function = [] + , ai_cur_ref_counts = {} + , ai_fun_heap = fun_heap + } + = (cfvog_accu, ai, fun_defs) +//final classification... + collect_classifications class_subst fun (class_env,fun_heap) + # (fun_class,fun_heap,class_env) = get_fun_class fun fun_heap class_env + fun_class = determine_classification fun_class class_subst + # (fun_heap,class_env) = set_fun_class fun fun_class fun_heap class_env + = (class_env,fun_heap) + + set_case_expr_info ({case_expr=case_expr=:(Var {var_info_ptr}), case_guards, case_info_ptr},fun_index) + (cleanup_acc, class_env, fun_defs, var_heap, expr_heap, fun_heap) + # (VI_AccVar _ arg_position, var_heap) = readPtr var_info_ptr var_heap + ({cc_size, cc_args, cc_linear_bits},fun_heap,class_env) = get_fun_class fun_index fun_heap class_env + (aci_linearity_of_patterns, var_heap) = get_linearity_info cc_linear_bits case_guards var_heap + | arg_position<cc_size && (arg_position>=cc_size || cc_args!!arg_position==CActive) && cc_linear_bits!!arg_position + // mark non multimatch cases whose case_expr is an active linear function argument + # aci = + { aci_params = [] + , aci_opt_unfolder = No + , aci_free_vars = No + , aci_linearity_of_patterns = aci_linearity_of_patterns + } + = ([case_info_ptr:cleanup_acc], class_env, fun_defs, var_heap, + setExtendedExprInfo case_info_ptr (EEI_ActiveCase aci) expr_heap, fun_heap) + = (cleanup_acc, class_env, fun_defs, var_heap, expr_heap, fun_heap) + + get_fun_class fun fun_heap class_env + | fun < size class_env + # (fun_cons_class,class_env) = class_env![fun] + = (fun_cons_class,fun_heap,class_env) + # (fun_def_ptr,fun_heap) = lookup_ptr fun new_functions fun_heap + with + lookup_ptr fun [] ti_fun_heap = abort "drat" + lookup_ptr fun [fun_def_ptr:new_functions] ti_fun_heap + # (FI_Function {gf_fun_index}, ti_fun_heap) + = readPtr fun_def_ptr ti_fun_heap + | gf_fun_index == fun + = (fun_def_ptr, ti_fun_heap) + = lookup_ptr fun new_functions ti_fun_heap + # (FI_Function {gf_cons_args}, fun_heap) = readPtr fun_def_ptr fun_heap + = (gf_cons_args, fun_heap, class_env) + + get_linearity_info cc_linear_bits (AlgebraicPatterns _ algebraic_patterns) var_heap + = mapSt (get_linearity_info_of_pattern cc_linear_bits) algebraic_patterns var_heap + get_linearity_info cc_linear_bits (OverloadedListPatterns _ _ algebraic_patterns) var_heap + = mapSt (get_linearity_info_of_pattern cc_linear_bits) algebraic_patterns var_heap + get_linearity_info cc_linear_bits _ var_heap + = ([], var_heap) + + get_linearity_info_of_pattern cc_linear_bits {ap_vars} var_heap + # (var_indices, var_heap) = mapSt get_var_index ap_vars var_heap + = ([if (index==cNope) True (cc_linear_bits!!index) \\ index<-var_indices], var_heap) + get_var_index {fv_info_ptr} var_heap # (vi, var_heap) = readPtr fv_info_ptr var_heap index = case vi of @@ -622,9 +1014,178 @@ where VI_Count 0 False -> cNope = (index, var_heap) -fresh_variables [{fv_name,fv_info_ptr} : vars] arg_position next_var_number var_heap - # (fresh_vars, last_var_number, var_heap) = fresh_variables vars (inc arg_position) (inc next_var_number) var_heap - var_heap = writePtr fv_info_ptr (VI_AccVar next_var_number arg_position) var_heap + get_fun_def fun fun_defs fun_heap + | fun < size fun_defs + # (fun_def, fun_defs) = fun_defs![fun] + = (fun_def, fun_defs, fun_heap) + # (fun_def_ptr, fun_heap) = lookup_ptr fun new_functions fun_heap + with + lookup_ptr fun [] ti_fun_heap = abort "drat" + lookup_ptr fun [fun_def_ptr:new_functions] ti_fun_heap + # (FI_Function {gf_fun_index}, ti_fun_heap) + = readPtr fun_def_ptr ti_fun_heap + | gf_fun_index == fun + = (fun_def_ptr, ti_fun_heap) + = lookup_ptr fun new_functions ti_fun_heap + # (FI_Function {gf_fun_def}, fun_heap) + = readPtr fun_def_ptr fun_heap + = (gf_fun_def, fun_defs, fun_heap) + +reanalyseFunction + :: !Int !FunctionInfoPtr !{# CommonDefs} !{#{#FunType}} !Int !Int !*{#FunDef} !*VarHeap !*FunctionHeap !*{!ConsClasses} + -> *(!ConsClasses,!*{#FunDef},!*VarHeap,!*FunctionHeap,!*{!ConsClasses}) +reanalyseFunction fun fun_info_ptr common_defs imported_funs main_dcl_module_n stdStrictLists_module_n fun_defs var_heap fun_heap class_env + # consumerAnalysisRO=ConsumerAnalysisRO + { common_defs = common_defs + , imported_funs = imported_funs + , main_dcl_module_n = main_dcl_module_n + , stdStrictLists_module_n = stdStrictLists_module_n + } + + # (fifun, fun_heap) = readPtr fun_info_ptr fun_heap + fun_def = case fifun of + FI_Function {gf_fun_def} -> gf_fun_def + FI_Empty -> abort "unexpected FI_Empty.\n" + + ({tb_args, tb_rhs}) = case fun_def.fun_body of + TransformedBody body -> body + body -> abort "unexpected non-Transformed body?\n" + + nr_of_locals = count_locals tb_rhs 0 + nr_of_args = length tb_args + + # (fresh_vars, next_var, var_heap) + = fresh_variables tb_args 0 0 var_heap + # fun_class = { cc_size = 0, cc_args = fresh_vars, cc_linear_bits=[], cc_producer=False} + + # (fun_info, fun_heap) = readPtr fun_info_ptr fun_heap + # fun_info = case fun_info of + FI_Function gf + -> FI_Function {gf & gf_cons_args = fun_class} + # fun_heap = writePtr fun_info_ptr fun_info fun_heap + + # ai = + { ai_var_heap = var_heap + , ai_cons_class = class_env + , ai_cur_ref_counts = createArray (nr_of_args + nr_of_locals) 0 + , ai_class_subst = createArray (nr_of_args + nr_of_locals) CPassive + , ai_next_var = next_var + , ai_next_var_of_fun = nr_of_args + , ai_cases_of_vars_for_function = [] + , ai_fun_heap = fun_heap + , ai_def_ref_counts = createArray (nr_of_args + nr_of_locals) 0 + } + + // classify + # (_, _, ai) = consumerRequirements tb_rhs consumerAnalysisRO ai + // set linearity info based on cur_ref_counts? + ai_cur_ref_counts = ai.ai_cur_ref_counts + ai_cons_class = ai.ai_cons_class + fun_cons_class = determine_classification fun_class ai.ai_class_subst + linear_bits = [ ref_count<2 \\ ref_count <-: ai_cur_ref_counts ] + fun_cons_class = { fun_cons_class & cc_linear_bits=linear_bits } + cc_args = add_unused_args fun_cons_class.cc_args ai_cur_ref_counts + fun_cons_class = { fun_cons_class & cc_args = cc_args } + cases_of_vars_for_function = [(a,fun) \\ a <- ai.ai_cases_of_vars_for_function ] + // set_case_expr_info cases_of_vars_for_function + = (fun_cons_class,fun_defs,ai.ai_var_heap,ai.ai_fun_heap,ai_cons_class) + + +fresh_variables [{fv_info_ptr} : vars] arg_position next_var_number var_heap + # (fresh_vars, last_var_number, var_heap) + = fresh_variables vars (inc arg_position) (inc next_var_number) var_heap + var_heap + = writePtr fv_info_ptr (VI_AccVar next_var_number arg_position) var_heap = ([next_var_number : fresh_vars], last_var_number, var_heap) fresh_variables [] _ next_var_number var_heap = ([], next_var_number, var_heap) + +// count_locals determines number of local variables... + +count_locals (Var _) n + = n +count_locals (App {app_args}) n + = foldSt count_locals app_args n +count_locals (fun_expr @ exprs) n + = foldSt count_locals exprs (count_locals fun_expr n) +count_locals (Let {let_strict_binds,let_lazy_binds,let_expr}) n + # let_binds = let_strict_binds ++ let_lazy_binds + = count_let_bind_locals let_binds (count_locals let_expr n) +count_locals (Case {case_expr,case_guards,case_default}) n + = count_case_locals case_guards (count_locals case_expr (count_optional_locals case_default n)) +count_locals (BasicExpr _) n + = n +count_locals (MatchExpr _ expr) n + = count_locals expr n +count_locals (Selection _ expr selectors) n + = count_selector_locals selectors (count_locals expr n) +count_locals (Update expr1 selectors expr2) n + # n = count_locals expr1 n + # n = count_locals expr2 n + # n = count_selector_locals selectors n + = n +count_locals (RecordUpdate _ expr exprs) n + = foldSt count_bind_locals exprs (count_locals expr n) +count_locals (TupleSelect _ _ expr) n + = count_locals expr n +count_locals (AnyCodeExpr _ _ _) n + = n +count_locals (ABCCodeExpr _ _) n + = n +count_locals (DynamicExpr {dyn_expr}) n + = count_locals dyn_expr n +count_locals (TypeCodeExpression _) n + = n +count_locals EE n + = n +count_locals (NoBind _) n + = n + +count_optional_locals (Yes e) n + = count_locals e n +count_optional_locals No n + = n + +count_bind_locals {bind_src} n + = count_locals bind_src n + +count_let_bind_locals binds n + = foldSt count_let_bind_locals binds n +where + count_let_bind_locals {lb_src,lb_dst} n + | lb_dst.fv_count > 0 + = count_locals lb_src (inc n) + = n + +count_case_locals (AlgebraicPatterns _ patterns) n + # pattern_exprs = [ ap_expr \\ {ap_expr} <- patterns ] + pattern_vars = flatten [ ap_vars \\ {ap_vars} <- patterns ] + = foldSt count_locals pattern_exprs (foldSt count_case_guard_locals pattern_vars n) +count_case_locals (BasicPatterns _ patterns) n + # pattern_exprs = [ bp_expr \\ {bp_expr} <- patterns ] + = foldSt count_locals pattern_exprs n +count_case_locals (OverloadedListPatterns _ _ patterns) n + # pattern_exprs = [ ap_expr \\ {ap_expr} <- patterns ] + pattern_vars = flatten [ ap_vars \\ {ap_vars} <- patterns ] + = foldSt count_locals pattern_exprs (foldSt count_case_guard_locals pattern_vars n) +count_case_locals NoPattern n + = n + +count_case_guard_locals {fv_count} n + | fv_count > 0 + = inc n + = n + +count_selector_locals selectors n + = foldSt count_selector_locals selectors n +where + count_selector_locals (ArraySelection _ _ index_expr) n + = count_locals index_expr n + count_selector_locals (DictionarySelection _ _ _ index_expr) n + = count_locals index_expr n + // record selection missing?! + count_selector_locals _ n + = n + +add_unused_args args ref_counts + = [if (ref_count > 0) arg CUnused \\ arg <- args & ref_count <-: ref_counts] |