C:/Users/Dennis/src/lang/russell.orig/src/pass5c/bld_analyze.c

Go to the documentation of this file.
00001 /* Fill in INSIDE_LOOP and CONTAINS_CLOSURE bits for blocks */
00002 /* These are used by allocate to decide whether to promote  */
00003 /* declarations to surrounding blocks, and whether to reuse */
00004 /* activation record slots.                                 */
00005 /* ASSUMES GC instead of reference counting.                */
00006 # include "parm.h"
00007 # include <stdio.h>
00008 # include "stree/ststructs.mh"
00009 # include "../pass3/is_local.h"
00010 
00011 extern FILE * unparse_file;
00012 
00013 extern boolean Vflag;
00014 extern boolean Oflag;
00015 extern boolean Nflag;
00016 
00017 extern NODE * insrtptr;     /* Root of user program */
00018 
00019 static boolean surr_loop = FALSE;       /* There is a surrounding loop, */
00020                                         /* w/o intervening function or  */
00021                                         /* block.                       */
00022             /* Note that for our purposes, string selection types are in */
00023             /* a loop, since theyt are represented only once, but may    */
00024             /* be repeatedly evaluated.                                  */
00025 
00026 
00027 static boolean callcc_call = FALSE;     /* Call to current function may save */
00028                                         /* continuation.                     */
00029 
00030 /* Fill in the information for tree rooted at *p.  Return true iff a */
00031 /* reference to the environment can escape.                          */
00032 /* We pass a reference to a node pointer, so that we can slightly    */
00033 /* modify *p to make this easier.  We only replace MODPRIMARY        */
00034 /* nodes.                                                            */
00035 boolean bld_analyze(arg)
00036 NODE **arg;
00037 {
00038     NODE * p = *arg;
00039     boolean r = FALSE;
00040 
00041     /* We claim that p points to an expression node */
00042     if (p -> signature -> kind == SIGNATURESIG) return(FALSE);
00043 
00044     switch(p -> kind) {
00045         case BLOCKDENOTATION:
00046             {
00047                 boolean Osurr_loop = surr_loop;
00048                 boolean nontr_decl = FALSE;
00049                 boolean contains_closure = FALSE;
00050                 extern boolean calls_callcc();
00051 
00052                 maplist(s, p -> bld_declaration_list, {
00053                     if (s -> decl_needed) {
00054                         /* Will need either act. record or register space */
00055                         nontr_decl = TRUE;
00056                     }
00057                 });
00058                 if (nontr_decl) {
00059                     /* This one's for real ... */
00060                     if (surr_loop || callcc_call) {
00061                         p -> bld_flags |= INSIDE_LOOP;
00062                     }
00063                     surr_loop = FALSE;
00064                 }
00065                 maplist(v, p -> bld_declaration_list, {
00066                     contains_closure |= bld_analyze(&(v -> decl_denotation));
00067                 });
00068                 maplistp(v, p -> bld_den_seq, {
00069                     contains_closure |= bld_analyze(v);
00070                 });
00071                 if (contains_closure) {
00072                     p -> bld_flags |= CONTAINS_CLOSURE;
00073                 }
00074                 if (callcc_call) {
00075                     if (Oflag) {
00076                         if (calls_callcc(p)) {
00077                             p -> bld_flags |= CALLCC_CALL;
00078                         }
00079                     } else if (!Nflag) {
00080                         p -> bld_flags |= CALLCC_CALL;
00081                     }
00082                 }
00083                 if ((p -> bld_flags & (CONTAINS_CLOSURE | CALLCC_CALL))
00084                      && (p -> bld_flags & INSIDE_LOOP)
00085                      && is_descendant(p, insrtptr)) {
00086                     p -> bld_flags |= REQUIRES_AR;
00087                     /* We claim that NO_SL cannot ever be set for the */
00088                     /* surrounding function, since there is either a  */
00089                     /* nested closure, or we cannot determine that    */
00090                     /* there is no Call/cc call.                      */
00091                     if (Vflag) {
00092                         findvl(p -> vlineno);
00093                         printf("Block requires a.r. (file: %s, line: %d)\n",
00094                                getname(getfn()), getrl());
00095                         if (Osurr_loop) {
00096                             printf("\t- explicit surrounding loop\n");
00097                         }
00098                         if (callcc_call) {
00099                             printf("\t- possible Callcc call in function may create loop\n");
00100                         }
00101                         if (p -> bld_flags & CONTAINS_CLOSURE) {
00102                             printf("\t- embedded closure\n");
00103                         }
00104                         if (p -> bld_flags & CALLCC_CALL) {
00105                             printf("\t- possible embedded Callcc call\n");
00106                         }
00107                     }
00108                 }
00109                 r |= contains_closure;
00110                 surr_loop = Osurr_loop;
00111             }
00112             break;
00113 
00114         case MODPRIMARY:
00115             if (p -> mp_type_modifier != NIL
00116                 && p -> mp_type_modifier -> kind == WITHLIST) {
00117                 boolean Osurr_loop = surr_loop;
00118                 boolean captures_cont;
00119 
00120                 surr_loop = FALSE;
00121                 maplist(v, p -> mp_type_modifier -> wl_component_list, {
00122                     r |= bld_analyze(&(v -> decl_denotation));
00123                 });
00124                 if (callcc_call) {
00125                     if (Oflag) {
00126                         captures_cont = calls_callcc(p);
00127                     } else {
00128                         if (Nflag) {
00129                             captures_cont = FALSE;
00130                         } else {
00131                             captures_cont = TRUE;
00132                         }
00133                     }
00134                 } else {
00135                     captures_cont = FALSE;
00136                 }
00137                 if (Osurr_loop || callcc_call) {
00138                     /* Introduce a surrounding block with its own */
00139                     /* activation record to hold the reference    */
00140                     /* to the new type.                           */
00141                     NODE * block = mknode(BLOCKDENOTATION,
00142                                           emptylist(), mklist(p, -1));
00143 
00144                     block -> vlineno = p -> vlineno;
00145                     block -> signature = p -> signature;
00146                     block -> sig_done = SIG_DONE;
00147                     if ((r || captures_cont) && p -> mp_needed) {
00148                         block -> bld_flags = INSIDE_LOOP;
00149                         if (is_descendant(p, insrtptr)) {
00150                           block -> bld_flags |= REQUIRES_AR;
00151                           if (Vflag) {
00152                             findvl(p -> vlineno);
00153                             printf("Introducing block with a.r. for type modification (file: %s, line: %d)\n",
00154                                    getname(getfn()), getrl());
00155                             printf("\t - type modification: ");
00156                             unparse_file = stdout;
00157                             unparse(p);
00158                             printf("\n");
00159                             if (Osurr_loop) {
00160                                 printf("\t- explicit surrounding loop\n");
00161                             }
00162                             if (callcc_call) {
00163                                 printf("\t- possible Callcc call in function may create loop\n");
00164                             }
00165                             if (r) {
00166                                 printf("\t- embedded closure\n");
00167                             }
00168                             if (captures_cont) {
00169                                 printf("\t- possible embedded Callcc call\n");
00170                             }
00171                           }
00172                         }
00173                         if (r) {
00174                             block -> bld_flags |= CONTAINS_CLOSURE;
00175                         }
00176                         if (captures_cont) {
00177                             block -> bld_flags |= CALLCC_CALL;
00178                         }
00179                     }
00180                     *arg = block;
00181                 }
00182                 surr_loop = Osurr_loop;
00183             }
00184             r |= bld_analyze(&(p -> mp_primary));
00185             break;
00186 
00187         case APPLICATION:
00188             r = bld_analyze(&(p -> ap_operator));
00189             maplistp(v, p -> ap_args, r |= bld_analyze(v));
00190             break;
00191 
00192         case LOOPDENOTATION:
00193             {
00194                 boolean Osurr_loop = surr_loop;
00195 
00196                 surr_loop = TRUE;
00197                 maplist(v, p -> gl_list, {
00198                     r |= bld_analyze(&(v -> ge_guard));
00199                     r |= bld_analyze(&(v -> ge_element));
00200                 });
00201                 surr_loop = Osurr_loop;
00202             }
00203             break;
00204 
00205         case QSTR:
00206         case UQSTR:
00207             {
00208                 boolean Osurr_loop = surr_loop;
00209 
00210                 surr_loop = TRUE;
00211                 bld_analyze(&(p -> sel_type));
00212                 surr_loop = Osurr_loop;
00213             }
00214             break;
00215 
00216         case GUARDEDLIST:
00217             maplist(v, p-> gl_list, {
00218                 r |= bld_analyze(&(v -> ge_guard));
00219                 r |= bld_analyze(&(v -> ge_element));
00220             });
00221             break;
00222 
00223         case OPRID:
00224         case LETTERID:
00225             if (p -> sel_type != NIL) {
00226                 r |= bld_analyze(&(p -> sel_type));
00227             }
00228             break;
00229 
00230         case FUNCCONSTR:
00231             if (p -> fc_body -> kind == EXTERNDEF) return;
00232             {
00233                 boolean Ocallcc_call = callcc_call;
00234                 boolean Osurr_loop = surr_loop;
00235 
00236                 callcc_call = !(p -> fc_complexity & NO_CALLCC);
00237                 if (Nflag) callcc_call = FALSE;
00238                 surr_loop = FALSE;
00239 
00240                 r |= (p -> fc_complexity & NEED_CL);
00241                 r |= bld_analyze(&(p -> fc_body));
00242 
00243                 callcc_call = Ocallcc_call;
00244                 surr_loop = Osurr_loop;
00245             }
00246             break;
00247 
00248         case REXTERNDEF:
00249             break;
00250 
00251         case USELIST:
00252             maplistp(q, p -> usl_den_seq, r |= bld_analyze(q));
00253             break;
00254 
00255         case EXTENSION:
00256             r = bld_analyze(&(p -> ext_denotation));
00257             break;
00258 
00259         case RECORDCONSTRUCTION:
00260             maplist(s, p -> rec_component_list, {
00261                 r |= bld_analyze(&(s -> re_denotation));
00262             });
00263             break;
00264 
00265         case WORDELSE:
00266             break;
00267 
00268         case PRODCONSTRUCTION:
00269         case UNIONCONSTRUCTION:
00270         case ENUMERATION:
00271             /* No evaluated subexpressions. */
00272             break;
00273 
00274         default:
00275             dbgmsg("bld_analyze: Bad kind: %d\n", p -> kind);
00276     }
00277     return(r);
00278 }

Generated on Fri Jan 25 10:39:47 2008 for russell by  doxygen 1.5.4