From 9e6324514c0fad2d026e9f3d7cb857902fb0a720 Mon Sep 17 00:00:00 2001 From: johnvg Date: Mon, 17 Jun 2002 13:57:04 +0000 Subject: smaller pattern_match.c for Clean 2.0 git-svn-id: https://svn.cs.ru.nl/repos/clean-compiler/trunk@1101 1f8540f1-abd5-4d5b-9d24-4c5ce8603e2d --- backendC/CleanCompilerSources/pattern_match_2.c | 986 ++++++++++++++++++++++++ 1 file changed, 986 insertions(+) create mode 100644 backendC/CleanCompilerSources/pattern_match_2.c (limited to 'backendC') diff --git a/backendC/CleanCompilerSources/pattern_match_2.c b/backendC/CleanCompilerSources/pattern_match_2.c new file mode 100644 index 0000000..e370790 --- /dev/null +++ b/backendC/CleanCompilerSources/pattern_match_2.c @@ -0,0 +1,986 @@ +/* + File: pattern_match.c + Author: John van Groningen +*/ + +#define DEBUG_OUTPUT 0 + +#if defined (applec) || defined (__MWERKS__) || defined (__MRC__) +# define __ppc__ +#endif + +#include + +#include "compiledefines.h" +#include "types.t" +#include "syntaxtr.t" +#include "pattern_match.h" +#include "buildtree.h" +#include "comsupport.h" +#include "statesgen.h" +#include "settings.h" +#include "codegen_types.h" + +#define for_l(v,l,n) for(v=(l);v!=NULL;v=v->n) + +static void error_in_function (char *m) +{ + ErrorInCompiler ("",m,""); +} + +#if DEBUG_OUTPUT +char *node_id_name (NodeId node_id) +{ + static char node_id_name_s[65]; + + if (node_id->nid_ident!=NULL && node_id->nid_ident->ident_name!=NULL) + return node_id->nid_ident->ident_name; + else { + sprintf (node_id_name_s,"i_%lx",(long)node_id); + return node_id_name_s; + } +} +#endif + +static NodeP new_switch_node (NodeIdP node_id,NodeP case_node,StateP state_p,NodeS ***root_l) +{ + NodeP switch_node; + + switch_node=CompAllocType (NodeS); + + switch_node->node_kind=SwitchNode; + switch_node->node_node_id=node_id; + switch_node->node_arity=1; + switch_node->node_arguments=NewArgument (case_node); + switch_node->node_state=*state_p; + +#if DEBUG_OUTPUT + printf ("dec %s %d\n",node_id_name (node_id),node_id->nid_refcount); +#endif + + --node_id->nid_refcount; + + **root_l=switch_node; + *root_l=&case_node->node_arguments->arg_node; + + return switch_node; +} + +static NodeP new_case_node (SymbolP symbol,int symbol_arity,NodeP node,NodeDefP **def_l +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + ,StrictNodeIdP **strict_node_ids_l +#endif + ) +{ + NodeP case_node; + + case_node=CompAllocType (NodeS); + + case_node->node_kind=CaseNode; + case_node->node_symbol=symbol; + case_node->node_arity=symbol_arity; + case_node->node_arguments=NewArgument (node); + +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + case_node->node_su.su_u.u_case=CompAllocType (CaseNodeContentsS); + case_node->node_strict_node_ids=NULL; +#endif + + case_node->node_node_id_ref_counts=NULL; + + case_node->node_node_defs=**def_l; + **def_l=NULL; + *def_l=&case_node->node_node_defs; + +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + case_node->node_strict_node_ids=**strict_node_ids_l; + **strict_node_ids_l=NULL; + *strict_node_ids_l=&case_node->node_strict_node_ids; +#endif + + return case_node; +} + +struct root_and_defs_l { + NodeP ** root_l; + NodeDefP ** def_l; +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + StrictNodeIdP **strict_node_ids_l; + NodeDefP ** end_lhs_defs_l; +#endif +}; + +struct root_and_defs { + NodeP root; + NodeDefP defs; +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + StrictNodeIdP strict_node_ids; +#endif +}; + +static NodeP new_push_node (Symbol symbol,int arity,ArgP arguments) +{ + NodeP push_node; + + push_node=CompAllocType (NodeS); + + push_node->node_kind=PushNode; + push_node->node_arity=arity; + push_node->node_arguments=arguments; + push_node->node_record_symbol=symbol; + push_node->node_number=0; /* if !=0 then unique */ + + return push_node; +} + +NodeIdRefCountListP new_node_id_ref_count (NodeIdRefCountListP node_id_ref_count_list,NodeIdP node_id,int ref_count) +{ + NodeIdRefCountListP new_node_id_ref_count_elem; + + new_node_id_ref_count_elem=CompAllocType (NodeIdRefCountListS); + + new_node_id_ref_count_elem->nrcl_next=node_id_ref_count_list; + new_node_id_ref_count_elem->nrcl_node_id=node_id; + new_node_id_ref_count_elem->nrcl_ref_count=ref_count; + + return new_node_id_ref_count_elem; +} + +static NodeIdRefCountListP *insert_new_node_id_ref_count (NodeIdRefCountListP *node_id_ref_count_p,NodeIdP node_id,int ref_count) +{ + NodeIdRefCountListP node_id_ref_count_elem; + + node_id_ref_count_elem=new_node_id_ref_count (NULL,node_id,ref_count); + *node_id_ref_count_p=node_id_ref_count_elem; + + return &node_id_ref_count_elem->nrcl_next; +} + +static void transform_normal_pattern_node (NodeP node,StateP state_p,NodeIdP node_id,struct root_and_defs_l *root_and_defs_lp); + +static void transform_pattern_arguments (SymbolP symbol,ArgP arguments,int arity,NodeIdP node_id,struct root_and_defs_l *root_and_defs_lp) +{ + NodeP push_node; + NodeIdListElementP *last_node_id_p; + ArgP arg,arg1,arg2; + + arg2=NewArgument (**root_and_defs_lp->root_l); + arg1=NewArgument (NULL); + arg1->arg_next=arg2; + + push_node=new_push_node (symbol,arity,arg1); + + **root_and_defs_lp->root_l=push_node; + *root_and_defs_lp->root_l=&arg2->arg_node; + + last_node_id_p=&push_node->node_node_ids; + + for_l (arg,arguments,arg_next){ + NodeIdP argument_node_id; + NodeP node; + + node=arg->arg_node; + if (node->node_kind==NormalNode){ + argument_node_id=NewNodeId (NULL); + argument_node_id->nid_refcount=-1; + + argument_node_id->nid_lhs_state_p_=&arg->arg_state; + + transform_normal_pattern_node (node,&arg->arg_state,argument_node_id,root_and_defs_lp); + } else { +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + NodeP argument_node_id_node; + + argument_node_id=node->node_node_id; + + argument_node_id->nid_lhs_state_p_=&arg->arg_state; + + argument_node_id_node=argument_node_id->nid_node; + if (argument_node_id_node){ + argument_node_id->nid_node=NULL; + transform_normal_pattern_node (argument_node_id_node,&arg->arg_state,argument_node_id,root_and_defs_lp); + } +#else + argument_node_id=node->node_node_id; + if (argument_node_id->nid_node) + transform_normal_pattern_node (argument_node_id->nid_node,&arg->arg_state,argument_node_id,root_and_defs_lp); +#endif + } + +#ifndef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + argument_node_id->nid_state_=arg->arg_state; +#endif + + *last_node_id_p=CompAllocType (NodeIdListElementS); + (*last_node_id_p)->nidl_node_id=argument_node_id; + last_node_id_p=&(*last_node_id_p)->nidl_next; + } + + *last_node_id_p=NULL; + + arg1->arg_node=NewNodeIdNode (node_id); +} + +static void transform_normal_pattern_node (NodeP node,StateP state_p,NodeIdP node_id,struct root_and_defs_l *root_and_defs_lp) +{ + SymbolP symbol; + NodeP switch_node,case_node; + NodeP **root_l; + NodeDefP **def_l; + + symbol=node->node_symbol; + root_l=root_and_defs_lp->root_l; + def_l=root_and_defs_lp->def_l; + + switch (symbol->symb_kind){ + case definition: + case_node=new_case_node (symbol,node->node_arity,**root_l,def_l +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + ,root_and_defs_lp->strict_node_ids_l +#endif + ); + switch_node=new_switch_node (node_id,case_node,state_p,root_l); + + if (node->node_arity>0) + transform_pattern_arguments (symbol,node->node_arguments,node->node_arity,node_id,root_and_defs_lp); + + return; + case cons_symb: + case_node=new_case_node (symbol,2,**root_l,def_l +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + ,root_and_defs_lp->strict_node_ids_l +#endif + ); + switch_node=new_switch_node (node_id,case_node,state_p,root_l); + transform_pattern_arguments (symbol,node->node_arguments,2,node_id,root_and_defs_lp); + return; + case nil_symb: + case_node=new_case_node (symbol,0,**root_l,def_l +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + ,root_and_defs_lp->strict_node_ids_l +#endif + ); + switch_node=new_switch_node (node_id,case_node,state_p,root_l); + return; + case tuple_symb: + case_node=new_case_node (symbol,node->node_arity,**root_l,def_l +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + ,root_and_defs_lp->strict_node_ids_l +#endif + ); + switch_node=new_switch_node (node_id,case_node,state_p,root_l); + transform_pattern_arguments (symbol,node->node_arguments,node->node_arity,node_id,root_and_defs_lp); + return; + case apply_symb: + case if_symb: + error_in_function ("transform_normal_pattern_node"); + return; + case string_denot: + case_node=new_case_node (symbol,0,**root_l,def_l +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + ,root_and_defs_lp->strict_node_ids_l +#endif + ); + switch_node=new_switch_node (node_id,case_node,state_p,root_l); + return; + default: + if (symbol->symb_kind < Nr_Of_Basic_Types) + error_in_function ("transform_normal_pattern_node"); + else { +#ifndef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + if (state_p->state_object==BasicSymbolStates [symbol->symb_kind].state_object){ +#endif + case_node=new_case_node (symbol,0,**root_l,def_l +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + ,root_and_defs_lp->strict_node_ids_l +#endif + ); + switch_node=new_switch_node (node_id,case_node,state_p,root_l); + return; +#ifndef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + } else if (state_p->state_object==UnknownObj +# if ABSTRACT_OBJECT + || state_p->state_object==AbstractObj +# endif + ){ + case_node=new_case_node (symbol,0,**root_l,def_l +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + ,root_and_defs_lp->strict_node_ids_l +#endif + ); + switch_node=new_switch_node (node_id,case_node,state_p,root_l); + return; + } else + error_in_function ("transform_normal_pattern_node"); +#endif + } + } +} + +static void transform_argument (ArgP arg_p,struct root_and_defs_l *root_and_defs_lp) +{ + NodeP node; + + node=arg_p->arg_node; + + switch (node->node_kind){ + case NormalNode: +#ifndef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + if (arg_p->arg_state.state_type==TupleState || arg_p->arg_state.state_type==RecordState){ + ArgP arg; + + for_l (arg,node->node_arguments,arg_next) + transform_argument (arg,root_and_defs_lp); + } else +#endif + { + NodeIdP node_id; + + node_id=NewNodeId (NULL); + node_id->nid_refcount=-1; + + node_id->nid_lhs_state_p_=&arg_p->arg_state; + +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + if (node->node_symbol->symb_kind==tuple_symb || + (node->node_symbol->symb_kind==definition && node->node_symbol->symb_def->sdef_kind==RECORDTYPE)) + { + error_in_function ("transform_argument"); + } else +#endif + transform_normal_pattern_node (node,&arg_p->arg_state,node_id,root_and_defs_lp); + +#ifndef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + node_id->nid_state_=arg_p->arg_state; +#endif + arg_p->arg_node=NewNodeIdNode (node_id); + } + break; + case NodeIdNode: + { + NodeIdP node_id; + + node_id=node->node_node_id; + + if (node_id->nid_node!=NULL){ +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + SymbolP node_id_nid_node_symbol; + + node_id_nid_node_symbol=node_id->nid_node->node_symbol; + if (node_id_nid_node_symbol->symb_kind==tuple_symb || + (node_id_nid_node_symbol->symb_kind==definition && node_id_nid_node_symbol->symb_def->sdef_kind==RECORDTYPE)) + { + error_in_function ("transform_argument 1"); + } +#else + if (arg_p->arg_state.state_type==TupleState || arg_p->arg_state.state_type==RecordState){ + error_in_function ("transform_argument 1"); + } else +#endif + { + transform_normal_pattern_node (node_id->nid_node,&arg_p->arg_state,node_id,root_and_defs_lp); + + node_id->nid_node=NULL; + } + } + +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + node_id->nid_lhs_state_p_=&arg_p->arg_state; +#else + node_id->nid_state_=arg_p->arg_state; +#endif + break; + } + default: + error_in_function ("transform_argument"); + } +} + +#if 0 +# include "dbprint.h" +#endif + +static void replace_global_ref_count_by_local_ref_count (NodeIdRefCountListP node_id_ref_count_list) +{ + NodeIdRefCountListP node_id_ref_count_elem; + + for_l (node_id_ref_count_elem,node_id_ref_count_list,nrcl_next){ + int local_ref_count; + NodeIdP node_id; + + node_id=node_id_ref_count_elem->nrcl_node_id; + local_ref_count=node_id_ref_count_elem->nrcl_ref_count; + +#if DEBUG_OUTPUT + 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 + + node_id_ref_count_elem->nrcl_ref_count=node_id->nid_refcount - local_ref_count; + node_id->nid_refcount = local_ref_count; + } + +#if DEBUG_OUTPUT + printf ("\n"); +#endif +} + +void set_local_reference_counts (NodeP case_node) +{ + replace_global_ref_count_by_local_ref_count (case_node->node_node_id_ref_counts); +} + +static void replace_local_ref_count_by_global_ref_count (NodeIdRefCountListP node_id_ref_count_list) +{ + NodeIdRefCountListP node_id_ref_count_elem; + + for_l (node_id_ref_count_elem,node_id_ref_count_list,nrcl_next){ + int local_ref_count; + NodeIdP node_id; + + node_id=node_id_ref_count_elem->nrcl_node_id; + local_ref_count=node_id->nid_refcount; + +#if DEBUG_OUTPUT + printf ("local_to_global %s %d %d ",node_id_name (node_id),node_id->nid_refcount,node_id_ref_count_elem->nrcl_ref_count); +#endif + + node_id->nid_refcount = local_ref_count + node_id_ref_count_elem->nrcl_ref_count; + node_id_ref_count_elem->nrcl_ref_count=local_ref_count; + } + +#if DEBUG_OUTPUT + printf ("\n"); +#endif +} + +void set_global_reference_counts (NodeP case_node) +{ + replace_local_ref_count_by_global_ref_count (case_node->node_node_id_ref_counts); +} + +static void merge_node_id_ref_count_lists (NodeIdRefCountListP *list1_p,NodeIdRefCountListP list2) +{ + while (list2!=NULL){ + NodeIdP node_id; + NodeIdRefCountListP next_list2,list1; + + node_id=list2->nrcl_node_id; + + while (list1=*list1_p,list1!=NULL && list1->nrcl_node_id<=node_id) + list1_p=&list1->nrcl_next; + + if (list1==NULL){ + *list1_p=list2; + return; + } + + next_list2=list2->nrcl_next; + + *list1_p=list2; + list2->nrcl_next=list1; + list1_p=&list2->nrcl_next; + + list2=next_list2; + } +} + +static void sort_node_id_ref_count_lists (NodeIdRefCountListP *list_p) +{ + NodeIdRefCountListP element1,element2,element3; + + element1=*list_p; + if (element1==NULL) + return; + + element2=element1->nrcl_next; + if (element2==NULL) + return; + + element3=element2->nrcl_next; + if (element3==NULL){ + if (element1->nrcl_node_id<=element2->nrcl_node_id) + return; + + *list_p=element2; + element2->nrcl_next=element1; + element1->nrcl_next=NULL; + } else { + NodeIdRefCountListP list2,end_list1,end_list2; + + list2=element2; + end_list1=element1; + end_list2=element2; + + element1=element3; + do { + end_list1->nrcl_next=element1; + end_list1=element1; + + element2=element1->nrcl_next; + if (element2==NULL) + break; + + end_list2->nrcl_next=element2; + end_list2=element2; + + element1=element2->nrcl_next; + } while (element1!=NULL); + + end_list1->nrcl_next=NULL; + end_list2->nrcl_next=NULL; + + sort_node_id_ref_count_lists (list_p); + sort_node_id_ref_count_lists (&list2); + + merge_node_id_ref_count_lists (list_p,list2); + } +} + +static void add_sorted_node_id_ref_count_list (NodeIdRefCountListP *node_id_ref_count_list1_p,NodeIdRefCountListP node_id_ref_count_list2) +{ + NodeIdRefCountListP node_id_ref_count_list1; + + while (node_id_ref_count_list2!=NULL){ + NodeIdP node_id; + + node_id=node_id_ref_count_list2->nrcl_node_id; + + while (node_id_ref_count_list1=*node_id_ref_count_list1_p,node_id_ref_count_list1!=NULL && node_id_ref_count_list1->nrcl_node_idnrcl_next; + + if (node_id_ref_count_list1!=NULL && node_id_ref_count_list1->nrcl_node_id==node_id){ + +#if DEBUG_OUTPUT + printf ("add %s %d %d %d\n",node_id_name (node_id),node_id->nid_refcount,node_id_ref_count_list1->nrcl_ref_count,node_id_ref_count_list2->nrcl_ref_count); +#endif + + node_id_ref_count_list1->nrcl_ref_count += node_id_ref_count_list2->nrcl_ref_count+1; + node_id_ref_count_list1_p=&node_id_ref_count_list1->nrcl_next; + } else { + NodeIdRefCountListP new_node_id_ref_count_elem; + +#if DEBUG_OUTPUT + printf ("addnew %s %d %d\n",node_id_name (node_id),node_id->nid_refcount,node_id_ref_count_list2->nrcl_ref_count); +#endif + + new_node_id_ref_count_elem=new_node_id_ref_count (node_id_ref_count_list1,node_id_ref_count_list2->nrcl_node_id,node_id_ref_count_list2->nrcl_ref_count); + + *node_id_ref_count_list1_p=new_node_id_ref_count_elem; + node_id_ref_count_list1_p=&new_node_id_ref_count_elem->nrcl_next; + } + + node_id_ref_count_list2=node_id_ref_count_list2->nrcl_next; + } +} + +/* JVG added 16-2-2000 */ +static void add_sorted_node_id_ref_count_list_for_case (NodeIdRefCountListP *node_id_ref_count_list1_p,NodeIdRefCountListP node_id_ref_count_list2) +{ + NodeIdRefCountListP node_id_ref_count_list1; + + while (node_id_ref_count_list2!=NULL){ + NodeIdP node_id; + + node_id=node_id_ref_count_list2->nrcl_node_id; + + while (node_id_ref_count_list1=*node_id_ref_count_list1_p,node_id_ref_count_list1!=NULL && node_id_ref_count_list1->nrcl_node_idnrcl_next; + + if (node_id_ref_count_list1!=NULL && node_id_ref_count_list1->nrcl_node_id==node_id){ + +#if DEBUG_OUTPUT + printf ("add %s %d %d %d\n",node_id_name (node_id),node_id->nid_refcount,node_id_ref_count_list1->nrcl_ref_count,node_id_ref_count_list2->nrcl_ref_count); +#endif + + node_id_ref_count_list1->nrcl_ref_count += node_id_ref_count_list2->nrcl_ref_count+1; + node_id_ref_count_list1_p=&node_id_ref_count_list1->nrcl_next; + } /* else do nothing*/ + + node_id_ref_count_list2=node_id_ref_count_list2->nrcl_next; + } +} +/**/ + +/* + static NodeIdRefCountListP merge_sorted_node_id_ref_count_lists + (NodeIdRefCountListP node_id_ref_count_list1,NodeIdRefCountListP node_id_ref_count_list2) + { + NodeIdRefCountListP node_id_ref_count_list,*node_id_ref_count_list_p; + + node_id_ref_count_list_p=&node_id_ref_count_list; + + while (node_id_ref_count_list2!=NULL){ + NodeIdP node_id; + + node_id=node_id_ref_count_list2->nrcl_node_id; + + while (node_id_ref_count_list1!=NULL && node_id_ref_count_list1->nrcl_node_idnrcl_node_id->nid_ident!=NULL && node_id_ref_count_list1->nrcl_node_id->nid_ident->ident_name!=NULL) + node_id_name=node_id_ref_count_list1->nrcl_node_id->nid_ident->ident_name; + + printf ("from1 %s %d %d\n",node_id_name,node_id_ref_count_list1->nrcl_node_id->nid_refcount,node_id_ref_count_list1->nrcl_ref_count); + } + #endif + + new_node_id_ref_count_elem=new_node_id_ref_count (NULL,node_id_ref_count_list1->nrcl_node_id,node_id_ref_count_list1->nrcl_ref_count); + + *node_id_ref_count_list_p=new_node_id_ref_count_elem; + node_id_ref_count_list_p=&new_node_id_ref_count_elem->nrcl_next; + + node_id_ref_count_list1=node_id_ref_count_list1->nrcl_next; + } + + if (node_id_ref_count_list1!=NULL && node_id_ref_count_list1->nrcl_node_id==node_id){ + NodeIdRefCountListP new_node_id_ref_count_elem; + + #if DEBUG_OUTPUT + { + char *node_id_name; + + node_id_name=""; + if (node_id->nid_ident!=NULL && node_id->nid_ident->ident_name!=NULL) + node_id_name=node_id->nid_ident->ident_name; + + printf ("combine %s %d %d\n",node_id_name,node_id_ref_count_list1->nrcl_node_id->nid_refcount,node_id_ref_count_list2->nrcl_ref_count); + } + #endif + + new_node_id_ref_count_elem=new_node_id_ref_count (NULL,node_id, + node_id_ref_count_list1->nrcl_ref_count+node_id_ref_count_list2->nrcl_ref_count+1); + + *node_id_ref_count_list_p=new_node_id_ref_count_elem; + node_id_ref_count_list_p=&new_node_id_ref_count_elem->nrcl_next; + + node_id_ref_count_list1=node_id_ref_count_list1->nrcl_next; + } else { + NodeIdRefCountListP new_node_id_ref_count_elem; + + #if DEBUG_OUTPUT + { + char *node_id_name; + + node_id_name=""; + if (node_id_ref_count_list2->nrcl_node_id->nid_ident!=NULL && node_id_ref_count_list2->nrcl_node_id->nid_ident->ident_name!=NULL) + node_id_name=node_id_ref_count_list2->nrcl_node_id->nid_ident->ident_name; + + printf ("from2 %s %d %d\n",node_id_name,node_id_ref_count_list2->nrcl_node_id->nid_refcount,node_id_ref_count_list2->nrcl_ref_count); + } + #endif + + new_node_id_ref_count_elem=new_node_id_ref_count (NULL,node_id_ref_count_list2->nrcl_node_id,node_id_ref_count_list2->nrcl_ref_count); + + *node_id_ref_count_list_p=new_node_id_ref_count_elem; + node_id_ref_count_list_p=&new_node_id_ref_count_elem->nrcl_next; + } + + node_id_ref_count_list2=node_id_ref_count_list2->nrcl_next; + } + + while (node_id_ref_count_list1!=NULL){ + NodeIdRefCountListP new_node_id_ref_count_elem; + + #if DEBUG_OUTPUT + { + char *node_id_name; + + node_id_name=""; + if (node_id_ref_count_list1->nrcl_node_id->nid_ident!=NULL && node_id_ref_count_list1->nrcl_node_id->nid_ident->ident_name!=NULL) + node_id_name=node_id_ref_count_list1->nrcl_node_id->nid_ident->ident_name; + + printf ("from1 %s %d %d\n",node_id_name,node_id_ref_count_list1->nrcl_node_id->nid_refcount,node_id_ref_count_list1->nrcl_ref_count); + } + #endif + + new_node_id_ref_count_elem=new_node_id_ref_count (NULL,node_id_ref_count_list1->nrcl_node_id,node_id_ref_count_list1->nrcl_ref_count); + + *node_id_ref_count_list_p=new_node_id_ref_count_elem; + node_id_ref_count_list_p=&new_node_id_ref_count_elem->nrcl_next; + + node_id_ref_count_list1=node_id_ref_count_list1->nrcl_next; + } + + *node_id_ref_count_list_p=NULL; + + return node_id_ref_count_list; + } +*/ + +static NodeIdRefCountListP duplicate_node_id_ref_count_list (NodeIdRefCountListP node_id_ref_count_list) +{ + NodeIdRefCountListP node_id_ref_count_elem,new_node_id_ref_count_list,*new_node_id_ref_count_list_p; + + new_node_id_ref_count_list_p=&new_node_id_ref_count_list; + + for (node_id_ref_count_elem=node_id_ref_count_list; node_id_ref_count_elem!=NULL; node_id_ref_count_elem=node_id_ref_count_elem->nrcl_next){ + NodeIdRefCountListP new_node_id_ref_count_elem; + + new_node_id_ref_count_elem=new_node_id_ref_count (NULL,node_id_ref_count_elem->nrcl_node_id,node_id_ref_count_elem->nrcl_ref_count); + +#if DEBUG_OUTPUT + printf ("duplicate %s %d %d\n",node_id_name (node_id_ref_count_elem->nrcl_node_id),node_id_ref_count_elem->nrcl_node_id->nid_refcount,node_id_ref_count_elem->nrcl_ref_count); +#endif + + *new_node_id_ref_count_list_p=new_node_id_ref_count_elem; + new_node_id_ref_count_list_p=&new_node_id_ref_count_elem->nrcl_next; + } + + *new_node_id_ref_count_list_p=NULL; + + return new_node_id_ref_count_list; +} + +#ifdef CLEAN2 +extern int contains_fail (NodeP node_p); +#endif + +static int determine_failing_cases_and_adjust_ref_counts (NodeP node,NodeIdRefCountListP *node_id_ref_count_list_p) +{ + switch (node->node_kind){ + case SwitchNode: + { + ArgP arg; + int switch_may_fail,default_may_fail; + int node_id_ref_count_list_sorted; + + node_id_ref_count_list_sorted=0; + + for (arg=node->node_arguments; arg!=NULL; arg=arg->arg_next) + if (arg->arg_node->node_kind!=CaseNode) + break; + + default_may_fail=1; + + if (arg!=NULL){ + NodeP arg_node; + + arg_node=arg->arg_node; + + if (arg_node->node_kind!=DefaultNode) + error_in_function ("determine_failing_cases_and_adjust_ref_counts"); + + default_may_fail=determine_failing_cases_and_adjust_ref_counts (arg_node->node_arguments->arg_node,node_id_ref_count_list_p); + arg_node->node_number=default_may_fail; + + if (default_may_fail){ + /* NodeP default_rhs_node; */ + + sort_node_id_ref_count_lists (&arg_node->node_node_id_ref_counts); + + if (!node_id_ref_count_list_sorted){ + sort_node_id_ref_count_lists (node_id_ref_count_list_p); + node_id_ref_count_list_sorted=1; + } + + /* JVG: maybe incorrect, optimisation: find simple case which can not fail and set node_id_refcounts + default_rhs_node=arg_node->node_arguments->arg_node; + + if (default_rhs_node->node_kind==PushNode) + default_rhs_node=default_rhs_node->node_arguments->arg_next->arg_node; + + if (default_rhs_node->node_kind==SwitchNode && default_rhs_node->node_arguments->arg_next==NULL) + default_rhs_node->node_arguments->arg_node->node_node_id_ref_counts + = duplicate_node_id_ref_count_list (arg_node->node_node_id_ref_counts); + */ + + add_sorted_node_id_ref_count_list (&arg_node->node_node_id_ref_counts,*node_id_ref_count_list_p); + node_id_ref_count_list_p=&arg_node->node_node_id_ref_counts; + + /* + arg_node->node_node_id_ref_counts=merge_sorted_node_id_ref_count_lists (arg_node->node_node_id_ref_counts,*node_id_ref_count_list_p); + node_id_ref_count_list_p=&arg_node->node_node_id_ref_counts; + */ + } else + node_id_ref_count_list_p=&arg_node->node_node_id_ref_counts; + } + + switch_may_fail=1; + + /* to do: if non failing case for every constructor, default not reachable */ + +#if 1 /* added 8-4-1999 */ + if (node->node_arguments->arg_next==NULL && node->node_arguments->arg_node->node_kind==CaseNode + && (node->node_arguments->arg_node->node_symbol->symb_kind==tuple_symb + || (node->node_arguments->arg_node->node_symbol->symb_kind==definition && + node->node_arguments->arg_node->node_symbol->symb_def->sdef_kind==RECORDTYPE))) + { + int case_may_fail; + NodeP arg_node; + + arg_node=node->node_arguments->arg_node; + + case_may_fail=determine_failing_cases_and_adjust_ref_counts (arg_node->node_arguments->arg_node,node_id_ref_count_list_p); + + arg_node->node_number=case_may_fail; + + switch_may_fail=case_may_fail; + } else +#endif + + for_l (arg,node->node_arguments,arg_next){ + NodeP arg_node; + + arg_node=arg->arg_node; + + switch (arg_node->node_kind){ + case CaseNode: + { + int case_may_fail; + + case_may_fail=determine_failing_cases_and_adjust_ref_counts (arg_node->node_arguments->arg_node,node_id_ref_count_list_p); + + if (case_may_fail && node->node_arguments->arg_next!=NULL){ + /* NodeP case_rhs_node; */ + + sort_node_id_ref_count_lists (&arg_node->node_node_id_ref_counts); + + if (!node_id_ref_count_list_sorted){ + sort_node_id_ref_count_lists (node_id_ref_count_list_p); + node_id_ref_count_list_sorted=1; + } + + /* JVG: maybe incorrect, optimisation: find simple case which can not fail and set node_id_refcounts + case_rhs_node=arg_node->node_arguments->arg_node; + + if (case_rhs_node->node_kind==PushNode) + case_rhs_node=case_rhs_node->node_arguments->arg_next->arg_node; + + if (case_rhs_node->node_kind==SwitchNode && case_rhs_node->node_arguments->arg_next==NULL) + case_rhs_node->node_arguments->arg_node->node_node_id_ref_counts + = duplicate_node_id_ref_count_list (arg_node->node_node_id_ref_counts); + */ + + /* JVG changed 16-2-2000 + add_sorted_node_id_ref_count_list (&arg_node->node_node_id_ref_counts,*node_id_ref_count_list_p); + */ + add_sorted_node_id_ref_count_list_for_case (&arg_node->node_node_id_ref_counts,*node_id_ref_count_list_p); + /**/ + + /* + arg_node->node_node_id_ref_counts= + merge_sorted_node_id_ref_count_lists (arg_node->node_node_id_ref_counts,*node_id_ref_count_list_p); + */ + } + + arg_node->node_number=case_may_fail; + break; + } + case DefaultNode: + switch_may_fail=default_may_fail; + break; + default: + error_in_function ("determine_failing_cases_and_adjust_ref_counts"); + } + } + return switch_may_fail; + } + case PushNode: + return determine_failing_cases_and_adjust_ref_counts (node->node_arguments->arg_next->arg_node,node_id_ref_count_list_p); + case GuardNode: + return determine_failing_cases_and_adjust_ref_counts (node->node_arguments->arg_next->arg_node,node_id_ref_count_list_p); + case IfNode: +#ifdef CLEAN2 + return contains_fail (node); +#else + { + NodeP else_node; + + else_node=node->node_arguments->arg_next->arg_next->arg_node; + while (else_node->node_kind==IfNode) + else_node=else_node->node_arguments->arg_next->arg_next->arg_node; + + return else_node->node_kind==NormalNode && else_node->node_symbol->symb_kind==fail_symb; + } +#endif + default: + return False; + } +} + +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS +void determine_failing_cases_and_adjust_ref_counts_of_rule (RuleAltP first_alt) +{ + NodeIdRefCountListP node_id_ref_count_list; + + if (first_alt->alt_kind!=Contractum) + return; + + node_id_ref_count_list=NULL; + determine_failing_cases_and_adjust_ref_counts (first_alt->alt_rhs_root,&node_id_ref_count_list); + +# if 0 + PrintRuleAlt (first_alt,4,StdOut); +# endif +} +#endif + +#if 0 +#include "dbprint.h" +#endif + +void transform_patterns_to_case_and_guard_nodes (RuleAltP rule_alts) +{ + RuleAltP first_alt; + ArgP arg; + struct root_and_defs_l root_and_defs_l; + NodeP *node_p; + NodeDefP *def_p; +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + StrictNodeIdP *strict_node_ids_p; + NodeDefP *end_lhs_defs_p; +#endif + + first_alt=rule_alts; + + if (first_alt->alt_kind!=Contractum) + return; + + node_p=&first_alt->alt_rhs_root; + def_p=&first_alt->alt_rhs_defs; +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + strict_node_ids_p=&first_alt->alt_strict_node_ids; + end_lhs_defs_p=&first_alt->alt_lhs_defs; +#endif + + root_and_defs_l.root_l=&node_p; + root_and_defs_l.def_l=&def_p; +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + root_and_defs_l.strict_node_ids_l=&strict_node_ids_p; + root_and_defs_l.end_lhs_defs_l=&end_lhs_defs_p; +#endif + + for_l (arg,first_alt->alt_lhs_root->node_arguments,arg_next) + transform_argument (arg,&root_and_defs_l); + + if (first_alt->alt_next!=NULL) + error_in_function ("transform_patterns_to_case_and_guard_nodes"); + +#ifdef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + *end_lhs_defs_p=NULL; +#endif + + first_alt->alt_next=NULL; + +#if 0 + PrintRuleAlt (first_alt,4,StdOut); +#endif + +#ifndef TRANSFORM_PATTERNS_BEFORE_STRICTNESS_ANALYSIS + { + NodeIdRefCountListP node_id_ref_count_list; + + node_id_ref_count_list=NULL; + determine_failing_cases_and_adjust_ref_counts (first_alt->alt_rhs_root,&node_id_ref_count_list); + } + +# if 0 + PrintRuleAlt (first_alt,4,StdOut); +# endif +#endif +} -- cgit v1.2.3