SSA.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2008, Johns Hopkins University.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or
00007  * without modification, are permitted provided that the following
00008  * conditions are met:
00009  *
00010  *   - Redistributions of source code must contain the above 
00011  *     copyright notice, this list of conditions, and the following
00012  *     disclaimer. 
00013  *
00014  *   - Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions, and the following
00016  *     disclaimer in the documentation and/or other materials 
00017  *     provided with the distribution.
00018  *
00019  *   - Neither the names of the copyright holders nor the names of any
00020  *     of any contributors may be used to endorse or promote products
00021  *     derived from this software without specific prior written
00022  *     permission. 
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00027  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  **************************************************************************/
00037 
00038 #include <stdint.h>
00039 #include <stdlib.h>
00040 #include <dirent.h>
00041 #include <fstream>
00042 #include <iostream>
00043 #include <string>
00044 #include "AST.hxx"
00045 #include "Environment.hxx"
00046 #include "Unify.hxx"
00047 #include "inter-pass.hxx"
00048 #include "Special.hxx"
00049 #include "Instantiate.hxx"
00050 
00051 #include "BUILD/TransitionParser.hxx"
00052 
00053 using namespace boost;
00054 using namespace sherpa;
00055 
00056 static inline shared_ptr<AST> 
00057 newGrandLet(shared_ptr<AST> ref)
00058 {
00059   shared_ptr<AST> lbs = AST::make(at_letbindings, ref->loc);
00060   shared_ptr<AST> res = AST::make(at_ident, ref->loc);
00061   res->s = res->fqn.ident = "NULL";
00062   shared_ptr<AST> grandLet = AST::make(at_letStar, ref->loc, lbs, res);
00063   return grandLet;
00064 }
00065 
00066 
00067 static inline shared_ptr<AST> 
00068 getLastLB(shared_ptr<AST> grandLet)
00069 {
00070   shared_ptr<AST> lbs = grandLet->child(0);
00071   return lbs->child(lbs->children.size() - 1);
00072 }
00073 
00078 static void
00079 addIL(shared_ptr<AST> identList, shared_ptr<AST> id)
00080 {
00081   identList->children.push_back(id);
00082 }
00083 
00084 
00085 // This is the use case, but input might be a definition,
00086 // or another use. Non-ident input is returned as is.
00087 static inline shared_ptr<AST> 
00088 UseCase(shared_ptr<AST> ast)
00089 {
00090   if (ast->astType == at_ident) {
00091     if (!ast->symbolDef)
00092       return ast->Use();
00093     else
00094       return ast->getTrueCopy();  
00095   }
00096   else
00097     return ast;
00098 }
00099 
00100 static shared_ptr<AST> 
00101 addLB(shared_ptr<AST> grandLet, shared_ptr<AST> identList, 
00102       shared_ptr<AST> ast, AstFlags lbFlags = NO_FLAGS,
00103       shared_ptr<AST> id=GC_NULL, bool addToIL=true)
00104 {
00105   if (!id)
00106     id = AST::genSym(ast, "t");
00107   id->symType = ast->symType;
00108   shared_ptr<AST> ip = AST::make(at_identPattern, id->loc, id);
00109   shared_ptr<AST> lb = AST::make(at_letbinding, ip->loc, ip, ast);
00110   // "Artificial" SSA introduced LBs were previously marked here
00111   // as: lb->Flags |= (LB_IS_ART | lbFlags);
00112   lb->flags |= lbFlags;
00113   grandLet->child(0)->children.push_back(lb);
00114   if (addToIL)
00115     addIL(identList, id);  
00116   return UseCase(id);
00117 }
00118 
00119 #if 0
00120 static bool
00121 warnTmp(std::ostream &errStream, shared_ptr<AST> ast)
00122 {
00123   switch(ast->astType) {
00124   case at_ident:
00125   case at_select:
00126   case at_array_nth:
00127   case at_vector_nth:
00128   case at_deref:
00129     return true;
00130     
00131   case at_typeAnnotation:
00132     return warnTmp(errStream, ast->child(0));
00133     
00134   default:
00135     if (!ast->symType->isRefType()) {
00136       errStream << ast->loc << ": WARNING:"
00137                 << " expression causing a temporary value copy"
00138                 << " appears in location context"
00139                 << "Type of expression is: "
00140                 << ast->symType->asString()
00141                 << std::endl;
00142       return false;
00143     }
00144     else {
00145       return true;
00146     }
00147   }
00148 }
00149 #endif
00150 
00151 #define SETGL(exp, gl)                     \
00152   do {                                     \
00153     if ((gl)->child(0)->children.size())   \
00154       (exp) = (gl);                        \
00155     else                                   \
00156       (exp) = FEXPR(gl);                   \
00157   } while (0)
00158  
00159 //WARNING: **REQUIRES** answer and errorFree.
00160 #define SSA(errStream, uoc, ast, grandLet, identList,      \
00161             parent, chno,  flags)                          \
00162   do {                                                     \
00163     answer = ssa((errStream), (uoc), (ast), (grandLet),    \
00164                  (identList), (parent), (chno), (flags));  \
00165     if (answer == false)                                   \
00166       errorFree = false;                                   \
00167   } while (0)
00168 
00169 
00170 bool
00171 isTrivialInit(shared_ptr<AST> ast)
00172 {
00173   switch(ast->astType) {
00174     
00175   case at_boolLiteral:
00176   case at_charLiteral:
00177   case at_intLiteral:
00178   case at_floatLiteral:
00179   case at_stringLiteral:
00180   case at_unit:
00181   case at_lambda:
00182     {
00183       return true;
00184     }
00185 
00186   case at_ident:
00187     {
00188       return ast->symType->isAtomic();
00189     }
00190 
00191   case at_typeAnnotation:
00192     {
00193       return isTrivialInit(ast->child(0));
00194     }
00195     
00196   case at_begin:
00197     {
00198       for (size_t c = 0; c < ast->children.size(); c++)
00199         if (!isTrivialInit(ast->child(c)))
00200           return false;
00201       return true;
00202     }
00203 
00204   default:
00205     return false;
00206   }
00207 }
00208 
00209 
00210 bool
00211 ssa(std::ostream& errStream, 
00212     shared_ptr<UocInfo> uoc,
00213     shared_ptr<AST> ast, 
00214     shared_ptr<AST> grandLet,
00215     shared_ptr<AST> identList,
00216     shared_ptr<AST> parent, 
00217     const size_t chno,
00218     unsigned long flags)
00219 {
00220   bool errorFree = true, answer = false;
00221   size_t c = 0;
00222   
00223   //errStream << "SSA: " << ast->asString();
00224 
00225   switch(ast->astType) {
00226 
00227   case at_Null:
00228   case at_boxedCat:
00229   case at_unboxedCat:
00230   case at_oc_closed:
00231   case at_oc_open:
00232   case at_opaqueCat:
00233   case agt_category:
00234   case at_AnyGroup:
00235   case agt_literal:
00236   case agt_tvar:
00237   case agt_var:
00238   case agt_definition:
00239   case agt_type:
00240   case agt_expr:
00241   case agt_expr_or_define:
00242   case agt_eform:
00243   case agt_type_definition:
00244   case agt_value_definition:
00245   case agt_openclosed:
00246   case at_letbindings:
00247   case at_letbinding:
00248   case at_loopbindings:
00249   case at_loopbinding:
00250   case at_looptest:
00251   case agt_CompilationUnit:
00252   case agt_tc_definition:
00253   case agt_if_definition:
00254   case agt_ow:
00255   case agt_qtype:
00256   case agt_fielditem:
00257   case at_localFrame:
00258   case at_frameBindings:
00259   case at_ifident:
00260   case at_declares:
00261   case at_declare:
00262   case at_tvlist:
00263   case at_constructors:
00264   case at_constructor:
00265   case at_fields:
00266   case at_field:
00267   case at_methdecl:
00268   case at_fill:
00269   case at_tcdecls:
00270   case at_tyfn:
00271   case at_tcapp:
00272   case at_method_decls:
00273   case at_method_decl:
00274   case at_usesel:
00275   case at_identList:
00276   case at_container:
00277   case agt_ucon:
00278   case agt_uselhs:
00279     
00280   case at_exceptionType:
00281   case at_dummyType:
00282   case at_boxedType:
00283   case at_unboxedType:
00284   case at_byRefType:
00285   case at_arrayRefType:
00286   case at_fn:
00287   case at_fnargVec:
00288   case at_primaryType:
00289   case at_arrayType:
00290   case at_vectorType:
00291   case at_mutableType:
00292   case at_constType:
00293   case at_typeapp:
00294   case at_bitfieldType:
00295   case at_qualType:    
00296   case at_constraints:
00297   case at_fieldType:
00298   case at_methType:
00299     
00300   case at_cond_legs:
00301   case at_cond_leg:
00302   case at_usw_legs:
00303   case at_usw_leg:
00304   case at_condelse:
00305   case at_otherwise:
00306   case at_letGather:
00307     {
00308       errStream << ast->loc << "Internal Compiler Error. " 
00309                 << "Function SSA, unexpected astType: " 
00310                 << ast->tagName()
00311                 << std::endl;
00312       
00313       FEXPR(grandLet) = GC_NULL;
00314       errorFree = false;
00315       break;
00316     }
00317 
00318   case at_identPattern:
00319     {
00320       if ((ast->child(0)->symbolDef) &&
00321          (ast->child(0)->isIdentType(idc_ctor)))
00322         break;
00323 
00324       addIL(identList, ast->child(0));
00325       break;
00326     }
00327     
00328   case at_interface:
00329   case at_module:
00330     {            
00331       // match agt_definition*
00332       for (c = (ast->astType == at_interface)?1:0;
00333            c < ast->children.size(); 
00334            c++) {
00335         shared_ptr<AST> defn = ast->child(c);
00336         SSA(errStream, uoc, defn, grandLet, 
00337                identList, ast, c, flags);
00338       }
00339       break;
00340     }
00341     
00342   case at_defunion:
00343   case at_defstruct:
00344   case at_defrepr:
00345   case at_declunion:
00346   case at_declstruct:
00347   case at_declrepr:
00348   case at_proclaim:
00349   case at_defexception:
00350   case at_deftypeclass:
00351   case at_definstance:
00352   case at_tcmethods:
00353   case at_tcmethod_binding:
00354   case at_importAs:
00355   case at_provide:
00356   case at_import:
00357   case at_ifsel:
00358     //case at_reprbody:
00359     //case at_reprcase:
00360     //case at_reprcaselegR:
00361     //case at_reprtag:
00362     //case agt_reprbodyitem:
00363   case at_reprctrs:
00364   case at_reprctr:
00365   case at_reprrepr:
00366   case at_docString:
00367     {
00368       break;
00369     }
00370     
00371   case at_boolLiteral:
00372   case at_charLiteral:
00373   case at_intLiteral:
00374   case at_floatLiteral:
00375   case at_stringLiteral:
00376   case at_unit:
00377     {
00378       FEXPR(grandLet) = ast;
00379       break;
00380     }
00381 
00382   case at_ident:
00383     {
00384       //       if ((ast->symbolDef == NULL) && 
00385       //          (!identList->contains(ast)))
00386       //         identList->append(ast);
00387       FEXPR(grandLet) = ast;
00388       break;
00389     }
00390     
00391   case at_define:
00392   case at_recdef:
00393     {
00394       if (ast->child(1)->astType == at_lambda) {
00395         SSA(errStream, uoc, ast->child(1), grandLet, identList, 
00396                ast, 1, flags);
00397         ast->flags |= DEF_IS_TRIVIAL_INIT;        
00398       }      
00399       else if (isTrivialInit(ast)) {
00400         ast->flags |= DEF_IS_TRIVIAL_INIT;
00401       }
00402       else {
00403         shared_ptr<AST> gl = newGrandLet(ast);
00404         identList = AST::make(at_identList, ast->loc);
00405         
00406         SSA(errStream, uoc, ast->child(1), gl, identList, 
00407             ast, 1, flags);
00408         
00409         shared_ptr<AST> body = GC_NULL;
00410         SETGL(body, gl);
00411         assert(body);
00412         ast->child(1) = AST::make(at_container, ast->loc, identList, body);        
00413       }
00414       break;
00415     }
00416 
00417   case at_lambda:
00418     {
00419       shared_ptr<AST> gl = newGrandLet(ast);
00420       identList = AST::make(at_identList, ast->loc);
00421       
00422       SSA(errStream, uoc, ast->child(0), gl, identList, 
00423              ast, 0, flags);
00424       SSA(errStream, uoc, ast->child(1), gl, identList, 
00425              ast, 1, flags);
00426       
00427       shared_ptr<AST> body = GC_NULL;
00428       SETGL(body, gl);
00429       assert(body);
00430       ast->child(1) = AST::make(at_container, ast->loc, identList, body);
00431         
00432       // FEXPR carry over
00433       break;
00434     }
00435 
00436   case at_argVec:
00437     {
00438       break;
00439     }
00440 
00441   case at_typeAnnotation:
00442     {
00443       // match agt_eform
00444       SSA(errStream, uoc, ast->child(0), grandLet, identList, 
00445              ast, 0, flags);      
00446       ast->child(0) = FEXPR(grandLet);
00447       FEXPR(grandLet) = ast;
00448       // No need to add a new Binding
00449       break;
00450     }
00451 
00452   case at_sizeof:
00453   case at_bitsizeof:
00454     {
00455       FEXPR(grandLet) = addLB(grandLet, identList, ast);
00456       break;
00457     }
00458     
00459   case at_suspend:
00460     {
00461       shared_ptr<AST> gl = newGrandLet(ast);
00462       shared_ptr<AST> res = AST::genSym(ast, "t");
00463       SSA(errStream, uoc, ast->child(1), gl, identList, 
00464           ast, 1, flags);
00465       FEXPR(gl) = addLB(gl, identList, FEXPR(gl), 
00466                         ID_IS_GLOBAL, res, true);
00467 
00468       SETGL(ast->child(1), gl);
00469       shared_ptr<AST> topres = UseCase(res);
00470       FEXPR(grandLet) = addLB(grandLet, identList, ast, 
00471                               LB_IS_DUMMY, topres, false);
00472       break;
00473     }
00474     
00475   case at_allocREF:
00476     {
00477       FEXPR(grandLet) = ast;
00478       break;
00479     }
00480     
00481   case at_copyREF:
00482   case at_setClosure:
00483     {      
00484       for (c=0; c < ast->children.size(); c++) {
00485         SSA(errStream, uoc, ast->child(c), grandLet, identList, 
00486             ast, c, flags);
00487         ast->child(c) = FEXPR(grandLet);
00488       }
00489       FEXPR(grandLet) = addLB(grandLet, identList, ast,
00490                               LB_IS_DUMMY);
00491       break;
00492     }
00493     
00494 #ifdef HAVE_INDEXABLE_LENGTH_OPS
00495   case at_array_length:
00496   case at_array_ref_length:
00497   case at_vector_length:
00498 #endif
00499   case at_struct_apply:
00500   case at_object_apply:
00501   case at_ucon_apply: 
00502     {
00503       for (c=0; c < ast->children.size(); c++) {
00504         SSA(errStream, uoc, ast->child(c), grandLet, identList, 
00505             ast, c, flags);
00506         ast->child(c) = FEXPR(grandLet);
00507       }
00508       FEXPR(grandLet) = addLB(grandLet, identList, ast);
00509       break;
00510     }
00511 
00512   case at_dup:
00513   case at_array:
00514   case at_vector:
00515   case at_MakeVector:
00516   case at_throw:
00517   case at_mkClosure:
00518   case at_mkArrayRef:
00519     {
00520       for (c=0; c < ast->children.size(); c++) {
00521         SSA(errStream, uoc, ast->child(c), grandLet, identList, 
00522             ast, c, flags);
00523          ast->child(c) = FEXPR(grandLet);
00524       }
00525       FEXPR(grandLet) = addLB(grandLet, identList, ast, 
00526                               LB_POSTPONED);
00527       break;
00528     }
00529     
00530   case at_fqCtr:
00531     {
00532       FEXPR(grandLet) = ast;
00533       break;      
00534     }
00535 
00536   case at_sel_ctr:
00537     {
00538       SSA(errStream, uoc, ast->child(0), grandLet, identList, 
00539           ast, 0, flags);      
00540       ast->child(0) = FEXPR(grandLet);
00541       
00542       FEXPR(grandLet) = addLB(grandLet, identList, ast);        
00543       break;      
00544     }
00545 
00546   case at_deref:
00547   case at_select:
00548     {
00549       SSA(errStream, uoc, ast->child(0), grandLet, identList, 
00550           ast, 0, flags);      
00551       ast->child(0) = FEXPR(grandLet);
00552       FEXPR(grandLet) = ast;
00553       break;      
00554     }
00555 
00556   case at_inner_ref:
00557     {
00558       shared_ptr<AST> expr = ast->child(0);
00559       
00560       SSA(errStream, uoc, expr, grandLet, identList, 
00561           ast, 0, flags);      
00562       ast->child(0) = FEXPR(grandLet);
00563 
00564       if (ast->flags & INNER_REF_NDX) {
00565         shared_ptr<AST> ndx = ast->child(1);
00566         SSA(errStream, uoc, ndx, grandLet, identList, 
00567             ast, 1, flags);      
00568         ast->child(1) = FEXPR(grandLet);
00569         
00570         // Need to Check Index bounds here, 
00571         // Get the array_nth or vector_nth case to do it
00572         // Final replacement of FEXPR(grandLet) will
00573         // change the resultant value to 
00574         // inner-ref.
00575         
00576         shared_ptr<AST> tempAst = GC_NULL;
00577         if (expr->symType->getBareType()->typeTag == ty_array_ref) {
00578           // This should have failed to type check.
00579           assert(false);
00580         }
00581         if (expr->symType->getBareType()->typeTag == ty_vector) {
00582           // Vector-Index
00583           tempAst = AST::make(at_vector_nth, expr->loc, 
00584                             expr, ndx);
00585           
00586         }
00587         else {
00588           // ref(Array)-Index
00589           assert(expr->symType->getBareType()->typeTag == ty_ref);
00590           tempAst = AST::make(at_array_nth, expr->loc, 
00591                             AST::make(at_deref, expr->loc, expr), ndx);          
00592         }
00593         
00594         // Careful: tempAst has no real parent. 
00595         // Fortunately, arrray_nth and vector_nth does not need this
00596         // information, and all other sub-trees will recieve correct
00597         // information from that case. Actually, there will be no
00598         // further cases as the sub-expression have already been
00599         // SSAed in the previous steps. 
00600         SSA(errStream, uoc, tempAst, grandLet, identList, 
00601             GC_NULL, 0, flags);      
00602         
00603       }
00604 
00605       FEXPR(grandLet) = ast;      
00606       break;      
00607     }
00608 
00609   case at_nth:
00610     // Shouldn't get here
00611     assert(false);
00612     break;
00613 
00614   case at_array_nth:
00615   case at_array_ref_nth:
00616   case at_vector_nth:
00617     {
00618       shared_ptr<AST> expr = ast->child(0);
00619       shared_ptr<AST> ndx = ast->child(1);
00620 
00621       SSA(errStream, uoc, expr, grandLet, identList, 
00622           ast, 0, flags);      
00623       ast->child(0) = FEXPR(grandLet);      
00624       //warnTmp(errStream, expr);
00625       expr = ast->child(0);
00626 
00627       SSA(errStream, uoc, ndx, grandLet, identList, 
00628           ast, 1, flags);      
00629       ast->child(1) = FEXPR(grandLet);
00630       ndx = ast->child(1);
00631 
00632       
00633       shared_ptr<AST> lt = AST::make(at_ident, ast->loc);
00634       shared_ptr<AST> unit = AST::make(at_unit, ast->loc);
00635       shared_ptr<AST> IOB = AST::make(at_ident, ast->loc);
00636 
00637       lt->s = "__index_lt";
00638       lt->fqn = FQName("bitc.prelude", "__index_lt");
00639       lt->symType = Type::make(ty_fn, 
00640                              Type::make(ty_fnarg, 
00641                                       Type::make(ty_word),
00642                                       Type::make(ty_word)),
00643                              Type::make(ty_bool));
00644       InstMangle(lt);
00645 
00646       IOB->s = "IndexBoundsError";
00647       IOB->fqn = FQName("bitc.prelude", "IndexBoundsError");
00648       IOB->symType = Type::make(ty_exn);
00649       InstMangle(IOB);
00650 
00651 #ifdef HAVE_INDEXABLE_LENGTH_OPS
00652       AstType lenType = 
00653         ((ast->astType == at_array_nth) ? at_array_length 
00654          : ((ast->astType == at_array_ref_nth) ? at_array_ref_length
00655             : at_vector_length));
00656       
00657       shared_ptr<AST> len = AST::make(lenType, ast->loc,
00658                                       UseCase(expr));
00659 #else
00660       shared_ptr<AST> lengthIdent = 
00661         AST::make(at_ident, LToken(tk_BlkIdent, "length"));
00662       shared_ptr<AST> len = AST::make(at_select, ast->loc,
00663                                       UseCase(expr), lengthIdent);
00664 #endif
00665 
00666       shared_ptr<AST> ltApp = AST::make(at_apply, ast->loc, lt, UseCase(ndx), len);
00667       
00668       shared_ptr<AST> throwAst = AST::make(at_throw, ast->loc, IOB);
00669       shared_ptr<AST> ifAst = AST::make(at_if, ast->loc, ltApp, unit, throwAst);
00670       addLB(grandLet, identList, ifAst, LB_IS_DUMMY);      
00671       
00672       FEXPR(grandLet) = ast;
00673       break;
00674     }
00675 
00676   case at_apply:
00677     {
00678       shared_ptr<AST> id = ast->child(0);      
00679 
00680       shared_ptr<Type> fn = id->symType->getBareType();
00681       assert(fn->isFnxn());
00682       shared_ptr<Type> argsType = fn->Args()->getType();
00683 
00684       SSA(errStream, uoc, ast->child(0), grandLet, identList, 
00685           ast, 0, flags);
00686       ast->child(0) = FEXPR(grandLet);
00687       
00688       for (c=1; c < ast->children.size(); c++) {
00689         
00690         SSA(errStream, uoc, ast->child(c), grandLet, identList, 
00691             ast, c, flags);
00692         
00693         /* We must make sure that all by-ref applications can be legal
00694            -- some applications may need temporary variable
00695            introductions. For example: 
00696            
00697            (fnxn:(fn ((by-ref bool)) ()) #t)
00698         */
00699         
00700         if ((argsType->CompFlags(c-1) & COMP_BYREF) && 
00701             ast->child(c)->isLiteral()) {
00702           // While application of literals to mutable-by-reference
00703           // parameters is illegal, this should have been a type
00704           // error. 
00705           assert(!argsType->CompType(c-1)->isMutable());
00706           
00707           // Now it is safe to allow the byref application by
00708           // introducing a temporary variable.
00709           FEXPR(grandLet) = addLB(grandLet, identList, ast->child(c));
00710         }
00711         
00712         ast->child(c) = FEXPR(grandLet);        
00713       }
00714 
00715       if (id->flags & SELF_TAIL) {
00716         assert(id == ast->child(0)); // we did not change the identifier
00717         FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY);
00718       }
00719       else {
00720         FEXPR(grandLet) = addLB(grandLet, identList, ast);
00721       }
00722       break;
00723     }
00724 
00725   case at_setbang:
00726     {
00727       shared_ptr<AST> lhs = ast->child(0);
00728       SSA(errStream, uoc, lhs, grandLet, identList, 
00729           ast, 0, flags);
00730       ast->child(0) = FEXPR(grandLet);
00731       //warnTmp(errStream, lhs);
00732       lhs = ast->child(0);
00733 
00734       shared_ptr<AST> rhs = ast->child(1);
00735       SSA(errStream, uoc, rhs, grandLet, identList, 
00736           ast, 1, flags);      
00737       ast->child(1) = FEXPR(grandLet);
00738       rhs = ast->child(1);
00739       
00740       FEXPR(grandLet) = addLB(grandLet, identList, ast, 
00741                               LB_POSTPONED);
00742       // This must be 
00743       // FEXPR(grandLet) = addLB(grandLet, identList, ast);      
00744       // and not:
00745       // FEXPR(grandLet) = ast; or
00746       // FEXPR(grandLet) = addLB(grandLet, identList, ast, 
00747       //                        LB_IS_DUMMY);
00748       break;
00749     }    
00750 
00751   case at_begin:
00752     {
00753       for (c=0; c < ast->children.size(); c++) {
00754         SSA(errStream, uoc, ast->child(c), grandLet, identList, 
00755                ast, c, flags);
00756         ast->child(c) = FEXPR(grandLet);
00757       }
00758       // FEXPR(grandLet), the last one is the right one.
00759       break;
00760     }    
00761 
00762   case at_if:
00763     {
00764       SSA(errStream, uoc, ast->child(0), grandLet, identList, 
00765              ast, 0, flags);
00766       ast->child(0) = FEXPR(grandLet);
00767 
00768       shared_ptr<AST> res = AST::genSym(ast, "t");
00769       shared_ptr<AST> gl1 = newGrandLet(ast);
00770       shared_ptr<AST> gl2 = newGrandLet(ast);
00771 
00772       SSA(errStream, uoc, ast->child(1), gl1, identList, 
00773              ast, 1, flags);
00774       SSA(errStream, uoc, ast->child(2), gl2, identList, 
00775              ast, 2, flags);
00776 
00777       FEXPR(gl1) = addLB(gl1, identList, FEXPR(gl1), 
00778                          NO_FLAGS, res, true);
00779       FEXPR(gl2) = addLB(gl2, identList, FEXPR(gl2), 
00780                          NO_FLAGS, res, false);
00781       SETGL(ast->child(1), gl1);
00782       SETGL(ast->child(2), gl2);
00783 
00784       shared_ptr<AST> topres = UseCase(res);
00785       FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY, topres, false);
00786       break;
00787     }
00788     
00789   case at_when:
00790   case at_unless:
00791     {
00792       SSA(errStream, uoc, ast->child(0), grandLet, identList, 
00793              ast, 0, flags);
00794       ast->child(0) = FEXPR(grandLet);
00795 
00796       shared_ptr<AST> res = AST::genSym(ast, "t");
00797       shared_ptr<AST> gl1 = newGrandLet(ast);
00798 
00799       SSA(errStream, uoc, ast->child(1), gl1, identList, 
00800              ast, 1, flags);
00801 
00802       FEXPR(gl1) = addLB(gl1, identList, FEXPR(gl1), 
00803                          NO_FLAGS, res, true);
00804       SETGL(ast->child(1), gl1);
00805 
00806       shared_ptr<AST> topres = UseCase(res);
00807       FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY, topres, false);
00808       break;
00809     }
00810     
00811   case at_and:
00812     {
00813       shared_ptr<AST> ifizedAST = AST::make(at_if, ast->child(0)->loc);
00814       shared_ptr<AST> ifAst = ifizedAST;
00815       shared_ptr<AST> prev = GC_NULL;
00816       for (c = 0; c < ast->children.size() - 1; c++) {
00817         shared_ptr<AST> falseAst =  AST::make(at_boolLiteral, ast->child(c)->loc);
00818         falseAst->litValue.b = false;
00819         falseAst->s = "#f";
00820         falseAst->symType = Type::make(ty_bool);
00821 
00822         ifAst->symType = ast->child(c)->symType;
00823         ifAst->children.push_back(ast->child(c));
00824         ifAst->children.push_back(AST::make(at_if, ast->child(c+1)->loc));
00825         ifAst->children.push_back(falseAst);
00826         prev = ifAst;
00827         ifAst = ifAst->child(1);
00828       }
00829       
00830       if (prev)
00831         prev->child(1) = ifAst = 
00832           ast->child(ast->children.size() -1);
00833       else
00834         ifAst = ast->child(ast->children.size() -1);
00835         
00836       parent->child(chno) = ifizedAST;
00837       SSA(errStream, uoc, ifizedAST, grandLet, identList, 
00838              parent, chno, flags);
00839       break;
00840     }
00841   case at_or:
00842     {
00843       shared_ptr<AST> ifizedAST = AST::make(at_if, ast->child(0)->loc);
00844       shared_ptr<AST> ifAst = ifizedAST;
00845       shared_ptr<AST> prev = GC_NULL;
00846       for (c = 0; c < ast->children.size() - 1; c++) {
00847         shared_ptr<AST> trueAst =  AST::make(at_boolLiteral, ast->child(c)->loc);
00848         trueAst->litValue.b = true;
00849         trueAst->s = "#t";
00850         trueAst->symType = Type::make(ty_bool);
00851 
00852         ifAst->symType = ast->child(c)->symType;
00853         ifAst->children.push_back(ast->child(c));
00854         ifAst->children.push_back(trueAst);
00855         ifAst->children.push_back(AST::make(at_if, ast->child(c+1)->loc));
00856         prev = ifAst;
00857         ifAst = ifAst->child(2);
00858       }      
00859 
00860       if (prev)
00861         prev->child(2) = ifAst = 
00862           ast->child(ast->children.size() -1);
00863       else
00864         ifAst = ast->child(ast->children.size() -1);
00865         
00866       parent->child(chno) = ifizedAST;
00867       SSA(errStream, uoc, ifizedAST, grandLet, identList, 
00868              parent, chno, flags);      
00869       break;
00870     }
00871 
00872   case at_cond:
00873     {
00874       shared_ptr<AST> caselegs = ast->child(0);
00875       shared_ptr<AST> ow = ast->child(1)->child(0);
00876       shared_ptr<AST> ifizedAST = AST::make(at_if, caselegs->loc);
00877       shared_ptr<AST> ifAst = ifizedAST;
00878       shared_ptr<AST> prev = GC_NULL;
00879       for (c = 0; c < caselegs->children.size(); c++) {
00880         shared_ptr<AST> caseleg = caselegs->child(c);        
00881         ifAst->loc = caseleg->loc;
00882         ifAst->symType = caseleg->symType;
00883         ifAst->children.push_back(caseleg->child(0));
00884         ifAst->children.push_back(caseleg->child(1));
00885 
00886         ifAst->children.push_back(AST::make(at_if,
00887                                        caselegs->child(c)->loc));
00888         prev = ifAst;
00889         ifAst = ifAst->child(2);        
00890       }
00891 
00892       if (prev) {        
00893         prev->child(2) = ifAst = ow;
00894       }
00895       else {
00896         ifAst = ow;
00897       }
00898       
00899       parent->child(chno) = ifizedAST;
00900       SSA(errStream, uoc, ifizedAST, grandLet, identList, 
00901              parent, chno, flags);      
00902       break;
00903     }
00904 
00905 
00906   case at_labeledBlock:
00907     {
00908       // This needs gensym-like behavior, but with a known resulting name.
00909       std::stringstream ss;
00910       ss << "__" << ast->child(0)->s << ast->child(0)->ID;
00911       std::string resultName = ss.str();
00912 
00913       shared_ptr<AST> res = 
00914         AST::make(at_ident, LToken(tk_BlkIdent, resultName));
00915       res->flags = ast->flags | ID_IS_GENSYM;
00916       res->identType = id_value;
00917       res->symType = ast->symType;
00918       res->scheme = ast->scheme;
00919       addIL(identList, res);
00920 
00921       shared_ptr<AST> gl = newGrandLet(ast);
00922       SSA(errStream, uoc, ast->child(1), gl, identList, 
00923           ast, 1, flags);        
00924       FEXPR(gl) = addLB(gl, identList, FEXPR(gl), NO_FLAGS, res, false);
00925       SETGL(ast->child(1), gl);
00926       FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY,
00927                               res, false); 
00928       break;
00929     }
00930 
00931   case at_return_from:
00932     {
00933       shared_ptr<AST> labelDef = ast->child(0)->symbolDef;
00934 
00935       std::stringstream ss;
00936       ss << "__" << labelDef->s << labelDef->ID;
00937       std::string resultName = ss.str();
00938 
00939       shared_ptr<AST> res = 
00940         AST::make(at_ident, LToken(tk_BlkIdent, resultName));
00941       res->flags = ast->flags | ID_IS_GENSYM;
00942       res->identType = id_value;
00943       res->symType = ast->symType;
00944       res->scheme = ast->scheme;
00945 
00946       SSA(errStream, uoc, ast->child(1), grandLet, identList, 
00947           ast, 1, flags);
00948 
00949       FEXPR(grandLet) = addLB(grandLet, identList, FEXPR(grandLet), 
00950                               NO_FLAGS, res, false);
00951 
00952       ast->child(1) = FEXPR(grandLet);
00953 
00954       FEXPR(grandLet) = addLB(grandLet, identList, ast, 
00955                               LB_POSTPONED);
00956       break;
00957     }
00958 
00959   case at_uswitch:
00960   case at_try:
00961     {           
00962       shared_ptr<AST> res = AST::genSym(ast, "t");
00963       addIL(identList, res);
00964       
00965       // The result of the top-expression is a return value        
00966       // only in the case of a try block
00967       // Top-expression is at position 1 for switch ans position 0 for try
00968       if (ast->astType == at_try) {
00969         shared_ptr<AST> gl = newGrandLet(ast);
00970         SSA(errStream, uoc, ast->child(0), gl, identList, 
00971             ast, 0, flags);        
00972         FEXPR(gl) = addLB(gl, identList, FEXPR(gl), NO_FLAGS, res, false);
00973         SETGL(ast->child(0), gl);
00974       }
00975       else {
00976         SSA(errStream, uoc, ast->child(1), grandLet, identList, 
00977             ast, 1, flags);
00978         ast->child(1) = FEXPR(grandLet);        
00979       }
00980       
00981       shared_ptr<AST> cases = ast->child(2);      
00982       // the cases
00983       for (c=0; c < cases->children.size(); c++) {
00984         shared_ptr<AST> theCase = cases->child(c);
00985         shared_ptr<AST> gl = newGrandLet(theCase);
00986 
00987         addIL(identList, theCase->child(0));
00988 
00989         SSA(errStream, uoc, theCase->child(1), gl, 
00990             identList, theCase, 1, flags);
00991 
00992         FEXPR(gl) = addLB(gl, identList, FEXPR(gl), NO_FLAGS, res, false);
00993         SETGL(theCase->child(1), gl);
00994       }
00995 
00996       // otherwise
00997       shared_ptr<AST> ow = ast->child(3);
00998       if (ow->astType == at_otherwise) {
00999         shared_ptr<AST> owIdent = ow->child(0);
01000         shared_ptr<AST> owExpr = ow->child(1);
01001         shared_ptr<AST> gl = newGrandLet(owExpr);
01002 
01003         addIL(identList, owIdent);
01004 
01005         SSA(errStream, uoc, owExpr, gl, identList, ast, 2, flags);
01006         FEXPR(gl) = addLB(gl, identList, FEXPR(gl), NO_FLAGS, res, false);
01007         SETGL(ow->child(1), gl);
01008       }
01009       shared_ptr<AST> topres = UseCase(res);
01010       FEXPR(grandLet) = addLB(grandLet, identList, ast, LB_IS_DUMMY, topres, false);
01011       break;
01012     }
01013 
01014   case at_letStar:
01015     {
01016       assert(false);
01017       break;
01018     }
01019  
01020   case at_loop:
01021     {
01022       shared_ptr<AST> res = AST::genSym(ast, "t");
01023       shared_ptr<AST> gl;
01024       shared_ptr<AST> theIdent;
01025 
01026       shared_ptr<AST> lbs = ast->child(0);     
01027       for (size_t c = 0; c < lbs->children.size(); c++) {
01028         shared_ptr<AST> lb = lbs->child(c);
01029         assert(lb->child(0)->astType == at_identPattern);        
01030         shared_ptr<AST> ident = lb->child(0)->child(0);
01031         addIL(identList, ident);
01032          
01033         shared_ptr<AST> init = lb->child(1);
01034         gl = newGrandLet(ast);      
01035         SSA(errStream, uoc, init, gl, identList, lb, 1, flags);
01036         theIdent = UseCase(ident);
01037         FEXPR(gl) = addLB(gl, identList, FEXPR(gl),
01038                           NO_FLAGS, theIdent, false);
01039         SETGL(lb->child(1), gl);
01040         lb->flags |= LB_IS_DUMMY; 
01041          
01042         shared_ptr<AST> step = lb->child(2);
01043         gl = newGrandLet(ast);      
01044         SSA(errStream, uoc, step, gl, identList, lb, 2, flags);
01045         theIdent = UseCase(ident);
01046         FEXPR(gl) = addLB(gl, identList, FEXPR(gl), 
01047                           NO_FLAGS, theIdent, false);
01048         SETGL(lb->child(2), gl);
01049       }
01050 
01051       // The test
01052       // test
01053       shared_ptr<AST> loopTest = ast->child(1);
01054       gl = newGrandLet(ast);
01055       SSA(errStream, uoc, loopTest->child(0), gl, identList, 
01056              loopTest, 0, flags);
01057       SETGL(loopTest->child(0), gl);
01058 
01059       // result
01060       gl = newGrandLet(loopTest);
01061       SSA(errStream, uoc, loopTest->child(1), gl, identList, 
01062              loopTest, 1, flags);
01063       FEXPR(gl) = addLB(gl, identList, FEXPR(gl), 
01064                         NO_FLAGS, res, true);
01065       SETGL(loopTest->child(1), gl);
01066       
01067       
01068       // The expression
01069       gl = newGrandLet(ast);      
01070       SSA(errStream, uoc, ast->child(2), gl, identList, 
01071           ast, 2, flags);      
01072       SETGL(ast->child(2), gl);
01073       
01074       shared_ptr<AST> topres = UseCase(res);
01075       FEXPR(grandLet) = addLB(grandLet, identList, ast, 
01076                               LB_IS_DUMMY, topres, false);
01077       break;
01078     }
01079 
01080   case at_let:
01081   case at_letrec:
01082     {
01083       shared_ptr<AST> res = AST::genSym(ast, "t");
01084 
01085       // Let bindings
01086       shared_ptr<AST> lbs = ast->child(0);     
01087       for (size_t c = 0; c < lbs->children.size(); c++) {
01088         shared_ptr<AST> lb = lbs->child(c);
01089         assert(lb->child(0)->astType == at_identPattern);        
01090         shared_ptr<AST> ident = lb->child(0)->child(0);
01091         shared_ptr<AST> gl = newGrandLet(ast);      
01092         SSA(errStream, uoc, lb->child(1), gl, identList, 
01093                lb, 1, flags);
01094         shared_ptr<AST> theIdent = ident;
01095         addIL(identList, theIdent);
01096         //theIdent->markFlags(ID_IS_LETBOUND);
01097         FEXPR(gl) = addLB(gl, identList, FEXPR(gl), 
01098                           NO_FLAGS, theIdent, false);
01099         SETGL(lb->child(1), gl);
01100         lb->flags |= LB_IS_DUMMY; 
01101       }
01102             
01103       // The real Final expression of the real let
01104       shared_ptr<AST> gl = newGrandLet(ast);      
01105       SSA(errStream, uoc, ast->child(1), gl, identList, 
01106              ast, 1, flags);      
01107       FEXPR(gl) = addLB(gl, identList, FEXPR(gl), 
01108                         NO_FLAGS, res, true);
01109       SETGL(ast->child(1), gl);
01110       
01111       shared_ptr<AST> topres = UseCase(res);
01112       FEXPR(grandLet) = addLB(grandLet, identList, ast, 
01113                               LB_IS_DUMMY, topres, false);
01114       break;
01115     }
01116   }
01117   return errorFree;
01118 }
01119 
01120 
01121 /* NOTE: SSA Pass introduces explicit bounds checks.
01122    Beyond this pass, no further bounds checks are done */
01123 
01124 bool
01125 UocInfo::be_ssaTrans(std::ostream& errStream,
01126                      bool init, unsigned long flags)
01127 {  
01128   bool errFree = true;
01129 
01130   shared_ptr<UocInfo> uoc = shared_from_this();
01131   
01132   CHKERR(errFree, ssa(errStream, uoc, uoc->uocAst, GC_NULL, 
01133                       GC_NULL, uoc->uocAst, 0, flags));
01134   
01135   //errStream << "ATransed AST = " << std::endl 
01136   //            << uoc->ast->asString() << std::endl;
01137   CHKERR(errFree, uoc->RandT(errStream, true, 
01138                              CL_SYM_FLAGS, CL_TYP_FLAGS));
01139   return errFree;
01140 }
01141 

Generated on Thu May 17 23:59:16 2012 for BitC Compiler by  doxygen 1.4.7