Changes in / [36ebd03:4040425]
- Location:
- src
- Files:
-
- 5 edited
-
GenPoly/Box.cc (modified) (5 diffs)
-
GenPoly/DeclMutator.cc (modified) (8 diffs)
-
GenPoly/DeclMutator.h (modified) (1 diff)
-
SynTree/Constant.cc (modified) (2 diffs)
-
SynTree/Constant.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r36ebd03 r4040425 22 22 23 23 #include "Box.h" 24 #include "DeclMutator.h"25 24 #include "InstantiateGeneric.h" 26 25 #include "PolyMutator.h" … … 55 54 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 56 55 57 /// Adds layout-generation functions to polymorphic types58 class LayoutFunctionBuilder : public DeclMutator {59 unsigned int functionNesting; // current level of nested functions60 public:61 LayoutFunctionBuilder() : functionNesting( 0 ) {}62 63 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );64 virtual Declaration *mutate( StructDecl *structDecl );65 virtual Declaration *mutate( UnionDecl *unionDecl );66 };67 68 56 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 69 57 class Pass1 : public PolyMutator { … … 171 159 } // anonymous namespace 172 160 161 void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) { 162 for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 163 if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) { 164 (*i)->print( os ); 165 os << std::endl; 166 } // if 167 } // for 168 } 169 173 170 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging 174 171 template< typename MutatorType > … … 198 195 199 196 void box( std::list< Declaration *>& translationUnit ) { 200 LayoutFunctionBuilder layoutBuilder;201 197 Pass1 pass1; 202 198 Pass2 pass2; 203 199 MemberExprFixer memberFixer; 204 200 Pass3 pass3; 205 layoutBuilder.mutateDeclarationList( translationUnit );206 201 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 207 202 mutateTranslationUnit/*All*/( translationUnit, pass2 ); … … 211 206 } 212 207 213 ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////214 215 DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {216 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );217 mutateAll( functionDecl->get_oldDecls(), *this );218 ++functionNesting;219 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );220 --functionNesting;221 return functionDecl;222 }223 224 /// Get a list of type declarations that will affect a layout function225 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {226 std::list< TypeDecl * > otypeDecls;227 228 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {229 if ( decl->get_kind() == TypeDecl::Any ) {230 otypeDecls.push_back( *decl );231 }232 }233 234 return otypeDecls;235 }236 237 /// Adds parameters for otype layout to a function type238 void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {239 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );240 241 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {242 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( (*param)->get_base() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );243 }244 }245 246 /// Builds a layout function declaration247 FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) {248 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units249 // because each unit generates copies of the default routines for each aggregate.250 FunctionDecl *layoutDecl = new FunctionDecl(251 "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );252 layoutDecl->fixUniqueId();253 return layoutDecl;254 }255 256 /// Makes a unary operation257 Expression *makeOp( const std::string &name, Expression *arg ) {258 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );259 expr->get_args().push_back( arg );260 return expr;261 }262 263 /// Makes a binary operation264 Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) {265 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );266 expr->get_args().push_back( lhs );267 expr->get_args().push_back( rhs );268 return expr;269 }270 271 /// Returns the dereference of a local pointer variable272 Expression *derefVar( ObjectDecl *var ) {273 return makeOp( "*?", new VariableExpr( var ) );274 }275 276 /// makes an if-statement with a single-expression if-block and no then block277 Statement *makeCond( Expression *cond, Expression *ifPart ) {278 return new IfStmt( noLabels, cond, new ExprStmt( ifPart ), 0 );279 }280 281 /// makes a statement that assigns rhs to lhs if lhs < rhs282 Statement *makeAssignMax( Expression *lhs, Expression *rhs ) {283 return makeCond( makeOp( "?<?", lhs, rhs ), makeOp( "?=?", lhs->clone(), rhs->clone() ) );284 }285 286 /// makes a statement that aligns lhs to rhs (rhs should be an integer power of two)287 Statement *makeAlignTo( Expression *lhs, Expression *rhs ) {288 // check that the lhs is zeroed out to the level of rhs289 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) );290 // if not aligned, increment to alignment291 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) );292 return makeCond( ifCond, ifExpr );293 }294 295 /// adds an expression to a compound statement296 void addExpr( CompoundStmt *stmts, Expression *expr ) {297 stmts->get_kids().push_back( new ExprStmt( noLabels, expr ) );298 }299 300 /// adds a statement to a compound statement301 void addStmt( CompoundStmt *stmts, Statement *stmt ) {302 stmts->get_kids().push_back( stmt );303 }304 305 virtual Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {306 // do not generate layout function for "empty" tag structs307 if ( structDecl->get_members().empty() ) return structDecl;308 309 // get parameters that can change layout, exiting early if none310 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );311 if ( otypeParams.empty() ) return structDecl;312 313 // build layout function signature314 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );315 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );316 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );317 318 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );319 layoutFnType->get_parameters().push_back( sizeParam );320 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );321 layoutFnType->get_parameters().push_back( alignParam );322 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );323 layoutFnType->get_parameters().push_back( offsetParam );324 addOtypeParams( layoutFnType, otypeParams );325 326 // build function decl327 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType );328 329 // calculate struct layout in function body330 331 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size332 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) );333 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );334 unsigned long n_members = 0;335 bool firstMember = true;336 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) {337 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );338 assert( dwt );339 340 if ( firstMember ) {341 firstMember = false;342 } else {343 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment344 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( dwt->get_type() ) ) );345 }346 347 // place current size in the current offset index348 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),349 derefVar( sizeParam ) ) );350 ++n_members;351 352 // add member size to current size353 addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( dwt->get_type() ) ) );354 355 // take max of member alignment and global alignment356 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( dwt->get_type() ) ) );357 }358 // make sure the type is end-padded to a multiple of its alignment359 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );360 361 addDeclarationAfter( layoutDecl );362 return structDecl;363 }364 365 virtual Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {366 // do not generate layout function for "empty" tag unions367 if ( unionDecl->get_members().empty() ) return unionDecl;368 369 // get parameters that can change layout, exiting early if none370 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );371 if ( otypeParams.empty() ) return unionDecl;372 373 // build layout function signature374 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );375 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );376 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );377 378 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );379 layoutFnType->get_parameters().push_back( sizeParam );380 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );381 layoutFnType->get_parameters().push_back( alignParam );382 addOtypeParams( layoutFnType, otypeParams );383 384 // build function decl385 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType );386 387 // calculate union layout in function body388 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );389 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );390 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) {391 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );392 assert( dwt );393 394 // take max member size and global size395 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( dwt->get_type() ) ) );396 397 // take max of member alignment and global alignment398 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( dwt->get_type() ) ) );399 }400 // make sure the type is end-padded to a multiple of its alignment401 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );402 403 addDeclarationAfter( layoutDecl );404 return unionDecl;405 }406 407 208 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 408 209 -
src/GenPoly/DeclMutator.cc
r36ebd03 r4040425 24 24 } 25 25 26 DeclMutator::DeclMutator() : Mutator(), declsToAdd(1) , declsToAddAfter(1){}26 DeclMutator::DeclMutator() : Mutator(), declsToAdd(1) {} 27 27 28 28 DeclMutator::~DeclMutator() {} 29 29 30 30 void DeclMutator::mutateDeclarationList( std::list< Declaration* > &decls ) { 31 for ( std::list< Declaration* >::iterator decl = decls.begin(); ; ++decl ) { 32 // splice in new declarations after previous decl 33 decls.splice( decl, declsToAddAfter.back() ); 34 35 if ( decl == decls.end() ) break; 36 31 for ( std::list< Declaration* >::iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 37 32 // run mutator on declaration 38 33 *decl = maybeMutate( *decl, *this ); … … 44 39 45 40 void DeclMutator::doBeginScope() { 46 // add new decl list sfor inside of scope41 // add new decl list for inside of scope 47 42 declsToAdd.resize( declsToAdd.size()+1 ); 48 declsToAddAfter.resize( declsToAddAfter.size()+1 );49 43 } 50 44 … … 55 49 newBack->splice( newBack->end(), *back ); 56 50 declsToAdd.pop_back(); 57 58 back = declsToAddAfter.rbegin();59 newBack = back + 1;60 newBack->splice( newBack->end(), *back );61 declsToAddAfter.pop_back();62 51 } 63 52 … … 72 61 stmt = maybeMutate( stmt, *this ); 73 62 // return if no declarations to add 74 if ( declsToAdd.back().empty() && declsToAddAfter.back().empty() ) { 75 doEndScope(); 76 return stmt; 77 } 63 if ( declsToAdd.back().empty() ) return stmt; 78 64 79 65 // otherwise add declarations to new compound statement … … 85 71 declsToAdd.back().clear(); 86 72 87 // add mutated statement 73 doEndScope(); 74 75 // add mutated statement and return 88 76 compound->get_kids().push_back( stmt ); 89 90 // add declarations after to new compound statement91 for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) {92 DeclStmt *declStmt = new DeclStmt( noLabels, *decl );93 compound->get_kids().push_back( declStmt );94 }95 declsToAddAfter.back().clear();96 97 doEndScope();98 77 return compound; 99 78 } … … 101 80 void DeclMutator::mutateStatementList( std::list< Statement* > &stmts ) { 102 81 doBeginScope(); 103 104 82 105 for ( std::list< Statement* >::iterator stmt = stmts.begin(); ; ++stmt ) { 106 // add any new declarations after the previous statement 107 for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) { 108 DeclStmt *declStmt = new DeclStmt( noLabels, *decl ); 109 stmts.insert( stmt, declStmt ); 110 } 111 declsToAddAfter.back().clear(); 112 113 if ( stmt == stmts.end() ) break; 114 83 for ( std::list< Statement* >::iterator stmt = stmts.begin(); stmt != stmts.end(); ++stmt ) { 115 84 // run mutator on statement 116 85 *stmt = maybeMutate( *stmt, *this ); … … 123 92 declsToAdd.back().clear(); 124 93 } 125 94 126 95 doEndScope(); 127 96 } … … 129 98 void DeclMutator::addDeclaration( Declaration *decl ) { 130 99 declsToAdd.back().push_back( decl ); 131 }132 133 void DeclMutator::addDeclarationAfter( Declaration *decl ) {134 declsToAddAfter.back().push_back( decl );135 100 } 136 101 -
src/GenPoly/DeclMutator.h
r36ebd03 r4040425 55 55 /// Add a declaration to the list to be added before the current position 56 56 void addDeclaration( Declaration* decl ); 57 /// Add a declaration to the list to be added after the current position58 void addDeclarationAfter( Declaration* decl );59 57 private: 60 58 /// A stack of declarations to add before the current declaration or statement 61 59 std::vector< std::list< Declaration* > > declsToAdd; 62 /// A stack of declarations to add after the current declaration or statement63 std::vector< std::list< Declaration* > > declsToAddAfter;64 60 }; 65 61 } // namespace -
src/SynTree/Constant.cc
r36ebd03 r4040425 16 16 #include <iostream> 17 17 #include <list> 18 #include <string>19 18 20 19 #include "Constant.h" … … 29 28 30 29 Constant::~Constant() { delete type; } 31 32 Constant Constant::from( int i ) {33 return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ) );34 }35 36 Constant Constant::from( unsigned long i ) {37 return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ) );38 }39 40 Constant Constant::from( double d ) {41 return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ) );42 }43 30 44 31 Constant *Constant::clone() const { assert( false ); return 0; } -
src/SynTree/Constant.h
r36ebd03 r4040425 32 32 void set_value( std::string newValue ) { value = newValue; } 33 33 34 /// generates an integer constant of the given int35 static Constant from( int i );36 /// generates an integer constant of the given unsigned long int37 static Constant from( unsigned long i );38 /// generates a floating point constant of the given double39 static Constant from( double d );40 41 34 virtual Constant *clone() const; 42 35 virtual void accept( Visitor &v ) { v.visit( this ); }
Note:
See TracChangeset
for help on using the changeset viewer.