Changeset 5f98ce5 for src/InitTweak


Ignore:
Timestamp:
Jul 19, 2016, 7:09:30 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
40e636a
Parents:
2be1023
Message:

hoist non-constexpr array dimension into const variable in case of side effects

Location:
src/InitTweak
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    r2be1023 r5f98ce5  
    7979                bool isConstExpr;
    8080        };
     81
     82        bool isConstExpr( Expression * expr ) {
     83                if ( expr ) {
     84                        ConstExprChecker checker;
     85                        expr->accept( checker );
     86                        return checker.isConstExpr;
     87                }
     88                return true;
     89        }
    8190
    8291        bool isConstExpr( Initializer * init ) {
  • src/InitTweak/GenInit.cc

    r2be1023 r5f98ce5  
    2626#include "SymTab/Autogen.h"
    2727#include "GenPoly/PolyMutator.h"
     28#include "GenPoly/DeclMutator.h"
    2829
    2930namespace InitTweak {
     
    5556          public:
    5657                /// create constructor and destructor statements for object declarations.
    57                 /// Destructors are inserted directly into the code, whereas constructors
    58                 /// will be added in after the resolver has run so that the initializer expression
    59                 /// is only removed if a constructor is found
     58                /// the actual call statements will be added in after the resolver has run
     59                /// so that the initializer expression is only removed if a constructor is found
     60                /// and the same destructor call is inserted in all of the appropriate locations.
    6061                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
    6162
     
    6465                virtual DeclarationWithType * mutate( ObjectDecl * );
    6566                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    66                 virtual Declaration* mutate( StructDecl *aggregateDecl );
    67                 virtual Declaration* mutate( UnionDecl *aggregateDecl );
    68                 virtual Declaration* mutate( EnumDecl *aggregateDecl );
    69                 virtual Declaration* mutate( TraitDecl *aggregateDecl );
    70                 virtual TypeDecl* mutate( TypeDecl *typeDecl );
    71                 virtual Declaration* mutate( TypedefDecl *typeDecl );
    72 
    73                 virtual Type * mutate( FunctionType *funcType );
     67                // should not traverse into any of these declarations to find objects
     68                // that need to be constructed or destructed
     69                virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
     70                virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
     71                virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
     72                virtual Declaration* mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
     73                virtual TypeDecl* mutate( TypeDecl *typeDecl ) { return typeDecl; }
     74                virtual Declaration* mutate( TypedefDecl *typeDecl ) { return typeDecl; }
     75
     76                virtual Type * mutate( FunctionType *funcType ) { return funcType; }
    7477
    7578          protected:
     
    7780        };
    7881
     82        class HoistArrayDimension : public GenPoly::DeclMutator {
     83          public:
     84                typedef GenPoly::DeclMutator Parent;
     85
     86                /// hoist dimension from array types in object declaration so that it uses a single
     87                /// const variable of type size_t, so that side effecting array dimensions are only
     88                /// computed once.
     89                static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
     90
     91          private:
     92                DeclarationWithType * mutate( ObjectDecl * objectDecl );
     93                // should not traverse into any of these declarations to find objects
     94                // that need to be constructed or destructed
     95                virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
     96                virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
     97                virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
     98                virtual Declaration* mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
     99                virtual TypeDecl* mutate( TypeDecl *typeDecl ) { return typeDecl; }
     100                virtual Declaration* mutate( TypedefDecl *typeDecl ) { return typeDecl; }
     101
     102                virtual Type* mutate( FunctionType *funcType ) { return funcType; }
     103
     104                void hoist( Type * type );
     105
     106                DeclarationNode::StorageClass storageclass = DeclarationNode::NoStorageClass;
     107        };
     108
    79109        void genInit( std::list< Declaration * > & translationUnit ) {
    80110                ReturnFixer::makeReturnTemp( translationUnit );
     111                HoistArrayDimension::hoistArrayDimension( translationUnit );
    81112                CtorDtor::generateCtorDtor( translationUnit );
    82113        }
     
    124155        }
    125156
     157        void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
     158                HoistArrayDimension hoister;
     159                mutateAll( translationUnit, hoister );
     160        }
     161
     162        DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {
     163                storageclass = objectDecl->get_storageClass();
     164                DeclarationWithType * temp = Parent::mutate( objectDecl );
     165                hoist( objectDecl->get_type() );
     166                storageclass = DeclarationNode::NoStorageClass;
     167                return temp;
     168        }
     169
     170        void HoistArrayDimension::hoist( Type * type ) {
     171                static UniqueName dimensionName( "_array_dim" );
     172                if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
     173                        if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist?
     174
     175                        // don't need to hoist dimension if it's a constexpr - only need to if there's potential
     176                        // for side effects.
     177                        if ( isConstExpr( arrayType->get_dimension() ) ) return;
     178
     179                        ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageclass, LinkageSpec::C, 0, SymTab::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
     180                        arrayDimension->get_type()->set_isConst( true );
     181
     182                        arrayType->set_dimension( new VariableExpr( arrayDimension ) );
     183                        addDeclaration( arrayDimension );
     184
     185                        hoist( arrayType->get_base() );
     186                        return;
     187                }
     188        }
    126189
    127190        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
     
    203266                return functionDecl;
    204267        }
    205 
    206         // should not traverse into any of these declarations to find objects
    207         // that need to be constructed or destructed
    208         Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
    209         Declaration* CtorDtor::mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
    210         Declaration* CtorDtor::mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
    211         Declaration* CtorDtor::mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
    212         TypeDecl* CtorDtor::mutate( TypeDecl *typeDecl ) { return typeDecl; }
    213         Declaration* CtorDtor::mutate( TypedefDecl *typeDecl ) { return typeDecl; }
    214         Type* CtorDtor::mutate( FunctionType *funcType ) { return funcType; }
    215 
    216268} // namespace InitTweak
    217269
  • src/InitTweak/InitTweak.h

    r2be1023 r5f98ce5  
    5454  /// returns the argument if it is a PointerType or ArrayType, else returns NULL
    5555  Type * isPointerType( Type * );
     56
     57  /// returns true if expr is trivially a compile-time constant
     58  bool isConstExpr( Expression * expr );
     59  bool isConstExpr( Initializer * init );
    5660} // namespace
    5761
Note: See TracChangeset for help on using the changeset viewer.