/* * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. * * This product is part of the Amsterdam Compiler Kit. * * Permission to use, sell, duplicate or disclose this software must be * obtained in writing. Requests for such permissions may be sent to * * Dr. Andrew S. Tanenbaum * Wiskundig Seminarium * Vrije Universiteit * Postbox 7161 * 1007 MC Amsterdam * The Netherlands * */ #include "ack.h" #include "list.h" #include "trans.h" #include "data.h" #ifndef NORCSID static char rcs_id[] = "$Header$" ; #endif enum f_path getpath(first) register trf **first ; { /* Try to find a transformation path */ start_scan(); /* The end result is the chaining of the consequtive phases with the t_next field. The list is scanned for possible transformations stopping at stopsuffix or the last transformation in the list. The scan flags are set by this process. When a transformation is found, it is compared with the last transformation found. */ try(l_first(tr_list),p_suffix); return scan_end(first); } /******************** data used only while scanning *******************/ static int last_ncount; /* The # of non-optimizing transformations in the best path sofar */ static int last_ocount; /* The # of optimizing transformations in the best path sofar */ static int suf_found; /* Was the suffix at least recognized ? */ /******************** The hard work ********************/ start_scan() { register list_elem *scan ; scanlist(l_first(tr_list),scan) { t_cont(*scan)->t_scan=NO ; } suf_found= 0 ; #ifdef DEBUG if ( debug>=3 ) vprint("Scan_start\n"); #endif last_ncount= -1 ; last_ocount= 0 ; } try(f_scan,suffix) list_elem *f_scan; char *suffix; { register list_elem *scan ; register trf *trafo ; /* Try to find a transformation path starting at f_scan for a file with the indicated suffix. If the suffix is already reached or a combiner is found call scan_found() to OK the scan. If a transformation is found it calls itself recursively with as starting point the next transformation in the list. */ if ( stopsuffix && *stopsuffix && strcmp(stopsuffix,suffix)==0 ) { scan_found(); return ; } scanlist(f_scan, scan) { trafo= t_cont(*scan) ; if ( satisfy(trafo,suffix) ) { /* Found a transformation */ suf_found= 1; #ifdef DEBUG if ( debug>=4 ) { vprint("Found %s for %s: result %s\n", trafo->t_name,suffix,trafo->t_out); } #endif trafo->t_scan=YES ; if ( trafo->t_prep ) { if ( !cpp_trafo ) { find_cpp() ; } if ( stopsuffix && strcmp(stopsuffix, cpp_trafo->t_out)==0 ) { scan_found() ; return ; } } if ( trafo->t_next ) { /* We know what happens from this phase on, so take a shortcut. */ register trf *sneak ; sneak= trafo ; while( sneak=sneak->t_next ) { sneak->t_scan=YES ; } scan_found() ; sneak= trafo ; while( sneak=sneak->t_next ) { sneak->t_scan=NO ; } return ; } if ( trafo->t_linker && stopsuffix && !*stopsuffix ) { trafo->t_scan=NO ; scan_found() ; return ; } if ( l_next(*scan) ) { try(l_next(*scan),trafo->t_out); } else { if ( !stopsuffix ) scan_found() ; } trafo->t_scan= NO ; } } } scan_found() { register list_elem *scan; int ncount, ocount ; suf_found= 1; #ifdef DEBUG if ( debug>=3 ) vprint("Scan found\n") ; #endif /* Gather data used in comparison */ ncount=0; ocount=0; scanlist(l_first(tr_list),scan) { if (t_cont(*scan)->t_scan) { #ifdef DEBUG if ( debug>=4 ) vprint("%s-",t_cont(*scan)->t_name) ; #endif if( t_cont(*scan)->t_optim ) ocount++ ;else ncount++ ; } } #ifdef DEBUG if ( debug>=4 ) vprint("\n"); #endif /* Is this transformation better then any found yet ? */ #ifdef DEBUG if ( debug>=3 ) { vprint("old n:%d, o:%d - new n:%d, o:%d\n", last_ncount,last_ocount,ncount,ocount) ; } #endif if ( last_ncount== -1 || /* None found yet */ last_ncount>ncount || /* Shorter nec. path */ (last_ncount==ncount && /* Same nec. path, optimize?*/ (Optflag? last_ocountocount ) ) ) { /* Yes it is */ #ifdef DEBUG if ( debug>=3 ) vprint("Better\n"); #endif scanlist(l_first(tr_list),scan) { t_cont(*scan)->t_bscan=t_cont(*scan)->t_scan; } last_ncount=ncount; last_ocount=ocount; } } int satisfy(trafo,suffix) register trf *trafo; char *suffix ; { register char *f_char, *l_char ; /* Check whether this transformation is present for the current machine and the parameter suffix is among the input suffices. If so, return 1. 0 otherwise */ if ( trafo->t_isprep ) return 0 ; l_char=trafo->t_in ; while ( l_char ) { f_char= l_char ; if ( *f_char!=SUFCHAR || ! *(f_char+1) ) { fuerror("Illegal input suffix entry for %s", trafo->t_name) ; } l_char=index(f_char+1,SUFCHAR); if ( l_char ? strncmp(f_char,suffix,l_char-f_char)==0 : strcmp(f_char,suffix)==0 ) { return 1 ; } } return 0 ; } enum f_path scan_end(first) trf **first ; { /* Finalization */ /* Return value indicating whether a transformation was found */ /* Set the flags for the transformation up to, but not including, the combiner */ register trf *prev, *curr ; register list_elem *scan; #ifdef DEBUG if ( debug>=3 ) vprint("End_scan\n"); #endif if ( last_ncount== -1 ) return suf_found ? F_NOPATH : F_NOMATCH ; #ifdef DEBUG if ( debug>=2 ) vprint("Transformation found\n"); #endif prev= (trf *)0 ; *first= prev ; scanlist(l_first(tr_list),scan) { curr= t_cont(*scan) ; if ( curr->t_bscan ) { if ( prev ) { prev->t_next= curr ; if ( curr->t_linker ) prev->t_keep=YES ; } else { *first= curr ; } if ( curr->t_next ) { return F_OK ; } prev=curr ; } } if ( cpp_trafo && stopsuffix && strcmp(stopsuffix,cpp_trafo->t_out)==0 ) { cpp_trafo->t_keep=YES ; } if ( prev ) { prev->t_keep=YES ; } return F_OK ; } find_cpp() { register list_elem *elem ; scanlist( l_first(tr_list), elem ) { if ( t_cont(*elem)->t_isprep ) { if ( cpp_trafo ) fuerror("Multiple cpp's present") ; cpp_trafo= t_cont(*elem) ; } } if ( !cpp_trafo ) fuerror("No cpp present") ; }