Changeset ae63a18 for src/GenPoly/Box.cc
- Timestamp:
- Dec 18, 2015, 2:56:11 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 8762501
- Parents:
- baf7fee (diff), c23f807 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rbaf7fee rae63a18 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Box.cc -- 7 // Box.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 02 11:52:37201513 // Update Count : 2 0112 // Last Modified On : Fri Dec 18 14:53:08 2015 13 // Update Count : 217 14 14 // 15 15 … … 28 28 #include "Parser/ParseNode.h" 29 29 30 #include "SynTree/Constant.h" 30 31 #include "SynTree/Type.h" 31 32 #include "SynTree/Expression.h" … … 61 62 virtual Expression *mutate( CommaExpr *commaExpr ); 62 63 virtual Expression *mutate( ConditionalExpr *condExpr ); 63 virtual Statement * mutate(ReturnStmt *catchStmt);64 virtual Statement * mutate( ReturnStmt *returnStmt ); 64 65 virtual Type *mutate( PointerType *pointerType ); 65 virtual Type * mutate( FunctionType *pointerType );66 66 virtual Type * mutate( FunctionType *functionType ); 67 67 68 virtual void doBeginScope(); 68 69 virtual void doEndScope(); … … 92 93 class Pass2 : public PolyMutator { 93 94 public: 94 Pass2();95 95 template< typename DeclClass > 96 96 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 103 103 private: 104 104 void addAdapters( FunctionType *functionType ); 105 105 106 106 std::map< UniqueId, std::string > adapterName; 107 107 }; … … 151 151 // the correct thing in some situations. It's not clear to me why this wasn't working. 152 152 153 // if the return type or a parameter type involved polymorphic types, then the adapter will need 154 // to take those polymorphic types as pointers. Therefore, there can be two different functions 153 // if the return type or a parameter type involved polymorphic types, then the adapter will need 154 // to take those polymorphic types as pointers. Therefore, there can be two different functions 155 155 // with the same mangled name, so we need to further mangle the names. 156 156 for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) { 157 if ( isPoly Val( (*retval)->get_type(), tyVars ) ) {157 if ( isPolyType( (*retval)->get_type(), tyVars ) ) { 158 158 name << "P"; 159 159 } else { … … 164 164 std::list< DeclarationWithType *> ¶mList = function->get_parameters(); 165 165 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 166 if ( isPoly Val( (*arg)->get_type(), tyVars ) ) {166 if ( isPolyType( (*arg)->get_type(), tyVars ) ) { 167 167 name << "P"; 168 168 } else { 169 name << "M"; 169 name << "M"; 170 170 } 171 171 } // for … … 181 181 } 182 182 183 Pass1::Pass1() 184 : useRetval( false ), tempNamer( "_temp" ) { 183 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 185 184 adapters.push(AdapterMap()); 186 185 } … … 194 193 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 195 194 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 196 name = typeInst->get_name(); 197 return true; 195 if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) { 196 if ( typeInst->get_name() == typeInst2->get_name() ) { 197 name = typeInst->get_name(); 198 return true; 199 } // if 200 } // if 198 201 } // if 199 202 } // if … … 231 234 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 232 235 retval = functionDecl->get_functionType()->get_returnVals().front(); 233 236 234 237 // give names to unnamed return values 235 238 if ( retval->get_name() == "" ) { … … 238 241 } // if 239 242 } // if 240 243 241 244 FunctionType *functionType = functionDecl->get_functionType(); 242 245 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); … … 263 266 264 267 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 265 268 266 269 scopeTyVars = oldtyVars; 267 270 assignOps = oldassignOps; … … 279 282 280 283 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 281 /// std::cerr << "add " << typeDecl->get_name() << "\n";282 284 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 283 285 return Mutator::mutate( typeDecl ); … … 305 307 306 308 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 309 // pass size/align for type variables 307 310 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { 308 311 ResolvExpr::EqvClass eqvClass; … … 313 316 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 314 317 arg++; 318 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 319 arg++; 315 320 } else { 316 321 throw SemanticError( "unbound type variable in application ", appExpr ); … … 318 323 } // if 319 324 } // for 325 326 // add size/align for generic types to parameter list 327 //assert( ! appExpr->get_function()->get_results().empty() ); 328 if ( appExpr->get_function()->get_results().empty() ) return; 329 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); 330 assert( funcType ); 331 332 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 333 std::list< Expression* >::const_iterator fnArg = arg; 334 std::set< std::string > seenTypes; //< names for generic types we've seen 335 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 336 Type *parmType = (*fnParm)->get_type(); 337 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) { 338 std::string sizeName = sizeofName( parmType ); 339 if ( seenTypes.count( sizeName ) ) continue; 340 341 assert( ! (*fnArg)->get_results().empty() ); 342 Type *argType = (*fnArg)->get_results().front(); 343 arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) ); 344 arg++; 345 arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) ); 346 arg++; 347 348 seenTypes.insert( sizeName ); 349 } 350 } 320 351 } 321 352 … … 326 357 } 327 358 328 TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {329 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {330 if ( env ) {331 if ( Type *newType = env->lookup( typeInst->get_name() ) ) {332 return isPolyType( newType, env, tyVars );333 } // if334 } // if335 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {336 return typeInst;337 } else {338 return 0;339 } // if340 } else {341 return 0;342 } // if343 }344 345 359 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 346 if ( useRetval ) { 347 assert( retval ); 348 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 349 arg++; 350 } else { 351 ObjectDecl *newObj = makeTemporary( retType->clone() ); 352 Expression *paramExpr = new VariableExpr( newObj ); 353 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) { 354 paramExpr = new AddressExpr( paramExpr ); 355 } // if 356 arg = appExpr->get_args().insert( arg, paramExpr ); 357 arg++; 358 /// stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) ); 359 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 360 commaExpr->set_env( appExpr->get_env() ); 361 appExpr->set_env( 0 ); 362 return commaExpr; 363 } // if 364 return appExpr; 360 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 361 // if ( useRetval ) { 362 // assert( retval ); 363 // arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 364 // arg++; 365 // } else { 366 367 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 368 // using a comma expression. Possibly change comma expression into statement expression "{}" for multiple 369 // return values. 370 ObjectDecl *newObj = makeTemporary( retType->clone() ); 371 Expression *paramExpr = new VariableExpr( newObj ); 372 // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the 373 // temporary is already boxed and can be used directly. 374 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) { 375 paramExpr = new AddressExpr( paramExpr ); 376 } // if 377 arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call 378 arg++; 379 // Build a comma expression to call the function and emulate a normal return. 380 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 381 commaExpr->set_env( appExpr->get_env() ); 382 appExpr->set_env( 0 ); 383 return commaExpr; 384 // } // if 385 // return appExpr; 365 386 } 366 387 … … 377 398 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 378 399 Expression *ret = appExpr; 379 if ( ! function->get_returnVals().empty() && isPoly Val( function->get_returnVals().front()->get_type(), tyVars ) ) {400 if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 380 401 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg ); 381 402 } // if … … 385 406 appExpr->get_args().push_front( appExpr->get_function() ); 386 407 appExpr->set_function( new NameExpr( adapterName ) ); 387 408 388 409 return ret; 389 410 } … … 391 412 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 392 413 assert( ! arg->get_results().empty() ); 393 // /if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {414 // if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) { 394 415 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param ); 395 416 if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) { … … 411 432 } // if 412 433 } // if 413 // /}434 // } 414 435 } 415 436 … … 428 449 429 450 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 430 /// std::cout << "function is ";431 /// function->print( std::cout );432 451 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) { 433 /// std::cout << "parameter is ";434 /// (*param)->print( std::fcout );435 /// std::cout << std::endl << "argument is ";436 /// (*arg)->print( std::cout );437 452 assert( arg != appExpr->get_args().end() ); 438 453 addCast( *arg, (*param)->get_type(), exprTyVars ); … … 469 484 // actually make the adapter type 470 485 FunctionType *adapter = adaptee->clone(); 471 if ( ! adapter->get_returnVals().empty() && isPoly Val( adapter->get_returnVals().front()->get_type(), tyVars ) ) {486 if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) { 472 487 makeRetParm( adapter ); 473 488 } // if … … 479 494 assert( param ); 480 495 assert( arg ); 481 /// std::cout << "arg type is "; 482 /// arg->get_type()->print( std::cout ); 483 /// std::cout << "param type is "; 484 /// param->get_type()->print( std::cout ); 485 /// std::cout << " tyVars are: "; 486 /// printTyVarMap( std::cout, tyVars ); 487 if ( isPolyVal( realParam->get_type(), tyVars ) ) { 488 /// if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 489 /// return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 490 /// } else { 496 if ( isPolyType( realParam->get_type(), tyVars ) ) { 497 // if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 498 // return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 499 // } else { 491 500 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 492 501 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); … … 495 504 return deref; 496 505 } // if 497 // /}506 // } 498 507 } // if 499 508 return new VariableExpr( param ); … … 520 529 ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) ); 521 530 Statement *bodyStmt; 522 531 523 532 std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin(); 524 533 std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin(); … … 534 543 } // for 535 544 } // for 536 545 537 546 std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin(); 538 547 std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin(); … … 542 551 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 543 552 bodyStmt = new ExprStmt( noLabels, adapteeApp ); 544 } else if ( isPoly Val( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {553 } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 545 554 if ( (*param)->get_name() == "" ) { 546 555 (*param)->set_name( "_ret" ); … … 591 600 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 592 601 adaptersDone.insert( adaptersDone.begin(), mangleName ); 593 602 594 603 // apply substitution to type variables to figure out what the adapter's type should look like 595 604 assert( env ); 596 605 env->apply( realFunction ); 597 mangleName = SymTab::Mangler::mangle( realFunction ); 606 mangleName = SymTab::Mangler::mangle( realFunction ); 598 607 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 599 608 … … 614 623 } // passAdapters 615 624 616 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 617 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 618 return isPolyType( ptr->get_base(), env, tyVars ); 619 } else if ( env ) { 620 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 621 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 622 return isPolyPtr( newType, env, tyVars ); 623 } // if 624 } // if 625 } // if 626 return 0; 627 } 628 629 TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 630 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 631 return isPolyPtr( ptr->get_base(), env, tyVars ); 632 } else if ( env ) { 633 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 634 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 635 return isPolyPtrPtr( newType, env, tyVars ); 636 } // if 637 } // if 638 } // if 639 return 0; 640 } 641 642 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) { 625 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) { 643 626 NameExpr *opExpr; 644 627 if ( isIncr ) { … … 653 636 addAssign->get_args().push_back( appExpr->get_args().front() ); 654 637 } // if 655 addAssign->get_args().push_back( new NameExpr( polyName) );638 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) ); 656 639 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 657 640 if ( appExpr->get_env() ) { … … 670 653 assert( ! appExpr->get_results().empty() ); 671 654 assert( appExpr->get_args().size() == 2 ); 672 Type InstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars);673 Type InstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars);674 assert( ! typeInst1 || ! typeInst2 );// the arguments cannot both be polymorphic pointers655 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 656 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 657 assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers 675 658 UntypedExpr *ret = 0; 676 if ( typeInst1 || typeInst2 ) { // one of the arguments is a polymorphic pointer659 if ( baseType1 || baseType2 ) { // one of the arguments is a polymorphic pointer 677 660 ret = new UntypedExpr( new NameExpr( "?+?" ) ); 678 661 } // if 679 if ( typeInst1 ) {662 if ( baseType1 ) { 680 663 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 681 664 multiply->get_args().push_back( appExpr->get_args().back() ); 682 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );665 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 683 666 ret->get_args().push_back( appExpr->get_args().front() ); 684 667 ret->get_args().push_back( multiply ); 685 } else if ( typeInst2 ) {668 } else if ( baseType2 ) { 686 669 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 687 670 multiply->get_args().push_back( appExpr->get_args().front() ); 688 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );671 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 689 672 ret->get_args().push_back( multiply ); 690 673 ret->get_args().push_back( appExpr->get_args().back() ); 691 674 } // if 692 if ( typeInst1 || typeInst2 ) {675 if ( baseType1 || baseType2 ) { 693 676 ret->get_results().push_front( appExpr->get_results().front()->clone() ); 694 677 if ( appExpr->get_env() ) { … … 703 686 assert( ! appExpr->get_results().empty() ); 704 687 assert( ! appExpr->get_args().empty() ); 705 if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars) ) {688 if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) { 706 689 Expression *ret = appExpr->get_args().front(); 707 690 delete ret->get_results().front(); … … 718 701 assert( ! appExpr->get_results().empty() ); 719 702 assert( appExpr->get_args().size() == 1 ); 720 if ( Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars) ) {703 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 721 704 Type *tempType = appExpr->get_results().front()->clone(); 722 705 if ( env ) { … … 732 715 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() ); 733 716 } // if 734 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );717 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "?++" ) ); 735 718 return new CommaExpr( firstComma, tempExpr ); 736 719 } // if … … 738 721 assert( ! appExpr->get_results().empty() ); 739 722 assert( appExpr->get_args().size() == 1 ); 740 if ( Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars) ) {741 return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );723 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 724 return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" ); 742 725 } // if 743 726 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 744 727 assert( ! appExpr->get_results().empty() ); 745 728 assert( appExpr->get_args().size() == 2 ); 746 Type InstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars);747 Type InstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars);748 if ( typeInst1 && typeInst2 ) {729 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 730 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 731 if ( baseType1 && baseType2 ) { 749 732 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 750 733 divide->get_args().push_back( appExpr ); 751 divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );734 divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 752 735 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 753 736 if ( appExpr->get_env() ) { … … 756 739 } // if 757 740 return divide; 758 } else if ( typeInst1 ) {741 } else if ( baseType1 ) { 759 742 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 760 743 multiply->get_args().push_back( appExpr->get_args().back() ); 761 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );744 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 762 745 appExpr->get_args().back() = multiply; 763 } else if ( typeInst2 ) {746 } else if ( baseType2 ) { 764 747 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 765 748 multiply->get_args().push_back( appExpr->get_args().front() ); 766 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );749 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 767 750 appExpr->get_args().front() = multiply; 768 751 } // if … … 770 753 assert( ! appExpr->get_results().empty() ); 771 754 assert( appExpr->get_args().size() == 2 ); 772 Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars);773 if ( typeInst) {755 Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ); 756 if ( baseType ) { 774 757 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 775 758 multiply->get_args().push_back( appExpr->get_args().back() ); 776 multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );759 multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) ); 777 760 appExpr->get_args().back() = multiply; 778 761 } // if … … 795 778 mutateAll( appExpr->get_args(), *this ); 796 779 useRetval = oldUseRetval; 797 780 798 781 assert( ! appExpr->get_function()->get_results().empty() ); 799 782 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); … … 801 784 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 802 785 assert( function ); 803 786 804 787 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) { 805 788 return newExpr; 806 789 } // if 807 790 808 791 Expression *ret = appExpr; 809 792 810 793 std::list< Expression *>::iterator arg = appExpr->get_args().begin(); 811 794 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 812 795 813 796 std::string typeName; 814 797 if ( isPolyRet( function, typeName ) ) { … … 824 807 } // if 825 808 arg = appExpr->get_args().begin(); 826 809 827 810 TyVarMap exprTyVars; 828 811 makeTyVarMap( function, exprTyVars ); 829 812 830 813 passTypeVars( appExpr, arg, exprTyVars ); 831 814 addInferredParams( appExpr, function, arg, exprTyVars ); 832 815 833 816 arg = paramBegin; 834 817 835 818 boxParams( appExpr, function, arg, exprTyVars ); 836 819 … … 841 824 842 825 Expression *Pass1::mutate( UntypedExpr *expr ) { 843 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars) ) {826 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 844 827 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 845 828 if ( name->get_name() == "*?" ) { … … 856 839 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 857 840 assert( ! addrExpr->get_arg()->get_results().empty() ); 841 842 bool needs = false; 843 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 844 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 845 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 846 if ( name->get_name() == "*?" ) { 847 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 848 assert( ! appExpr->get_function()->get_results().empty() ); 849 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); 850 assert( pointer ); 851 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 852 assert( function ); 853 needs = needsAdapter( function, scopeTyVars ); 854 } // if 855 } // if 856 } // if 857 } // if 858 } // if 858 859 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 859 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars )) {860 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) { 860 861 Expression *ret = addrExpr->get_arg(); 861 862 delete ret->get_results().front(); … … 869 870 } 870 871 871 Statement * Pass1::mutate(ReturnStmt *retStmt) { 872 // by this point, a cast expr on a polymorphic return value is redundant 873 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 874 retStmt->set_expr( castExpr->get_arg() ); 875 retStmt->get_expr()->set_env( castExpr->get_env() ); 876 castExpr->set_env( 0 ); 877 castExpr->set_arg( 0 ); 878 delete castExpr; 879 } 880 if ( retval && retStmt->get_expr() ) { 881 assert( ! retStmt->get_expr()->get_results().empty() ); 882 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 883 /// retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 884 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 885 assert( typeInst ); 886 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 887 if ( assignIter == assignOps.end() ) { 888 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() ); 889 } // if 890 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 891 Expression *retParm = new NameExpr( retval->get_name() ); 892 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 893 assignExpr->get_args().push_back( retParm ); 894 assignExpr->get_args().push_back( retStmt->get_expr() ); 895 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 896 } else { 897 useRetval = true; 898 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) ); 899 useRetval = false; 872 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 873 if ( retval && returnStmt->get_expr() ) { 874 assert( ! returnStmt->get_expr()->get_results().empty() ); 875 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 876 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) { 877 // by this point, a cast expr on a polymorphic return value is redundant 878 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) { 879 returnStmt->set_expr( castExpr->get_arg() ); 880 returnStmt->get_expr()->set_env( castExpr->get_env() ); 881 castExpr->set_env( 0 ); 882 castExpr->set_arg( 0 ); 883 delete castExpr; 884 } //while 885 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 886 assert( typeInst ); 887 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 888 if ( assignIter == assignOps.end() ) { 889 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 900 890 } // if 901 retStmt->set_expr( 0 ); 891 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 892 Expression *retParm = new NameExpr( retval->get_name() ); 893 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 894 assignExpr->get_args().push_back( retParm ); 895 assignExpr->get_args().push_back( returnStmt->get_expr() ); 896 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 897 // } else { 898 // useRetval = true; 899 // stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) ); 900 // useRetval = false; 901 // } // if 902 returnStmt->set_expr( 0 ); 902 903 } else { 903 ret Stmt->set_expr( mutateExpression( retStmt->get_expr() ) );904 } // if 905 return ret Stmt;904 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) ); 905 } // if 906 return returnStmt; 906 907 } 907 908 … … 909 910 TyVarMap oldtyVars = scopeTyVars; 910 911 makeTyVarMap( pointerType, scopeTyVars ); 911 912 912 913 Type *ret = Mutator::mutate( pointerType ); 913 914 914 915 scopeTyVars = oldtyVars; 915 916 return ret; … … 919 920 TyVarMap oldtyVars = scopeTyVars; 920 921 makeTyVarMap( functionType, scopeTyVars ); 921 922 922 923 Type *ret = Mutator::mutate( functionType ); 923 924 924 925 scopeTyVars = oldtyVars; 925 926 return ret; … … 936 937 937 938 ////////////////////////////////////////// Pass2 //////////////////////////////////////////////////// 938 939 Pass2::Pass2() {}940 939 941 940 void Pass2::addAdapters( FunctionType *functionType ) { … … 956 955 } 957 956 } 958 // /deleteAll( functions );957 // deleteAll( functions ); 959 958 } 960 959 … … 990 989 TyVarMap oldtyVars = scopeTyVars; 991 990 makeTyVarMap( pointerType, scopeTyVars ); 992 991 993 992 Type *ret = Mutator::mutate( pointerType ); 994 993 995 994 scopeTyVars = oldtyVars; 996 995 return ret; … … 1000 999 TyVarMap oldtyVars = scopeTyVars; 1001 1000 makeTyVarMap( funcType, scopeTyVars ); 1002 1001 1002 // move polymorphic return type to parameter list 1003 1003 std::string typeName; 1004 1004 if ( isPolyRet( funcType, typeName ) ) { … … 1008 1008 funcType->get_returnVals().pop_front(); 1009 1009 } 1010 1010 1011 // add size/align and assertions for type parameters to parameter list 1011 1012 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 1012 1013 std::list< DeclarationWithType *> inferredParams; 1013 ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );1014 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 1014 1015 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1015 1016 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1016 ObjectDecl * thisParm;1017 // add all size parameters to parameter list1017 ObjectDecl *sizeParm, *alignParm; 1018 // add all size and alignment parameters to parameter list 1018 1019 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1019 thisParm = newObj->clone(); 1020 thisParm->set_name( (*tyParm)->get_name() ); 1021 last = funcType->get_parameters().insert( last, thisParm ); 1020 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 1021 1022 sizeParm = newObj.clone(); 1023 sizeParm->set_name( sizeofName( &parmType ) ); 1024 last = funcType->get_parameters().insert( last, sizeParm ); 1025 ++last; 1026 1027 alignParm = newObj.clone(); 1028 alignParm->set_name( alignofName( &parmType ) ); 1029 last = funcType->get_parameters().insert( last, alignParm ); 1022 1030 ++last; 1023 1031 } … … 1029 1037 (*tyParm)->get_assertions().clear(); 1030 1038 } 1031 delete newObj; 1039 1040 // add size/align for generic types to parameter list 1041 std::set< std::string > seenTypes; //< sizeofName for generic types we've seen 1042 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1043 Type *parmType = (*fnParm)->get_type(); 1044 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) { 1045 std::string sizeName = sizeofName( parmType ); 1046 if ( seenTypes.count( sizeName ) ) continue; 1047 1048 ObjectDecl *sizeParm, *alignParm; 1049 sizeParm = newObj.clone(); 1050 sizeParm->set_name( sizeName ); 1051 last = funcType->get_parameters().insert( last, sizeParm ); 1052 ++last; 1053 1054 alignParm = newObj.clone(); 1055 alignParm->set_name( alignofName( parmType ) ); 1056 last = funcType->get_parameters().insert( last, alignParm ); 1057 ++last; 1058 1059 seenTypes.insert( sizeName ); 1060 } 1061 } 1062 1063 // splice assertion parameters into parameter list 1032 1064 funcType->get_parameters().splice( last, inferredParams ); 1033 1065 addAdapters( funcType ); 1034 1066 mutateAll( funcType->get_returnVals(), *this ); 1035 1067 mutateAll( funcType->get_parameters(), *this ); 1036 1068 1037 1069 scopeTyVars = oldtyVars; 1038 1070 return funcType; … … 1045 1077 TyVarMap oldtyVars = scopeTyVars; 1046 1078 makeTyVarMap( type, scopeTyVars ); 1047 1079 1048 1080 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1049 1081 ScrubTyVars::scrub( decl, scopeTyVars ); … … 1081 1113 TyVarMap oldtyVars = scopeTyVars; 1082 1114 makeTyVarMap( pointerType, scopeTyVars ); 1083 1115 1084 1116 Type *ret = Mutator::mutate( pointerType ); 1085 1117 1086 1118 scopeTyVars = oldtyVars; 1087 1119 return ret; … … 1091 1123 TyVarMap oldtyVars = scopeTyVars; 1092 1124 makeTyVarMap( functionType, scopeTyVars ); 1093 1125 1094 1126 Type *ret = Mutator::mutate( functionType ); 1095 1127 1096 1128 scopeTyVars = oldtyVars; 1097 1129 return ret; … … 1100 1132 Statement *Pass3::mutate( DeclStmt *declStmt ) { 1101 1133 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1102 if ( isPoly Val( objectDecl->get_type(), scopeTyVars ) ) {1134 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1103 1135 // change initialization of a polymorphic value object 1104 1136 // to allocate storage with alloca 1105 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() ); 1106 assert( typeInst ); 1137 Type *declType = objectDecl->get_type(); 1107 1138 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1108 alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );1139 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) ); 1109 1140 1110 1141 delete objectDecl->get_init();
Note: See TracChangeset
for help on using the changeset viewer.