diff options
Diffstat (limited to 'backendC/CleanCompilerSources')
-rw-r--r-- | backendC/CleanCompilerSources/codegen.c | 3 | ||||
-rw-r--r-- | backendC/CleanCompilerSources/codegen.h | 5 | ||||
-rw-r--r-- | backendC/CleanCompilerSources/codegen1.c | 27 | ||||
-rw-r--r-- | backendC/CleanCompilerSources/codegen1.h | 3 | ||||
-rw-r--r-- | backendC/CleanCompilerSources/codegen2.c | 479 | ||||
-rw-r--r-- | backendC/CleanCompilerSources/codegen2.h | 68 | ||||
-rw-r--r-- | backendC/CleanCompilerSources/codegen3.c | 378 | ||||
-rw-r--r-- | backendC/CleanCompilerSources/optimisations.c | 480 | ||||
-rw-r--r-- | backendC/CleanCompilerSources/optimisations.h | 1 |
9 files changed, 1169 insertions, 275 deletions
diff --git a/backendC/CleanCompilerSources/codegen.c b/backendC/CleanCompilerSources/codegen.c index cc9e8a1..2505f5f 100644 --- a/backendC/CleanCompilerSources/codegen.c +++ b/backendC/CleanCompilerSources/codegen.c @@ -1,4 +1,5 @@ + #define for_l(v,l,n) for(v=(l);v!=NULL;v=v->n) #define SHARE_UPDATE_CODE 0 /* also in codegen1.c */ @@ -1186,7 +1187,7 @@ void CodeGeneration (ImpMod imod, char *fname) OptimiseRules (imod->im_rules,imod->im_start); ExitOnInterrupt(); #if 0 - PrintRules (imod->im_rules); + PrintRules (imod->im_rules,rules_file); #endif if (DoCode && !CompilerError){ ImpRuleS *rule; diff --git a/backendC/CleanCompilerSources/codegen.h b/backendC/CleanCompilerSources/codegen.h index 7719a4d..cc588f6 100644 --- a/backendC/CleanCompilerSources/codegen.h +++ b/backendC/CleanCompilerSources/codegen.h @@ -4,4 +4,7 @@ void EvalArgsEntry (StateS *const function_state_p,SymbDef rule_sdef,int maxasiz void EvaluateAndMoveStateArguments (int state_arity,States states,int oldasp,int maxassize); void EvaluateAndMoveArguments (int arity,StateP argstates,int *locasp_p,int *aselmts_p); -extern int function_called_only_curried_or_lazy_with_one_return;
\ No newline at end of file +extern int function_called_only_curried_or_lazy_with_one_return; +#if GENERATE_CODE_AGAIN + extern int call_code_generator_again; +#endif diff --git a/backendC/CleanCompilerSources/codegen1.c b/backendC/CleanCompilerSources/codegen1.c index be5c51c..957dc78 100644 --- a/backendC/CleanCompilerSources/codegen1.c +++ b/backendC/CleanCompilerSources/codegen1.c @@ -3119,6 +3119,10 @@ void set_local_reference_counts_and_add_free_node_ids (NodeP case_node,NodeIdLis node_id=node_id_ref_count_elem->nrcl_node_id; local_ref_count=node_id_ref_count_elem->nrcl_ref_count; +# if BOXED_RECORDS + node_id_ref_count_elem->nrcl_mark2=node_id->nid_mark2 & NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +# endif + # if 0 printf ("global_to_local_ %s %d %d ",node_id_name (node_id),node_id->nid_refcount,node_id_ref_count_elem->nrcl_ref_count); # endif @@ -3518,16 +3522,32 @@ static int generate_code_for_switch_node (NodeP node,int asp,int bsp,struct esc { need_next_alternative=1; } +#if BOXED_RECORDS + set_global_reference_counts_and_exchange_record_update_marks (case_node); +#endif } else { +#if BOXED_RECORDS + ArgP arg2; + + for_l (arg2,node->node_arguments,arg_next){ + if (arg2->arg_node->node_kind==CaseNode && arg2->arg_node->node_number) + or_then_record_update_marks (case_node->node_node_id_ref_counts); + } +#endif if (generate_code_for_root_node (case_node->node_arguments->arg_node,asp,bsp,&old_esc,case_node->node_node_defs, result_state_p,&saved_node_id_states,ab_node_ids_p)) { need_next_alternative=1; } +#if BOXED_RECORDS + set_global_reference_counts (case_node); +#endif } +#if !BOXED_RECORDS set_global_reference_counts (case_node); +#endif #if BUILD_FREE_NODE_ID_LIST_DURING_PATTER_MATCH ab_node_ids_p->free_node_ids=old_free_node_ids; } @@ -3714,9 +3734,12 @@ static int generate_code_for_push_node (NodeP node,int asp,int bsp,struct esc *e # ifdef DESTRUCTIVE_RECORD_UPDATES else if (node->node_record_symbol->symb_kind==definition && node->node_record_symbol->symb_def->sdef_kind==RECORDTYPE && - (node_id_p->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && + (((node_id_p->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && node_id_p->nid_number==-2) - { +# if BOXED_RECORDS + || (node_id_p->nid_mark2 & NID_RECORD_USED_BY_UPDATE)!=0 +# endif + )){ node_id_p->nid_number=-1; if (b_size==0) GenPushArgsU (asp-node_id_p->nid_a_index,a_size,a_size); diff --git a/backendC/CleanCompilerSources/codegen1.h b/backendC/CleanCompilerSources/codegen1.h index e3f6eec..a2ea483 100644 --- a/backendC/CleanCompilerSources/codegen1.h +++ b/backendC/CleanCompilerSources/codegen1.h @@ -111,9 +111,8 @@ extern SymbDef CreateUpdateFunction (ArgS *record_arg,ArgS *first_field_arg,Node ,int unbox_record #endif ); -#if U_RECORD_SELECTORS + extern SymbDef create_select_function (Symbol selector_symbol,int selector_kind); -#endif extern SymbDef create_match_function (struct symbol *constructor_symbol,int constructor_arity,int strict_constructor); extern SymbDef create_select_and_match_function (struct symbol *constructor_symbol,int strict_constructor); diff --git a/backendC/CleanCompilerSources/codegen2.c b/backendC/CleanCompilerSources/codegen2.c index dd1c7d0..e1446a0 100644 --- a/backendC/CleanCompilerSources/codegen2.c +++ b/backendC/CleanCompilerSources/codegen2.c @@ -24,11 +24,11 @@ #include "sizes.h" #include "checker.h" #include "codegen_types.h" +#include "statesgen.h" #include "codegen.h" #include "codegen1.h" #include "codegen2.h" #include "sa.h" -#include "statesgen.h" #include "transform.h" #include "instructions.h" #include "typechecker.h" @@ -1173,6 +1173,30 @@ Bool CopyNodeIdArgument (StateS demstate,NodeId node_id,int *asp_p,int *bsp_p) return CopyArgument (demstate,node_id->nid_state,a_index,b_index,asp_p,bsp_p,a_size,b_size,True); } +void PushField (StateS recstate,int fieldnr,int offset,int *asp_p,int *bsp_p,int *a_size_p,int *b_size_p) +{ + int apos,bpos,totasize,totbsize; + + DetermineFieldSizeAndPositionAndRecordSize (fieldnr,a_size_p,b_size_p,&apos,&bpos,&totasize,&totbsize,&recstate); + + GenPushRArgB (offset, totasize, totbsize, bpos+1, *b_size_p); + GenPushRArgA (offset, totasize, totbsize, apos+1, *a_size_p); + *bsp_p += *b_size_p; + *asp_p += *a_size_p; +} + +void ReplaceRecordByField (StateS recstate,int fieldnr,int *asp_p,int *bsp_p,int *a_size_p,int *b_size_p) +{ + int apos,bpos,totasize,totbsize; + + DetermineFieldSizeAndPositionAndRecordSize (fieldnr,a_size_p,b_size_p,&apos,&bpos,&totasize,&totbsize,&recstate); + + GenPushRArgB (0, totasize, totbsize, bpos+1, *b_size_p); + GenReplRArgA ( totasize, totbsize, apos+1, *a_size_p); + *bsp_p += *b_size_p; + *asp_p += *a_size_p - 1; +} + static void FillOrReduceFieldSelection (Node node,SymbDef seldef,int *asp_p,int *bsp_p,NodeId update_node_id,CodeGenNodeIdsP code_gen_node_ids_p) { Node arg_node; @@ -1209,9 +1233,16 @@ static void FillOrReduceFieldSelection (Node node,SymbDef seldef,int *asp_p,int BuildArg (arg,asp_p,bsp_p,code_gen_node_ids_p); record_state_p=&seldef->sdef_type->type_lhs->ft_symbol->symb_def->sdef_record_state; - +#if BOXED_RECORDS + if (arg->arg_state.state_type==SimpleState){ + if (node->node_arity<SELECTOR_L) + PushField (*record_state_p,fieldnr,0,asp_p,bsp_p,&asize,&bsize); + else + ReplaceRecordByField (*record_state_p,fieldnr,asp_p,bsp_p,&asize,&bsize); + } else { +#endif DetermineFieldSizeAndPosition (fieldnr,&asize,&bsize,&aindex,&bindex,record_state_p->state_record_arguments); - + if (node->node_arity<SELECTOR_L){ int n; @@ -1228,6 +1259,9 @@ static void FillOrReduceFieldSelection (Node node,SymbDef seldef,int *asp_p,int DetermineSizeOfState (*record_state_p,&record_a_size,&record_b_size); ReplaceRecordOnTopOfStackByField (asp_p,bsp_p,aindex,bindex,asize,bsize,record_a_size,record_b_size); } +#if BOXED_RECORDS + } +#endif } else { int a_size,b_size,apos,bpos,record_a_size,record_b_size,n; StateS tuple_state,tuple_state_arguments[2],*record_state_p; @@ -1237,9 +1271,24 @@ static void FillOrReduceFieldSelection (Node node,SymbDef seldef,int *asp_p,int record_state_p=&seldef->sdef_type->type_lhs->ft_symbol->symb_def->sdef_record_state; - DetermineFieldSizeAndPositionAndRecordSize (fieldnr,&a_size,&b_size,&apos,&bpos,&record_a_size,&record_b_size,record_state_p); + tuple_state.state_type=TupleState; + tuple_state.state_arity=2; + tuple_state.state_tuple_arguments=tuple_state_arguments; - CopyNodeIdArgument (*record_state_p,arg_node_id,asp_p,bsp_p); + tuple_state_arguments[0]=record_state_p->state_record_arguments[fieldnr]; + + CopyNodeIdArgument (arg->arg_state,arg_node_id,asp_p,bsp_p); + +#if BOXED_RECORDS + if (arg->arg_state.state_type==SimpleState){ + PushField (*record_state_p,fieldnr,0,asp_p,bsp_p,&a_size,&b_size); + + tuple_state_arguments[1]=arg->arg_state; + + CoerceArgumentOnTopOfStack (asp_p,bsp_p,tuple_state,node->node_state,1+a_size,b_size); + } else { +#endif + DetermineFieldSizeAndPositionAndRecordSize (fieldnr,&a_size,&b_size,&apos,&bpos,&record_a_size,&record_b_size,record_state_p); for (n=0; n<a_size; ++n) GenPushA (apos+a_size-1); @@ -1249,15 +1298,12 @@ static void FillOrReduceFieldSelection (Node node,SymbDef seldef,int *asp_p,int GenPushB (bpos+b_size-1); *bsp_p+=b_size; - tuple_state.state_type=TupleState; - tuple_state.state_arity=2; - tuple_state.state_tuple_arguments=tuple_state_arguments; - - tuple_state_arguments[0]=record_state_p->state_record_arguments[fieldnr]; tuple_state_arguments[1]=*record_state_p; CoerceArgumentOnTopOfStack (asp_p,bsp_p,tuple_state,node->node_state,record_a_size+a_size,record_b_size+b_size); - +#if BOXED_RECORDS + } +#endif decrement_reference_count_of_node_id (arg_node_id,&code_gen_node_ids_p->free_node_ids); } } @@ -1297,14 +1343,19 @@ static void FillOrReduceFieldSelection (Node node,SymbDef seldef,int *asp_p,int BuildOrFillLazyFieldSelector (seldef,node->node_state.state_kind,asp_p,update_node_id); } else { int asize,bsize,apos,bpos,tot_asize,tot_bsize; - + StateP record_state_p; +#if 1 + record_state_p=&seldef->sdef_type->type_lhs->ft_symbol->symb_def->sdef_record_state; +#else + record_state_p=&arg->arg_state; +#endif Build (arg_node,asp_p,bsp_p,code_gen_node_ids_p); - DetermineFieldSizeAndPositionAndRecordSize (fieldnr,&asize,&bsize,&apos,&bpos,&tot_asize,&tot_bsize,&arg->arg_state); - CoerceArgumentOnTopOfStack (asp_p,bsp_p,arg->arg_state,arg_node->node_state,tot_asize,tot_bsize); + DetermineFieldSizeAndPositionAndRecordSize (fieldnr,&asize,&bsize,&apos,&bpos,&tot_asize,&tot_bsize,record_state_p); + CoerceArgumentOnTopOfStack (asp_p,bsp_p,*record_state_p,arg_node->node_state,tot_asize,tot_bsize); ReplaceRecordOnTopOfStackByField (asp_p,bsp_p,apos,bpos,asize,bsize,tot_asize,tot_bsize); - CoerceArgumentOnTopOfStack (asp_p,bsp_p,node->node_state,arg->arg_state.state_record_arguments[fieldnr],asize,bsize); + CoerceArgumentOnTopOfStack (asp_p,bsp_p,node->node_state,record_state_p->state_record_arguments[fieldnr],asize,bsize); } } else { StateS recstate; @@ -1358,18 +1409,49 @@ static void FillOrReduceFieldSelection (Node node,SymbDef seldef,int *asp_p,int #ifdef DO_LAZY_SELECTORS_FROM_BOXED_STRICT_RECORDS if ((recstate.state_kind==StrictOnA || recstate.state_kind==StrictRedirection) && update_node_id==NULL){ int asize,bsize,apos,bpos,tot_asize,tot_bsize,recindex; + SymbDef record_sdef; StateP record_state_p,field_state_p; recindex = arg_node_id->nid_a_index; - record_state_p=&seldef->sdef_type->type_lhs->ft_symbol->symb_def->sdef_record_state; + record_sdef=seldef->sdef_type->type_lhs->ft_symbol->symb_def; + record_state_p=&record_sdef->sdef_record_state; if (record_state_p->state_type!=RecordState) error_in_function ("FillOrReduceFieldSelection"); DetermineFieldSizeAndPositionAndRecordSize (fieldnr,&asize,&bsize,&apos,&bpos,&tot_asize,&tot_bsize,record_state_p); - - GenPushRArgB (*asp_p-recindex,tot_asize,tot_bsize,bpos+1,bsize); - GenPushRArgA (*asp_p-recindex,tot_asize,tot_bsize,apos+1,asize); +# if BOXED_RECORDS + if (record_sdef->sdef_boxed_record && (arg_node_id->nid_mark2 & (NID_RECORD_USED_BY_UPDATE | NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES))==NID_RECORD_USED_BY_UPDATE + && +# if 1 + (( + (arg_node_id->nid_state.state_mark & STATE_UNIQUE_MASK)!=0 +/* + && + (arg_node_id->nid_refcount==-2 || ((arg_node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && arg_node_id->nid_number== -1)) +*/ + ) + || + ((arg_node_id->nid_mark2 & NID_SELECTION_NODE_ID)==0 + ? (arg_node_id->nid_refcount>=0 && arg_node_id->nid_node->node_kind==NodeIdNode && + (arg_node_id->nid_node->node_node_id->nid_mark2 & (NID_SELECTION_NODE_ID | NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES))==NID_SELECTION_NODE_ID) + : (arg_node_id->nid_mark2 & (NID_SELECTION_NODE_ID | NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES))==NID_SELECTION_NODE_ID + ) + ) +# else + ((arg_node_id->nid_mark2 & NID_SELECTION_NODE_ID)==0 + ? (arg_node_id->nid_refcount>=0 && arg_node_id->nid_node->node_kind==NodeIdNode && + (arg_node_id->nid_node->node_node_id->nid_mark & NID_SHARED_SELECTION_NODE_ID)==0) + : (arg_node_id->nid_mark & NID_SHARED_SELECTION_NODE_ID)==0) +# endif + ){ + GenPushRArgU (*asp_p-recindex,tot_asize,tot_bsize,apos+1,asize,bpos+1,bsize); + } else +# endif + { + GenPushRArgB (*asp_p-recindex,tot_asize,tot_bsize,bpos+1,bsize); + GenPushRArgA (*asp_p-recindex,tot_asize,tot_bsize,apos+1,asize); + } *asp_p+=asize; *bsp_p+=bsize; @@ -1390,13 +1472,12 @@ static void FillOrReduceFieldSelection (Node node,SymbDef seldef,int *asp_p,int } } else { int a_size,b_size,apos, bpos, tot_asize, tot_bsize,recindex; + SymbDef record_sdef; /* the selector is strict but the record is not */ recindex = arg_node_id->nid_a_index; - DetermineFieldSizeAndPositionAndRecordSize (fieldnr,&a_size,&b_size,&apos, &bpos,&tot_asize,&tot_bsize,&arg->arg_state); - if (ResultIsNotInRootNormalForm (recstate)){ GenJsrEval (*asp_p-recindex); ChangeEvalStatusKindToStrictOnA (arg_node_id,code_gen_node_ids_p->saved_nid_state_l); @@ -1404,15 +1485,54 @@ static void FillOrReduceFieldSelection (Node node,SymbDef seldef,int *asp_p,int recstate.state_kind = StrictOnA; } - GenPushRArgB (*asp_p-recindex, tot_asize, tot_bsize, bpos+1,b_size); - GenPushRArgA (*asp_p-recindex, tot_asize, tot_bsize, apos+1,a_size); + record_sdef=seldef->sdef_type->type_lhs->ft_symbol->symb_def; + DetermineFieldSizeAndPositionAndRecordSize (fieldnr,&a_size,&b_size,&apos, &bpos,&tot_asize,&tot_bsize, +#if 1 + &record_sdef->sdef_record_state); +#else + &arg->arg_state); +#endif +# if BOXED_RECORDS + if (record_sdef->sdef_boxed_record && (arg_node_id->nid_mark2 & (NID_RECORD_USED_BY_UPDATE | NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES))==NID_RECORD_USED_BY_UPDATE + && +# if 1 + (( + (arg_node_id->nid_state.state_mark & STATE_UNIQUE_MASK)!=0 +/* && + (arg_node_id->nid_refcount==-2 || ((arg_node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && arg_node_id->nid_number== -1)) +*/ + ) + || + ((arg_node_id->nid_mark2 & NID_SELECTION_NODE_ID)==0 + ? (arg_node_id->nid_refcount>=0 && arg_node_id->nid_node->node_kind==NodeIdNode && + (arg_node_id->nid_node->node_node_id->nid_mark2 & (NID_SELECTION_NODE_ID | NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES))==NID_SELECTION_NODE_ID) + : (arg_node_id->nid_mark2 & (NID_SELECTION_NODE_ID | NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES))==NID_SELECTION_NODE_ID + ) + ) +# else + ((arg_node_id->nid_mark2 & NID_SELECTION_NODE_ID)==0 + ? (arg_node_id->nid_refcount>=0 && arg_node_id->nid_node->node_kind==NodeIdNode && + (arg_node_id->nid_node->node_node_id->nid_mark & NID_SHARED_SELECTION_NODE_ID)==0) + : (arg_node_id->nid_mark & NID_SHARED_SELECTION_NODE_ID)==0) +# endif + ){ + GenPushRArgU (*asp_p-recindex,tot_asize,tot_bsize,apos+1,a_size,bpos+1,b_size); + } else +# endif + { + GenPushRArgB (*asp_p-recindex, tot_asize, tot_bsize, bpos+1,b_size); + GenPushRArgA (*asp_p-recindex, tot_asize, tot_bsize, apos+1,a_size); + } *asp_p+=a_size; *bsp_p+=b_size; - recstate = arg->arg_state.state_record_arguments [fieldnr]; - CoerceArgumentOnTopOfStack (asp_p,bsp_p, node->node_state, recstate,a_size,b_size); - + CoerceArgumentOnTopOfStack (asp_p,bsp_p, node->node_state, +#if 1 + record_sdef->sdef_record_state.state_record_arguments [fieldnr],a_size,b_size); +#else + arg->arg_state.state_record_arguments [fieldnr],a_size,b_size); +#endif decrement_reference_count_of_node_id (arg_node_id,&code_gen_node_ids_p->free_node_ids); } } @@ -2055,7 +2175,6 @@ void DetermineSizeOfArguments (ArgS *args,int *a_offset_p,int *b_offset_p) AddSizeOfState (arg->arg_state,a_offset_p,b_offset_p); } -static void BuildLazyArgs (Args args,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p); static Bool BuildNonParArgs (Args args,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p); static void BuildParArgs (ArgS* args,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p); static void ReorderParallelAndNonParallelArgsWithResultNode (Args args,int *asize_p,int *bsize_p); @@ -2522,8 +2641,11 @@ static void build_strict_then_or_else (Node then_or_else_node,Node else_node,int } else { NodeId nid; int a_size,b_size; - + nid=then_or_else_node->node_node_id; +#if BOXED_RECORDS + nid->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif DetermineSizeOfState (nid->nid_state,&a_size,&b_size); CopyArgument (result_state,nid->nid_state,nid->nid_a_index,nid->nid_b_index,asp_p,bsp_p,a_size,b_size,True); } @@ -3230,7 +3352,7 @@ void UpdateNodeAndAddSelectorsToUpdateNode #endif #ifdef DESTRUCTIVE_RECORD_UPDATES -static void compute_bits_and_add_selectors_to_update_node +void compute_bits_and_add_selectors_to_update_node (ArgS *record_arg,ArgS *first_field_arg,StateS *field_states,int record_a_size,int record_b_size, char bits[],int *n_a_fill_bits_p,int *n_b_fill_bits_p) { @@ -3284,19 +3406,11 @@ static void compute_bits_and_add_selectors_to_update_node bits[0]='0'; - for (n=0; n<record_a_size; ++n){ - if (a_bits & (1<<n)) - bits[n+1]='1'; - else - bits[n+1]='0'; - } + for (n=0; n<record_a_size; ++n) + bits[n+1]='0' + ((a_bits>>n) & 1); - for (n=0; n<record_b_size; ++n){ - if (b_bits & (1<<n)) - bits[n+record_a_size+1]='1'; - else - bits[n+record_a_size+1]='0'; - } + for (n=0; n<record_b_size; ++n) + bits[n+record_a_size+1]='0' + ((b_bits>>n) & 1); bits[record_a_size+record_b_size+1]='\0'; @@ -3374,6 +3488,127 @@ static void adjust_state_of_unbox_update_function_argument (ArgP call_arg_p,ArgP } #endif +int is_unique_record_update (NodeIdP record_node_id,NodeP record_node) +{ + NodeP selector_node_p; + + if (!DoReuseUniqueNodes) + return 0; +#if 0 + printf ("is_unique_record_update\n"); +#endif + + if ((record_node_id->nid_state.state_mark & STATE_UNIQUE_MASK)!=0 && +#if 1 + ( + ((record_node_id->nid_mark2 & (NID_RECORD_USED_BY_UPDATE | NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES))==NID_RECORD_USED_BY_UPDATE + && record_node_id->nid_refcount==-2) + || + ((record_node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && record_node_id->nid_number== -1) + ) && +#else + (record_node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && + record_node_id->nid_number== -1 && +#endif + record_node_id->nid_state.state_type==SimpleState && + record_node_id->nid_state.state_kind==StrictOnA) + { + return 1; + } + +# if 1 +# if 0 + printf ("%d %d %d %d\n",record_node_id->nid_state.state_type==SimpleState,record_node_id->nid_mark2,record_node_id->nid_mark,record_node_id->nid_refcount); +# endif + if (record_node_id->nid_state.state_type==SimpleState && (record_node_id->nid_mark2 & (NID_RECORD_USED_BY_UPDATE | NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES))==NID_RECORD_USED_BY_UPDATE){ +# if 0 + printf ("is_unique_record_update 2\n"); +# endif + selector_node_p=record_node; + + if ((record_node_id->nid_mark2 & NID_SELECTION_NODE_ID)==0){ + if (record_node_id->nid_refcount==1 && record_node_id->nid_node->node_kind==NodeIdNode){ +# if 0 + printf ("is_unique_record_update_3 %d %d %d\n",record_node_id->nid_mark2,record_node_id->nid_mark,record_node_id->nid_refcount); +# endif + selector_node_p=record_node_id->nid_node; + record_node_id=selector_node_p->node_node_id; +# if 0 + printf ("is_unique_record_update 3 %d %d %d\n",record_node_id->nid_mark2,record_node_id->nid_mark,record_node_id->nid_refcount); +# endif + } else { +# if 0 + printf ("is_unique_record_update 4 %d %d %d\n",record_node_id->nid_mark2,record_node_id->nid_mark,record_node_id->nid_refcount); +# endif + if (record_node_id->nid_refcount>=0 && record_node_id->nid_node->node_kind==NodeIdNode){ + record_node_id=record_node_id->nid_node->node_node_id; +# if 0 + printf ("is_unique_record_update_4 %d %d %d\n",record_node_id->nid_mark2,record_node_id->nid_mark,record_node_id->nid_refcount); +# endif + } + return 0; + } + } + + if ((record_node_id->nid_mark2 & (NID_SELECTION_NODE_ID | NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES))==NID_SELECTION_NODE_ID + + && ((record_node_id->nid_mark & NID_SHARED_SELECTION_NODE_ID)==0 || record_node_id->nid_refcount==0) +# if 0 + && (record_node_id->nid_mark & NID_SHARED_SELECTION_NODE_ID)==0 +# endif + ){ +# if 0 + printf ("UpdateNode NodeId NID_UNSHARED_SELECTION_NODE_ID\n"); +# endif + if (selector_node_p->node_arguments->arg_node->node_kind==NodeIdNode){ + NodeIdP tuple_node_id; +# if 0 + printf ("UpdateNode sel NodeIdNode\n"); +# endif + tuple_node_id=selector_node_p->node_arguments->arg_node->node_node_id; + +# if 0 + if (tuple_node_id->nid_node_def->def_node->node_kind==TupleSelectorsNode) + printf ("UpdateNode sel TupleSelectorsNode %d\n",record_node_id->nid_number); +# endif + if (tuple_node_id->nid_node->node_kind==NormalNode && tuple_node_id->nid_node->node_symbol->symb_kind==definition){ + StateP tuple_result_state_p; + + switch (tuple_node_id->nid_node->node_symbol->symb_def->sdef_kind){ + case IMPRULE: +# if 0 + printf ("UpdateNode sel IMPRULE\n"); +# endif + tuple_result_state_p=&tuple_node_id->nid_node->node_symbol->symb_def->sdef_rule->rule_state_p[-1]; + break; + case DEFRULE: + case SYSRULE: +# if 0 + printf ("UpdateNode sel DEFRULE or SYSRULE\n"); +# endif + tuple_result_state_p=&tuple_node_id->nid_node->node_symbol->symb_def->sdef_rule_type->rule_type_state_p[-1]; + break; + default: + return 0; + } + + if (tuple_result_state_p->state_type==TupleState + && (tuple_result_state_p->state_tuple_arguments[record_node_id->nid_number].state_mark & STATE_UNIQUE_MASK)!=0) + { +# if 0 + printf ("UpdateNode * sel RULE\n"); +# endif + return 1; + } + } + } + } + } +#endif + + return 0; +} + static void FillUpdateNode (Node node,int *asp_p,int *bsp_p,NodeId update_node_id,CodeGenNodeIdsP code_gen_node_ids_p) { ArgS *record_arg,*first_field_arg; @@ -3482,24 +3717,25 @@ static void FillUpdateNode (Node node,int *asp_p,int *bsp_p,NodeId update_node_i } if (update_immediately){ - if (node->node_state.state_kind==StrictOnA && record_node->node_kind==NodeIdNode){ +#if 1 + BuildArgs (record_arg->arg_next,asp_p,bsp_p,code_gen_node_ids_p); +#endif + if (record_node->node_kind==NodeIdNode){ NodeIdP record_node_id; record_node_id=record_node->node_node_id; - if ((record_node_id->nid_state.state_mark & STATE_UNIQUE_MASK)!=0 && - (record_node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && - record_node_id->nid_number== -1 && - record_node_id->nid_state.state_type==SimpleState && - record_node_id->nid_state.state_kind==StrictOnA && - update_node_id==NULL) - { + if (is_unique_record_update (record_node_id,record_node) && update_node_id==NULL){ int n_a_fill_bits,n_b_fill_bits; char bits[MaxNodeArity+2]; LabDef record_lab; +#if BOXED_RECORDS + record_node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif +#if 0 BuildArgs (record_arg->arg_next,asp_p,bsp_p,code_gen_node_ids_p); - +#endif DetermineSizeOfState (*record_state_p,&record_a_size,&record_b_size); compute_bits_and_add_selectors_to_update_node (record_arg,first_field_arg, @@ -3523,14 +3759,20 @@ static void FillUpdateNode (Node node,int *asp_p,int *bsp_p,NodeId update_node_i return; } +# if BOXED_RECORDS + record_node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +# endif } #else if (update_immediately){ #endif - record_arg->arg_state=*record_state_p; + record_arg->arg_state=*record_state_p; +#if 1 + BuildArg (node->node_arguments,asp_p,bsp_p,code_gen_node_ids_p); +#else BuildArgs (node->node_arguments,asp_p,bsp_p,code_gen_node_ids_p); - +#endif DetermineSizeOfState (*record_state_p,&record_a_size,&record_b_size); #if UPDATE_RECORD_NOT_ON_TOP @@ -3779,9 +4021,13 @@ static void FillUpdateNode (Node node,int *asp_p,int *bsp_p,NodeId update_node_i } else { #if UPDATE_RECORD_NOT_ON_TOP int n_a_elements_above_record,n_b_elements_above_record; +#endif + +#if BOXED_RECORDS + node->node_arguments->arg_state=node->node_symbol->symb_def->sdef_record_state; #endif BuildArgs (node->node_arguments,asp_p,bsp_p,code_gen_node_ids_p); - + DetermineSizeOfState (node->node_state,&record_a_size,&record_b_size); #if UPDATE_RECORD_NOT_ON_TOP UpdateRecordAndAddSelectorsToUpdateNode (record_arg,first_field_arg, @@ -4003,9 +4249,7 @@ void FillMatchNode (Node node,int *asp_p,int *bsp_p,NodeId update_node_id,CodeGe #ifdef REUSE_UNIQUE_NODES # if GENERATE_CODE_AGAIN -extern int call_code_generator_again; - -static void restore_removed_arguments (ArgP *arg_h,ArgP removed_args,unsigned int argument_overwrite_bits,int node_arity) +void restore_removed_arguments (ArgP *arg_h,ArgP removed_args,unsigned int argument_overwrite_bits,int node_arity) { int arg_n; ArgP not_removed_args; @@ -4026,11 +4270,10 @@ static void restore_removed_arguments (ArgP *arg_h,ArgP removed_args,unsigned in } # endif -static #if GENERATE_CODE_AGAIN - ArgP + ArgP #else - void + void #endif compute_bits_and_remove_unused_arguments_for_strict_node (NodeP node,char bits[],unsigned int argument_overwrite_bits, int *a_size_p,int *b_size_p,int *n_a_fill_bits_p,int *n_b_fill_bits_p) @@ -4103,12 +4346,10 @@ static #endif } - -static #if GENERATE_CODE_AGAIN - ArgP + ArgP #else - void + void #endif compute_bits_and_remove_unused_arguments (NodeP node,char bits[],unsigned int argument_overwrite_bits,unsigned int *n_args_p) { @@ -4543,7 +4784,9 @@ void BuildArg (Args arg,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_ NodeId arg_node_id; arg_node_id=node->node_node_id; - +#if BOXED_RECORDS + arg_node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif if (CopyNodeIdArgument (arg->arg_state,arg_node_id,asp_p,bsp_p)) ChangeEvalStatusKindToStrictOnA (arg_node_id,code_gen_node_ids_p->saved_nid_state_l); @@ -4692,6 +4935,9 @@ static Bool BuildNonParArgs (Args args,int *asp_p,int *bsp_p,CodeGenNodeIdsP cod } else { ArgComment (args); +#if BOXED_RECORDS + arg_node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif if (CopyNodeIdArgument (args->arg_state,arg_node_id,asp_p,bsp_p)) ChangeEvalStatusKindToStrictOnA (arg_node_id,code_gen_node_ids_p->saved_nid_state_l); @@ -4902,7 +5148,7 @@ void BuildArgs (Args args,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_id } } -static void BuildLazyArgs (Args args,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p) +void BuildLazyArgs (Args args,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p) { if (args==NULL) return; @@ -5255,11 +5501,14 @@ static int FillNodeDefs (NodeDefs nds,int node_id_number,int *asp_p,int *bsp_p,N NodeId node_id; node_id=tuple_node->node_node_id; +#if BOXED_RECORDS + node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif if (CopyNodeIdArgument (tuple_node->node_arguments->arg_state,node_id,asp_p,bsp_p)) ChangeEvalStatusKindToStrictOnA (node_id,code_gen_node_ids_p->saved_nid_state_l); tuple_state_p=&tuple_node->node_arguments->arg_state; - + decrement_reference_count_of_node_id (node_id,&code_gen_node_ids_p->free_node_ids); } @@ -5352,10 +5601,16 @@ static int FillNodeDefs (NodeDefs nds,int node_id_number,int *asp_p,int *bsp_p,N #ifdef DO_LAZY_SELECTORS_FROM_BOXED_STRICT_RECORDS if (result_state_p->state_type==SimpleState && result_state_p->state_kind==OnA && !ResultIsNotInRootNormalForm (node_id->nid_state)) result_state_p->state_kind=StrictOnA; -#endif +#endif +#if BOXED_RECORDS + if (node_id->nid_refcount>1) + node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif if (CopyNodeIdArgument (*result_state_p,node_id,asp_p,bsp_p)) ChangeEvalStatusKindToStrictOnA (node_id,code_gen_node_ids_p->saved_nid_state_l); - +# if 0 + printf ("decrement_reference_count_of_node_id %d\n",node_id->nid_refcount); +# endif decrement_reference_count_of_node_id (node_id,&code_gen_node_ids_p->free_node_ids); } } else @@ -5733,41 +5988,31 @@ static void AdjustStacksAndJumpToThenOrElseLabel } if (asp==else_asp && bsp - else_bsp - bsize == 0){ -#if 1 if (falselab==next_label && asp==then_asp && bsp-bsize==then_bsp){ GenJmpTrue (truelab); truelab->lab_mod=NULL; - } else -#endif - { + } else { GenJmpFalse (falselab); falselab->lab_mod=NULL; UpdateStackPointers (asp, bsp-bsize, then_asp, then_bsp); -#if 1 - if (truelab!=next_label) -#endif - { + + if (truelab!=next_label){ GenJmp (truelab); truelab->lab_mod=NULL; } } } else if (asp==then_asp && bsp - then_bsp - bsize == 0){ -#if 1 if (truelab==next_label && asp==else_asp && bsp-bsize==else_bsp){ GenJmpTrue (falselab); falselab->lab_mod=NULL; - } else -#endif - { + } else { GenJmpTrue (truelab); truelab->lab_mod=NULL; UpdateStackPointers (asp, bsp-bsize, else_asp, else_bsp); -#if 1 - if (falselab!=next_label) -#endif - { + + if (falselab!=next_label){ GenJmp (falselab); falselab->lab_mod=NULL; } @@ -5785,10 +6030,7 @@ static void AdjustStacksAndJumpToThenOrElseLabel GenLabelDefinition (&loclab); UpdateStackPointers (asp, bsp-bsize, else_asp, else_bsp); -#if 1 - if (falselab!=next_label) -#endif - { + if (falselab!=next_label){ GenJmp (falselab); falselab->lab_mod=NULL; } @@ -5802,8 +6044,12 @@ void EvaluateCondition (Node cond_node,int *asp_p,int *bsp_p,CodeGenNodeIdsP cod { NodeId nid; int boolean_b_size; - + nid=cond_node->node_node_id; + +#if BOXED_RECORDS + nid->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif CopyNodeIdArgument (resultstate,nid,asp_p,bsp_p); decrement_reference_count_of_node_id (nid,&code_gen_node_ids_p->free_node_ids); @@ -5851,7 +6097,9 @@ void subtract_else_ref_counts (struct node_id_ref_count_list *else_node_id_ref_c int ref_count; node_id=else_node_id_ref_count->nrcl_node_id; - +#if BOXED_RECORDS + else_node_id_ref_count->nrcl_mark2=node_id->nid_mark2 & NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif ref_count=node_id->nid_refcount; if (ref_count>=0){ ref_count -= else_node_id_ref_count->nrcl_ref_count; @@ -5877,8 +6125,17 @@ void add_else_ref_counts (struct node_id_ref_count_list *else_node_id_ref_counts for_l (else_node_id_ref_count,else_node_id_ref_counts,nrcl_next){ struct node_id *node_id; - +#if BOXED_RECORDS + unsigned int node_id_mark2; +#endif node_id=else_node_id_ref_count->nrcl_node_id; + +#if BOXED_RECORDS + node_id_mark2=node_id->nid_mark2; + node_id->nid_mark2=(node_id_mark2 & ~NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES) | else_node_id_ref_count->nrcl_mark2; + else_node_id_ref_count->nrcl_mark2=node_id_mark2 & NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif + if (node_id->nid_refcount>=0) node_id->nid_refcount += else_node_id_ref_count->nrcl_ref_count; else @@ -5886,10 +6143,20 @@ void add_else_ref_counts (struct node_id_ref_count_list *else_node_id_ref_counts } } +#if BOXED_RECORDS +void or_then_record_update_marks (struct node_id_ref_count_list *else_node_id_ref_counts) +{ + struct node_id_ref_count_list *else_node_id_ref_count; + + for_l (else_node_id_ref_count,else_node_id_ref_counts,nrcl_next) + else_node_id_ref_count->nrcl_node_id->nid_mark2 |= else_node_id_ref_counts->nrcl_mark2; +} +#endif + static void EvaluateThenOrElsePartOfCondition (NodeDefs defs,Node node,int asp,int bsp,StateS resultstate, Label truelab, Label falselab,Label next_label, int then_asp,int then_bsp,int else_asp,int else_bsp,NodeIdListElementP a_node_ids,NodeIdListElementP b_node_ids, - struct node_id_ref_count_list *else_node_id_ref_counts,NodeIdListElementP free_node_ids); + NodeIdListElementP free_node_ids); void BranchOnCondition (Node condnode,int asp,int bsp,CodeGenNodeIdsP code_gen_node_ids_p, StateS resultstate, Label truelab,Label falselab,Label next_label,int then_asp,int then_bsp,int else_asp,int else_bsp) @@ -5957,13 +6224,23 @@ void BranchOnCondition (Node condnode,int asp,int bsp,CodeGenNodeIdsP code_gen_n new_then_asp, new_then_bsp, new_else_asp, new_else_bsp); if (!thenlabel){ + NodeIdListElementP free_node_ids; + if (thenlab.lab_mod==NULL) GenLabelDefinition (&thenlab); + free_node_ids=code_gen_node_ids_p->free_node_ids; + + if (condnode->node_else_node_id_ref_counts!=NULL) + subtract_else_ref_counts (condnode->node_else_node_id_ref_counts,&free_node_ids); + EvaluateThenOrElsePartOfCondition (condnode->node_then_node_defs, condpart->arg_next->arg_node, asp,bsp,resultstate,truelab,falselab,!elselabel ? &elselab : next_label, then_asp,then_bsp,else_asp,else_bsp,code_gen_node_ids_p->a_node_ids,code_gen_node_ids_p->b_node_ids, - condnode->node_else_node_id_ref_counts,code_gen_node_ids_p->free_node_ids); + free_node_ids); + + if (condnode->node_else_node_id_ref_counts!=NULL) + add_else_ref_counts (condnode->node_else_node_id_ref_counts); } if (!elselabel){ @@ -5973,8 +6250,14 @@ void BranchOnCondition (Node condnode,int asp,int bsp,CodeGenNodeIdsP code_gen_n EvaluateThenOrElsePartOfCondition (condnode->node_else_node_defs, condpart->arg_next->arg_next->arg_node,asp,bsp,resultstate,truelab,falselab,next_label, then_asp,then_bsp,else_asp,else_bsp,code_gen_node_ids_p->a_node_ids,code_gen_node_ids_p->b_node_ids, - NULL,code_gen_node_ids_p->free_node_ids); + code_gen_node_ids_p->free_node_ids); } + +#if BOXED_RECORDS + if (!thenlabel && condnode->node_else_node_id_ref_counts) + + or_then_record_update_marks (condnode->node_else_node_id_ref_counts); +#endif break; } default: @@ -5985,7 +6268,7 @@ void BranchOnCondition (Node condnode,int asp,int bsp,CodeGenNodeIdsP code_gen_n static void EvaluateThenOrElsePartOfCondition (NodeDefs defs,Node node,int asp,int bsp,StateS resultstate, Label truelab, Label falselab,Label next_label, int then_asp,int then_bsp,int else_asp,int else_bsp,NodeIdListElementP a_node_ids,NodeIdListElementP b_node_ids, - struct node_id_ref_count_list *else_node_id_ref_counts,NodeIdListElementP free_node_ids) + NodeIdListElementP free_node_ids) { SavedNidStateP saved_node_id_states; MovedNodeIdP moved_node_ids; @@ -5994,9 +6277,6 @@ static void EvaluateThenOrElsePartOfCondition saved_node_id_states=NULL; moved_node_ids=NULL; - if (else_node_id_ref_counts!=NULL) - subtract_else_ref_counts (else_node_id_ref_counts,&free_node_ids); - code_gen_node_ids.free_node_ids=free_node_ids; code_gen_node_ids.saved_nid_state_l=&saved_node_id_states; code_gen_node_ids.doesnt_fail=False; @@ -6011,9 +6291,6 @@ static void EvaluateThenOrElsePartOfCondition BranchOnCondition (node,asp,bsp,&code_gen_node_ids,resultstate,truelab,falselab,next_label,then_asp,then_bsp,else_asp,else_bsp); restore_saved_node_id_states (saved_node_id_states); - - if (else_node_id_ref_counts!=NULL) - add_else_ref_counts (else_node_id_ref_counts); } void InitCoding (void) diff --git a/backendC/CleanCompilerSources/codegen2.h b/backendC/CleanCompilerSources/codegen2.h index a6eb383..39f0456 100644 --- a/backendC/CleanCompilerSources/codegen2.h +++ b/backendC/CleanCompilerSources/codegen2.h @@ -6,6 +6,25 @@ typedef { NormalFill, ReleaseAndFill, PartialFill } FillKind; +typedef enum { + AToA, AToB, BToA, BToB, Reduce,AToRoot, MayBecomeCyclicSpine, CyclicSpine +} Coercions; + +STRUCT (moved_node_id,MovedNodeId){ + struct node_id * mnid_node_id; + struct moved_node_id * mnid_next; + int mnid_a_stack_offset; +}; + +STRUCT (code_gen_node_ids,CodeGenNodeIds){ + struct saved_nid_state **saved_nid_state_l; + struct node_id_list_element *free_node_ids; + struct moved_node_id **moved_node_ids_l; + struct node_id_list_element *a_node_ids; + struct node_id_list_element *b_node_ids; + int doesnt_fail; +}; + extern StateS OnAState; extern LabDef BasicDescriptors []; extern unsigned NewLabelNr; @@ -38,24 +57,29 @@ extern void PackArgument (StateS argstate,int aindex,int bindex,int asp,int bsp, extern void save_node_id_state (NodeId node_id,struct saved_nid_state **ifrule); extern void restore_saved_node_id_states (struct saved_nid_state *saved_node_id_states); -typedef enum { - AToA, AToB, BToA, BToB, Reduce,AToRoot, MayBecomeCyclicSpine, CyclicSpine -} Coercions; - -STRUCT (moved_node_id,MovedNodeId){ - struct node_id * mnid_node_id; - struct moved_node_id * mnid_next; - int mnid_a_stack_offset; -}; - -STRUCT (code_gen_node_ids,CodeGenNodeIds){ - struct saved_nid_state **saved_nid_state_l; - struct node_id_list_element *free_node_ids; - struct moved_node_id **moved_node_ids_l; - struct node_id_list_element *a_node_ids; - struct node_id_list_element *b_node_ids; - int doesnt_fail; -}; +#if GENERATE_CODE_AGAIN +extern ArgP +#else +extern void +#endif + compute_bits_and_remove_unused_arguments (NodeP node,char bits[],unsigned int argument_overwrite_bits,unsigned int *n_args_p); +#if GENERATE_CODE_AGAIN +extern ArgP +#else +extern void +#endif + compute_bits_and_remove_unused_arguments_for_strict_node (NodeP node,char bits[],unsigned int argument_overwrite_bits, + int *a_size_p,int *b_size_p,int *n_a_fill_bits_p,int *n_b_fill_bits_p); +#if GENERATE_CODE_AGAIN +extern void restore_removed_arguments (ArgP *arg_h,ArgP removed_args,unsigned int argument_overwrite_bits,int node_arity); +#endif + +#ifdef DESTRUCTIVE_RECORD_UPDATES +extern void compute_bits_and_add_selectors_to_update_node + (ArgS *record_arg,ArgS *first_field_arg,StateS *field_states,int record_a_size,int record_b_size, + char bits[],int *n_a_fill_bits_p,int *n_b_fill_bits_p); +#endif +int is_unique_record_update (NodeIdP record_node_id,NodeP record_node); Coercions CoerceStateKind (StateKind dem_state_kind, StateKind off_state_kind); void GenReduceError (void); @@ -69,6 +93,7 @@ int get_b_index_of_unpacked_lhs_node (ArgS *arg); void decrement_reference_count_of_node_id (struct node_id *node_id,NodeIdListElementS **free_node_ids_l); void BuildArgs (Args args,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p); +void BuildLazyArgs (Args args,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p); void build_and_cleanup (Node node,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p); #define RECORD_N_PREF c_pref @@ -85,6 +110,9 @@ void Build (Node node,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p) Coercions CoerceSimpleStateArgument (StateS demstate,StateKind offkind,int aindex,int *asp_p,Bool leaveontop, Bool *ontop); void subtract_else_ref_counts (struct node_id_ref_count_list *else_node_id_ref_counts,NodeIdListElementS **free_node_ids_l); void add_else_ref_counts (struct node_id_ref_count_list *else_node_id_ref_counts); +#if BOXED_RECORDS + void or_then_record_update_marks (struct node_id_ref_count_list *else_node_id_ref_counts); +#endif void EvaluateCondition (Node cond_node,int *asp_p,int *bsp_p,CodeGenNodeIdsP code_gen_node_ids_p,StateS resultstate); void DetermineFieldSizeAndPositionAndRecordSize (int fieldnr,int *asize_p,int *bsize_p,int *apos_p,int *bpos_p,int *rec_asize_p,int *rec_bsize_p,StateS *record_state_p); @@ -114,4 +142,6 @@ void cleanup_stack void ChangeEvalStatusKindToStrictOnA (NodeId node_id,SavedNidStateS **saved_nid_state_l); #if OPTIMIZE_LAZY_TUPLE_RECURSION void FillNodeOnACycle (Node node,int *asp_p,int *bsp_p,NodeId update_node_id,CodeGenNodeIdsP code_gen_node_ids_p); -#endif
\ No newline at end of file +#endif +void PushField (StateS recstate,int fieldnr,int offset,int *asp_p,int *bsp_p,int *a_size_p,int *b_size_p); +void ReplaceRecordByField (StateS recstate,int fieldnr,int *asp_p,int *bsp_p,int *a_size_p,int *b_size_p); diff --git a/backendC/CleanCompilerSources/codegen3.c b/backendC/CleanCompilerSources/codegen3.c index 0402a8c..c055041 100644 --- a/backendC/CleanCompilerSources/codegen3.c +++ b/backendC/CleanCompilerSources/codegen3.c @@ -17,6 +17,8 @@ #include "comsupport.h" #include "codegen_types.h" +#include "statesgen.h" +#include "optimisations.h" #include "codegen.h" #include "codegen1.h" #include "codegen2.h" @@ -688,26 +690,18 @@ static void CodeRootSelection (Node root, NodeId rootid,int asp,int bsp,CodeGenN static int CodeRhsNodeDefsAndRestoreNodeIdStates (Node root_node,NodeDefs defs,int asp,int bsp,StateS resultstate,struct esc *esc_p, NodeIdListElementP a_node_ids,NodeIdListElementP b_node_ids, - struct node_id_ref_count_list *else_node_id_ref_counts,int doesnt_fail) + NodeIdListElementP free_node_ids,int doesnt_fail) { SavedNidStateP saved_node_id_states; - NodeIdListElementP free_node_ids; int need_next_alternative; saved_node_id_states=NULL; - free_node_ids=NULL; - - if (else_node_id_ref_counts!=NULL) - subtract_else_ref_counts (else_node_id_ref_counts,&free_node_ids); - + need_next_alternative=CodeRhsNodeDefs (root_node,defs,asp,bsp,&saved_node_id_states,resultstate,esc_p,a_node_ids,b_node_ids, free_node_ids,doesnt_fail); restore_saved_node_id_states (saved_node_id_states); - if (else_node_id_ref_counts!=NULL) - add_else_ref_counts (else_node_id_ref_counts); - return need_next_alternative; } @@ -928,18 +922,6 @@ static void CodeNormalRootNode (Node root,NodeId rootid,int asp,int bsp,CodeGenN } } -static void PushField (StateS recstate,int fieldnr,int offset,int *asp_p,int *bsp_p,int *a_size_p,int *b_size_p) -{ - int apos,bpos,totasize,totbsize; - - DetermineFieldSizeAndPositionAndRecordSize (fieldnr,a_size_p,b_size_p,&apos,&bpos,&totasize,&totbsize,&recstate); - - GenPushRArgB (offset, totasize, totbsize, bpos+1, *b_size_p); - GenPushRArgA (offset, totasize, totbsize, apos+1, *a_size_p); - *bsp_p += *b_size_p; - *asp_p += *a_size_p; -} - static void CodeRootFieldSelector (Node root,NodeId rootid,int asp,int bsp,CodeGenNodeIdsP code_gen_node_ids_p,StateS demstate) { int fieldnr; @@ -976,19 +958,31 @@ static void CodeRootFieldSelector (Node root,NodeId rootid,int asp,int bsp,CodeG if (arg_node->node_kind!=NodeIdNode){ StateS offstate; + StateP record_state_p; offstate = arg_node->node_state; Build (arg_node,&asp,&bsp,code_gen_node_ids_p); + record_state_p=&seldef->sdef_type->type_lhs->ft_symbol->symb_def->sdef_record_state; + if (root->node_arity>=SELECTOR_U){ int record_a_size,record_b_size,asize,bsize,aindex,bindex,offstate_a_size,offstate_b_size; - StateP record_state_p; - - record_state_p=&seldef->sdef_type->type_lhs->ft_symbol->symb_def->sdef_record_state; - + DetermineSizeOfState (offstate,&offstate_a_size,&offstate_b_size); CoerceArgumentOnTopOfStack (&asp,&bsp,arg->arg_state,offstate,offstate_a_size,offstate_b_size); +#if BOXED_RECORDS + if (arg->arg_state.state_type==SimpleState){ + if (root->node_arity<SELECTOR_L){ + PushField (*record_state_p,fieldnr,0,&asp,&bsp,&asize,&bsize); + RedirectResultAndReturn (asp,bsp,asp,bsp,root->node_state,demstate,1+asize,bsize); + } else { + ReplaceRecordByField (*record_state_p,fieldnr,&asp,&bsp,&asize,&bsize); + DetermineSizeOfState (root->node_state,&offstate_a_size,&offstate_b_size); + RedirectResultAndReturn (asp,bsp,asp,bsp,root->node_state,demstate,offstate_a_size,offstate_b_size); + } + } else { +#endif DetermineFieldSizeAndPositionAndRecordSize (fieldnr,&asize,&bsize,&aindex,&bindex,&record_a_size,&record_b_size,record_state_p); if (root->node_arity<SELECTOR_L){ @@ -1008,7 +1002,9 @@ static void CodeRootFieldSelector (Node root,NodeId rootid,int asp,int bsp,CodeG DetermineSizeOfState (root->node_state,&offstate_a_size,&offstate_b_size); RedirectResultAndReturn (asp,bsp,asp,bsp,root->node_state,demstate,offstate_a_size,offstate_b_size); } - +#if BOXED_RECORDS + } +#endif return; } @@ -1023,9 +1019,13 @@ static void CodeRootFieldSelector (Node root,NodeId rootid,int asp,int bsp,CodeG return; } else { int a_size,b_size; - +#if 1 + PushField (*record_state_p, fieldnr, 0, & asp, & bsp,&a_size,&b_size); + RedirectResultAndReturn (asp,bsp,asp,bsp,record_state_p->state_record_arguments[fieldnr],demstate,a_size,b_size); +#else PushField (arg->arg_state, fieldnr, 0, & asp, & bsp,&a_size,&b_size); RedirectResultAndReturn (asp,bsp,asp,bsp,arg->arg_state.state_record_arguments[fieldnr],demstate,a_size,b_size); +#endif return; } } else { @@ -1079,14 +1079,21 @@ static void CodeRootFieldSelector (Node root,NodeId rootid,int asp,int bsp,CodeG } else { Bool ontop; int a_size,b_size; + StateP record_state_p; + record_state_p=&seldef->sdef_type->type_lhs->ft_symbol->symb_def->sdef_record_state; if (root->node_arity>=SELECTOR_U){ int asize,bsize,aindex,bindex,offered_a_size,offered_b_size; - StateP record_state_p; - record_state_p=&seldef->sdef_type->type_lhs->ft_symbol->symb_def->sdef_record_state; CopyNodeIdArgument (arg->arg_state,arg_node_id,&asp,&bsp); - +#if BOXED_RECORDS + if (arg->arg_state.state_type==SimpleState){ + if (root->node_arity<SELECTOR_L) + PushField (*record_state_p,fieldnr,0,&asp,&bsp,&asize,&bsize); + else + ReplaceRecordByField (*record_state_p,fieldnr,&asp,&bsp,&asize,&bsize); + } else { +#endif DetermineFieldSizeAndPosition (fieldnr,&asize,&bsize,&aindex,&bindex,record_state_p->state_record_arguments); if (root->node_arity<SELECTOR_L){ @@ -1105,17 +1112,22 @@ static void CodeRootFieldSelector (Node root,NodeId rootid,int asp,int bsp,CodeG DetermineSizeOfState (*record_state_p,&record_a_size,&record_b_size); ReplaceRecordOnTopOfStackByField (&asp,&bsp,aindex,bindex,asize,bsize,record_a_size,record_b_size); } - +#if BOXED_RECORDS + } +#endif DetermineSizeOfState (root->node_state,&offered_a_size,&offered_b_size); RedirectResultAndReturn (asp,bsp,asp,bsp,root->node_state,demstate,offered_a_size,offered_b_size); return; } CoerceSimpleStateArgument (demstate, offstate.state_kind,arg_node_id->nid_a_index,&asp,False,&ontop); - +#if 1 + PushField (*record_state_p,fieldnr,asp-arg_node_id->nid_a_index,&asp,&bsp,&a_size,&b_size); + RedirectResultAndReturn (asp, bsp, asp, bsp,record_state_p->state_record_arguments[fieldnr],demstate,a_size,b_size); +#else PushField (arg->arg_state,fieldnr,asp-arg_node_id->nid_a_index,&asp,&bsp,&a_size,&b_size); - RedirectResultAndReturn (asp, bsp, asp, bsp,arg->arg_state.state_record_arguments[fieldnr],demstate,a_size,b_size); +#endif return; } } @@ -1200,24 +1212,85 @@ static void CodeRootUpdateNode (Node root,NodeId rootid,int asp,int bsp,CodeGenN first_field_arg=record_arg->arg_next; RemoveSelectorsFromUpdateNode (record_arg,first_field_arg); - - /* BuildNewStackFrame (record_arg,asp,bsp,False,code_gen_node_ids_p); */ - + +#if 1 + BuildArgs (record_arg->arg_next,&asp,&bsp,code_gen_node_ids_p); +#endif + + if (IsSimpleState (root->node_state) && record_arg->arg_node->node_kind==NodeIdNode){ + NodeIdP record_node_id; + + record_node_id=record_arg->arg_node->node_node_id; + + if (is_unique_record_update (record_node_id,record_arg->arg_node) && rootid==NULL){ +/* + if ((record_node_id->nid_state.state_mark & STATE_UNIQUE_MASK)!=0 && + (record_node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && + record_node_id->nid_number== -1 && + record_node_id->nid_state.state_type==SimpleState && + record_node_id->nid_state.state_kind==StrictOnA && + !DoReuseUniqueNodes && rootid==NULL) + { +*/ int n_a_fill_bits,n_b_fill_bits; + char bits[MaxNodeArity+2]; + LabDef record_lab; + +#if BOXED_RECORDS + record_node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif + DetermineSizeOfState (record_sdef->sdef_record_state,&record_a_size,&record_b_size); + + if (record_a_size+record_b_size>2){ +#if 0 + BuildArgs (record_arg->arg_next,&asp,&bsp,code_gen_node_ids_p); +#endif + compute_bits_and_add_selectors_to_update_node (record_arg,first_field_arg, + record_sdef->sdef_record_state.state_record_arguments,record_a_size,record_b_size, + bits,&n_a_fill_bits,&n_b_fill_bits); + + ConvertSymbolToRLabel (&record_lab,record_sdef->sdef_record_state.state_record_symbol); + + GenPushA (asp-record_node_id->nid_a_index); + asp+=1; + + GenFill3R (&record_lab,record_a_size,record_b_size,asp,bits+1); + + asp-=n_a_fill_bits+1; + bsp-=n_b_fill_bits; + + decrement_reference_count_of_node_id (record_node_id,&code_gen_node_ids_p->free_node_ids); + + GenPopA (asp); + GenPopB (bsp); + GenRtn (1,0,OnAState); + return; + } + } +#if BOXED_RECORDS + record_node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif + } + { int a_size,b_size; + StateP record_state_p; + + record_state_p=&root->node_symbol->symb_def->sdef_record_state; + record_arg->arg_state=*record_state_p; +#if 1 + BuildArg (record_arg,&asp,&bsp,code_gen_node_ids_p); +#else BuildArgs (record_arg,&asp,&bsp,code_gen_node_ids_p); +#endif DetermineSizeOfArguments (record_arg,&a_size,&b_size); UpdateAAndBStack (asp,bsp,a_size,b_size,&asp,&bsp); - } + + /* BuildNewStackFrame (record_arg,asp,bsp,False,code_gen_node_ids_p); */ if (IsSimpleState (root->node_state)){ LabDef record_label; - StateP record_state_p; -/* error_in_function ("CodeRootUpdateNode"); */ - - record_state_p=&root->node_symbol->symb_def->sdef_record_state; DetermineSizeOfState (*record_state_p,&record_a_size,&record_b_size); UpdateNodeAndAddSelectorsToUpdateNode (record_arg,first_field_arg, @@ -1240,12 +1313,130 @@ static void CodeRootUpdateNode (Node root,NodeId rootid,int asp,int bsp,CodeGenN GenRtn (record_a_size,record_b_size,result_state); } } + + } } #ifdef CLEAN2 extern int contains_fail (NodeP node_p); #endif +static void fill_strict_root_unique_node (NodeP node,NodeP update_node,char bits[],LabDef *label_p,NodeIdP free_unique_node_id,int asp,int bsp,CodeGenNodeIdsP code_gen_node_ids_p) +{ + int a_size,b_size,n_a_fill_bits,n_b_fill_bits; +#if GENERATE_CODE_AGAIN + ArgP removed_args= +#endif + compute_bits_and_remove_unused_arguments_for_strict_node (node,bits,update_node->node_arguments->arg_occurrence, + &a_size,&b_size,&n_a_fill_bits,&n_b_fill_bits); + + BuildArgs (node->node_arguments,&asp,&bsp,code_gen_node_ids_p); + +#if GENERATE_CODE_AGAIN + if (call_code_generator_again) + restore_removed_arguments (&node->node_arguments,removed_args,update_node->node_arguments->arg_occurrence,node->node_arity); +#endif + + GenPushA (asp-free_unique_node_id->nid_a_index); + asp+=1; + + GenFill3R (label_p,a_size,b_size,asp,bits+1); + + asp-=n_a_fill_bits+1; + bsp-=n_b_fill_bits; + + decrement_reference_count_of_node_id (free_unique_node_id,&code_gen_node_ids_p->free_node_ids); + + GenPopA (asp); + GenPopB (bsp); + GenRtn (1,0,OnAState); +} + +static void CodeRootFillUniqueNode (Node update_node,int asp,int bsp,CodeGenNodeIdsP code_gen_node_ids_p) +{ + unsigned int n_args,node_arity; + char bits[MaxNodeArity+2]; + NodeIdP free_unique_node_id; + NodeP node,push_node; + LabDef name,*label_p; + SymbolP symbol; + + node=update_node->node_arguments->arg_node; + push_node=update_node->node_node; + free_unique_node_id=push_node->node_arguments->arg_node->node_node_id; + + symbol=node->node_symbol; + + switch (symbol->symb_kind){ + case definition: + { + SymbDef sdef; + + sdef=node->node_symbol->symb_def; + + node_arity=node->node_arity; + + switch (sdef->sdef_kind){ + case CONSTRUCTOR: + bits[0]='1'; + + if (sdef->sdef_strict_constructor){ + ConvertSymbolToKLabel (&name,sdef); + + fill_strict_root_unique_node (node,update_node,bits,&name,free_unique_node_id,asp,bsp,code_gen_node_ids_p); + + return; + } else { + ConvertSymbolToConstructorDLabel (&name,sdef); + label_p=&name; + } + break; + case RECORDTYPE: + bits[0]='1'; + + ConvertSymbolToRLabel (&name,sdef); + + fill_strict_root_unique_node (node,update_node,bits,&name,free_unique_node_id,asp,bsp,code_gen_node_ids_p); + + return; + default: + error_in_function ("CodeRootFillUniqueNode"); + return; + } + break; + } + default: + error_in_function ("CodeRootFillUniqueNode"); + return; + } + +#if GENERATE_CODE_AGAIN + { + ArgP removed_args= +#endif + compute_bits_and_remove_unused_arguments (node,bits,update_node->node_arguments->arg_occurrence,&n_args); + + BuildLazyArgs (node->node_arguments,&asp,&bsp,code_gen_node_ids_p); + +#if GENERATE_CODE_AGAIN + if (call_code_generator_again) + restore_removed_arguments (&node->node_arguments,removed_args,update_node->node_arguments->arg_occurrence,node_arity); + } +#endif + + GenPushA (asp-free_unique_node_id->nid_a_index); + asp+=1; + + GenFill3 (label_p,node_arity,asp,bits+1); + asp-=n_args+1; + + decrement_reference_count_of_node_id (free_unique_node_id,&code_gen_node_ids_p->free_node_ids); + + GenPopA (asp); + GenPopB (bsp); + GenRtn (1,0,OnAState); +} + static int CodeRootNode (Node root,NodeId rootid,int asp,int bsp,CodeGenNodeIdsP code_gen_node_ids_p,StateS resultstate,struct esc *esc_p) { switch (root->node_kind){ @@ -1272,7 +1463,7 @@ static int CodeRootNode (Node root,NodeId rootid,int asp,int bsp,CodeGenNodeIdsP EvaluateCondition (condpart->arg_node,&asp,&bsp,code_gen_node_ids_p,condpart->arg_state); MakeLabel (&elselab, else_symb, NewLabelNr, no_pref); - MakeLabel (&thenlab, then_symb, NewLabelNr++, no_pref); + MakeLabel (&thenlab, then_symb, NewLabelNr++, no_pref); thenlab.lab_mod=notused_string; @@ -1282,15 +1473,23 @@ static int CodeRootNode (Node root,NodeId rootid,int asp,int bsp,CodeGenNodeIdsP if (thenlab.lab_mod==NULL) GenLabelDefinition (&thenlab); -#ifdef CLEAN2 + { + NodeIdListElementP free_node_ids; +#ifdef CLEAN2 int needs_next_alt; +#endif + free_node_ids=NULL; + if (root->node_else_node_id_ref_counts!=NULL) + subtract_else_ref_counts (root->node_else_node_id_ref_counts,&free_node_ids); + +#ifdef CLEAN2 needs_next_alt= #endif CodeRhsNodeDefsAndRestoreNodeIdStates (then_arg->arg_node,root->node_then_node_defs,asp,bsp,resultstate,esc_p, code_gen_node_ids_p->a_node_ids,code_gen_node_ids_p->b_node_ids, - root->node_else_node_id_ref_counts, + free_node_ids, #ifdef CLEAN2 !contains_fail (then_arg->arg_node) #else @@ -1300,6 +1499,9 @@ static int CodeRootNode (Node root,NodeId rootid,int asp,int bsp,CodeGenNodeIdsP code_gen_node_ids_p->doesnt_fail */ ); + + if (root->node_else_node_id_ref_counts!=NULL) + add_else_ref_counts (root->node_else_node_id_ref_counts); GenLabelDefinition (&elselab); @@ -1308,6 +1510,11 @@ static int CodeRootNode (Node root,NodeId rootid,int asp,int bsp,CodeGenNodeIdsP if (else_node->node_kind==NormalNode && else_node->node_symbol->symb_kind==fail_symb){ UpdateStackPointers (asp,bsp,esc_p->esc_asp,esc_p->esc_bsp); GenJmp (esc_p->esc_label); + +#if BOXED_RECORDS + if (root->node_else_node_id_ref_counts) + or_then_record_update_marks (root->node_else_node_id_ref_counts); +#endif return 1; } else @@ -1319,16 +1526,26 @@ static int CodeRootNode (Node root,NodeId rootid,int asp,int bsp,CodeGenNodeIdsP CodeRhsNodeDefsAndRestoreNodeIdStates (else_node,root->node_else_node_defs,asp,bsp,resultstate,esc_p, code_gen_node_ids_p->a_node_ids,code_gen_node_ids_p->b_node_ids, NULL,code_gen_node_ids_p->doesnt_fail); +#if BOXED_RECORDS + if (root->node_else_node_id_ref_counts) + or_then_record_update_marks (root->node_else_node_id_ref_counts); +#endif + #ifdef CLEAN2 return needs_next_alt; - } #endif + } } case NodeIdNode: if (rootid==NULL){ CodeRedirection (root->node_node_id,asp,bsp,resultstate,&code_gen_node_ids_p->free_node_ids); return 0; } + case FillUniqueNode: + if (rootid==NULL){ + CodeRootFillUniqueNode (root,asp,bsp,code_gen_node_ids_p); + return 0; + } default: error_in_function ("CodeRootNode"); return 0; @@ -1433,20 +1650,14 @@ static void generate_code_for_tail_call_modulo_cons (NodeP node_p,NodeId node_de NodeIdListElementP node_id_list; char bits[MaxNodeArity+2]; unsigned int a_bits,b_bits,a_size,b_size,a_size2,b_size2,n,arg_n; + int a_destination_offset,b_destination_offset; int total_a_size2,total_b_size2; int node_arity; ArgP arg_p; total_a_size2=0; total_b_size2=0; - - for_l (node_id_list,push_node->node_node_ids,nidl_next){ -# ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS - AddSizeOfState (*node_id_list->nidl_node_id->nid_lhs_state_p,&total_a_size2,&total_b_size2); -# else - AddSizeOfState (node_id_list->nidl_node_id->nid_state,&total_a_size2,&total_b_size2); -# endif - } + add_sizes_of_states_of_node_ids (push_node->node_node_ids,&total_a_size2,&total_b_size2); a_bits=0; b_bits=0; @@ -1497,23 +1708,51 @@ static void generate_code_for_tail_call_modulo_cons (NodeP node_p,NodeId node_de else b_bits|=1; - for (n=0; n<a_size; ++n) - bits[n]='0' + ((a_bits>>n) & 1); + a_destination_offset=a_size; + for (n=a_size-1; n>=0; --n) + if ((a_bits>>n) & 1){ + bits[n]='1'; + --a_destination_offset; + if (a_destination_offset!=n) + GenUpdateA (n,a_destination_offset); + } else + bits[n]='0'; + + if (a_destination_offset!=0){ + GenPopA (a_destination_offset); + asp-=a_destination_offset; + } + + b_destination_offset=b_size; + for (n=b_size-1; n>=0; --n) + if ((b_bits>>n) & 1){ + bits[n+a_size]='1'; + --b_destination_offset; + if (b_destination_offset!=n) + GenUpdateB (n,b_destination_offset); + } else + bits[n+a_size]='0'; + + if (b_destination_offset!=0){ + GenPopB (b_destination_offset); + bsp-=b_destination_offset; + } - for (n=0; n<b_size; ++n) - bits[n+a_size]='0' + ((b_bits>>n) & 1); - bits[a_size+b_size]='\0'; GenPushA (asp-node_def_id->nid_a_index); GenFill3R (constructor_name_p,asize,bsize,asp+1,bits); - } else + + asp-=asize-a_destination_offset; + bsp-=bsize-b_destination_offset; + } else { GenFillR (constructor_name_p,asize,bsize,asp,0,0,ReleaseAndFill,True); - asp-=asize; - bsp-=bsize; + asp-=asize; + bsp-=bsize; + } } - + if (tail_call_modulo_cons) name.lab_post=2; @@ -1641,7 +1880,10 @@ static void fill_lazy_tuple_result_arguments (Args arg,int *asp_p,int *bsp_p,int NodeId arg_node_id; arg_node_id=node->node_node_id; - + +# if BOXED_RECORDS + arg_node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +# endif if (CopyNodeIdArgument (arg->arg_state,arg_node_id,asp_p,bsp_p)) ChangeEvalStatusKindToStrictOnA (arg_node_id,code_gen_node_ids_p->saved_nid_state_l); @@ -1672,7 +1914,10 @@ static void fill_lazy_tuple_result_arguments (Args arg,int *asp_p,int *bsp_p,int NodeId arg_node_id; arg_node_id=node->node_node_id; - + +# if BOXED_RECORDS + arg_node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +# endif if (arg_node_id->nid_state.state_type==SimpleState && arg_node_id->nid_state.state_kind!=OnB){ if (CopyNodeIdArgument (arg->arg_state,arg_node_id,asp_p,bsp_p)) ChangeEvalStatusKindToStrictOnA (arg_node_id,code_gen_node_ids_p->saved_nid_state_l); @@ -1739,6 +1984,9 @@ static void fill_strict_tuple_result_arguments (Args arg,ArgP *function_result_t arg_node_id=node->node_node_id; +#if BOXED_RECORDS + arg_node_id->nid_mark2 |= NID_RECORD_USED_BY_NON_SELECTOR_OR_UPDATES; +#endif if (arg_node_id->nid_state.state_type==SimpleState && arg_node_id->nid_state.state_kind!=OnB){ if (CopyNodeIdArgument (arg->arg_state,arg_node_id,asp_p,bsp_p)) ChangeEvalStatusKindToStrictOnA (arg_node_id,code_gen_node_ids_p->saved_nid_state_l); diff --git a/backendC/CleanCompilerSources/optimisations.c b/backendC/CleanCompilerSources/optimisations.c index 7458205..9ceed19 100644 --- a/backendC/CleanCompilerSources/optimisations.c +++ b/backendC/CleanCompilerSources/optimisations.c @@ -12,8 +12,8 @@ #include "checker.h" #include "scanner.h" #include "buildtree.h" -#include "optimisations.h" #include "codegen_types.h" +#include "optimisations.h" #include "codegen1.h" #include "codegen2.h" #include "sa.h" @@ -1804,8 +1804,6 @@ static int ChangeArgumentNodeStatesIfStricter (NodeP node_p,StateP demanded_stat #ifdef REUSE_UNIQUE_NODES - - static NodeP replace_node_by_unique_fill_node (NodeP node,NodeP push_node,int node_size) { NodeP node_copy; @@ -1836,7 +1834,20 @@ static NodeP replace_node_by_unique_fill_node (NodeP node,NodeP push_node,int no return node_copy; } -static int compute_n_not_updated_words (NodeP push_node,NodeP node,int node_a_size) +void add_sizes_of_states_of_node_ids (NodeIdListElementP node_id_list,int *total_a_size_p,int *total_b_size_p) +{ + NodeIdListElementP node_id_list_elem_p; + + for_l (node_id_list_elem_p,node_id_list,nidl_next){ +# ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + AddSizeOfState (*node_id_list_elem_p->nidl_node_id->nid_lhs_state_p,total_a_size_p,total_b_size_p); +# else + AddSizeOfState (node_id_list_elem_p->nidl_node_id->nid_state,total_a_size_p,total_b_size_p); +# endif + } +} + +static int compute_root_n_not_updated_words (NodeP push_node,NodeP node,int node_a_size) { NodeIdListElementP node_id_list; unsigned long n_not_updated_words; @@ -1847,14 +1858,66 @@ static int compute_n_not_updated_words (NodeP push_node,NodeP node,int node_a_si total_a_size2=0; total_b_size2=0; + add_sizes_of_states_of_node_ids (push_node->node_node_ids,&total_a_size2,&total_b_size2); - for_l (node_id_list,push_node->node_node_ids,nidl_next){ + n_not_updated_words=0; + node_arg_p=node->node_arguments; + arity=node->node_arity; + node_id_list=push_node->node_node_ids; + + a_size1=0; + b_size1=0; + a_size2=0; + b_size2=0; + + for (n=0; n<arity; ++n){ + int e_a_size1,e_b_size1,e_a_size2,e_b_size2; + + DetermineSizeOfState (node_arg_p->arg_state,&e_a_size1,&e_b_size1); + + if (node_id_list!=NULL){ + NodeIdP node_id_p; + + node_id_p=node_id_list->nidl_node_id; # ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS - AddSizeOfState (*node_id_list->nidl_node_id->nid_lhs_state_p,&total_a_size2,&total_b_size2); + DetermineSizeOfState (*node_id_p->nid_lhs_state_p,&e_a_size2,&e_b_size2); # else - AddSizeOfState (node_id_list->nidl_node_id->nid_state,&total_a_size2,&total_b_size2); -# endif - } + DetermineSizeOfState (node_id_p->nid_state,&e_a_size2,&e_b_size2); +# endif + if (node_arg_p->arg_node->node_kind==NodeIdNode && node_arg_p->arg_node->node_node_id==node_id_list->nidl_node_id){ + if (! (e_a_size1!=e_a_size2 || e_b_size1!=e_b_size2 || + ((e_a_size1 | e_a_size2)!=0 && a_size1!=a_size2 && a_size1!=0) || + ((e_b_size1 | e_b_size2)!=0 && b_size1+node_a_size!=b_size2+total_a_size2 && b_size1+node_a_size!=0))) + { + n_not_updated_words += e_a_size1+e_b_size1; + } + } + + a_size2+=e_a_size2; + b_size2+=e_b_size2; + node_id_list=node_id_list->nidl_next; + } + + a_size1+=e_a_size1; + b_size1+=e_b_size1; + node_arg_p=node_arg_p->arg_next; + } + + return n_not_updated_words; +} + +static int compute_n_not_updated_words (NodeP push_node,NodeP node,int node_a_size) +{ + NodeIdListElementP node_id_list; + unsigned long n_not_updated_words; + ArgP node_arg_p; + unsigned int n,arity; + int a_size1,b_size1,a_size2,b_size2; + int total_a_size2,total_b_size2; + + total_a_size2=0; + total_b_size2=0; + add_sizes_of_states_of_node_ids (push_node->node_node_ids,&total_a_size2,&total_b_size2); n_not_updated_words=0; node_arg_p=node->node_arguments; @@ -1867,22 +1930,20 @@ static int compute_n_not_updated_words (NodeP push_node,NodeP node,int node_a_si b_size2=0; for (n=0; n<arity; ++n){ + int e_a_size1,e_b_size1,e_a_size2,e_b_size2; + + DetermineSizeOfState (node_arg_p->arg_state,&e_a_size1,&e_b_size1); + if (node_id_list!=NULL){ NodeIdP node_id_p; - StateP arg_node_id_state_p; node_id_p=node_id_list->nidl_node_id; - - if (node_arg_p->arg_node->node_kind==NodeIdNode && node_arg_p->arg_node->node_node_id==node_id_list->nidl_node_id){ - int e_a_size1,e_b_size1,e_a_size2,e_b_size2; - - DetermineSizeOfState (node_arg_p->arg_state,&e_a_size1,&e_b_size1); - # ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS - DetermineSizeOfState (*node_id_p->nid_lhs_state_p,&e_a_size2,&e_b_size2); + DetermineSizeOfState (*node_id_p->nid_lhs_state_p,&e_a_size2,&e_b_size2); # else - DetermineSizeOfState (node_id_p->nid_state,&e_a_size2,&e_b_size2); -# endif + DetermineSizeOfState (node_id_p->nid_state,&e_a_size2,&e_b_size2); +# endif + if (node_arg_p->arg_node->node_kind==NodeIdNode && node_arg_p->arg_node->node_node_id==node_id_list->nidl_node_id){ if (! (e_a_size1!=e_a_size2 || e_b_size1!=e_b_size2 || ((e_a_size1 | e_a_size2)!=0 && a_size1!=a_size2) || ((e_b_size1 | e_b_size2)!=0 && b_size1+node_a_size!=b_size2+total_a_size2))) @@ -1891,24 +1952,142 @@ static int compute_n_not_updated_words (NodeP push_node,NodeP node,int node_a_si } } -# ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS - arg_node_id_state_p=node_id_p->nid_lhs_state_p; -# else - arg_node_id_state_p=&node_id_p->nid_state; -# endif - AddSizeOfState (*arg_node_id_state_p,&a_size2,&b_size2); - + a_size2+=e_a_size2; + b_size2+=e_b_size2; node_id_list=node_id_list->nidl_next; } - AddSizeOfState (node_arg_p->arg_state,&a_size1,&b_size1); - + a_size1+=e_a_size1; + b_size1+=e_b_size1; node_arg_p=node_arg_p->arg_next; } return n_not_updated_words; } +static Bool insert_root_unique_fill_node (NodeP node,FreeUniqueNodeIdsP *f_node_ids,int node_a_size,int node_b_size) +{ + FreeUniqueNodeIdsP f_node_id; + NodeP push_node,node_copy; + ArgP node_copy_arg_p; + unsigned long argument_overwrite_bits; + NodeIdListElementP node_id_list; + unsigned int n,arity; + int node_size; + + node_size=node_a_size+node_b_size; + + arity=node->node_arity; + + /* optimization: update node with fewest number of words to be updated */ + { + FreeUniqueNodeIdsP *f_node_id_h,*found_f_node_id_h; + int found_size,found_n_not_updated_words; + + found_f_node_id_h=NULL; + f_node_id_h=f_node_ids; + + while ((f_node_id=*f_node_id_h)!=NULL){ + int new_found_size; + + new_found_size=f_node_id->fnid_node_size; + + if (new_found_size>=node_size){ + int new_found_n_not_updated_words; + + new_found_n_not_updated_words=compute_root_n_not_updated_words (f_node_id->fnid_push_node,node,node_a_size); + + if (found_f_node_id_h==NULL || new_found_size<found_size || new_found_n_not_updated_words>found_n_not_updated_words){ + found_f_node_id_h=f_node_id_h; + found_size=new_found_size; + found_n_not_updated_words=new_found_n_not_updated_words; + } + } + + f_node_id_h=&f_node_id->fnid_next; + } + + if (found_f_node_id_h==NULL) + return False; + + f_node_id=*found_f_node_id_h; + *found_f_node_id_h=f_node_id->fnid_next; + } + + push_node=f_node_id->fnid_push_node; + + node_copy=replace_node_by_unique_fill_node (node,push_node,f_node_id->fnid_node_size); + + { + int a_size1,b_size1,a_size2,b_size2; + int total_a_size2,total_b_size2; + + total_a_size2=0; + total_b_size2=0; + add_sizes_of_states_of_node_ids (push_node->node_node_ids,&total_a_size2,&total_b_size2); + + argument_overwrite_bits=0; + node_copy_arg_p=node_copy->node_arguments; + node_id_list=push_node->node_node_ids; + + a_size1=0; + b_size1=0; + a_size2=0; + b_size2=0; + + for (n=0; n<arity; ++n){ + int e_a_size1,e_b_size1,e_a_size2,e_b_size2; + + DetermineSizeOfState (node_copy_arg_p->arg_state,&e_a_size1,&e_b_size1); + + if (node_id_list!=NULL){ + NodeIdP node_id_p; + + node_id_p=node_id_list->nidl_node_id; +# ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + DetermineSizeOfState (*node_id_p->nid_lhs_state_p,&e_a_size2,&e_b_size2); +# else + DetermineSizeOfState (node_id_p->nid_state,&e_a_size2,&e_b_size2); +# endif + if (node_copy_arg_p->arg_node->node_kind==NodeIdNode && node_copy_arg_p->arg_node->node_node_id==node_id_list->nidl_node_id){ + if (e_a_size1!=e_a_size2 || + e_b_size1!=e_b_size2 || + (e_a_size1!=0 && (a_size1!=a_size2 || + a_size1==0 || + ((a_size1==1 || (a_size1==0 && e_a_size1>1)) && + ((node_size==2) != (total_a_size2+total_b_size2==2))) + )) || + (e_b_size1!=0 && (b_size1+node_a_size!=b_size2+total_a_size2 || + b_size1+node_a_size==0 || + ((b_size1+node_a_size==1 || (b_size1+node_a_size==0 && e_b_size1>1)) && + ((node_size==2) != (total_a_size2+total_b_size2==2))) + ))) + { + argument_overwrite_bits|=1<<n; + } else { + ++node_id_p->nid_refcount; + node_id_p->nid_mark |= NID_EXTRA_REFCOUNT_MASK; + } + } else + argument_overwrite_bits|=1<<n; + + a_size2+=e_a_size2; + b_size2+=e_b_size2; + node_id_list=node_id_list->nidl_next; + } else + argument_overwrite_bits|=1<<n; + + a_size1+=e_a_size1; + b_size1+=e_b_size1; + node_copy_arg_p=node_copy_arg_p->arg_next; + } + } + + node->node_arguments->arg_occurrence=argument_overwrite_bits; + + return True; +} + static Bool insert_unique_fill_node (NodeP node,FreeUniqueNodeIdsP *f_node_ids,int node_a_size,int node_b_size) { FreeUniqueNodeIdsP f_node_id; @@ -1981,21 +2160,14 @@ static Bool insert_unique_fill_node (NodeP node,FreeUniqueNodeIdsP *f_node_ids,i push_node=f_node_id->fnid_push_node; node_copy=replace_node_by_unique_fill_node (node,push_node,f_node_id->fnid_node_size); - + { int a_size1,b_size1,a_size2,b_size2; int total_a_size2,total_b_size2; total_a_size2=0; total_b_size2=0; - - for_l (node_id_list,push_node->node_node_ids,nidl_next){ -# ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS - AddSizeOfState (*node_id_list->nidl_node_id->nid_lhs_state_p,&total_a_size2,&total_b_size2); -# else - AddSizeOfState (node_id_list->nidl_node_id->nid_state,&total_a_size2,&total_b_size2); -# endif - } + add_sizes_of_states_of_node_ids (push_node->node_node_ids,&total_a_size2,&total_b_size2); argument_overwrite_bits=0; node_copy_arg_p=node_copy->node_arguments; @@ -2007,22 +2179,20 @@ static Bool insert_unique_fill_node (NodeP node,FreeUniqueNodeIdsP *f_node_ids,i b_size2=0; for (n=0; n<arity; ++n){ + int e_a_size1,e_b_size1,e_a_size2,e_b_size2; + + DetermineSizeOfState (node_copy_arg_p->arg_state,&e_a_size1,&e_b_size1); + if (node_id_list!=NULL){ NodeIdP node_id_p; - StateP arg_node_id_state_p; node_id_p=node_id_list->nidl_node_id; - - if (node_copy_arg_p->arg_node->node_kind==NodeIdNode && node_copy_arg_p->arg_node->node_node_id==node_id_list->nidl_node_id){ - int e_a_size1,e_b_size1,e_a_size2,e_b_size2; - - DetermineSizeOfState (node_copy_arg_p->arg_state,&e_a_size1,&e_b_size1); - # ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS - DetermineSizeOfState (*node_id_p->nid_lhs_state_p,&e_a_size2,&e_b_size2); + DetermineSizeOfState (*node_id_p->nid_lhs_state_p,&e_a_size2,&e_b_size2); # else - DetermineSizeOfState (node_id_p->nid_state,&e_a_size2,&e_b_size2); -# endif + DetermineSizeOfState (node_id_p->nid_state,&e_a_size2,&e_b_size2); +# endif + if (node_copy_arg_p->arg_node->node_kind==NodeIdNode && node_copy_arg_p->arg_node->node_node_id==node_id_list->nidl_node_id){ if (e_a_size1!=e_a_size2 || e_b_size1!=e_b_size2 || (e_a_size1!=0 && (a_size1!=a_size2 || @@ -2034,7 +2204,7 @@ static Bool insert_unique_fill_node (NodeP node,FreeUniqueNodeIdsP *f_node_ids,i ((node_size==2) != (total_a_size2+total_b_size2==2))) ))) { - argument_overwrite_bits|=1<<n; + argument_overwrite_bits|=1<<n; } else { ++node_id_p->nid_refcount; node_id_p->nid_mark |= NID_EXTRA_REFCOUNT_MASK; @@ -2042,19 +2212,14 @@ static Bool insert_unique_fill_node (NodeP node,FreeUniqueNodeIdsP *f_node_ids,i } else argument_overwrite_bits|=1<<n; -# ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS - arg_node_id_state_p=node_id_p->nid_lhs_state_p; -# else - arg_node_id_state_p=&node_id_p->nid_state; -# endif - AddSizeOfState (*arg_node_id_state_p,&a_size2,&b_size2); - + a_size2+=e_a_size2; + b_size2+=e_b_size2; node_id_list=node_id_list->nidl_next; } else argument_overwrite_bits|=1<<n; - AddSizeOfState (node_copy_arg_p->arg_state,&a_size1,&b_size1); - + a_size1+=e_a_size1; + b_size1+=e_b_size1; node_copy_arg_p=node_copy_arg_p->arg_next; } } @@ -2119,6 +2284,55 @@ static Bool try_insert_constructor_update_node (NodeP node,FreeUniqueNodeIdsP *f return False; } +static Bool try_insert_root_constructor_update_node (NodeP node,FreeUniqueNodeIdsP *f_node_ids) +{ + if (node->node_state.state_type==SimpleState && node->node_state.state_kind!=SemiStrict){ + switch (node->node_symbol->symb_kind){ + case definition: + { + SymbDef sdef; + + sdef=node->node_symbol->symb_def; + switch (sdef->sdef_kind){ + case CONSTRUCTOR: + if (sdef->sdef_arity==node->node_arity){ + if (sdef->sdef_strict_constructor){ + int a_size,b_size; + + DetermineSizeOfArguments (node->node_arguments,&a_size,&b_size); + + if (a_size+b_size>2) + return insert_root_unique_fill_node (node,f_node_ids,a_size,b_size); + } else { + if (node->node_arity>2) + return insert_root_unique_fill_node (node,f_node_ids,node->node_arity,0); + } + } + return False; + case RECORDTYPE: + if (sdef->sdef_boxed_record){ + if (sdef->sdef_strict_constructor){ + int a_size,b_size; + + DetermineSizeOfArguments (node->node_arguments,&a_size,&b_size); + + if (a_size+b_size>2) + return insert_root_unique_fill_node (node,f_node_ids,a_size,b_size); + } else { + if (node->node_arity>2) + return insert_root_unique_fill_node (node,f_node_ids,node->node_arity,0); + } + } + return False; + } + break; + } + } + } + + return False; +} + static NodeP try_insert_function_update_node (NodeP node,FreeUniqueNodeIdsS **f_node_ids_l) { if (!(node->node_state.state_type==SimpleState && node->node_state.state_kind==SemiStrict) && @@ -2354,15 +2568,11 @@ static void optimise_node_in_then_or_else (NodeP node,FreeUniqueNodeIdsS **f_nod #ifdef REUSE_UNIQUE_NODES if (*f_node_ids_l!=NULL && try_insert_constructor_update_node (node,f_node_ids_l)){ - unsigned int n,arity,argument_overwrite_bits; - NodeP fill_node; + unsigned int n,argument_overwrite_bits; - fill_node=node; - node=fill_node->node_arguments->arg_node; + argument_overwrite_bits=node->node_arguments->arg_occurrence; + node=node->node_arguments->arg_node; - argument_overwrite_bits=fill_node->node_arguments->arg_occurrence; - arity=node->node_arity; - n=0; for_l (arg,node->node_arguments,arg_next){ if (argument_overwrite_bits & (1<<n)) @@ -2409,6 +2619,10 @@ static void optimise_node_in_then_or_else (NodeP node,FreeUniqueNodeIdsS **f_nod } } #endif +#if DESTRUCTIVE_RECORD_UPDATES + if (node->node_arguments->arg_node->node_kind==NodeIdNode && node->node_arity==1) + return; +#endif case MatchNode: optimise_node_in_then_or_else (node->node_arguments->arg_node,f_node_ids_l,local_scope); return; @@ -2418,12 +2632,32 @@ static void optimise_node_in_then_or_else (NodeP node,FreeUniqueNodeIdsS **f_nod #if DESTRUCTIVE_RECORD_UPDATES arg=node->node_arguments; - if (arg->arg_node->node_kind==NodeIdNode && (arg->arg_node->node_node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 - && arg->arg_node->node_node_id->nid_refcount==-2) - ++arg->arg_node->node_node_id->nid_number; -#endif + if (arg->arg_node->node_kind==NodeIdNode){ + NodeIdP node_id; + + node_id=arg->arg_node->node_node_id; + if ((node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && node_id->nid_refcount==-2) + ++node_id->nid_number; + + node_id->nid_mark2 |= NID_RECORD_USED_BY_UPDATE; + + arg=arg->arg_next; + } +# if BOXED_RECORDS + else { + optimise_node_in_then_or_else (arg->arg_node,f_node_ids_l,local_scope); + if (arg->arg_node->node_kind==NodeIdNode) + arg->arg_node->node_node_id->nid_mark2 |= NID_RECORD_USED_BY_UPDATE; + + arg=arg->arg_next; + } +# endif + for (; arg!=NULL; arg=arg->arg_next) + optimise_node_in_then_or_else (arg->arg_node,f_node_ids_l,local_scope); +#else for_l (arg,node->node_arguments,arg_next) optimise_node_in_then_or_else (arg->arg_node,f_node_ids_l,local_scope); +#endif return; } @@ -2522,7 +2756,7 @@ static void optimise_then_or_else (NodeP node,NodeDefP node_defs,FreeUniqueNodeI NodeP node; node=node_def->def_node; - + optimise_normal_node (node); for_l (arg,node->node_arguments,arg_next) @@ -2540,7 +2774,26 @@ static void optimise_then_or_else (NodeP node,NodeDefP node_defs,FreeUniqueNodeI #ifdef REUSE_UNIQUE_NODES if (node->node_kind==NormalNode){ ArgP arg; + +#if 1 + if (f_node_ids!=NULL && try_insert_root_constructor_update_node (node,&f_node_ids)){ + unsigned int n,argument_overwrite_bits; + + argument_overwrite_bits=node->node_arguments->arg_occurrence; + node=node->node_arguments->arg_node; + + n=0; + for_l (arg,node->node_arguments,arg_next){ + if (argument_overwrite_bits & (1<<n)) + optimise_node_in_then_or_else (arg->arg_node,&f_node_ids,local_scope); + + ++n; + } + } else { +#endif + + optimise_normal_node (node); #if OPTIMIZE_LAZY_TUPLE_RECURSION @@ -2568,6 +2821,13 @@ static void optimise_then_or_else (NodeP node,NodeDefP node_defs,FreeUniqueNodeI optimise_node_in_then_or_else (arg->arg_node,&f_node_ids,local_scope); optimise_strict_constructor_in_lazy_context (node,&no_free_unique_node_ids); + + +#if 1 + } +#endif + + } else #endif optimise_node_in_then_or_else (node,&f_node_ids,local_scope); @@ -2584,15 +2844,11 @@ static void optimise_node (NodeP node,FreeUniqueNodeIdsS **f_node_ids_l) #ifdef REUSE_UNIQUE_NODES if (*f_node_ids_l!=NULL && try_insert_constructor_update_node (node,f_node_ids_l)){ - unsigned int n,arity,argument_overwrite_bits; - NodeP fill_node; + unsigned int n,argument_overwrite_bits; - fill_node=node; - node=fill_node->node_arguments->arg_node; + argument_overwrite_bits=node->node_arguments->arg_occurrence; + node=node->node_arguments->arg_node; - argument_overwrite_bits=fill_node->node_arguments->arg_occurrence; - arity=node->node_arity; - n=0; for_l (arg,node->node_arguments,arg_next){ if (argument_overwrite_bits & (1<<n)) @@ -2639,22 +2895,47 @@ static void optimise_node (NodeP node,FreeUniqueNodeIdsS **f_node_ids_l) } } #endif +#if DESTRUCTIVE_RECORD_UPDATES + if (node->node_arguments->arg_node->node_kind==NodeIdNode && node->node_arity==1) + return; +#endif case MatchNode: optimise_node (node->node_arguments->arg_node,f_node_ids_l); return; case UpdateNode: { - ArgS *arg; + ArgP arg; #if DESTRUCTIVE_RECORD_UPDATES arg=node->node_arguments; - if (arg->arg_node->node_kind==NodeIdNode && (arg->arg_node->node_node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 - && arg->arg_node->node_node_id->nid_refcount==-2) - ++arg->arg_node->node_node_id->nid_number; -#endif - for_l (arg,node->node_arguments,arg_next) + + if (arg->arg_node->node_kind==NodeIdNode){ + NodeIdP node_id; + + node_id=arg->arg_node->node_node_id; + if ((node_id->nid_mark2 & NID_HAS_REFCOUNT_WITHOUT_UPDATES)!=0 && node_id->nid_refcount==-2) + ++node_id->nid_number; + + node_id->nid_mark2 |= NID_RECORD_USED_BY_UPDATE; + + arg=arg->arg_next; + } +# if BOXED_RECORDS + else { optimise_node (arg->arg_node,f_node_ids_l); + if (arg->arg_node->node_kind==NodeIdNode) + arg->arg_node->node_node_id->nid_mark2 |= NID_RECORD_USED_BY_UPDATE; + + arg=arg->arg_next; + } +# endif + for (; arg!=NULL; arg=arg->arg_next) + optimise_node (arg->arg_node,f_node_ids_l); +#else + for_l (arg,node->node_arguments,arg_next) + optimise_node (arg->arg_node,f_node_ids_l); +#endif return; } case TupleSelectorsNode: @@ -2853,6 +3134,25 @@ static void optimise_root_node (NodeP node,NodeDefP node_defs,FreeUniqueNodeIdsP if (node->node_kind==NormalNode){ ArgS *arg; + +#if 1 + if (f_node_ids!=NULL && try_insert_root_constructor_update_node (node,&f_node_ids)){ + unsigned int n,argument_overwrite_bits; + + argument_overwrite_bits=node->node_arguments->arg_occurrence; + node=node->node_arguments->arg_node; + + n=0; + for_l (arg,node->node_arguments,arg_next){ + if (argument_overwrite_bits & (1<<n)) + optimise_node (arg->arg_node,&f_node_ids); + + ++n; + } + } else { +#endif + + optimise_normal_node (node); #if OPTIMIZE_LAZY_TUPLE_RECURSION @@ -2880,6 +3180,13 @@ static void optimise_root_node (NodeP node,NodeDefP node_defs,FreeUniqueNodeIdsP optimise_node (arg->arg_node,&f_node_ids); optimise_strict_constructor_in_lazy_context (node,&no_free_unique_node_ids); + + +#if 1 + } +#endif + + } else optimise_node (node,&f_node_ids); @@ -3121,11 +3428,12 @@ static void MarkTupleSelectorsNode (NodeIdP node_id,NodeP tuple_node) element_node_id->nid_number=element_n; element_node_id->nid_node=select_node; element_node_id->nid_scope = node_id->nid_scope; + element_node_id->nid_mark2 |= NID_SELECTION_NODE_ID; select_nodes[element_n]=select_node; } ++element_node_id->nid_refcount; - + select_node->node_kind=NodeIdNode; select_node->node_node_id=element_node_id; @@ -3838,6 +4146,7 @@ void OptimiseRules (ImpRules rules,SymbDef start_sdef) new_call_state_p = call_arg_state_p2; *lhs_arg_state_p = *new_call_state_p; + *function_arg_state_p = *new_call_state_p; arg_p1->arg_state = *new_call_state_p; @@ -3856,7 +4165,10 @@ void OptimiseRules (ImpRules rules,SymbDef start_sdef) call_arg_node2->node_node_id->nid_refcount==1 && call_arg_node2->node_node_id->nid_node->node_kind==NodeIdNode) { - call_arg_node2->node_node_id->nid_node->node_arguments->arg_state = *new_call_state_p; + StateP state_p; + + state_p=&call_arg_node2->node_node_id->nid_node->node_arguments->arg_state; + *state_p = *new_call_state_p; } } } else { diff --git a/backendC/CleanCompilerSources/optimisations.h b/backendC/CleanCompilerSources/optimisations.h index 206059d..e1be58c 100644 --- a/backendC/CleanCompilerSources/optimisations.h +++ b/backendC/CleanCompilerSources/optimisations.h @@ -5,3 +5,4 @@ int optimise_tuple_result_function (Node node,StateS demanded_state); void generate_states (struct imp_rule *rules,int do_strictness_analysis); StateP state_of_node_or_node_id (NodeP node_p); void copy_rhs_node_defs_and_root (RuleAltP old_alt_p,NodeP *new_root_node_h,NodeDefP *node_defs_p); +void add_sizes_of_states_of_node_ids (NodeIdListElementP node_id_list,int *total_a_size_p,int *total_b_size_p); |