Changeset 05d47278 for src/GenPoly


Ignore:
Timestamp:
Jan 21, 2016, 4:35:33 PM (9 years ago)
Author:
Aaron Moss <a3moss@…>
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:
421edab
Parents:
bfebb6c5
Message:

First draft of member expressions by passed offset

Location:
src/GenPoly
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rbfebb6c5 r05d47278  
    2222
    2323#include "Box.h"
     24#include "InstantiateGeneric.h"
    2425#include "PolyMutator.h"
    2526#include "FindFunction.h"
     
    7071                        virtual void doEndScope();
    7172                  private:
     73                        /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it
     74                        Expression *makeOffsetArray( StructInstType *type );
     75                        /// passes extra type parameters into a polymorphic function application
    7276                        void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    7377                        /// wraps a function application with a new temporary for the out-parameter return value
     
    8892                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    8993                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     94                        /// Replaces intrinsic operator functions with their arithmetic desugaring
    9095                        Expression *handleIntrinsics( ApplicationExpr *appExpr );
     96                        /// Inserts a new temporary variable into the current scope with an auto-generated name
    9197                        ObjectDecl *makeTemporary( Type *type );
    9298
     
    117123                };
    118124
    119                 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
    120                 class Pass3 : public PolyMutator {
     125                /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
     126                class MemberExprFixer : public PolyMutator {
    121127                  public:
    122128                        template< typename DeclClass >
     
    129135                        virtual Type *mutate( PointerType *pointerType );
    130136                        virtual Type *mutate( FunctionType *funcType );
     137                        virtual Expression *mutate( MemberExpr *memberExpr );
     138                };
     139               
     140                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
     141                class Pass3 : public PolyMutator {
     142                  public:
     143                        template< typename DeclClass >
     144                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     145                        virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
     146                        virtual ObjectDecl *mutate( ObjectDecl *objectDecl );
     147                        virtual TypedefDecl *mutate( TypedefDecl *objectDecl );
     148                        virtual TypeDecl *mutate( TypeDecl *objectDecl );
     149                        virtual Type *mutate( PointerType *pointerType );
     150                        virtual Type *mutate( FunctionType *funcType );
    131151                  private:
    132152                };
     
    143163        }
    144164
     165        /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
     166        template< typename MutatorType >
     167        inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) {
     168                bool seenIntrinsic = false;
     169                SemanticError errors;
     170                for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     171                        try {
     172                                if ( *i ) {
     173                                        if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) {
     174                                                seenIntrinsic = true;
     175                                        } else if ( seenIntrinsic ) {
     176                                                seenIntrinsic = false; // break on this line when debugging for end of prelude
     177                                        }
     178                                       
     179                                        *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );
     180                                        assert( *i );
     181                                } // if
     182                        } catch( SemanticError &e ) {
     183                                errors.append( e );
     184                        } // try
     185                } // for
     186                if ( ! errors.isEmpty() ) {
     187                        throw errors;
     188                } // if
     189        }
     190
    145191        void box( std::list< Declaration *>& translationUnit ) {
    146192                Pass1 pass1;
    147193                Pass2 pass2;
     194                MemberExprFixer memberFixer;
    148195                Pass3 pass3;
    149                 mutateAll( translationUnit, pass1 );
    150                 mutateAll( translationUnit, pass2 );
    151                 mutateAll( translationUnit, pass3 );
     196                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     197                mutateTranslationUnit/*All*/( translationUnit, pass2 );
     198                instantiateGeneric( translationUnit );
     199                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
     200                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    152201        }
    153202
     
    269318                                        findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    270319                                } // for
     320                               
    271321                                AdapterMap & adapters = Pass1::adapters.top();
    272322                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     
    319369                }
    320370
     371                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
     372                        // make a new temporary array
     373                        Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     374                        ObjectDecl *arrayTemp = makeTemporary( new PointerType( Type::Qualifiers(), offsetType ) );
     375
     376                        // build initializer list for temporary
     377                        std::list< Initializer* > inits;
     378                        StructDecl *tyBase = ty->get_baseStruct();
     379                        for ( std::list< Declaration* >::const_iterator member = tyBase->get_members().begin(); member != tyBase->get_members().end(); ++member ) {
     380                                DeclarationWithType *memberDecl;
     381                                if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
     382                                        memberDecl = origMember->clone();
     383                                } else {
     384                                        memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
     385                                }
     386                                inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
     387                        }
     388                        arrayTemp->set_init( new ListInit( inits ) );
     389
     390                        // return variable pointing to temporary
     391                        return new VariableExpr( arrayTemp );
     392                }
     393               
    321394                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    322395                        // pass size/align for type variables
     
    338411
    339412                        // add size/align for generic types to parameter list
    340                         //assert( ! appExpr->get_function()->get_results().empty() );
    341413                        if ( appExpr->get_function()->get_results().empty() ) return;
    342414                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     
    358430                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
    359431                                        arg++;
     432                                        if ( dynamic_cast< StructInstType* >( parmType ) ) {
     433                                                if ( StructInstType *argStructType = dynamic_cast< StructInstType* >( argType ) ) {
     434                                                        arg = appExpr->get_args().insert( arg, makeOffsetArray( argStructType ) );
     435                                                        arg++;
     436                                                } else {
     437                                                        throw SemanticError( "Cannot pass non-struct type for generic struct" );
     438                                                }
     439                                        }
    360440
    361441                                        seenTypes.insert( sizeName );
     
    9291009                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    9301010                                        }
    931                                         assignDecl = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0,
    932                                                                                                  new PointerType( Type::Qualifiers(), assignIter->second->get_type()->clone() ), 0 );
     1011                                        DeclarationWithType *functionDecl = assignIter->second;
     1012                                        // line below cloned from FixFunction.cc
     1013                                        assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
     1014                                                                     new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     1015                                        assignDecl->set_mangleName( functionDecl->get_mangleName() );
    9331016                                }
    9341017                                assert( assignDecl );
     
    10601143                        std::list< DeclarationWithType *> inferredParams;
    10611144                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     1145                        ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
     1146                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
    10621147//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    10631148                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
     
    10931178                                        if ( seenTypes.count( sizeName ) ) continue;
    10941179
    1095                                         ObjectDecl *sizeParm, *alignParm;
     1180                                        ObjectDecl *sizeParm, *alignParm, *offsetParm;
    10961181                                        sizeParm = newObj.clone();
    10971182                                        sizeParm->set_name( sizeName );
     
    11031188                                        last = funcType->get_parameters().insert( last, alignParm );
    11041189                                        ++last;
     1190
     1191                                        if ( dynamic_cast< StructInstType* >( parmType ) ) {
     1192                                                offsetParm = newPtr.clone();
     1193                                                offsetParm->set_name( offsetofName( parmType ) );
     1194                                                last = funcType->get_parameters().insert( last, offsetParm );
     1195                                                ++last;
     1196                                        }
    11051197
    11061198                                        seenTypes.insert( sizeName );
     
    11161208                        scopeTyVars = oldtyVars;
    11171209                        return funcType;
     1210                }
     1211
     1212////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
     1213
     1214                template< typename DeclClass >
     1215                DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {
     1216                        TyVarMap oldtyVars = scopeTyVars;
     1217                        makeTyVarMap( type, scopeTyVars );
     1218
     1219                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
     1220
     1221                        scopeTyVars = oldtyVars;
     1222                        return ret;
     1223                }
     1224
     1225                ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {
     1226                        return handleDecl( objectDecl, objectDecl->get_type() );
     1227                }
     1228
     1229                DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {
     1230                        return handleDecl( functionDecl, functionDecl->get_functionType() );
     1231                }
     1232
     1233                TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {
     1234                        return handleDecl( typedefDecl, typedefDecl->get_base() );
     1235                }
     1236
     1237                TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {
     1238                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     1239                        return Mutator::mutate( typeDecl );
     1240                }
     1241
     1242                Type * MemberExprFixer::mutate( PointerType *pointerType ) {
     1243                        TyVarMap oldtyVars = scopeTyVars;
     1244                        makeTyVarMap( pointerType, scopeTyVars );
     1245
     1246                        Type *ret = Mutator::mutate( pointerType );
     1247
     1248                        scopeTyVars = oldtyVars;
     1249                        return ret;
     1250                }
     1251
     1252                Type * MemberExprFixer::mutate( FunctionType *functionType ) {
     1253                        TyVarMap oldtyVars = scopeTyVars;
     1254                        makeTyVarMap( functionType, scopeTyVars );
     1255
     1256                        Type *ret = Mutator::mutate( functionType );
     1257
     1258                        scopeTyVars = oldtyVars;
     1259                        return ret;
     1260                }
     1261
     1262                Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {
     1263                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
     1264                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
     1265                                        // change initialization of a polymorphic value object
     1266                                        // to allocate storage with alloca
     1267                                        Type *declType = objectDecl->get_type();
     1268                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
     1269                                        alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
     1270
     1271                                        delete objectDecl->get_init();
     1272
     1273                                        std::list<Expression*> designators;
     1274                                        objectDecl->set_init( new SingleInit( alloc, designators ) );
     1275                                }
     1276                        }
     1277                        return Mutator::mutate( declStmt );
     1278                }
     1279
     1280                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
     1281                        // mutate, exiting early if no longer MemberExpr
     1282                        Expression *expr = Mutator::mutate( memberExpr );
     1283                        memberExpr = dynamic_cast< MemberExpr* >( expr );
     1284                        if ( ! memberExpr ) return expr;
     1285
     1286                        // get declaration for base struct, exiting early if not found
     1287                        VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate() );
     1288                        if ( ! varExpr ) return memberExpr;
     1289                        ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     1290                        if ( ! objectDecl ) return memberExpr;
     1291
     1292                        // only mutate member expressions for polymorphic types
     1293                        Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars );
     1294                        if ( ! objectType ) return memberExpr;
     1295
     1296                        // get base aggregate for type so members can be looked up
     1297                        AggregateDecl *memberBase = 0;
     1298                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
     1299                                memberBase = structType->get_baseStruct();
     1300                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
     1301                                memberBase = unionType->get_baseUnion();
     1302                        } else return memberExpr;
     1303
     1304                        // look up numeric index of member in base aggregate
     1305                        DeclarationWithType *memberDecl = memberExpr->get_member();
     1306                        std::list< Declaration* > &baseDecls = memberBase->get_members();
     1307                        std::list< Declaration* >::const_iterator decl = baseDecls.begin();
     1308                        unsigned long i = 0;
     1309                        for( ; decl != baseDecls.end(); ++decl, ++i ) {
     1310                                if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
     1311
     1312                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
     1313                                        if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break;
     1314                                        else continue;
     1315                                } else break;
     1316                        }
     1317                        if ( decl == baseDecls.end() ) return memberExpr;
     1318
     1319                        // replace member expression with dereference of pointer offset
     1320                        std::stringstream offset_namer;
     1321                        offset_namer << i;
     1322                        ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
     1323                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
     1324                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
     1325                        fieldOffset->get_args().push_back( fieldIndex );
     1326                        UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
     1327                        fieldLoc->get_args().push_back( memberExpr->get_aggregate() );
     1328                        fieldLoc->get_args().push_back( fieldOffset );
     1329                        UntypedExpr *ret = new UntypedExpr( new NameExpr( "*?" ) );
     1330                        ret->get_args().push_back( fieldLoc );
     1331
     1332                        memberExpr->set_aggregate( 0 );
     1333                        delete memberExpr;
     1334                        return ret;
    11181335                }
    11191336
     
    11761393                        return ret;
    11771394                }
    1178 
    1179                 Statement *Pass3::mutate( DeclStmt *declStmt ) {
    1180                         if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    1181                                 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
    1182                                         // change initialization of a polymorphic value object
    1183                                         // to allocate storage with alloca
    1184                                         Type *declType = objectDecl->get_type();
    1185                                         UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1186                                         alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
    1187 
    1188                                         delete objectDecl->get_init();
    1189 
    1190                                         std::list<Expression*> designators;
    1191                                         objectDecl->set_init( new SingleInit( alloc, designators ) );
    1192                                 }
    1193                         }
    1194                         return Mutator::mutate( declStmt );
    1195                 }
    11961395        } // anonymous namespace
    11971396} // namespace GenPoly
  • src/GenPoly/GenPoly.cc

    rbfebb6c5 r05d47278  
    127127        }
    128128
     129        Type *hasPolyBase( Type *type, const TypeSubstitution *env ) {
     130                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     131                        return hasPolyBase( ptr->get_base(), env );
     132                } else if ( env ) {
     133                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     134                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     135                                        return hasPolyBase( newType, env );
     136                                } // if
     137                        } // if
     138                }
     139
     140                return isPolyType( type, env );
     141        }
     142       
     143        Type *hasPolyBase( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     144                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     145                        return hasPolyBase( ptr->get_base(), tyVars, env );
     146                } else if ( env ) {
     147                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     148                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     149                                        return hasPolyBase( newType, tyVars, env );
     150                                } // if
     151                        } // if
     152                }
     153
     154                return isPolyType( type, tyVars, env );
     155        }
     156
    129157        FunctionType * getFunctionType( Type *ty ) {
    130158                PointerType *ptrType;
     
    136164        }
    137165
     166        VariableExpr *getBaseVar( Expression *expr ) {
     167                if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {
     168                        // found the variable directly
     169                        return varExpr;
     170                } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {
     171                        // look for compiler-inserted dereference operator
     172                        NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );
     173                        if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
     174                        return getBaseVar( *untypedExpr->begin_args() );
     175                } else return 0;
     176        }
     177
    138178        void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
    139179                for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
     
    160200                return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
    161201        }
     202
     203        std::string offsetofName( Type* ty ) {
     204                return std::string( "_offsetof_" ) + SymTab::Mangler::mangleType( ty );
     205        }
     206
    162207} // namespace GenPoly
    163208
  • src/GenPoly/GenPoly.h

    rbfebb6c5 r05d47278  
    4747        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    4848
     49        /// returns polymorphic base type if the base type (after dereferencing any number of pointers) is a polymorphic type, NULL otherwise;
     50        /// will look up substitution in env if provided
     51        Type *hasPolyBase( Type *type, const TypeSubstitution *env = 0 );
     52
     53        /// returns polymorphic base type if the base type (after dereferencing any number of pointers) is a polymorphic type in tyVars, NULL otherwise;
     54        /// will look up substitution in env if provided
     55        Type *hasPolyBase( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     56
    4957        /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
    50         FunctionType * getFunctionType( Type *ty );
     58        FunctionType *getFunctionType( Type *ty );
     59
     60        /// Returns the base variable (possibly repeatedly dereferenced) for an expression, NULL if none found
     61        VariableExpr *getBaseVar( Expression *expr );
    5162
    5263        /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
     
    6172        /// Gets the name of the alignof parameter for the type
    6273        std::string alignofName( Type *ty );
     74
     75        /// Gets the name of the offsetof parameter for the type
     76        std::string offsetofName( Type *ty );
    6377} // namespace GenPoly
    6478
Note: See TracChangeset for help on using the changeset viewer.