Changeset 90152a4 for src/Tuples
- Timestamp:
- Aug 27, 2018, 4:40:34 PM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
- Children:
- b7c89aa
- Parents:
- f9feab8 (diff), 305581d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/Tuples
- Files:
-
- 3 edited
-
Explode.h (modified) (7 diffs)
-
TupleAssignment.cc (modified) (5 diffs)
-
TupleExpansion.cc (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/Explode.h
rf9feab8 r90152a4 43 43 /// Append alternative to an OutputIterator of Alternatives 44 44 template<typename OutputIterator> 45 void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 45 void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 46 46 const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) { 47 47 *out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost }; … … 49 49 50 50 /// Append alternative to an ExplodedActual 51 static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 51 static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 52 52 const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 53 53 ea.exprs.emplace_back( expr ); … … 57 57 /// helper function used by explode 58 58 template< typename Output > 59 void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, 59 void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, 60 60 const SymTab::Indexer & indexer, Output&& out, bool isTupleAssign ) { 61 61 if ( isTupleAssign ) { … … 63 63 if ( CastExpr * castExpr = isReferenceCast( expr ) ) { 64 64 ResolvExpr::AltList alts; 65 explodeUnique( 65 explodeUnique( 66 66 castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); 67 67 for ( ResolvExpr::Alternative & alt : alts ) { 68 68 // distribute reference cast over all components 69 append( std::forward<Output>(out), distributeReference( alt.release_expr() ), 69 append( std::forward<Output>(out), distributeReference( alt.release_expr() ), 70 70 alt.env, alt.cost, alt.cvtCost ); 71 71 } … … 108 108 /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type 109 109 template< typename Output > 110 void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, 110 void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, 111 111 Output&& out, bool isTupleAssign = false ) { 112 112 explodeUnique( alt.expr, alt, indexer, std::forward<Output>(out), isTupleAssign ); … … 115 115 // explode list of alternatives 116 116 template< typename AltIterator, typename Output > 117 void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, 117 void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, 118 118 Output&& out, bool isTupleAssign = false ) { 119 119 for ( ; altBegin != altEnd; ++altBegin ) { … … 123 123 124 124 template< typename Output > 125 void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, Output&& out, 125 void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, Output&& out, 126 126 bool isTupleAssign = false ) { 127 127 explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign ); -
src/Tuples/TupleAssignment.cc
rf9feab8 r90152a4 154 154 lhsAlt.expr = new CastExpr( lhsAlt.expr, 155 155 new ReferenceType( Type::Qualifiers(), 156 lhsAlt.expr-> get_result()->clone() ) );156 lhsAlt.expr->result->clone() ) ); 157 157 } 158 158 … … 231 231 232 232 ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(), 233 currentFinder.get_environ() }; 233 matcher->compositeEnv }; 234 234 235 try { 235 236 finder.findWithAdjustment(*i); … … 272 273 // args.push_back( new AddressExpr( new VariableExpr( left ) ) ); 273 274 if ( right ) args.push_back( new VariableExpr( right ) ); 274 return new UntypedExpr( new NameExpr( fname ), args ); 275 } 276 277 // removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator. 275 if ( left->type->referenceDepth() > 1 && CodeGen::isConstructor( fname ) ) { 276 args.front() = new AddressExpr( args.front() ); 277 if ( right ) args.back() = new AddressExpr( args.back() ); 278 return new UntypedExpr( new NameExpr( "?=?" ), args ); 279 } else { 280 return new UntypedExpr( new NameExpr( fname ), args ); 281 } 282 } 283 284 // removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator, and adds the bindings to the compositeEnv 278 285 // xxx - maybe this should happen in alternative finder for every StmtExpr? 279 // xxx - it's possible that these environments could contain some useful information. Maybe the right thing to do is aggregate the environments and pass the aggregate back to be added into the compositeEnv280 286 struct EnvRemover { 281 287 void previsit( ExprStmt * stmt ) { 282 delete stmt->expr->env; 283 stmt->expr->env = nullptr; 284 } 288 assert( compositeEnv ); 289 if ( stmt->expr->env ) { 290 compositeEnv->add( *stmt->expr->env ); 291 delete stmt->expr->env; 292 stmt->expr->env = nullptr; 293 } 294 } 295 296 ResolvExpr::TypeEnvironment * compositeEnv = nullptr; 285 297 }; 286 298 287 299 ObjectDecl * TupleAssignSpotter::Matcher::newObject( UniqueName & namer, Expression * expr ) { 288 300 assert( expr->result && ! expr->get_result()->isVoid() ); 289 ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr-> get_result()->clone(), new SingleInit( expr->clone() ) );301 ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->result->clone(), new SingleInit( expr->clone() ) ); 290 302 // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient. 291 if ( ! dynamic_cast< ReferenceType * >( expr-> get_result()) ) {303 if ( ! dynamic_cast< ReferenceType * >( expr->result ) ) { 292 304 ConstructorInit * ctorInit = InitTweak::genCtorInit( ret ); 293 ret-> set_init( ctorInit );305 ret->init = ctorInit; 294 306 ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object 295 307 PassVisitor<EnvRemover> rm; // remove environments from subexpressions of StmtExprs 308 rm.pass.compositeEnv = &compositeEnv; 296 309 ctorInit->accept( rm ); 297 310 } … … 306 319 assert( (! lhs.empty() && rhs.size() <= 1) || (lhs.empty() && rhs.empty()) ); 307 320 321 // xxx - may need to split this up into multiple declarations, because potential conversion to references 322 // probably should not reference local variable - see MultipleAssignMatcher::match 308 323 ObjectDecl * rtmp = rhs.size() == 1 ? newObject( rhsNamer, rhs.front().expr ) : nullptr; 309 324 for ( ResolvExpr::Alternative & lhsAlt : lhs ) { … … 324 339 std::list< ObjectDecl * > ltmp; 325 340 std::list< ObjectDecl * > rtmp; 326 std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), [&]( ResolvExpr::Alternative & alt ){ 327 return newObject( lhsNamer, alt.expr ); 328 }); 329 std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), [&]( ResolvExpr::Alternative & alt ){ 330 return newObject( rhsNamer, alt.expr ); 331 }); 332 zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), [&](ObjectDecl * obj1, ObjectDecl * obj2 ) { return createFunc(spotter.fname, obj1, obj2); } ); 341 for ( auto p : group_iterate( lhs, rhs ) ) { 342 ResolvExpr::Alternative & lhsAlt = std::get<0>(p); 343 ResolvExpr::Alternative & rhsAlt = std::get<1>(p); 344 // convert RHS to LHS type minus one reference -- important for the case where LHS is && and RHS is lvalue, etc. 345 ReferenceType * lhsType = strict_dynamic_cast<ReferenceType *>( lhsAlt.expr->result ); 346 rhsAlt.expr = new CastExpr( rhsAlt.expr, lhsType->base->clone() ); 347 ObjectDecl * lobj = newObject( lhsNamer, lhsAlt.expr ); 348 ObjectDecl * robj = newObject( rhsNamer, rhsAlt.expr ); 349 out.push_back( createFunc(spotter.fname, lobj, robj) ); 350 ltmp.push_back( lobj ); 351 rtmp.push_back( robj ); 352 353 // resolve the cast expression so that rhsAlt return type is bound by the cast type as needed, and transfer the resulting environment 354 ResolvExpr::AlternativeFinder finder{ spotter.currentFinder.get_indexer(), compositeEnv }; 355 finder.findWithAdjustment( rhsAlt.expr ); 356 assert( finder.get_alternatives().size() == 1 ); 357 compositeEnv = std::move( finder.get_alternatives().front().env ); 358 } 333 359 tmpDecls.splice( tmpDecls.end(), ltmp ); 334 360 tmpDecls.splice( tmpDecls.end(), rtmp ); -
src/Tuples/TupleExpansion.cc
rf9feab8 r90152a4 30 30 #include "SynTree/Type.h" // for Type, Type::Qualifiers, TupleType 31 31 #include "SynTree/Visitor.h" // for Visitor 32 #include "Tuples.h" 32 33 33 34 class CompoundStmt; … … 36 37 namespace Tuples { 37 38 namespace { 38 struct MemberTupleExpander final : public Mutator { 39 typedef Mutator Parent; 40 using Parent::mutate; 41 42 virtual Expression * mutate( UntypedMemberExpr * memberExpr ) override; 39 struct MemberTupleExpander final : public WithShortCircuiting, public WithVisitorRef<MemberTupleExpander> { 40 void premutate( UntypedMemberExpr * ) { visit_children = false; } 41 Expression * postmutate( UntypedMemberExpr * memberExpr ); 43 42 }; 44 43 … … 79 78 80 79 void expandMemberTuples( std::list< Declaration * > & translationUnit ) { 81 MemberTupleExpanderexpander;80 PassVisitor<MemberTupleExpander> expander; 82 81 mutateAll( translationUnit, expander ); 83 82 } … … 109 108 // construct a new UntypedMemberExpr with the correct structure , and recursively 110 109 // expand that member expression. 111 MemberTupleExpanderexpander;112 UntypedMemberExpr * inner = new UntypedMemberExpr( memberExpr-> get_aggregate(), aggr->clone() );113 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr-> get_member(), inner );110 PassVisitor<MemberTupleExpander> expander; 111 UntypedMemberExpr * inner = new UntypedMemberExpr( memberExpr->aggregate, aggr->clone() ); 112 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->member, inner ); 114 113 inner->location = newMemberExpr->location = loc; 115 memberExpr-> set_member(nullptr);116 memberExpr-> set_aggregate(nullptr);114 memberExpr->member = nullptr; 115 memberExpr->aggregate = nullptr; 117 116 delete memberExpr; 118 117 return newMemberExpr->acceptMutator( expander ); … … 126 125 } 127 126 128 Expression * MemberTupleExpander:: mutate( UntypedMemberExpr * memberExpr ) {129 if ( UntypedTupleExpr * tupleExpr = dynamic_cast< UntypedTupleExpr * > ( memberExpr-> get_member()) ) {130 Expression * aggr = memberExpr-> get_aggregate()->clone()->acceptMutator( *this);127 Expression * MemberTupleExpander::postmutate( UntypedMemberExpr * memberExpr ) { 128 if ( UntypedTupleExpr * tupleExpr = dynamic_cast< UntypedTupleExpr * > ( memberExpr->member ) ) { 129 Expression * aggr = memberExpr->aggregate->clone()->acceptMutator( *visitor ); 131 130 // aggregate expressions which might be impure must be wrapped in unique expressions 132 // xxx - if there's a member-tuple expression nested in the aggregate, this currently generates the wrong code if a UniqueExpr is not used, and it's purely an optimization to remove the UniqueExpr 133 // if ( Tuples::maybeImpureIgnoreUnique( memberExpr->get_aggregate() ) ) aggr = new UniqueExpr( aggr ); 134 aggr = new UniqueExpr( aggr ); 135 for ( Expression *& expr : tupleExpr->get_exprs() ) { 131 if ( Tuples::maybeImpureIgnoreUnique( memberExpr->aggregate ) ) aggr = new UniqueExpr( aggr ); 132 for ( Expression *& expr : tupleExpr->exprs ) { 136 133 expr = reconstructMemberExpr( expr, aggr, memberExpr->location ); 137 134 expr->location = memberExpr->location; … … 143 140 // there may be a tuple expr buried in the aggregate 144 141 // xxx - this is a memory leak 145 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr-> get_member()->clone(), memberExpr->get_aggregate()->acceptMutator( *this) );142 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->member->clone(), memberExpr->aggregate->acceptMutator( *visitor ) ); 146 143 newMemberExpr->location = memberExpr->location; 147 144 return newMemberExpr; … … 202 199 // generate struct type to replace tuple type based on the number of components in the tuple 203 200 StructDecl * decl = new StructDecl( toString( "_tuple", tupleSize, "_" ) ); 201 decl->location = tupleType->location; 204 202 decl->set_body( true ); 205 203 for ( size_t i = 0; i < tupleSize; ++i ) { … … 228 226 229 227 Expression * TupleIndexExpander::postmutate( TupleIndexExpr * tupleExpr ) { 230 Expression * tuple = tupleExpr-> get_tuple();228 Expression * tuple = tupleExpr->tuple; 231 229 assert( tuple ); 232 tupleExpr-> set_tuple( nullptr );233 unsigned int idx = tupleExpr-> get_index();234 TypeSubstitution * env = tupleExpr-> get_env();235 tupleExpr-> set_env( nullptr );230 tupleExpr->tuple = nullptr; 231 unsigned int idx = tupleExpr->index; 232 TypeSubstitution * env = tupleExpr->env; 233 tupleExpr->env = nullptr; 236 234 delete tupleExpr; 237 235 238 StructInstType * type = strict_dynamic_cast< StructInstType * >( tuple->get_result() ); 239 StructDecl * structDecl = type->get_baseStruct(); 240 assert( structDecl->get_members().size() > idx ); 241 Declaration * member = *std::next(structDecl->get_members().begin(), idx); 236 if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * > ( tuple ) ) { 237 if ( ! maybeImpureIgnoreUnique( tupleExpr ) ) { 238 // optimization: definitely pure tuple expr => can reduce to the only relevant component. 239 assert( tupleExpr->exprs.size() > idx ); 240 Expression *& expr = *std::next(tupleExpr->exprs.begin(), idx); 241 Expression * ret = expr; 242 ret->env = env; 243 expr = nullptr; // remove from list so it can safely be deleted 244 delete tupleExpr; 245 return ret; 246 } 247 } 248 249 StructInstType * type = strict_dynamic_cast< StructInstType * >( tuple->result ); 250 StructDecl * structDecl = type->baseStruct; 251 assert( structDecl->members.size() > idx ); 252 Declaration * member = *std::next(structDecl->members.begin(), idx); 242 253 MemberExpr * memExpr = new MemberExpr( strict_dynamic_cast< DeclarationWithType * >( member ), tuple ); 243 memExpr-> set_env( env );254 memExpr->env = env; 244 255 return memExpr; 245 256 }
Note:
See TracChangeset
for help on using the changeset viewer.