Changeset 01aeade for translator/GenPoly/Specialize.cc
- Timestamp:
- May 19, 2015, 7:57:09 AM (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:
- a08ba92
- Parents:
- 51587aa
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
translator/GenPoly/Specialize.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // Specialize.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:55:09 2015 13 // Update Count : 4 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: Specialize.cc,v 1.4 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 16 #include <cassert> … … 35 29 #include "utility.h" 36 30 31 namespace GenPoly { 32 const std::list<Label> noLabels; 37 33 38 namespace GenPoly { 34 class Specialize : public PolyMutator { 35 public: 36 Specialize( std::string paramPrefix = "_p" ); 39 37 40 const std::list<Label> noLabels; 38 virtual Expression * mutate( ApplicationExpr *applicationExpr ); 39 virtual Expression * mutate( AddressExpr *castExpr ); 40 virtual Expression * mutate( CastExpr *castExpr ); 41 virtual Expression * mutate( LogicalExpr *logicalExpr ); 42 virtual Expression * mutate( ConditionalExpr *conditionalExpr ); 43 virtual Expression * mutate( CommaExpr *commaExpr ); 41 44 42 class Specialize : public PolyMutator 43 { 44 public: 45 Specialize( std::string paramPrefix = "_p" ); 46 47 virtual Expression* mutate(ApplicationExpr *applicationExpr); 48 virtual Expression* mutate(AddressExpr *castExpr); 49 virtual Expression* mutate(CastExpr *castExpr); 50 virtual Expression* mutate(LogicalExpr *logicalExpr); 51 virtual Expression* mutate(ConditionalExpr *conditionalExpr); 52 virtual Expression* mutate(CommaExpr *commaExpr); 45 private: 46 Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 ); 47 void handleExplicitParams( ApplicationExpr *appExpr ); 53 48 54 private: 55 Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 ); 56 void handleExplicitParams( ApplicationExpr *appExpr ); 57 58 UniqueName thunkNamer; 59 std::string paramPrefix; 60 }; 49 UniqueName thunkNamer; 50 std::string paramPrefix; 51 }; 61 52 62 void 63 convertSpecializations( std::list< Declaration* >& translationUnit ) 64 { 65 Specialize specializer; 66 mutateAll( translationUnit, specializer ); 67 } 53 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 54 Specialize specializer; 55 mutateAll( translationUnit, specializer ); 56 } 68 57 69 Specialize::Specialize( std::string paramPrefix ) 70 : thunkNamer( "_thunk" ), paramPrefix( paramPrefix ) 71 { 72 } 58 Specialize::Specialize( std::string paramPrefix ) 59 : thunkNamer( "_thunk" ), paramPrefix( paramPrefix ) { 60 } 73 61 74 bool 75 needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) 76 { 77 if ( env ) { 78 using namespace ResolvExpr; 79 OpenVarSet openVars, closedVars; 80 AssertionSet need, have; 81 findOpenVars( formalType, openVars, closedVars, need, have, false ); 82 findOpenVars( actualType, openVars, closedVars, need, have, true ); 83 for ( OpenVarSet::const_iterator openVar = openVars.begin(); openVar != openVars.end(); ++openVar ) { 84 Type *boundType = env->lookup( openVar->first ); 85 if ( ! boundType ) continue; 86 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( boundType ) ) { 87 if ( closedVars.find( typeInst->get_name() ) == closedVars.end() ) { 88 return true; 89 } 90 } else { 91 return true; 92 } 93 } 94 return false; 95 } else { 96 return false; 97 } 98 } 62 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) { 63 if ( env ) { 64 using namespace ResolvExpr; 65 OpenVarSet openVars, closedVars; 66 AssertionSet need, have; 67 findOpenVars( formalType, openVars, closedVars, need, have, false ); 68 findOpenVars( actualType, openVars, closedVars, need, have, true ); 69 for ( OpenVarSet::const_iterator openVar = openVars.begin(); openVar != openVars.end(); ++openVar ) { 70 Type *boundType = env->lookup( openVar->first ); 71 if ( ! boundType ) continue; 72 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( boundType ) ) { 73 if ( closedVars.find( typeInst->get_name() ) == closedVars.end() ) { 74 return true; 75 } // if 76 } else { 77 return true; 78 } // if 79 } // for 80 return false; 81 } else { 82 return false; 83 } // if 84 } 99 85 100 Expression* 101 Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) 102 { 103 if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) { 104 PointerType *ptrType; 105 FunctionType *funType; 106 if ( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) { 107 FunctionType *newType = funType->clone(); 108 if ( env ) { 109 TypeSubstitution newEnv( *env ); 110 // it is important to replace only occurrences of type variables that occur free in the 111 // thunk's type 112 newEnv.applyFree( newType ); 113 } 114 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false ); 115 thunkFunc->fixUniqueId(); 116 117 UniqueName paramNamer( paramPrefix ); 118 ApplicationExpr *appExpr = new ApplicationExpr( actual ); 119 for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) { 120 (*param)->set_name( paramNamer.newName() ); 121 appExpr->get_args().push_back( new VariableExpr( *param ) ); 122 } 123 appExpr->set_env( maybeClone( env ) ); 124 if ( inferParams ) { 125 appExpr->get_inferParams() = *inferParams; 126 } 127 128 // handle any specializations that may still be present 129 std::string oldParamPrefix = paramPrefix; 130 paramPrefix += "p"; 131 std::list< Statement* > oldStmts; 132 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 133 handleExplicitParams( appExpr ); 134 paramPrefix = oldParamPrefix; 135 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 136 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 137 138 Statement *appStmt; 139 if ( funType->get_returnVals().empty() ) { 140 appStmt = new ExprStmt( noLabels, appExpr ); 141 } else { 142 appStmt = new ReturnStmt( noLabels, appExpr ); 143 } 144 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 145 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 146 return new AddressExpr( new VariableExpr( thunkFunc ) ); 147 } else { 148 return actual; 149 } 150 } else { 151 return actual; 152 } 153 } 86 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 87 if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) { 88 PointerType *ptrType; 89 FunctionType *funType; 90 if ( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) { 91 FunctionType *newType = funType->clone(); 92 if ( env ) { 93 TypeSubstitution newEnv( *env ); 94 // it is important to replace only occurrences of type variables that occur free in the 95 // thunk's type 96 newEnv.applyFree( newType ); 97 } // if 98 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false ); 99 thunkFunc->fixUniqueId(); 154 100 155 void 156 Specialize::handleExplicitParams( ApplicationExpr *appExpr ) 157 { 158 // create thunks for the explicit parameters 159 assert( ! appExpr->get_function()->get_results().empty() ); 160 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 161 assert( pointer ); 162 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 163 std::list< DeclarationWithType* >::iterator formal; 164 std::list< Expression* >::iterator actual; 165 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 166 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() ); 167 } 168 } 101 UniqueName paramNamer( paramPrefix ); 102 ApplicationExpr *appExpr = new ApplicationExpr( actual ); 103 for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) { 104 (*param )->set_name( paramNamer.newName() ); 105 appExpr->get_args().push_back( new VariableExpr( *param ) ); 106 } // for 107 appExpr->set_env( maybeClone( env ) ); 108 if ( inferParams ) { 109 appExpr->get_inferParams() = *inferParams; 110 } // if 169 111 170 Expression* 171 Specialize::mutate(ApplicationExpr *appExpr) 172 { 173 appExpr->get_function()->acceptMutator( *this ); 174 mutateAll( appExpr->get_args(), *this ); 175 176 // create thunks for the inferred parameters 177 for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) { 178 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &appExpr->get_inferParams() ); 179 } 180 181 handleExplicitParams(appExpr); 182 183 return appExpr; 184 } 112 // handle any specializations that may still be present 113 std::string oldParamPrefix = paramPrefix; 114 paramPrefix += "p"; 115 std::list< Statement* > oldStmts; 116 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 117 handleExplicitParams( appExpr ); 118 paramPrefix = oldParamPrefix; 119 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 120 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 185 121 186 Expression* 187 Specialize::mutate(AddressExpr *addrExpr) 188 { 189 addrExpr->get_arg()->acceptMutator( *this ); 190 addrExpr->set_arg( doSpecialization( addrExpr->get_results().front(), addrExpr->get_arg() ) ); 191 return addrExpr; 192 } 122 Statement *appStmt; 123 if ( funType->get_returnVals().empty() ) { 124 appStmt = new ExprStmt( noLabels, appExpr ); 125 } else { 126 appStmt = new ReturnStmt( noLabels, appExpr ); 127 } // if 128 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 129 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 130 return new AddressExpr( new VariableExpr( thunkFunc ) ); 131 } else { 132 return actual; 133 } // if 134 } else { 135 return actual; 136 } // if 137 } 193 138 194 Expression* 195 Specialize::mutate(CastExpr *castExpr) 196 { 197 castExpr->get_arg()->acceptMutator( *this ); 198 castExpr->set_arg( doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ) ); 199 return castExpr; 200 } 139 void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) { 140 // create thunks for the explicit parameters 141 assert( ! appExpr->get_function()->get_results().empty() ); 142 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 143 assert( pointer ); 144 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 145 std::list< DeclarationWithType* >::iterator formal; 146 std::list< Expression* >::iterator actual; 147 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 148 *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() ); 149 } 150 } 201 151 202 Expression* 203 Specialize::mutate(LogicalExpr *logicalExpr) 204 { 205 return logicalExpr; 206 } 152 Expression * Specialize::mutate( ApplicationExpr *appExpr ) { 153 appExpr->get_function()->acceptMutator( *this ); 154 mutateAll( appExpr->get_args(), *this ); 207 155 208 Expression* 209 Specialize::mutate(ConditionalExpr *condExpr) 210 { 211 return condExpr; 212 } 156 // create thunks for the inferred parameters 157 for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) { 158 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &appExpr->get_inferParams() ); 159 } 213 160 214 Expression* 215 Specialize::mutate(CommaExpr *commaExpr) 216 { 217 return commaExpr; 218 } 161 handleExplicitParams( appExpr ); 219 162 163 return appExpr; 164 } 165 166 Expression * Specialize::mutate( AddressExpr *addrExpr ) { 167 addrExpr->get_arg()->acceptMutator( *this ); 168 addrExpr->set_arg( doSpecialization( addrExpr->get_results().front(), addrExpr->get_arg() ) ); 169 return addrExpr; 170 } 171 172 Expression * Specialize::mutate( CastExpr *castExpr ) { 173 castExpr->get_arg()->acceptMutator( *this ); 174 castExpr->set_arg( doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ) ); 175 return castExpr; 176 } 177 178 Expression * Specialize::mutate( LogicalExpr *logicalExpr ) { 179 return logicalExpr; 180 } 181 182 Expression * Specialize::mutate( ConditionalExpr *condExpr ) { 183 return condExpr; 184 } 185 186 Expression * Specialize::mutate( CommaExpr *commaExpr ) { 187 return commaExpr; 188 } 220 189 } // namespace GenPoly 190 221 191 // Local Variables: // 222 192 // tab-width: 4 //
Note: See TracChangeset
for help on using the changeset viewer.