Changes in src/GenPoly/Specialize.cc [fc72845d:ae4038d]
- File:
-
- 1 edited
-
src/GenPoly/Specialize.cc (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Specialize.cc
rfc72845d rae4038d 14 14 // 15 15 16 #include <cassert> // for assert, assertf 17 #include <iterator> // for back_insert_iterator, back_i... 18 #include <map> // for _Rb_tree_iterator, _Rb_tree_... 19 #include <memory> // for unique_ptr 20 #include <string> // for string 21 #include <tuple> // for get 22 #include <utility> // for pair 23 24 #include "Common/PassVisitor.h" 25 #include "Common/SemanticError.h" // for SemanticError 26 #include "Common/UniqueName.h" // for UniqueName 27 #include "Common/utility.h" // for group_iterate 28 #include "GenPoly.h" // for getFunctionType 29 #include "InitTweak/InitTweak.h" // for isIntrinsicCallExpr 30 #include "Parser/LinkageSpec.h" // for C 31 #include "ResolvExpr/FindOpenVars.h" // for findOpenVars 32 #include "ResolvExpr/TypeEnvironment.h" // for OpenVarSet, AssertionSet 16 #include <cassert> 17 33 18 #include "Specialize.h" 34 #include "SynTree/Attribute.h" // for Attribute 35 #include "SynTree/Declaration.h" // for FunctionDecl, DeclarationWit... 36 #include "SynTree/Expression.h" // for ApplicationExpr, Expression 37 #include "SynTree/Label.h" // for Label, noLabels 38 #include "SynTree/Mutator.h" // for mutateAll 39 #include "SynTree/Statement.h" // for CompoundStmt, DeclStmt, Expr... 40 #include "SynTree/Type.h" // for FunctionType, TupleType, Type 41 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 42 #include "SynTree/Visitor.h" // for Visitor 19 #include "GenPoly.h" 20 #include "PolyMutator.h" 21 22 #include "Parser/ParseNode.h" 23 24 #include "SynTree/Expression.h" 25 #include "SynTree/Statement.h" 26 #include "SynTree/Type.h" 27 #include "SynTree/Attribute.h" 28 #include "SynTree/TypeSubstitution.h" 29 #include "SynTree/Mutator.h" 30 #include "ResolvExpr/FindOpenVars.h" 31 #include "Common/UniqueName.h" 32 #include "Common/utility.h" 33 #include "InitTweak/InitTweak.h" 34 #include "Tuples/Tuples.h" 43 35 44 36 namespace GenPoly { 45 struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> { 46 Expression * postmutate( ApplicationExpr *applicationExpr ); 47 Expression * postmutate( AddressExpr *castExpr ); 48 Expression * postmutate( CastExpr *castExpr ); 37 class Specialize final : public PolyMutator { 38 public: 39 using PolyMutator::mutate; 40 virtual Expression * mutate( ApplicationExpr *applicationExpr ) override; 41 virtual Expression * mutate( AddressExpr *castExpr ) override; 42 virtual Expression * mutate( CastExpr *castExpr ) override; 43 // virtual Expression * mutate( LogicalExpr *logicalExpr ); 44 // virtual Expression * mutate( ConditionalExpr *conditionalExpr ); 45 // virtual Expression * mutate( CommaExpr *commaExpr ); 49 46 50 47 void handleExplicitParams( ApplicationExpr *appExpr ); … … 126 123 // conversion of 0 (null) to function type does not require tuple specialization 127 124 if ( dynamic_cast< ZeroType * >( actualType ) ) return false; 128 FunctionType * aftype = getFunctionType( actualType ->stripReferences());129 assertf( aftype, "formal type is a function type, but actual type is not : %s", toString( actualType ).c_str());125 FunctionType * aftype = getFunctionType( actualType ); 126 assertf( aftype, "formal type is a function type, but actual type is not." ); 130 127 // Can't tuple specialize if parameter sizes deeply-differ. 131 128 if ( functionParameterSize( fftype ) != functionParameterSize( aftype ) ) return false; … … 199 196 } 200 197 201 struct EnvTrimmer {198 struct EnvTrimmer : public Visitor { 202 199 TypeSubstitution * env, * newEnv; 203 200 EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 204 v oid previsit( TypeDecl * tyDecl ) {201 virtual void visit( TypeDecl * tyDecl ) { 205 202 // transfer known bindings for seen type variables 206 if ( Type * t = env->lookup( tyDecl-> name) ) {207 newEnv->add( tyDecl-> name, t );203 if ( Type * t = env->lookup( tyDecl->get_name() ) ) { 204 newEnv->add( tyDecl->get_name(), t ); 208 205 } 209 206 } … … 214 211 if ( env ) { 215 212 TypeSubstitution * newEnv = new TypeSubstitution(); 216 PassVisitor<EnvTrimmer>trimmer( env, newEnv );213 EnvTrimmer trimmer( env, newEnv ); 217 214 expr->accept( trimmer ); 218 215 return newEnv; … … 272 269 std::string oldParamPrefix = paramPrefix; 273 270 paramPrefix += "p"; 274 // save stmtsToAdd Beforein oldStmts271 // save stmtsToAdd in oldStmts 275 272 std::list< Statement* > oldStmts; 276 oldStmts.splice( oldStmts.end(), stmtsToAdd Before);277 appExpr->acceptMutator( *visitor );273 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 274 mutate( appExpr ); 278 275 paramPrefix = oldParamPrefix; 279 276 // write any statements added for recursive specializations into the thunk body 280 thunkFunc-> statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore);281 // restore oldStmts into stmtsToAdd Before282 stmtsToAdd Before.splice( stmtsToAddBefore.end(), oldStmts );277 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 278 // restore oldStmts into stmtsToAdd 279 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 283 280 284 281 // add return (or valueless expression) to the thunk 285 282 Statement *appStmt; 286 if ( funType-> returnVals.empty() ) {283 if ( funType->get_returnVals().empty() ) { 287 284 appStmt = new ExprStmt( noLabels, appExpr ); 288 285 } else { 289 286 appStmt = new ReturnStmt( noLabels, appExpr ); 290 287 } // if 291 thunkFunc-> statements->kids.push_back( appStmt );288 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 292 289 293 290 // add thunk definition to queue of statements to add 294 stmtsToAdd Before.push_back( new DeclStmt( noLabels, thunkFunc ) );291 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 295 292 // return address of thunk function as replacement expression 296 293 return new AddressExpr( new VariableExpr( thunkFunc ) ); … … 299 296 void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) { 300 297 // create thunks for the explicit parameters 301 assert( appExpr-> function->result);302 FunctionType *function = getFunctionType( appExpr-> function->result);298 assert( appExpr->get_function()->has_result() ); 299 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() ); 303 300 assert( function ); 304 301 std::list< DeclarationWithType* >::iterator formal; 305 302 std::list< Expression* >::iterator actual; 306 303 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 307 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() ); 308 } 309 } 310 311 Expression * Specialize::postmutate( ApplicationExpr *appExpr ) { 304 *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() ); 305 } 306 } 307 308 Expression * Specialize::mutate( ApplicationExpr *appExpr ) { 309 appExpr->get_function()->acceptMutator( *this ); 310 mutateAll( appExpr->get_args(), *this ); 311 312 312 if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) { 313 313 // create thunks for the inferred parameters … … 323 323 } 324 324 325 Expression * Specialize::postmutate( AddressExpr *addrExpr ) { 326 assert( addrExpr->result ); 327 addrExpr->set_arg( doSpecialization( addrExpr->result, addrExpr->arg ) ); 325 Expression * Specialize::mutate( AddressExpr *addrExpr ) { 326 addrExpr->get_arg()->acceptMutator( *this ); 327 assert( addrExpr->has_result() ); 328 addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) ); 328 329 return addrExpr; 329 330 } 330 331 331 Expression * Specialize::postmutate( CastExpr *castExpr ) { 332 if ( castExpr->result->isVoid() ) { 332 Expression * Specialize::mutate( CastExpr *castExpr ) { 333 castExpr->get_arg()->acceptMutator( *this ); 334 if ( castExpr->get_result()->isVoid() ) { 333 335 // can't specialize if we don't have a return value 334 336 return castExpr; 335 337 } 336 Expression *specialized = doSpecialization( castExpr-> result, castExpr->arg);337 if ( specialized != castExpr-> arg) {338 Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() ); 339 if ( specialized != castExpr->get_arg() ) { 338 340 // assume here that the specialization incorporates the cast 339 341 return specialized; … … 343 345 } 344 346 347 // Removing these for now. Richard put these in for some reason, but it's not clear why. 348 // In particular, copy constructors produce a comma expression, and with this code the parts 349 // of that comma expression are not specialized, which causes problems. 350 351 // Expression * Specialize::mutate( LogicalExpr *logicalExpr ) { 352 // return logicalExpr; 353 // } 354 355 // Expression * Specialize::mutate( ConditionalExpr *condExpr ) { 356 // return condExpr; 357 // } 358 359 // Expression * Specialize::mutate( CommaExpr *commaExpr ) { 360 // return commaExpr; 361 // } 362 345 363 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 346 PassVisitor<Specialize>spec;364 Specialize spec; 347 365 mutateAll( translationUnit, spec ); 348 366 }
Note:
See TracChangeset
for help on using the changeset viewer.