Changes in / [85855b0:42cdd07d]
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/lstlang.sty
r85855b0 r42cdd07d 8 8 %% Created On : Sat May 13 16:34:42 2017 9 9 %% Last Modified By : Peter A. Buhr 10 %% Last Modified On : Mon Apr 15 11:28:44202411 %% Update Count : 4 310 %% Last Modified On : Fri May 31 14:36:02 2024 11 %% Update Count : 44 12 12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 13 … … 115 115 morekeywords={ 116 116 alignas, _Alignas, alignof, _Alignof, __alignof, __alignof__, and, asm, __asm, __asm__, _Atomic, __attribute, __attribute__, 117 __auto_type, basetypeof, _Bool, catch, catchResume, choose, coerce, corun, cofor, _Complex, __complex, __complex__,117 __auto_type, basetypeof, _Bool, bool, catch, catchResume, choose, coerce, corun, cofor, _Complex, __complex, __complex__, 118 118 __const, __const__, continue, coroutine, _Decimal32, _Decimal64, _Decimal128, disable, dtype, enable, exception, __extension__, 119 119 fallthrough, fallthru, finally, fixup, __float80, float80, __float128, float128, _Float16, _Float32, _Float32x, _Float64, -
doc/bibliography/pl.bib
r85855b0 r42cdd07d 813 813 title = {The Art of Multiprocessor Programming}, 814 814 year = 2008, 815 isbn = {0123705916, 9780123705914},816 815 publisher = {Morgan Kaufmann Publishers}, 817 816 address = {San Francisco}, … … 928 927 month = sep, 929 928 year = 2013, 930 pages = {46- -53},929 pages = {46-53}, 931 930 publisher = {ACM}, 932 931 address = {New York, NY, USA}, 932 } 933 934 @inproceedings{Aravind18, 935 contributer = {pabuhr@plg}, 936 author = {Alex Aravind}, 937 title = {Barrier Synchronization: Simplified, Generalized, and Solved without Mutual Exclusion}, 938 organization= {IEEE International Parallel and Distributed Processing Symposium Workshops}, 939 series = {IPDPSW'18}, 940 month = may, 941 year = 2018, 942 pages = {773-782}, 933 943 } 934 944 … … 1106 1116 publisher = {ACM}, 1107 1117 address = {New York, NY, USA}, 1118 } 1119 1120 @article{Brooks87, 1121 author = {Eugene D. Brooks III}, 1122 title = {The Butterfly Barrier}, 1123 journal = {International Journal of Parallel Programming}, 1124 volume = 15, 1125 number = 4, 1126 pages = {295-307}, 1127 year = 1987, 1108 1128 } 1109 1129 … … 4340 4360 chapter = {1}, 4341 4361 publisher = {The MIT Press} 4362 } 4363 4364 @article{Lamport08, 4365 keywords = {concurrency, barrier}, 4366 contributer = {pabuhr@plg}, 4367 author = {Leslie Lamport}, 4368 title = {Implementing Dataflow with Threads}, 4369 journal = {Distributed Computing}, 4370 year = 2008, 4371 month = jul, 4372 volume = 21, 4373 number = 3, 4374 pages = {163-181}, 4342 4375 } 4343 4376 … … 5171 5204 journal = {ACM Trans. Parallel Comput.}, 5172 5205 issn = {2329-4949}, 5173 url = {https://doi.org/10.1145/3584696},5174 doi = {10.1145/3584696},5175 5206 articleno = 11, 5176 5207 numpages = 23, … … 7769 7800 } 7770 7801 7802 @book{Scott24, 7803 author = {Michael L. Scott and Trevor Brown}, 7804 booktitle = {Shared-Memory Synchronization}, 7805 series = {Synthesis Lectures on Computer Architecture}, 7806 edition = {2nd}, 7807 year = 2024, 7808 publisher = {Springer International Publishing}, 7809 address = {Cham, Switzerland}, 7810 } 7811 7771 7812 @inproceedings{Leissa14, 7772 7813 title = {{S}ierra: a {SIMD} extension for {C}++}, … … 8661 8702 } 8662 8703 8704 @article{Hensgen88, 8705 author = {Debra Hensgen and Raphael Finkel and Udi Manber}, 8706 title = {Two algorithms for barrier synchronization}, 8707 journal = {International Journal of Parallel Programming}, 8708 volume = 17, 8709 number = 1, 8710 pages = {1-17}, 8711 year = 1988, 8712 } 8713 8663 8714 @article{Leroy00, 8664 8715 keywords = {type-systems, exceptions}, … … 8752 8803 title = {Understanding Control Flow: Concurrent Programming using $\mu${C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}}}, 8753 8804 publisher = {Springer}, 8754 address = { Switzerland},8805 address = {Cham, Switzerland}, 8755 8806 year = 2016, 8756 8807 } -
doc/proposals/modules.md
r85855b0 r42cdd07d 5 5 ====================== 6 6 7 Modules are a term for the base in separate compilation. Different languages have different ways to implement it, for C/C++ the module is the code/source file and usually header file. 7 In this proposal we will be descussing modules. Although their exact nature changes between programming languages, modules are the smallest unit of code reuse between programs, or the base unit in separate compilation. Modules, and the extended module system, will be tied up in various stages of compilation and execution, with a particular focus on visibility between different parts of the program. 8 9 Note that terminology is not fixed across languages. For instance, some languages use the word package or library instead. Module was chosen as the generic term because it seems to have the least amount of other uses (for example, a package is sometimes a group of modules). 10 11 In C there is no formal definition of module, but informally modules are a pair of files, the body file (.c) and the header (.h). The header provides the interface and the body file gives the implementation. (A translation unit is a source file, usually a .c file, and all the recursively included files.) Some modules, like the main module, 8 12 9 13 Uses of Modules 10 14 --------------- 11 The most straight forward purpose of modules is to enable separate compilation. 12 This in turn reduces recompilation, by isolating changes, and parallel compilation, but making modules independent. 15 This section covers the features module system to allow for the separatation of code across modules and why 13 16 14 An related feature is sharing information between modules. Information needed by other modules must be shared. However, avoiding sharing extra information can further isolating changes, and can also reduces the work of compiling a single module.17 Modules are often, but not always, the means by which a language views source files. There is almost always some kind of parity between modules and source files, with modules being mapped onto one (or a few) source files. Sometimes the use of modules is used to find the approprate source files, requring this parity to be enforced in the language. Other times the parity is just a convention or is enforced for other reasons. 15 18 16 Modules are also used as a base for other organizational features. Such as namespacing on module names, using the module as a space for visibility modifiers. 19 [] 20 21 If there is a universal feature of modules, it is information visibility. Modules decide what information within them is visible to other modules. Here visibility is the course grained sense of "visible in another module for any purpose". 22 23 [] 24 25 Accessablity is the more fine grained partner to visibility, allowing for information to be visible, but only usable for certain purposes. This includes privacy and friendship - only usable in certain parts of the program - or inlining information - only usable by the optimizer. 26 27 In languages that have namespacing/qualified-names, modules will often interact with namespaces. Such as each module placing its declarations in a namespace of the same name. 17 28 18 29 C Comparisons … … 80 91 Second, this does nothing to solve the oversized header issue. It does not reduce any requirements on what includes need to be use. 81 92 93 Alternate Solutions 94 ------------------- 95 There are other ways C's modules could be improved in Cforall. 96 97 Explicit Module Blocks 98 ...................... 99 Instead of trying map files to modules, they could instead be declared explicitly. Marking out the beginning and the end of a section of code as a module. If built on top of the body/header and include system might look like this. 100 101 > extern module NAME { 102 > BODY 103 > } 104 > 105 > module NAME { 106 > BODY 107 > } 108 109 The extern module goes in the header, the other module goes in the body. The basic usage is the forward declarations in the header module and the body contains the definitions. It can be used to check that the two sets match, but on its own it is only replicates the current header/body divide with a bit more explicit syntax. However, it can be used as the base for a lot of features of the module linkage system. It does solve the "knowning two declarations came from the same other module" problem (and could work with namespaces) but is otherwise very similar for a heavier syntax. 110 111 Compiled Headers 112 ................ 113 Most programming languages do not share source code between modules. Instead each module is compiled without looking at the source code in other modules. The result of compilation includes all the information required for later stages of compilation and information for compiling other modules. 114 115 This is a more popular pattern more recent programming languages. It does have some advantages, such as reducing the amount of times that a file will need to be processed and can cut out unneeded transitive information. It is downsides include adding dependences between modules and it prevents any circlar dependences between modules. 116 117 There is one other notable downside, and that is retrofitting this pattern on top of C. The problems with GCC precompiled headers and C++ modules give some indication of how tricky the situation is. The problem is the C pre-processor, not only is this the tool by which modules are implemented, but they contain information for the preprocessor itself, such as macros. Macro definitions must also be applied to the text of source files and so must be preserved. This might be possible in cases with strict dependences from the included file, but there are more unusual uses where macros depend on their context (previous includes or a define before the include) in their definition and these would almost imposible to translate over. 82 118 83 119 ########################################################################################## … … 86 122 ----' 87 123 88 Programming languages are divided into those embedded in an IDE, think Smalltalk and Racket, largely manipulating a symbol-table/abstract-symbol-tree, and those where the IDE is an external program largely manipulating program text.124 Programming languages are divided into those embedded in an IDE, think Smalltalk and Lisp, Database, largely manipulating a symbol-table/abstract-symbol-tree, and those where the IDE is an external program largely manipulating program text. 89 125 Separate compilation in programming languages without an embedded IDE is the process of giving a compiler command a series of files that are read and processed as a whole. 90 126 The compiler output is placed in another set of files for execution loading or further processing. … … 97 133 In a file system where file-links can be embedded in data creating a tree, duplicate source code can be eliminated by generating a complex linking structure among the source files. 98 134 Without embedded file-links, dynamic embedding using #include/import is necessary to compose all the program components necessary for a compilation. 135 136 inlining? 99 137 100 138 I see two separate issues with respect to program structuring for controlling visibility and initializing a program. -
src/InitTweak/GenInit.cpp
r85855b0 r42cdd07d 32 32 #include "Common/ToString.hpp" // for toCString 33 33 #include "Common/UniqueName.hpp" // for UniqueName 34 #include "Common/Utility.hpp" // for ValueGuard, maybeClone35 34 #include "GenPoly/GenPoly.hpp" // for getFunctionType, isPolyType 36 35 #include "GenPoly/ScopedSet.hpp" // for ScopedSet, ScopedSet<>::const_iter... … … 277 276 } 278 277 // need to clear and reset qualifiers when determining if a type is managed 279 // ValueGuard< Type::Qualifiers > qualifiers( type->get_qualifiers() );280 278 auto tmp = shallowCopy(type); 281 279 tmp->qualifiers = {}; -
src/Tuples/TupleAssignment.cpp
r85855b0 r42cdd07d 241 241 ResolvExpr::CandidateFinder & crntFinder; 242 242 std::string fname; 243 std::unique_ptr< Matcher > matcher;244 243 245 244 public: 246 245 TupleAssignSpotter( ResolvExpr::CandidateFinder & f ) 247 : crntFinder( f ), fname() , matcher(){}248 249 // Find left- and right-hand-sides for mass or multiple assignment.246 : crntFinder( f ), fname() {} 247 248 /// Find left- and right-hand-sides for mass or multiple assignment. 250 249 void spot( 251 250 const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 252 ) { 253 if ( auto op = expr->func.as< ast::NameExpr >() ) { 254 // Skip non-assignment functions. 255 if ( !CodeGen::isCtorDtorAssign( op->name ) ) return; 256 fname = op->name; 257 258 // Handled by CandidateFinder if applicable (both odd cases). 259 if ( args.empty() || ( 1 == args.size() && CodeGen::isAssignment( fname ) ) ) { 260 return; 261 } 262 263 // Look over all possible left-hand-side. 264 for ( ResolvExpr::CandidateRef & lhsCand : args[0] ) { 265 // Skip non-tuple LHS. 266 if ( !refToTuple( lhsCand->expr ) ) continue; 267 268 // Explode is aware of casts - ensure every LHS 269 // is sent into explode with a reference cast. 270 if ( !lhsCand->expr.as< ast::CastExpr >() ) { 271 lhsCand->expr = new ast::CastExpr( 272 lhsCand->expr, new ast::ReferenceType( lhsCand->expr->result ) ); 251 ); 252 /// Wrapper around matcher.match. 253 void match( Matcher & matcher ); 254 }; 255 256 void TupleAssignSpotter::spot( 257 const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 258 ) { 259 // Skip non-"assignment" functions. 260 auto op = expr->func.as< ast::NameExpr >(); 261 if ( nullptr == op || !CodeGen::isCtorDtorAssign( op->name ) ) return; 262 263 // Handled by CandidateFinder if applicable (both odd cases). 264 if ( args.empty() || ( 1 == args.size() && CodeGen::isAssignment( op->name ) ) ) { 265 return; 266 } 267 268 fname = op->name; 269 270 // Look over all possible left-hand-side. 271 for ( ResolvExpr::CandidateRef & lhsCand : args[0] ) { 272 // Skip non-tuple LHS. 273 if ( !refToTuple( lhsCand->expr ) ) continue; 274 275 // Explode is aware of casts - ensure every LHS 276 // is sent into explode with a reference cast. 277 if ( !lhsCand->expr.as< ast::CastExpr >() ) { 278 lhsCand->expr = new ast::CastExpr( 279 lhsCand->expr, new ast::ReferenceType( lhsCand->expr->result ) ); 280 } 281 282 // Explode the LHS so that each field of a tuple-valued expr is assigned. 283 ResolvExpr::CandidateList lhs; 284 explode( *lhsCand, crntFinder.context.symtab, back_inserter(lhs), true ); 285 for ( ResolvExpr::CandidateRef & cand : lhs ) { 286 // Each LHS value must be a reference - some come in 287 // with a cast, if not just cast to reference here. 288 if ( !cand->expr->result.as< ast::ReferenceType >() ) { 289 cand->expr = new ast::CastExpr( 290 cand->expr, new ast::ReferenceType( cand->expr->result ) ); 291 } 292 } 293 294 if ( 1 == args.size() ) { 295 // Mass default-initialization/destruction. 296 ResolvExpr::CandidateList rhs{}; 297 MassAssignMatcher matcher( *this, expr->location, lhs, rhs ); 298 match( matcher ); 299 } else if ( 2 == args.size() ) { 300 for ( const ResolvExpr::CandidateRef & rhsCand : args[1] ) { 301 ResolvExpr::CandidateList rhs; 302 if ( isTuple( rhsCand->expr ) ) { 303 // Multiple assignment: 304 explode( *rhsCand, crntFinder.context.symtab, back_inserter( rhs ), true ); 305 MultipleAssignMatcher matcher( *this, expr->location, lhs, rhs ); 306 match( matcher ); 307 } else { 308 // Mass assignment: 309 rhs.emplace_back( rhsCand ); 310 MassAssignMatcher matcher( *this, expr->location, lhs, rhs ); 311 match( matcher ); 273 312 } 274 275 // Explode the LHS so that each field of a tuple-valued expr is assigned. 276 ResolvExpr::CandidateList lhs; 277 explode( *lhsCand, crntFinder.context.symtab, back_inserter(lhs), true ); 278 for ( ResolvExpr::CandidateRef & cand : lhs ) { 279 // Each LHS value must be a reference - some come in 280 // with a cast, if not just cast to reference here. 281 if ( !cand->expr->result.as< ast::ReferenceType >() ) { 282 cand->expr = new ast::CastExpr( 283 cand->expr, new ast::ReferenceType( cand->expr->result ) ); 284 } 285 } 286 287 if ( 1 == args.size() ) { 288 // Mass default-initialization/destruction. 289 ResolvExpr::CandidateList rhs{}; 290 matcher.reset( new MassAssignMatcher( *this, expr->location, lhs, rhs ) ); 291 match(); 292 } else if ( 2 == args.size() ) { 293 for ( const ResolvExpr::CandidateRef & rhsCand : args[1] ) { 294 ResolvExpr::CandidateList rhs; 295 if ( isTuple( rhsCand->expr ) ) { 296 // Multiple assignment: 297 explode( *rhsCand, crntFinder.context.symtab, back_inserter( rhs ), true ); 298 matcher.reset( 299 new MultipleAssignMatcher( *this, expr->location, lhs, rhs ) ); 300 } else { 301 // Mass assignment: 302 rhs.emplace_back( rhsCand ); 303 matcher.reset( 304 new MassAssignMatcher( *this, expr->location, lhs, rhs ) ); 305 } 306 match(); 307 } 308 } else { 309 // Expand all possible RHS possibilities. 310 std::vector< ResolvExpr::CandidateList > rhsCands; 311 combos( 312 std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) ); 313 for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) { 314 // Multiple assignment: 315 ResolvExpr::CandidateList rhs; 316 explode( rhsCand, crntFinder.context.symtab, back_inserter( rhs ), true ); 317 matcher.reset( 318 new MultipleAssignMatcher( *this, expr->location, lhs, rhs ) ); 319 match(); 320 } 321 } 322 } 323 } 324 } 325 326 void match() { 327 assert( matcher ); 328 329 std::vector< ast::ptr< ast::Expr > > newAssigns = matcher->match(); 330 331 if ( !( matcher->lhs.empty() && matcher->rhs.empty() ) ) { 332 // If both LHS and RHS are empty than this is the empty tuple 333 // case, wherein it's okay for newAssigns to be empty. Otherwise, 334 // return early so that no new candidates are generated. 335 if ( newAssigns.empty() ) return; 336 } 337 338 ResolvExpr::CandidateList crnt; 339 // Now resolve new assignments. 340 for ( const ast::Expr * expr : newAssigns ) { 341 PRINT( 342 std::cerr << "== resolving tuple assign ==" << std::endl; 343 std::cerr << expr << std::endl; 344 ) 345 346 ResolvExpr::CandidateFinder finder( crntFinder.context, matcher->env ); 347 finder.allowVoid = true; 348 349 try { 350 finder.find( expr, ResolvExpr::ResolveMode::withAdjustment() ); 351 } catch (...) { 352 // No match is not failure, just that this tuple assignment is invalid. 353 return; 354 } 355 356 ResolvExpr::CandidateList & cands = finder.candidates; 357 assert( 1 == cands.size() ); 358 assert( cands.front()->expr ); 359 crnt.emplace_back( std::move( cands.front() ) ); 360 } 361 362 // extract expressions from the assignment candidates to produce a list of assignments 363 // that together form a sigle candidate 364 std::vector< ast::ptr< ast::Expr > > solved; 365 for ( ResolvExpr::CandidateRef & cand : crnt ) { 366 solved.emplace_back( cand->expr ); 367 matcher->combineState( *cand ); 368 } 369 370 crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >( 371 new ast::TupleAssignExpr( 372 matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) ), 373 std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ), 374 ResolvExpr::sumCost( crnt ) + matcher->baseCost ) ); 375 } 376 }; 313 } 314 } else { 315 // Expand all possible RHS possibilities. 316 std::vector< ResolvExpr::CandidateList > rhsCands; 317 combos( 318 std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) ); 319 for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) { 320 // Multiple assignment: 321 ResolvExpr::CandidateList rhs; 322 explode( rhsCand, crntFinder.context.symtab, back_inserter( rhs ), true ); 323 MultipleAssignMatcher matcher( *this, expr->location, lhs, rhs ); 324 match( matcher ); 325 } 326 } 327 } 328 } 329 330 void TupleAssignSpotter::match( TupleAssignSpotter::Matcher & matcher ) { 331 std::vector< ast::ptr< ast::Expr > > newAssigns = matcher.match(); 332 333 if ( !( matcher.lhs.empty() && matcher.rhs.empty() ) ) { 334 // If both LHS and RHS are empty than this is the empty tuple 335 // case, wherein it's okay for newAssigns to be empty. Otherwise, 336 // return early so that no new candidates are generated. 337 if ( newAssigns.empty() ) return; 338 } 339 340 ResolvExpr::CandidateList crnt; 341 // Now resolve new assignments. 342 for ( const ast::Expr * expr : newAssigns ) { 343 PRINT( 344 std::cerr << "== resolving tuple assign ==" << std::endl; 345 std::cerr << expr << std::endl; 346 ) 347 348 ResolvExpr::CandidateFinder finder( crntFinder.context, matcher.env ); 349 finder.allowVoid = true; 350 351 try { 352 finder.find( expr, ResolvExpr::ResolveMode::withAdjustment() ); 353 } catch (...) { 354 // No match is not failure, just that this tuple assignment is invalid. 355 return; 356 } 357 358 ResolvExpr::CandidateList & cands = finder.candidates; 359 assert( 1 == cands.size() ); 360 assert( cands.front()->expr ); 361 crnt.emplace_back( std::move( cands.front() ) ); 362 } 363 364 // extract expressions from the assignment candidates to produce a list of assignments 365 // that together form a sigle candidate 366 std::vector< ast::ptr< ast::Expr > > solved; 367 for ( ResolvExpr::CandidateRef & cand : crnt ) { 368 solved.emplace_back( cand->expr ); 369 matcher.combineState( *cand ); 370 } 371 372 crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >( 373 new ast::TupleAssignExpr( 374 matcher.location, std::move( solved ), std::move( matcher.tmpDecls ) ), 375 std::move( matcher.env ), std::move( matcher.open ), std::move( matcher.need ), 376 ResolvExpr::sumCost( crnt ) + matcher.baseCost ) ); 377 } 377 378 378 379 } // anonymous namespace
Note: See TracChangeset
for help on using the changeset viewer.