Changeset 5f98ce5


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
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/DeclMutator.h

    r2be1023 r5f98ce5  
    2828        class DeclMutator : public Mutator {
    2929        public:
     30                typedef Mutator Parent;
     31
    3032                DeclMutator();
    3133                virtual ~DeclMutator();
    32                
     34
     35                using Parent::mutate;
    3336                virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
    3437                virtual Statement* mutate(IfStmt *ifStmt);
     
    4245                /// Mutates a list of declarations with this visitor
    4346                void mutateDeclarationList(std::list< Declaration* >& decls);
    44                
     47
    4548                /// Called on entry to a new scope; overriders should call this as a super-class call
    4649                virtual void doBeginScope();
  • 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
  • src/ResolvExpr/Resolver.cc

    r2be1023 r5f98ce5  
    2424#include "SynTree/Initializer.h"
    2525#include "SymTab/Indexer.h"
     26#include "SymTab/Autogen.h"
    2627#include "Common/utility.h"
    2728#include "InitTweak/InitTweak.h"
     
    194195        void Resolver::visit( ArrayType * at ) {
    195196                if ( at->get_dimension() ) {
    196                         BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    197                         CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() );
     197                        CastExpr *castExpr = new CastExpr( at->get_dimension(), SymTab::SizeType->clone() );
    198198                        Expression *newExpr = findSingleExpression( castExpr, *this );
    199199                        delete at->get_dimension();
  • src/SymTab/Autogen.cc

    r2be1023 r5f98ce5  
    2626
    2727namespace SymTab {
     28        Type * SizeType = 0;
     29
    2830        class AutogenerateRoutines : public Visitor {
    2931                public:
  • src/SymTab/Autogen.h

    r2be1023 r5f98ce5  
    2929        /// returns true if obj's name is the empty string and it has a bitfield width
    3030        bool isUnnamedBitfield( ObjectDecl * obj );
     31
     32        /// size_t type - set when size_t typedef is seen. Useful in a few places,
     33        /// such as in determining array dimension type
     34        extern Type * SizeType;
    3135
    3236        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
  • src/SymTab/Validate.cc

    r2be1023 r5f98ce5  
    174174
    175175                virtual void visit( FunctionDecl *funcDecl );
    176 };
     176        };
    177177
    178178        class CompoundLiteral : public GenPoly::DeclMutator {
     
    490490                EliminateTypedef eliminator;
    491491                mutateAll( translationUnit, eliminator );
     492                if ( eliminator.typedefNames.count( "size_t" ) ) {
     493                        // grab and remember declaration of size_t
     494                        SizeType = eliminator.typedefNames["size_t"].first->get_base()->clone();
     495                } else {
     496                        assert( false && "missing global typedef for size_t" );
     497                }
    492498                filter( translationUnit, isTypedef, true );
     499
    493500        }
    494501
     
    518525        Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) {
    519526                Declaration *ret = Mutator::mutate( tyDecl );
     527
    520528                if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
    521529                        // typedef to the same name from the same scope
Note: See TracChangeset for help on using the changeset viewer.