// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // Explode.cc -- // // Author : Rob Schluntz // Created On : Wed Nov 9 13:12:24 2016 // Last Modified By : Rob Schluntz // Last Modified On : Wed Nov 9 13:20:24 2016 // Update Count : 2 // #include "Explode.h" #include "SynTree/Mutator.h" namespace Tuples { namespace { struct AddrExploder : public Mutator { bool foundUniqueExpr = false; Expression * applyAddr( Expression * expr, bool first = true ) { if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ){ foundUniqueExpr = true; std::list< Expression * > exprs; for ( Expression *& expr : tupleExpr->get_exprs() ) { // move & into tuple exprs exprs.push_back( applyAddr( expr, false ) ); } // want the top-level expression to be address-taken, but not nested // tuple expressions if ( first ) { return new AddressExpr( new TupleExpr( exprs ) ); } else { return new TupleExpr( exprs ); } } // anything else should be address-taken as normal return new AddressExpr( expr->clone() ); } virtual Expression * mutate( UniqueExpr * uniqueExpr ) { // move & into unique expr so that the unique expr has type T* rather than // type T. In particular, this transformation helps with generating the // correct code for address-taken member tuple expressions, since the result // should now be a tuple of addresses rather than the address of a tuple. // Still, this code is a bit awkward, and could use some improvement. if ( dynamic_cast< AddressExpr * > ( uniqueExpr->get_expr() ) ) { // this unique expression has already been mutated or otherwise shouldn't be (can't take the address-of an address-of expression) return uniqueExpr; } UniqueExpr * newUniqueExpr = new UniqueExpr( applyAddr( uniqueExpr->get_expr() ), uniqueExpr->get_id() ); delete uniqueExpr; UntypedExpr * deref = UntypedExpr::createDeref( Mutator::mutate( newUniqueExpr ) ); return deref; } virtual Expression * mutate( TupleIndexExpr * tupleExpr ) { // tuple index expr needs to be rebuilt to ensure that the type of the // field is consistent with the type of the tuple expr, since the field // may have changed from type T to T*. Expression * expr = tupleExpr->get_tuple()->acceptMutator( *this ); tupleExpr->set_tuple( nullptr ); TupleIndexExpr * ret = new TupleIndexExpr( expr, tupleExpr->get_index() ); delete tupleExpr; return ret; } }; } // namespace Expression * distributeAddr( Expression * expr ) { AddrExploder addrExploder; expr = expr->acceptMutator( addrExploder ); if ( ! addrExploder.foundUniqueExpr ) { expr = new AddressExpr( expr ); } return expr; } } // namespace Tuples // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //