Ignore:
Timestamp:
Jul 21, 2017, 9:51:17 AM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
53a8e68
Parents:
17f22e78
Message:

Fix reference conversion cost for qualified references and add pass that removes redundant *&/&* pattern

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Lvalue.cc

    r17f22e78 rcb43451  
    3939// need to be careful about polymorphic references... e.g. in *? (___operator_deref__A0_1_0_0__Fd0_Pd0_intrinsic___1)
    4040// the variable is automatically dereferenced and this causes errors dereferencing void*.
     41
     42#if 0
     43#define PRINT(x) x
     44#else
     45#define PRINT(x)
     46#endif
    4147
    4248namespace GenPoly {
     
    7985                        Expression * postmutate( AddressExpr * addressExpr );
    8086                };
     87
     88                /// Removes redundant &*/*& pattern that this pass can generate
     89                struct CollapseAddrDeref final {
     90                        Expression * postmutate( AddressExpr * addressExpr );
     91                        Expression * postmutate( ApplicationExpr * appExpr );
     92                };
    8193        } // namespace
    8294
     
    8799                PassVisitor<GeneralizedLvalue> genLval;
    88100                PassVisitor<FixIntrinsicArgs> fixer;
     101                PassVisitor<CollapseAddrDeref> collapser;
    89102                mutateAll( translationUnit, refCvt );
    90103                mutateAll( translationUnit, fixer );
    91104                mutateAll( translationUnit, elim );
    92105                mutateAll( translationUnit, genLval );
     106                mutateAll( translationUnit, collapser );
    93107        }
    94108
     
    139153                                delete arg->get_result();
    140154                                arg->set_result( ptrType );
    141                                 arg = mkDeref( new CastExpr( arg, arg->get_result()->clone() ) );
    142                         }
    143                 }
    144 
     155                                arg = mkDeref( arg );
     156                        }
     157                }
     158
     159                // xxx - might need to & every * (or every * that is an arg to non-intrinsic function??)
    145160                Expression * FixIntrinsicArgs::postmutate( ApplicationExpr * appExpr ) {
    146161                        // intrinsic functions don't really take reference-typed parameters, so they require an implicit dereference on their arguments.
     
    152167                                                Expression *& arg = std::get<0>( p );
    153168                                                DeclarationWithType * formal = std::get<1>( p );
    154                                                 std::cerr << "pair<0>: " << arg << std::endl;
    155                                                 std::cerr << "pair<1>: " << formal->get_type() << std::endl;
     169                                                PRINT(
     170                                                        std::cerr << "pair<0>: " << arg << std::endl;
     171                                                        std::cerr << "pair<1>: " << formal->get_type() << std::endl;
     172                                                )
    156173                                                if ( isIntrinsicReference( arg ) ) { // intrinsic functions that turn pointers into references
    157174                                                        // if argument is dereference or array subscript, the result isn't REALLY a reference, so it's not necessary to fix the argument
    158                                                         std::cerr << "skipping intrinsic reference" << std::endl;
     175                                                        PRINT( std::cerr << "skipping intrinsic reference" << std::endl; )
    159176                                                        continue;
    160177                                                } else {
     
    181198                                        // nothing to do if casting from reference to reference.
    182199                                        (void)otherRef;
    183                                         std::cerr << "convert reference to reference -- nop" << std::endl;
     200                                        PRINT( std::cerr << "convert reference to reference -- nop" << std::endl; )
    184201                                        if ( isIntrinsicReference( castExpr->get_arg() ) ) {
    185202                                                Expression * callExpr = castExpr->get_arg();
    186                                                 std::cerr << "but arg is deref -- &" << std::endl;
    187                                                 std::cerr << callExpr << std::endl;
     203                                                PRINT(
     204                                                        std::cerr << "but arg is deref -- &" << std::endl;
     205                                                        std::cerr << callExpr << std::endl;
     206                                                )
    188207                                                // move environment out to new top-level
    189208                                                callExpr->set_env( castExpr->get_env() );
     
    194213                                        }
    195214                                        assertf( false, "non-intrinsic reference with cast of reference to reference not yet supported: ", toString( castExpr ) );
    196                                         std::cerr << castExpr << std::endl;
     215                                        PRINT( std::cerr << castExpr << std::endl; )
    197216                                        return castExpr;
    198217                                } else if ( castExpr->get_arg()->get_result()->get_lvalue() ) {
     
    200219                                        // xxx - keep cast, but turn into pointer cast??
    201220                                        // xxx - memory
    202                                         std::cerr << "convert lvalue to reference -- &" << std::endl;
    203                                         std::cerr << castExpr->get_arg() << std::endl;
    204                                         Expression * ret = new AddressExpr( castExpr->get_arg() );
     221                                        PRINT(
     222                                                std::cerr << "convert lvalue to reference -- &" << std::endl;
     223                                                std::cerr << castExpr->get_arg() << std::endl;
     224                                        )
     225                                        AddressExpr * ret = new AddressExpr( castExpr->get_arg() );
     226                                        if ( refType->get_base()->get_qualifiers() != castExpr->get_arg()->get_result()->get_qualifiers() ) {
     227                                                // must keep cast if cast-to type is different from the actual type
     228                                                castExpr->set_arg( ret );
     229
     230                                                return castExpr;
     231                                        }
    205232                                        ret->set_env( castExpr->get_env() );
    206233                                        castExpr->set_env( nullptr );
     
    215242                                // conversion from reference to rvalue
    216243                                // should be easy, just need to move deref code up here?
    217                                 std::cerr << "convert reference to rvalue -- *" << std::endl;
     244                                PRINT( std::cerr << "convert reference to rvalue -- *" << std::endl; )
    218245                                if ( isIntrinsicReference( castExpr->get_arg() ) ) {
    219                                         std::cerr << "but arg is intrinsic reference -- nop" << std::endl;
     246                                        PRINT( std::cerr << "but arg is intrinsic reference -- nop" << std::endl; )
    220247                                        return castExpr;
    221248                                }
    222                                 std::cerr << "was = " << castExpr << std::endl;
     249                                PRINT( std::cerr << "was = " << castExpr << std::endl; )
    223250
    224251                                Expression * deref = mkDeref( castExpr->get_arg() );
     
    227254                                castExpr->set_env( nullptr );
    228255                                delete castExpr;
    229                                 std::cerr << "now: " << deref << std::endl;
     256                                PRINT( std::cerr << "now: " << deref << std::endl; )
    230257                                return deref;
    231258                        }
     
    255282                        return addrExpr;
    256283                }
     284
     285                Expression * CollapseAddrDeref::postmutate( AddressExpr * addressExpr ) {
     286                        Expression * arg = addressExpr->get_arg();
     287                        if ( isIntrinsicReference( arg ) ) {
     288                                std::string fname = InitTweak::getFunctionName( arg );
     289                                if ( fname == "*?" ) {
     290                                        Expression *& arg0 = InitTweak::getCallArg( arg, 0 );
     291                                        Expression * ret = arg0;
     292                                        ret->set_env( addressExpr->get_env() );
     293                                        arg0 = nullptr;
     294                                        addressExpr->set_env( nullptr );
     295                                        delete addressExpr;
     296                                        return ret;
     297                                }
     298                        }
     299                        return addressExpr;
     300                }
     301
     302                Expression * CollapseAddrDeref::postmutate( ApplicationExpr * appExpr ) {
     303                        if ( isIntrinsicReference( appExpr ) ) {
     304                                std::string fname = InitTweak::getFunctionName( appExpr );
     305                                if ( fname == "*?" ) {
     306                                        Expression * arg = InitTweak::getCallArg( appExpr, 0 );
     307                                        // xxx - this isn't right, because it can remove casts that should be there...
     308                                        // while ( CastExpr * castExpr = dynamic_cast< CastExpr * >( arg ) ) {
     309                                        //      arg = castExpr->get_arg();
     310                                        // }
     311                                        if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( arg ) ) {
     312                                                Expression * ret = addrExpr->get_arg();
     313                                                ret->set_env( appExpr->get_env() );
     314                                                addrExpr->set_arg( nullptr );
     315                                                appExpr->set_env( nullptr );
     316                                                delete appExpr;
     317                                                return ret;
     318                                        }
     319                                }
     320                        }
     321                        return appExpr;
     322                }
    257323        } // namespace
    258324} // namespace GenPoly
Note: See TracChangeset for help on using the changeset viewer.