Changes in / [ac71a86:04cdd9b]


Ignore:
Location:
src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/InitTweak.cc

    rac71a86 r04cdd9b  
    291291        }
    292292
     293        namespace {
     294                template <typename Predicate>
     295                bool allofCtorDtor( Statement * stmt, const Predicate & pred ) {
     296                        std::list< Expression * > callExprs;
     297                        collectCtorDtorCalls( stmt, callExprs );
     298                        // if ( callExprs.empty() ) return false; // xxx - do I still need this check?
     299                        return std::all_of( callExprs.begin(), callExprs.end(), pred);
     300                }
     301        }
     302
    293303        bool isIntrinsicSingleArgCallStmt( Statement * stmt ) {
    294                 std::list< Expression * > callExprs;
    295                 collectCtorDtorCalls( stmt, callExprs );
    296                 // if ( callExprs.empty() ) return false; // xxx - do I still need this check?
    297                 return std::all_of( callExprs.begin(), callExprs.end(), []( Expression * callExpr ){
     304                return allofCtorDtor( stmt, []( Expression * callExpr ){
    298305                        if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
    299306                                assert( ! appExpr->get_function()->get_results().empty() );
     
    303310                        }
    304311                        return false;
     312                });
     313        }
     314
     315        bool isIntrinsicCallStmt( Statement * stmt ) {
     316                return allofCtorDtor( stmt, []( Expression * callExpr ) {
     317                        return isIntrinsicCallExpr( callExpr );
    305318                });
    306319        }
  • src/InitTweak/InitTweak.h

    rac71a86 r04cdd9b  
    4141        /// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
    4242        /// Currently has assertions that make it less than fully general.
    43         bool isIntrinsicSingleArgCallStmt( Statement * expr );
     43        bool isIntrinsicSingleArgCallStmt( Statement * stmt );
     44
     45        /// True if stmt is a call statement where the function called is intrinsic.
     46        bool isIntrinsicCallStmt( Statement * stmt );
    4447
    4548        /// get all Ctor/Dtor call expressions from a Statement
  • src/ResolvExpr/Resolver.cc

    rac71a86 r04cdd9b  
    446446                } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) {
    447447                        resolveAggrInit( st->get_baseStruct(), iter, end );
    448                 } else if ( UnionInstType *st = dynamic_cast< UnionInstType * >( initContext ) ) {
     448                } else if ( UnionInstType * st = dynamic_cast< UnionInstType * >( initContext ) ) {
    449449                        resolveAggrInit( st->get_baseUnion(), iter, end );
     450                } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
     451                        Type * base = tt->get_baseType()->get_base();
     452                        if ( base ) {
     453                                // know the implementation type, so try using that as the initContext
     454                                initContext = base;
     455                                visit( listInit );
     456                        } else {
     457                                // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
     458                                Visitor::visit( listInit );
     459                        }
    450460                } else {
     461                        assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext ) );
    451462                        // basic types are handled here
    452463                        Visitor::visit( listInit );
     
    539550                }
    540551
    541                 // xxx - todo
    542                 // if ( InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
    543                 //      // can reduce the constructor down to a SingleInit using the
    544                 //      // second argument from the ctor call
    545                 // }
    546 
    547552                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
    548553                        delete ctorInit->get_dtor();
    549554                        ctorInit->set_dtor( NULL );
    550555                }
     556
     557                // xxx - todo -- what about arrays?
     558                // if ( dtor == NULL && InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
     559                //      // can reduce the constructor down to a SingleInit using the
     560                //      // second argument from the ctor call, since
     561                //      delete ctorInit->get_ctor();
     562                //      ctorInit->set_ctor( NULL );
     563
     564                //      Expression * arg =
     565                //      ctorInit->set_init( new SingleInit( arg ) );
     566                // }
    551567        }
    552568} // namespace ResolvExpr
  • src/ResolvExpr/TypeEnvironment.cc

    rac71a86 r04cdd9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeEnvironment.cc -- 
     7// TypeEnvironment.cc --
    88//
    99// Author           : Richard C. Bilson
     
    2323
    2424namespace ResolvExpr {
     25        // adding this comparison operator significantly improves assertion resolution run time for
     26        // some cases. The current resolution algorithm's speed partially depends on the order of
     27        // assertions. Assertions which have fewer possible matches should appear before
     28        // assertions which have more possible matches. This seems to imply that this could
     29        // be further improved by providing an indexer as an additional argument and ordering based
     30        // on the number of matches of the same kind (object, function) for the names of the
     31        // declarations.
     32        //
     33        // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.
     34        bool AssertCompare::operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) {
     35                        // Objects are always less than functions
     36                        if ( ObjectDecl * objectDecl1 = dynamic_cast< ObjectDecl * >( d1 ) ) {
     37                                if ( ObjectDecl * objectDecl2 = dynamic_cast< ObjectDecl * >( d2 ) ) {
     38                                        // objects are ordered by name then type pointer, in that order
     39                                        int cmp = objectDecl1->get_name().compare( objectDecl2->get_name() );
     40                                        return cmp < 0 ||
     41                                                ( cmp == 0 && objectDecl1->get_type() < objectDecl2->get_type() );
     42                                } else {
     43                                        return true;
     44                                }
     45                        } else if ( FunctionDecl * funcDecl1 = dynamic_cast< FunctionDecl * >( d1 ) ) {
     46                                if ( FunctionDecl * funcDecl2 = dynamic_cast< FunctionDecl * >( d2 ) ) {
     47                                        // functions are ordered by name, # parameters, # returnVals, type pointer in that order
     48                                        FunctionType * ftype1 = funcDecl1->get_functionType();
     49                                        FunctionType * ftype2 = funcDecl2->get_functionType();
     50                                        int numThings1 = ftype1->get_parameters().size() + ftype1->get_returnVals().size();
     51                                        int numThings2 = ftype2->get_parameters().size() + ftype2->get_returnVals().size();
     52                                        if ( numThings1 < numThings2 ) return true;
     53                                        if ( numThings1 > numThings2 ) return false;
     54
     55                                        // if ( ftype1->get_parameters().size() < ftype2->get_parameters().size() ) return true;
     56                                        // else if ( ftype1->get_parameters().size() > ftype2->get_parameters().size() ) return false;
     57                                        // // same number of parameters
     58                                        // if ( ftype1->get_returnVals().size() < ftype2->get_returnVals().size() ) return true;
     59                                        // else if ( ftype1->get_returnVals().size() > ftype2->get_returnVals().size() ) return false;
     60                                        // same number of return vals
     61                                        // int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() );
     62                                        // if ( cmp < 0 ) return true;
     63                                        // else if ( cmp > 0 ) return false;
     64                                        // // same name
     65                                        return ftype1 < ftype2;
     66                                } else {
     67                                        return false;
     68                                }
     69                        } else {
     70                                assert( false );
     71                        }
     72                }
     73
    2574        void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) {
    2675                for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
  • src/ResolvExpr/TypeEnvironment.h

    rac71a86 r04cdd9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeEnvironment.h -- 
     7// TypeEnvironment.h --
    88//
    99// Author           : Richard C. Bilson
     
    2828
    2929namespace ResolvExpr {
    30         typedef std::map< DeclarationWithType*, bool > AssertionSet;
     30        struct AssertCompare {
     31                bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 );
     32        };
     33        typedef std::map< DeclarationWithType*, bool, AssertCompare > AssertionSet;
    3134        typedef std::map< std::string, TypeDecl::Kind > OpenVarSet;
    3235
     
    3942                bool allowWidening;
    4043                TypeDecl::Kind kind;
    41  
     44
    4245                void initialize( const EqvClass &src, EqvClass &dest );
    4346                EqvClass();
     
    6265                void extractOpenVars( OpenVarSet &openVars ) const;
    6366                TypeEnvironment *clone() const { return new TypeEnvironment( *this ); }
    64  
     67
    6568                typedef std::list< EqvClass >::iterator iterator;
    6669                iterator begin() { return env.begin(); }
  • src/ResolvExpr/Unify.cc

    rac71a86 r04cdd9b  
    484484                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    485485                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    486 
    487                         if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    488 
    489                                 if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    490 
    491                                         markAssertions( haveAssertions, needAssertions, functionType );
    492                                         markAssertions( haveAssertions, needAssertions, otherFunction );
    493 
    494                                         result = true;
     486                        if ( functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size() ) {
     487                                if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     488                                        if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     489
     490                                                markAssertions( haveAssertions, needAssertions, functionType );
     491                                                markAssertions( haveAssertions, needAssertions, otherFunction );
     492
     493                                                result = true;
     494                                        } // if
    495495                                } // if
    496496                        } // if
  • src/SymTab/Autogen.cc

    rac71a86 r04cdd9b  
    6868                copy->get_args().push_back( new VariableExpr( dstParam ) );
    6969                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    70                 copy->get_args().push_back( new SizeofExpr( unionType ) );
     70                copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
    7171
    7272                *out++ = new ExprStmt( noLabels, copy );
     
    420420                copyCtorDecl->set_statements( assignDecl->get_statements()->clone() );
    421421
     422                // create a constructor which takes the first member type as a parameter.
     423                // for example, for Union A { int x; double y; }; generate
     424                // void ?{}(A *, int)
     425                // This is to mimic C's behaviour which initializes the first member of the union.
     426                std::list<Declaration *> memCtors;
     427                for ( Declaration * member : aggregateDecl->get_members() ) {
     428                        if ( DeclarationWithType * field = dynamic_cast< DeclarationWithType * >( member ) ) {
     429                                ObjectDecl * srcParam = new ObjectDecl( "src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, field->get_type()->clone(), 0 );
     430
     431                                FunctionType * memCtorType = ctorType->clone();
     432                                memCtorType->get_parameters().push_back( srcParam );
     433                                FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType, new CompoundStmt( noLabels ), true, false );
     434                                ctor->fixUniqueId();
     435
     436                                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( ctor->get_statements()->get_kids() ) );
     437                                memCtors.push_back( ctor );
     438                                // only generate a ctor for the first field
     439                                break;
     440                        }
     441                }
     442
    422443                declsToAdd.push_back( assignDecl );
    423444                declsToAdd.push_back( ctorDecl );
    424445                declsToAdd.push_back( copyCtorDecl );
    425446                declsToAdd.push_back( dtorDecl );
     447                declsToAdd.splice( declsToAdd.end(), memCtors );
    426448        }
    427449
  • src/SymTab/Validate.cc

    rac71a86 r04cdd9b  
    162162
    163163                typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap;
     164                typedef std::map< std::string, TypeDecl * > TypeDeclMap;
    164165                TypedefMap typedefNames;
     166                TypeDeclMap typedeclNames;
    165167                int scopeLevel;
    166168        };
     
    521523                        delete typeInst;
    522524                        return ret;
     525                } else {
     526                        TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
     527                        assert( base != typedeclNames.end() );
     528                        typeInst->set_baseType( base->second->clone() );
    523529                } // if
    524530                return typeInst;
     
    565571                        typedefNames.erase( i ) ;
    566572                } // if
     573
     574                typedeclNames[ typeDecl->get_name() ] = typeDecl;
    567575                return typeDecl;
    568576        }
  • src/tests/.expect/32/extension.txt

    rac71a86 r04cdd9b  
    7070static inline void ___destructor__F_P2uU_autogen___1(union U *___dst__P2uU_1){
    7171}
     72static inline void ___constructor__F_P2uUi_autogen___1(union U *___dst__P2uU_1, int __src__i_1){
     73    void *_tmp_cp_ret2;
     74    ((void)((_tmp_cp_ret2=__builtin_memcpy(((void *)___dst__P2uU_1), ((const void *)(&__src__i_1)), sizeof(int ))) , _tmp_cp_ret2));
     75    ((void)(_tmp_cp_ret2) /* ^?{} */);
     76}
    7277__extension__ enum E {
    7378    __R__C2eE_1,
     
    8994    __extension__ int __c__i_2;
    9095    ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2)));
    91     int _tmp_cp_ret2;
    92     ((void)((_tmp_cp_ret2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2));
    93     ((void)(_tmp_cp_ret2) /* ^?{} */);
     96    int _tmp_cp_ret3;
     97    ((void)((_tmp_cp_ret3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3));
     98    ((void)(_tmp_cp_ret3) /* ^?{} */);
    9499    ((void)__extension__ sizeof(3));
    95100    ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0))));
  • src/tests/.expect/64/extension.txt

    rac71a86 r04cdd9b  
    7070static inline void ___destructor__F_P2uU_autogen___1(union U *___dst__P2uU_1){
    7171}
     72static inline void ___constructor__F_P2uUi_autogen___1(union U *___dst__P2uU_1, int __src__i_1){
     73    void *_tmp_cp_ret2;
     74    ((void)((_tmp_cp_ret2=__builtin_memcpy(((void *)___dst__P2uU_1), ((const void *)(&__src__i_1)), sizeof(int ))) , _tmp_cp_ret2));
     75    ((void)(_tmp_cp_ret2) /* ^?{} */);
     76}
    7277__extension__ enum E {
    7378    __R__C2eE_1,
     
    8994    __extension__ int __c__i_2;
    9095    ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2)));
    91     int _tmp_cp_ret2;
    92     ((void)((_tmp_cp_ret2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2));
    93     ((void)(_tmp_cp_ret2) /* ^?{} */);
     96    int _tmp_cp_ret3;
     97    ((void)((_tmp_cp_ret3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3));
     98    ((void)(_tmp_cp_ret3) /* ^?{} */);
    9499    ((void)__extension__ sizeof(3));
    95100    ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0))));
Note: See TracChangeset for help on using the changeset viewer.