Changeset ad861ef
- Timestamp:
- Jan 20, 2023, 1:25:37 PM (2 months ago)
- Branches:
- master
- Children:
- 79a6b17, cd5eb4b
- Parents:
- 466787a (diff), a0d1f1c (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. - Files:
-
- 19 added
- 3 deleted
- 51 edited
- 27 moved
Legend:
- Unmodified
- Added
- Removed
-
configure.ac
r466787a rad861ef 226 226 AC_PROG_YACC 227 227 if test "${YACC}" = "yacc" ; then echo "Error: bison required." ; exit 1 ; fi 228 AC_PROG_LEX 228 AC_PROG_LEX(yywrap) 229 229 if test "${LEX}" = "lex" ; then echo "Error: flex required." ; exit 1 ; fi 230 AC_PROG_LIBTOOL 230 LT_INIT 231 231 AC_PROG_INSTALL 232 232 … … 284 284 tools/Makefile 285 285 tools/prettyprinter/Makefile 286 benchmark/Cargo.toml 286 287 ]) 287 288 AC_OUTPUT(benchmark/Cargo.toml)289 288 ]) 290 289 291 290 AC_CONFIG_LINKS([tests/test.py:tests/test.py]) 292 293 AC_OUTPUT(tests/config.py) 291 AC_CONFIG_FILES([tests/config.py]) 292 293 AC_OUTPUT 294 294 295 295 # Final text -
libcfa/configure.ac
r466787a rad861ef 122 122 AC_PROG_CC 123 123 AM_PROG_AS 124 AC_PROG_LIBTOOL 124 LT_INIT 125 125 AC_PROG_INSTALL 126 126 AC_PROG_MAKE_SET … … 246 246 AC_CONFIG_HEADERS(prelude/defines.hfa) 247 247 248 AC_OUTPUT ()248 AC_OUTPUT 249 249 250 250 # Final text -
libcfa/src/Makefile.am
r466787a rad861ef 113 113 concurrency/once.hfa \ 114 114 concurrency/kernel/fwd.hfa \ 115 concurrency/mutex_stmt.hfa 115 concurrency/mutex_stmt.hfa \ 116 concurrency/select.hfa \ 117 concurrency/channel.hfa 116 118 117 119 inst_thread_headers_src = \ -
libcfa/src/concurrency/clib/cfathread.cfa
r466787a rad861ef 439 439 // Mutex 440 440 struct cfathread_mutex { 441 linear_backoff_then_block_lock impl;441 exp_backoff_then_block_lock impl; 442 442 }; 443 443 int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict) __attribute__((nonnull (1))) { *mut = new(); return 0; } … … 454 454 // Condition 455 455 struct cfathread_condition { 456 condition_variable( linear_backoff_then_block_lock) impl;456 condition_variable(exp_backoff_then_block_lock) impl; 457 457 }; 458 458 int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict) __attribute__((nonnull (1))) { *cond = new(); return 0; } -
libcfa/src/concurrency/future.hfa
r466787a rad861ef 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // io/types.hfa --8 // 9 // Author : Thierry Delisle & Peiran Hong 7 // concurrency/future.hfa -- 8 // 9 // Author : Thierry Delisle & Peiran Hong & Colby Parsons 10 10 // Created On : Wed Jan 06 17:33:18 2021 11 11 // Last Modified By : … … 14 14 // 15 15 16 #pragma once16 // #pragma once 17 17 18 18 #include "bits/locks.hfa" 19 19 #include "monitor.hfa" 20 20 #include "select.hfa" 21 22 //---------------------------------------------------------------------------- 23 // future 24 // I don't use future_t here since I need to use a lock for this future 25 // since it supports multiple consumers 26 // future_t is lockfree and uses atomics which aren't needed given we use locks here 21 27 forall( T ) { 28 // enum(int) { FUTURE_EMPTY = 0, FUTURE_FULFILLED = 1 }; // Enums seem to be broken so feel free to add this back afterwards 29 30 // temporary enum replacement 31 const int FUTURE_EMPTY = 0; 32 const int FUTURE_FULFILLED = 1; 33 22 34 struct future { 35 int state; 36 T result; 37 dlist( select_node ) waiters; 38 futex_mutex lock; 39 }; 40 41 struct future_node { 42 inline select_node; 43 T * my_result; 44 }; 45 46 // C_TODO: perhaps allow exceptions to be inserted like uC++? 47 48 static inline { 49 50 void ?{}( future_node(T) & this, thread$ * blocked_thread, T * my_result ) { 51 ((select_node &)this){ blocked_thread }; 52 this.my_result = my_result; 53 } 54 55 void ?{}(future(T) & this) { 56 this.waiters{}; 57 this.state = FUTURE_EMPTY; 58 this.lock{}; 59 } 60 61 // Reset future back to original state 62 void reset(future(T) & this) with(this) 63 { 64 lock( lock ); 65 if( ! waiters`isEmpty ) 66 abort("Attempting to reset a future with blocked waiters"); 67 state = FUTURE_EMPTY; 68 unlock( lock ); 69 } 70 71 // check if the future is available 72 // currently no mutual exclusion because I can't see when you need this call to be synchronous or protected 73 bool available( future(T) & this ) { return this.state; } 74 75 76 // memcpy wrapper to help copy values 77 void copy_T( T & from, T & to ) { 78 memcpy((void *)&to, (void *)&from, sizeof(T)); 79 } 80 81 // internal helper to signal waiters off of the future 82 void _internal_flush( future(T) & this ) with(this) { 83 while( ! waiters`isEmpty ) { 84 select_node &s = try_pop_front( waiters ); 85 86 if ( s.race_flag == 0p ) 87 // poke in result so that woken threads do not need to reacquire any locks 88 // *(((future_node(T) &)s).my_result) = result; 89 copy_T( result, *(((future_node(T) &)s).my_result) ); 90 else if ( !install_select_winner( s, &this ) ) continue; 91 92 // only unpark if future is not selected 93 // or if it is selected we only unpark if we win the race 94 unpark( s.blocked_thread ); 95 } 96 } 97 98 // Fulfil the future, returns whether or not someone was unblocked 99 bool fulfil( future(T) & this, T & val ) with(this) { 100 lock( lock ); 101 if( state != FUTURE_EMPTY ) 102 abort("Attempting to fulfil a future that has already been fulfilled"); 103 104 copy_T( val, result ); 105 106 bool ret_val = ! waiters`isEmpty; 107 state = FUTURE_FULFILLED; 108 _internal_flush( this ); 109 unlock( lock ); 110 return ret_val; 111 } 112 113 // Wait for the future to be fulfilled 114 // Also return whether the thread had to block or not 115 [T, bool] get( future(T) & this ) with( this ) { 116 lock( lock ); 117 T ret_val; 118 if( state == FUTURE_FULFILLED ) { 119 copy_T( result, ret_val ); 120 unlock( lock ); 121 return [ret_val, false]; 122 } 123 124 future_node(T) node = { active_thread(), &ret_val }; 125 insert_last( waiters, ((select_node &)node) ); 126 unlock( lock ); 127 park( ); 128 129 return [ret_val, true]; 130 } 131 132 // Wait for the future to be fulfilled 133 T get( future(T) & this ) { 134 [T, bool] tt; 135 tt = get(this); 136 return tt.0; 137 } 138 139 // Gets value if it is available and returns [ val, true ] 140 // otherwise returns [ default_val, false] 141 // will not block 142 [T, bool] try_get( future(T) & this ) with(this) { 143 lock( lock ); 144 T ret_val; 145 if( state == FUTURE_FULFILLED ) { 146 copy_T( result, ret_val ); 147 unlock( lock ); 148 return [ret_val, true]; 149 } 150 unlock( lock ); 151 152 return [ret_val, false]; 153 } 154 155 void * register_select( future(T) & this, select_node & s ) with(this) { 156 lock( lock ); 157 158 // future not ready -> insert select node and return 0p 159 if( state == FUTURE_EMPTY ) { 160 insert_last( waiters, s ); 161 unlock( lock ); 162 return 0p; 163 } 164 165 // future ready and we won race to install it as the select winner return 1p 166 if ( install_select_winner( s, &this ) ) { 167 unlock( lock ); 168 return 1p; 169 } 170 171 unlock( lock ); 172 // future ready and we lost race to install it as the select winner 173 return 2p; 174 } 175 176 void unregister_select( future(T) & this, select_node & s ) with(this) { 177 lock( lock ); 178 if ( s`isListed ) remove( s ); 179 unlock( lock ); 180 } 181 182 } 183 } 184 185 //-------------------------------------------------------------------------------------------------------- 186 // These futures below do not support select statements so they may not be as useful as 'future' 187 // however the 'single_future' is cheap and cheerful and is most likely more performant than 'future' 188 // since it uses raw atomics and no locks afaik 189 // 190 // As far as 'multi_future' goes I can't see many use cases as it will be less performant than 'future' 191 // since it is monitor based and also is not compatible with select statements 192 //-------------------------------------------------------------------------------------------------------- 193 194 forall( T ) { 195 struct single_future { 23 196 inline future_t; 24 197 T result; … … 27 200 static inline { 28 201 // Reset future back to original state 29 void reset( future(T) & this) { reset( (future_t&)this ); }202 void reset(single_future(T) & this) { reset( (future_t&)this ); } 30 203 31 204 // check if the future is available 32 bool available( future(T) & this ) { return available( (future_t&)this ); }205 bool available( single_future(T) & this ) { return available( (future_t&)this ); } 33 206 34 207 // Mark the future as abandoned, meaning it will be deleted by the server 35 208 // This doesn't work beause of the potential need for a destructor 36 void abandon( future(T) & this );209 void abandon( single_future(T) & this ); 37 210 38 211 // Fulfil the future, returns whether or not someone was unblocked 39 thread$ * fulfil( future(T) & this, T result ) {212 thread$ * fulfil( single_future(T) & this, T result ) { 40 213 this.result = result; 41 214 return fulfil( (future_t&)this ); … … 44 217 // Wait for the future to be fulfilled 45 218 // Also return whether the thread had to block or not 46 [T, bool] wait( future(T) & this ) {219 [T, bool] wait( single_future(T) & this ) { 47 220 bool r = wait( (future_t&)this ); 48 221 return [this.result, r]; … … 50 223 51 224 // Wait for the future to be fulfilled 52 T wait( future(T) & this ) {225 T wait( single_future(T) & this ) { 53 226 [T, bool] tt; 54 227 tt = wait(this); -
libcfa/src/concurrency/locks.hfa
r466787a rad861ef 38 38 #include <unistd.h> 39 39 40 // undef to make a number of the locks not reacquire upon waking from a condlock 41 #define REACQ 1 40 // C_TODO: cleanup this and locks.cfa 41 // - appropriate separation of interface and impl 42 // - clean up unused/unneeded locks 43 // - change messy big blocking lock from inheritance to composition to remove need for flags 42 44 43 45 //----------------------------------------------------------------------------- … … 249 251 static inline void on_notify(clh_lock & this, struct thread$ * t ) { unpark(t); } 250 252 static inline size_t on_wait(clh_lock & this) { unlock(this); return 0; } 251 static inline void on_wakeup(clh_lock & this, size_t recursion ) { 252 #ifdef REACQ 253 lock(this); 254 #endif 255 } 256 257 258 //----------------------------------------------------------------------------- 259 // Linear backoff Spinlock 260 struct linear_backoff_then_block_lock { 253 static inline void on_wakeup(clh_lock & this, size_t recursion ) { lock(this); } 254 255 256 //----------------------------------------------------------------------------- 257 // Exponential backoff then block lock 258 struct exp_backoff_then_block_lock { 261 259 // Spin lock used for mutual exclusion 262 260 __spinlock_t spinlock; … … 269 267 }; 270 268 271 static inline void ?{}( linear_backoff_then_block_lock & this ) {269 static inline void ?{}( exp_backoff_then_block_lock & this ) { 272 270 this.spinlock{}; 273 271 this.blocked_threads{}; 274 272 this.lock_value = 0; 275 273 } 276 static inline void ^?{}( linear_backoff_then_block_lock & this ) {}277 // static inline void ?{}( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;278 // static inline void ?=?( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;279 280 static inline bool internal_try_lock( linear_backoff_then_block_lock & this, size_t & compare_val) with(this) {274 static inline void ^?{}( exp_backoff_then_block_lock & this ) {} 275 // static inline void ?{}( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void; 276 // static inline void ?=?( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void; 277 278 static inline bool internal_try_lock(exp_backoff_then_block_lock & this, size_t & compare_val) with(this) { 281 279 if (__atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { 282 280 return true; … … 285 283 } 286 284 287 static inline bool try_lock( linear_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }288 289 static inline bool try_lock_contention( linear_backoff_then_block_lock & this) with(this) {285 static inline bool try_lock(exp_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); } 286 287 static inline bool try_lock_contention(exp_backoff_then_block_lock & this) with(this) { 290 288 if (__atomic_exchange_n(&lock_value, 2, __ATOMIC_ACQUIRE) == 0) { 291 289 return true; … … 294 292 } 295 293 296 static inline bool block( linear_backoff_then_block_lock & this) with(this) {294 static inline bool block(exp_backoff_then_block_lock & this) with(this) { 297 295 lock( spinlock __cfaabi_dbg_ctx2 ); // TODO change to lockfree queue (MPSC) 298 296 if (lock_value != 2) { … … 306 304 } 307 305 308 static inline void lock( linear_backoff_then_block_lock & this) with(this) {306 static inline void lock(exp_backoff_then_block_lock & this) with(this) { 309 307 size_t compare_val = 0; 310 308 int spin = 4; … … 324 322 } 325 323 326 static inline void unlock( linear_backoff_then_block_lock & this) with(this) {324 static inline void unlock(exp_backoff_then_block_lock & this) with(this) { 327 325 if (__atomic_exchange_n(&lock_value, 0, __ATOMIC_RELEASE) == 1) return; 328 326 lock( spinlock __cfaabi_dbg_ctx2 ); … … 332 330 } 333 331 334 static inline void on_notify(linear_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); } 335 static inline size_t on_wait(linear_backoff_then_block_lock & this) { unlock(this); return 0; } 336 static inline void on_wakeup(linear_backoff_then_block_lock & this, size_t recursion ) { 337 #ifdef REACQ 338 lock(this); 339 #endif 340 } 332 static inline void on_notify(exp_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); } 333 static inline size_t on_wait(exp_backoff_then_block_lock & this) { unlock(this); return 0; } 334 static inline void on_wakeup(exp_backoff_then_block_lock & this, size_t recursion ) { lock(this); } 341 335 342 336 //----------------------------------------------------------------------------- … … 390 384 391 385 static inline void on_notify(fast_block_lock & this, struct thread$ * t ) with(this) { 392 #ifdef REACQ 393 lock( lock __cfaabi_dbg_ctx2 ); 394 insert_last( blocked_threads, *t ); 395 unlock( lock ); 396 #else 397 unpark(t); 398 #endif 386 lock( lock __cfaabi_dbg_ctx2 ); 387 insert_last( blocked_threads, *t ); 388 unlock( lock ); 399 389 } 400 390 static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; } … … 553 543 } 554 544 static inline size_t on_wait(spin_queue_lock & this) { unlock(this); return 0; } 555 static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { 556 #ifdef REACQ 557 lock(this); 558 #endif 559 } 545 static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { lock(this); } 560 546 561 547 … … 598 584 static inline void on_notify(mcs_block_spin_lock & this, struct thread$ * t ) { unpark(t); } 599 585 static inline size_t on_wait(mcs_block_spin_lock & this) { unlock(this); return 0; } 600 static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) { 601 #ifdef REACQ 602 lock(this); 603 #endif 604 } 586 static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {lock(this); } 605 587 606 588 //----------------------------------------------------------------------------- … … 640 622 641 623 static inline void on_notify(block_spin_lock & this, struct thread$ * t ) with(this.lock) { 642 #ifdef REACQ643 624 // first we acquire internal fast_block_lock 644 625 lock( lock __cfaabi_dbg_ctx2 ); … … 652 633 unlock( lock ); 653 634 654 #endif655 635 unpark(t); 656 657 636 } 658 637 static inline size_t on_wait(block_spin_lock & this) { unlock(this); return 0; } 659 638 static inline void on_wakeup(block_spin_lock & this, size_t recursion ) with(this) { 660 #ifdef REACQ661 639 // now we acquire the entire block_spin_lock upon waking up 662 640 while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause(); 663 641 __atomic_store_n(&held, true, __ATOMIC_RELEASE); 664 642 unlock( lock ); // Now we release the internal fast_spin_lock 665 #endif666 643 } 667 644 -
src/AST/Expr.cpp
r466787a rad861ef 30 30 #include "Common/SemanticError.h" 31 31 #include "GenPoly/Lvalue.h" // for referencesPermissable 32 #include "ResolvExpr/ typeops.h"// for extractResultType32 #include "ResolvExpr/Unify.h" // for extractResultType 33 33 #include "Tuples/Tuples.h" // for makeTupleType 34 34 -
src/AST/Node.hpp
r466787a rad861ef 19 19 #include <cstddef> // for nullptr_t 20 20 #include <iosfwd> 21 #include <type_traits> // for remove_reference22 21 23 22 #include "Common/ErrorObjects.h" // for SemanticErrorException … … 36 35 Node(const Node&) : strong_count(0), weak_count(0) {} 37 36 Node(Node&&) : strong_count(0), weak_count(0) {} 38 Node& operator= 39 Node& operator= 37 Node& operator=(const Node&) = delete; 38 Node& operator=(Node&&) = delete; 40 39 virtual ~Node() {} 41 40 -
src/AST/SymbolTable.cpp
r466787a rad861ef 22 22 #include "Inspect.hpp" 23 23 #include "Type.hpp" 24 #include "CodeGen/OperatorTable.h" // for isCtorDtorAssign24 #include "CodeGen/OperatorTable.h" // for isCtorDtorAssign 25 25 #include "Common/SemanticError.h" 26 26 #include "Common/Stats/Counter.h" … … 28 28 #include "InitTweak/InitTweak.h" 29 29 #include "ResolvExpr/Cost.h" 30 #include "ResolvExpr/typeops.h" 30 #include "ResolvExpr/CandidateFinder.hpp" // for referenceToRvalueConversion 31 #include "ResolvExpr/Unify.h" 31 32 #include "SymTab/Mangler.h" 32 33 -
src/CodeGen/CodeGenerator.cc
r466787a rad861ef 273 273 } 274 274 275 template<typename pass_type> 276 inline void genEnumInitializer( PassVisitor<pass_type> * visitor, Type * baseType, std::ostream & output, 277 Initializer * init, long long * cur_val, Options options) { 278 auto baseTypeAsBasic = baseType ? dynamic_cast<BasicType *>( baseType ) : nullptr; 279 if ( init ) { // If value has an explicit initiazatior 280 output << " = "; 281 output << "(" << genType(baseType, "", options) << ")"; 282 init->accept( *visitor ); 283 if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // if it is an integral type and initilizer offered, 284 // need to update the cur_val 285 Expression* expr = ((SingleInit *)(init))->value; 286 while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { // unwrap introduced cast 287 expr = temp->arg; 288 } 289 *cur_val = ((ConstantExpr *)expr)->constant.get_ival()+1; 290 } 291 } else if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // integral implicitly init to cur_val + 1 292 output << " = " << "(" << genType(baseType, "", options) << ")"; 293 output << (*cur_val)++; 294 } 295 } 296 275 297 void CodeGenerator::postvisit( EnumDecl * enumDecl ) { 276 298 extension( enumDecl ); 277 299 std::list< Declaration* > &memb = enumDecl->get_members(); 278 300 if (enumDecl->base && ! memb.empty()) { 279 unsigned long long last_val = -1; // if the first enum value has no explicit initializer, 280 // as other 301 long long cur_val = 0; 281 302 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 282 303 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); 283 304 assert( obj ); 284 305 output << "static "; 285 output << genType(enumDecl->base, "", options) << " const "; 286 output << mangleName( obj ) << " "; 287 output << " = "; 288 output << "(" << genType(enumDecl->base, "", options) << ")"; 289 if ( (BasicType *)(enumDecl->base) && ((BasicType *)(enumDecl->base))->isWholeNumber() ) { 290 if ( obj->get_init() ) { 291 obj->get_init()->accept( *visitor ); 292 Expression* expr = ((SingleInit *)(obj->init))->value; 293 while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { 294 expr = temp->arg; 295 } 296 last_val = ((ConstantExpr *)expr)->constant.get_ival(); 297 } else { 298 output << ++last_val; 299 } // if 300 } else { 301 if ( obj->get_init() ) { 302 obj->get_init()->accept( *visitor ); 303 } else { 304 // Should not reach here! 305 } 306 } 306 output << genType(enumDecl->base, mangleName( obj ), options); 307 genEnumInitializer( visitor, enumDecl->base, output, obj->get_init(), &cur_val, options); 307 308 output << ";" << endl; 308 309 } // for -
src/CodeGen/GenType.cc
r466787a rad861ef 255 255 void GenType::postvisit( EnumInstType * enumInst ) { 256 256 if ( enumInst->baseEnum && enumInst->baseEnum->base ) { 257 typeString = genType(enumInst->baseEnum->base, "", options) + typeString;257 typeString = genType(enumInst->baseEnum->base, typeString, options); 258 258 } else { 259 259 typeString = enumInst->name + " " + typeString; -
src/GenPoly/Box.cc
r466787a rad861ef 14 14 // 15 15 16 #include "Box.h" 17 16 18 #include <algorithm> // for mismatch 17 19 #include <cassert> // for assert, strict_dynamic_cast … … 23 25 #include <string> // for string, allocator, basic_string 24 26 #include <utility> // for pair 25 26 #include "Box.h"27 27 28 28 #include "CodeGen/OperatorTable.h" … … 37 37 #include "InitTweak/InitTweak.h" // for getFunctionName, isAssignment 38 38 #include "Lvalue.h" // for generalizedLvalue 39 #include "ResolvExpr/ typeops.h"// for typesCompatible39 #include "ResolvExpr/Unify.h" // for typesCompatible 40 40 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iter... 41 41 #include "ScrubTyVars.h" // for ScrubTyVars … … 911 911 912 912 for ( FunctionType const * const funType : functions ) { 913 FunctionType *originalFunction = funType->clone(); 914 FunctionType *realFunction = funType->clone(); 915 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 913 std::string mangleName = SymTab::Mangler::mangle( funType ); 916 914 917 915 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this 918 916 // pre-substitution parameter function type. 919 917 // The second part of the insert result is "is the value new". 920 if ( adaptersDone.insert( mangleName ).second ) { 921 922 // apply substitution to type variables to figure out what the adapter's type should look like 923 assert( env ); 924 env->apply( realFunction ); 925 mangleName = SymTab::Mangler::mangle( realFunction ); 926 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 927 928 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter; 929 AdapterIter adapter = adapters.find( mangleName ); 930 if ( adapter == adapters.end() ) { 931 // adapter has not been created yet in the current scope, so define it 932 FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars ); 933 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 934 adapter = answer.first; 935 stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) ); 936 } // if 937 assert( adapter != adapters.end() ); 938 939 // add the appropriate adapter as a parameter 940 appExpr->get_args().push_front( new VariableExpr( adapter->second ) ); 918 if ( !adaptersDone.insert( mangleName ).second ) continue; 919 920 // Apply substitution to type variables to figure out what the adapter's type should look like. 921 assert( env ); 922 FunctionType *realType = funType->clone(); 923 env->apply( realType ); 924 mangleName = SymTab::Mangler::mangle( realType ); 925 mangleName += makePolyMonoSuffix( funType, exprTyVars ); 926 927 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter; 928 AdapterIter adapter = adapters.find( mangleName ); 929 if ( adapter == adapters.end() ) { 930 // Adapter has not been created yet in the current scope, so define it. 931 FunctionDecl *newAdapter = makeAdapter( funType, realType, mangleName, exprTyVars ); 932 std::pair< AdapterIter, bool > answer = adapters.insert( mangleName, newAdapter ); 933 adapter = answer.first; 934 stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) ); 941 935 } // if 936 assert( adapter != adapters.end() ); 937 938 // Add the appropriate adapter as a parameter. 939 appExpr->args.push_front( new VariableExpr( adapter->second ) ); 942 940 } // for 943 941 } // passAdapters -
src/GenPoly/GenPoly.cc
r466787a rad861ef 24 24 #include <vector> // for vector 25 25 26 #include "AST/Expr.hpp" 26 27 #include "AST/Type.hpp" 28 #include "AST/TypeSubstitution.hpp" 27 29 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 28 30 #include "ResolvExpr/typeops.h" // for flatten … … 490 492 } 491 493 494 /// Flattens a list of types. 495 // There is another flattenList in Unify. 492 496 void flattenList( vector<ast::ptr<ast::Type>> const & src, 493 497 vector<ast::ptr<ast::Type>> & out ) { -
src/GenPoly/InstantiateGeneric.cc
r466787a rad861ef 28 28 #include "GenPoly.h" // for isPolyType, typesPolyCompatible 29 29 #include "InitTweak/InitTweak.h" 30 #include "ResolvExpr/typeops.h" 30 #include "ResolvExpr/AdjustExprType.hpp" // for adjustExprType 31 #include "ResolvExpr/Unify.h" // for typesCompatible 31 32 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 32 33 #include "ScrubTyVars.h" // for ScrubTyVars -
src/GenPoly/InstantiateGenericNew.cpp
r466787a rad861ef 32 32 #include "GenPoly/GenPoly.h" // for isPolyType, typesPolyCompatible 33 33 #include "GenPoly/ScrubTyVars.h" // for scrubAll 34 #include "ResolvExpr/typeops.h" // for typesCompatible 34 #include "ResolvExpr/AdjustExprType.hpp" // for adjustExprType 35 #include "ResolvExpr/Unify.h" // for typesCompatible 35 36 36 37 namespace GenPoly { -
src/InitTweak/FixInit.cc
r466787a rad861ef 39 39 #include "InitTweak.h" // for getFunctionName, getCallArg 40 40 #include "ResolvExpr/Resolver.h" // for findVoidExpression 41 #include "ResolvExpr/ typeops.h"// for typesCompatible41 #include "ResolvExpr/Unify.h" // for typesCompatible 42 42 #include "SymTab/Autogen.h" // for genImplicitCall 43 43 #include "SymTab/Indexer.h" // for Indexer -
src/InitTweak/FixInitNew.cpp
r466787a rad861ef 26 26 #include "GenPoly/GenPoly.h" // for getFunctionType 27 27 #include "ResolvExpr/Resolver.h" // for findVoidExpression 28 #include "ResolvExpr/ typeops.h"// for typesCompatible28 #include "ResolvExpr/Unify.h" // for typesCompatible 29 29 #include "SymTab/Autogen.h" // for genImplicitCall 30 30 #include "SymTab/Indexer.h" // for Indexer -
src/InitTweak/InitTweak.cc
r466787a rad861ef 35 35 #include "GenPoly/GenPoly.h" // for getFunctionType 36 36 #include "InitTweak.h" 37 #include "ResolvExpr/ typeops.h"// for typesCompatibleIgnoreQualifiers37 #include "ResolvExpr/Unify.h" // for typesCompatibleIgnoreQualifiers 38 38 #include "SymTab/Autogen.h" 39 39 #include "SymTab/Indexer.h" // for Indexer -
src/Parser/TypeData.cc
r466787a rad861ef 933 933 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) ); 934 934 } else if ( !cur->initializer ) { 935 if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->is WholeNumber())) {935 if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) { 936 936 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." ); 937 937 } -
src/ResolvExpr/AlternativeFinder.cc
r466787a rad861ef 14 14 // 15 15 16 #include "AlternativeFinder.h" 17 16 18 #include <algorithm> // for copy 17 19 #include <cassert> // for strict_dynamic_cast, assert, assertf … … 26 28 27 29 #include "CompilationState.h" // for resolvep 30 #include "AdjustExprType.hpp" // for adjustExprType 28 31 #include "Alternative.h" // for AltList, Alternative 29 #include "AlternativeFinder.h"30 32 #include "AST/Expr.hpp" 31 33 #include "AST/SymbolTable.hpp" 32 34 #include "AST/Type.hpp" 35 #include "CastCost.hpp" // for castCost 33 36 #include "Common/SemanticError.h" // for SemanticError 34 37 #include "Common/utility.h" // for deleteAll, printAll, CodeLocation 38 #include "ConversionCost.h" // for conversionCost 35 39 #include "Cost.h" // for Cost, Cost::zero, operator<<, Cost... 36 40 #include "ExplodedActual.h" // for ExplodedActual 37 41 #include "InitTweak/InitTweak.h" // for getFunctionName 42 #include "PolyCost.hpp" // for polyCost 38 43 #include "RenameVars.h" // for RenameVars, global_renamer 39 44 #include "ResolveAssertions.h" // for resolveAssertions 40 45 #include "ResolveTypeof.h" // for resolveTypeof 41 46 #include "Resolver.h" // for resolveStmtExpr 47 #include "SpecCost.hpp" // for specCost 42 48 #include "SymTab/Indexer.h" // for Indexer 43 49 #include "SymTab/Mangler.h" // for Mangler … … 51 57 #include "Tuples/Explode.h" // for explode 52 58 #include "Tuples/Tuples.h" // for isTtype, handleTupleAssignment 59 #include "typeops.h" // for combos 53 60 #include "Unify.h" // for unify 54 #include "typeops.h" // for adjustExprType, polyCost, castCost55 61 56 62 #define PRINT( text ) if ( resolvep ) { text } -
src/ResolvExpr/AlternativeFinder.h
r466787a rad861ef 34 34 namespace ResolvExpr { 35 35 struct ArgPack; 36 37 Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue, 38 const SymTab::Indexer & indexer, const TypeEnvironment & env ); 39 40 void referenceToRvalueConversion( Expression *& expr, Cost & cost ); 36 41 37 42 /// First index is which argument, second index is which alternative for that argument, -
src/ResolvExpr/CandidateFinder.cpp
r466787a rad861ef 23 23 #include <vector> 24 24 25 #include "AdjustExprType.hpp" 25 26 #include "Candidate.hpp" 27 #include "CastCost.hpp" // for castCost 26 28 #include "CompilationState.h" 29 #include "ConversionCost.h" // for conversionCast 27 30 #include "Cost.h" 28 31 #include "ExplodedArg.hpp" 32 #include "PolyCost.hpp" 29 33 #include "RenameVars.h" // for renameTyVars 30 34 #include "Resolver.h" 31 35 #include "ResolveTypeof.h" 32 36 #include "SatisfyAssertions.hpp" 33 #include "typeops.h" // for adjustExprType, conversionCost, polyCost, specCost 37 #include "SpecCost.hpp" 38 #include "typeops.h" // for combos 34 39 #include "Unify.h" 35 40 #include "AST/Expr.hpp" -
src/ResolvExpr/CandidateFinder.hpp
r466787a rad861ef 63 63 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 64 64 65 /// Create an expression that preforms reference to rvalue conversion on 66 /// the given expression and update the cost of the expression. 67 const ast::Expr * referenceToRvalueConversion( 68 const ast::Expr * expr, Cost & cost ); 69 65 70 } // namespace ResolvExpr 66 71 -
src/ResolvExpr/CastCost.cc
r466787a rad861ef 13 13 // Update Count : 9 14 14 // 15 16 #include "CastCost.hpp" 15 17 16 18 #include <cassert> // for assert … … 22 24 #include "ConversionCost.h" // for ConversionCost 23 25 #include "Cost.h" // for Cost, Cost::infinity 26 #include "ResolvExpr/ConversionCost.h" // for conversionCost 27 #include "ResolvExpr/PtrsCastable.hpp" // for ptrsCastable 24 28 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment, EqvClass 29 #include "ResolvExpr/typeops.h" // for ptrsCastable 30 #include "ResolvExpr/Unify.h" // for typesCompatibleIgnoreQualifiers 25 31 #include "SymTab/Indexer.h" // for Indexer 26 32 #include "SynTree/Declaration.h" // for TypeDecl, NamedTypeDecl 27 33 #include "SynTree/Type.h" // for PointerType, Type, TypeInstType 28 #include "typeops.h" // for typesCompatibleIgnoreQualifiers29 34 30 35 #if 0 -
src/ResolvExpr/CommonType.cc
r466787a rad861ef 13 13 // Update Count : 24 14 14 // 15 16 #include "CommonType.hpp" 15 17 16 18 #include <cassert> // for strict_dynamic_cast -
src/ResolvExpr/ConversionCost.cc
r466787a rad861ef 22 22 #include "ResolvExpr/Cost.h" // for Cost 23 23 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment 24 #include "ResolvExpr/Unify.h" 24 #include "ResolvExpr/Unify.h" // for typesCompatibleIgnoreQualifiers 25 #include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable 25 26 #include "SymTab/Indexer.h" // for Indexer 26 27 #include "SynTree/Declaration.h" // for TypeDecl, NamedTypeDecl 27 28 #include "SynTree/Type.h" // for Type, BasicType, TypeInstType 28 #include "typeops.h" // for typesCompatibleIgnoreQualifiers29 29 30 30 -
src/ResolvExpr/ConversionCost.h
r466787a rad861ef 32 32 namespace ResolvExpr { 33 33 class TypeEnvironment; 34 35 Cost conversionCost( 36 const Type * src, const Type * dest, bool srcIsLvalue, 37 const SymTab::Indexer & indexer, const TypeEnvironment & env ); 34 38 35 39 typedef std::function<Cost(const Type *, const Type *, bool, … … 80 84 const ast::SymbolTable &, const ast::TypeEnvironment &)>; 81 85 86 Cost conversionCost( 87 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue, 88 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 89 90 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest, 91 bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env, 92 PtrsCalculation func ); 93 82 94 #warning when the old ConversionCost is removed, get ride of the _new suffix. 83 95 class ConversionCost_new : public ast::WithShortCircuiting { … … 119 131 }; 120 132 121 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,122 bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env,123 PtrsCalculation func );124 125 133 } // namespace ResolvExpr 126 134 -
src/ResolvExpr/PtrsAssignable.cc
r466787a rad861ef 14 14 // 15 15 16 #include " typeops.h"16 #include "PtrsAssignable.hpp" 17 17 18 18 #include "AST/Pass.hpp" -
src/ResolvExpr/PtrsCastable.cc
r466787a rad861ef 14 14 // 15 15 16 #include "PtrsCastable.hpp" 17 16 18 #include "AST/Decl.hpp" 17 19 #include "AST/Pass.hpp" … … 19 21 #include "AST/TypeEnvironment.hpp" 20 22 #include "Common/PassVisitor.h" 23 #include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable 21 24 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment 22 25 #include "SymTab/Indexer.h" // for Indexer … … 24 27 #include "SynTree/Type.h" // for TypeInstType, Type, BasicType 25 28 #include "SynTree/Visitor.h" // for Visitor 26 #include "typeops.h" // for ptrsAssignable27 29 28 30 namespace ResolvExpr { … … 291 293 return objectCast( src, env, symtab ); 292 294 } else { 293 ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab }; 294 src->accept( ptrs ); 295 return ptrs.core.result; 295 return ast::Pass<PtrsCastable_new>::read( src, dst, env, symtab ); 296 296 } 297 297 } -
src/ResolvExpr/RenameVars.cc
r466787a rad861ef 83 83 84 84 const ast::TypeInstType * rename( const ast::TypeInstType * type ) { 85 // rename86 85 auto it = idMap.find( type->name ); 87 if ( it != idMap.end() ) { 88 // unconditionally mutate because map will *always* have different name 89 ast::TypeInstType * mut = ast::shallowCopy( type ); 90 // reconcile base node since some copies might have been made 91 mut->base = it->second.base; 92 mut->formal_usage = it->second.formal_usage; 93 mut->expr_id = it->second.expr_id; 94 type = mut; 95 } 96 97 return type; 86 if ( it == idMap.end() ) return type; 87 88 // Unconditionally mutate because map will *always* have different name. 89 ast::TypeInstType * mut = ast::shallowCopy( type ); 90 // Reconcile base node since some copies might have been made. 91 mut->base = it->second.base; 92 mut->formal_usage = it->second.formal_usage; 93 mut->expr_id = it->second.expr_id; 94 return mut; 98 95 } 99 96 … … 187 184 188 185 const ast::Type * renameTyVars( const ast::Type * t, RenameMode mode, bool reset ) { 189 // ast::Type *tc = ast::deepCopy(t);190 186 ast::Pass<RenameVars_new> renamer; 191 187 renamer.core.mode = mode; -
src/ResolvExpr/ResolveAssertions.cc
r466787a rad861ef 26 26 #include <vector> // for vector 27 27 28 #include "AdjustExprType.hpp" // for adjustExprType 28 29 #include "Alternative.h" // for Alternative, AssertionItem, AssertionList 29 30 #include "Common/FilterCombos.h" // for filterCombos … … 31 32 #include "Common/utility.h" // for sort_mins 32 33 #include "GenPoly/GenPoly.h" // for getFunctionType 34 #include "ResolvExpr/AlternativeFinder.h" // for computeConversionCost 33 35 #include "ResolvExpr/RenameVars.h" // for renameTyVars 36 #include "SpecCost.hpp" // for specCost 34 37 #include "SymTab/Indexer.h" // for Indexer 35 38 #include "SymTab/Mangler.h" // for Mangler 36 39 #include "SynTree/Expression.h" // for InferredParams 37 40 #include "TypeEnvironment.h" // for TypeEnvironment, etc. 38 #include "typeops.h" // for adjustExprType, specCost39 41 #include "Unify.h" // for unify 40 42 -
src/ResolvExpr/SatisfyAssertions.cpp
r466787a rad861ef 23 23 #include <vector> 24 24 25 #include "AdjustExprType.hpp" 25 26 #include "Candidate.hpp" 26 27 #include "CandidateFinder.hpp" 28 #include "CommonType.hpp" 27 29 #include "Cost.h" 28 30 #include "RenameVars.h" 31 #include "SpecCost.hpp" 29 32 #include "typeops.h" 30 33 #include "Unify.h" -
src/ResolvExpr/Unify.cc
r466787a rad861ef 33 33 #include "AST/TypeEnvironment.hpp" 34 34 #include "Common/PassVisitor.h" // for PassVisitor 35 #include "CommonType.hpp" // for commonType 35 36 #include "FindOpenVars.h" // for findOpenVars 37 #include "SpecCost.hpp" // for SpecCost 36 38 #include "SynTree/LinkageSpec.h" // for C 37 39 #include "SynTree/Constant.h" // for Constant … … 43 45 #include "Tuples/Tuples.h" // for isTtype 44 46 #include "TypeEnvironment.h" // for EqvClass, AssertionSet, OpenVarSet 45 #include "typeops.h" // for flatten, occurs , commonType47 #include "typeops.h" // for flatten, occurs 46 48 47 49 namespace ast { … … 50 52 51 53 namespace SymTab { 52 class Indexer;54 class Indexer; 53 55 } // namespace SymTab 54 56 … … 56 58 57 59 namespace ResolvExpr { 60 61 // Template Helpers: 62 template< typename Iterator1, typename Iterator2 > 63 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) { 64 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 65 Type *commonType = 0; 66 if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 67 return false; 68 } // if 69 commonTypes.push_back( commonType ); 70 } // for 71 return ( list1Begin == list1End && list2Begin == list2End ); 72 } 73 74 template< typename Iterator1, typename Iterator2 > 75 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 76 std::list< Type* > commonTypes; 77 if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) { 78 deleteAll( commonTypes ); 79 return true; 80 } else { 81 return false; 82 } // if 83 } 58 84 59 85 struct Unify_old : public WithShortCircuiting { -
src/ResolvExpr/Unify.h
r466787a rad861ef 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 13:09:04 2015 11 // Last Modified By : A aron B. Moss12 // Last Modified On : Mon Jun 18 11:58:00 201813 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Jan 17 11:12:00 2023 13 // Update Count : 5 14 14 // 15 15 … … 37 37 38 38 namespace ResolvExpr { 39 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );40 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );41 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );42 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common );43 39 44 template< typename Iterator1, typename Iterator2 > 45 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) { 46 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 47 Type *commonType = 0; 48 if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 49 return false; 50 } // if 51 commonTypes.push_back( commonType ); 52 } // for 53 if ( list1Begin != list1End || list2Begin != list2End ) { 54 return false; 55 } else { 56 return true; 57 } // if 58 } 40 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ); 41 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType ); 42 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ); 43 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common ); 59 44 60 template< typename Iterator1, typename Iterator2 > 61 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 62 std::list< Type* > commonTypes; 63 if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) { 64 deleteAll( commonTypes ); 65 return true; 66 } else { 67 return false; 68 } // if 69 } 45 bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 46 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 70 47 71 bool unify( 72 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,73 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,74 ast::OpenVarSet & open, const ast::SymbolTable & symtab ); 48 inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 49 TypeEnvironment env; 50 return typesCompatible( t1, t2, indexer, env ); 51 } 75 52 76 bool unify( 77 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,78 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,79 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common ); 53 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 54 TypeEnvironment env; 55 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env ); 56 } 80 57 81 bool unifyExact( 82 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,83 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,84 WidenMode widen, const ast::SymbolTable & symtab );58 bool unify( 59 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 60 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 61 ast::OpenVarSet & open, const ast::SymbolTable & symtab ); 85 62 86 bool unifyInexact( 87 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 88 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 89 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 90 ast::ptr<ast::Type> & common ); 63 bool unify( 64 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 65 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 66 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common ); 67 68 bool unifyExact( 69 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 70 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 71 WidenMode widen, const ast::SymbolTable & symtab ); 72 73 bool unifyInexact( 74 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 75 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 76 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 77 ast::ptr<ast::Type> & common ); 78 79 bool typesCompatible( 80 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 81 const ast::TypeEnvironment & env = {} ); 82 83 bool typesCompatibleIgnoreQualifiers( 84 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 85 const ast::TypeEnvironment & env = {} ); 86 87 /// Creates the type represented by the list of returnVals in a FunctionType. 88 /// The caller owns the return value. 89 Type * extractResultType( FunctionType * functionType ); 90 /// Creates or extracts the type represented by returns in a `FunctionType`. 91 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ); 92 93 std::vector<ast::ptr<ast::Type>> flattenList( 94 const std::vector<ast::ptr<ast::Type>> & src, ast::TypeEnvironment & env 95 ); 91 96 92 97 } // namespace ResolvExpr -
src/ResolvExpr/WidenMode.h
r466787a rad861ef 19 19 struct WidenMode { 20 20 WidenMode( bool first, bool second ): first( first ), second( second ) {} 21 21 22 22 WidenMode &operator|=( const WidenMode &other ) { 23 23 first |= other.first; second |= other.second; return *this; … … 35 35 WidenMode newWM( *this ); newWM &= other; return newWM; 36 36 } 37 37 38 38 operator bool() { return first && second; } 39 39 -
src/ResolvExpr/module.mk
r466787a rad861ef 17 17 SRC_RESOLVEXPR = \ 18 18 ResolvExpr/AdjustExprType.cc \ 19 ResolvExpr/AdjustExprType.hpp \ 19 20 ResolvExpr/Alternative.cc \ 20 21 ResolvExpr/AlternativeFinder.cc \ … … 26 27 ResolvExpr/Candidate.hpp \ 27 28 ResolvExpr/CastCost.cc \ 29 ResolvExpr/CastCost.hpp \ 28 30 ResolvExpr/CommonType.cc \ 31 ResolvExpr/CommonType.hpp \ 29 32 ResolvExpr/ConversionCost.cc \ 30 33 ResolvExpr/ConversionCost.h \ … … 40 43 ResolvExpr/Occurs.cc \ 41 44 ResolvExpr/PolyCost.cc \ 45 ResolvExpr/PolyCost.hpp \ 42 46 ResolvExpr/PtrsAssignable.cc \ 47 ResolvExpr/PtrsAssignable.hpp \ 43 48 ResolvExpr/PtrsCastable.cc \ 49 ResolvExpr/PtrsCastable.hpp \ 44 50 ResolvExpr/RenameVars.cc \ 45 51 ResolvExpr/RenameVars.h \ … … 54 60 ResolvExpr/SatisfyAssertions.hpp \ 55 61 ResolvExpr/SpecCost.cc \ 62 ResolvExpr/SpecCost.hpp \ 56 63 ResolvExpr/TypeEnvironment.cc \ 57 64 ResolvExpr/TypeEnvironment.h \ -
src/ResolvExpr/typeops.h
r466787a rad861ef 10 10 // Created On : Sun May 17 07:28:22 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Oct 1 09:45:00 201913 // Update Count : 612 // Last Modified On : Wed Jan 18 11:54:00 2023 13 // Update Count : 7 14 14 // 15 15 … … 18 18 #include <vector> 19 19 20 #include "Cost.h"21 #include "TypeEnvironment.h"22 #include "WidenMode.h"23 #include "AST/Fwd.hpp"24 #include "AST/Node.hpp"25 #include "AST/SymbolTable.hpp"26 20 #include "AST/Type.hpp" 27 #include "AST/TypeEnvironment.hpp"28 #include "SynTree/SynTree.h"29 21 #include "SynTree/Type.h" 30 22 … … 34 26 35 27 namespace ResolvExpr { 28 class TypeEnvironment; 29 36 30 // combos: takes a list of sets and returns a set of lists representing every possible way of forming a list by 37 31 // picking one element out of each set … … 61 55 } 62 56 63 // in AdjustExprType.cc64 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function65 void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer );66 67 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer68 void adjustExprType( Type *& type );69 70 template< typename ForwardIterator >71 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) {72 while ( begin != end ) {73 adjustExprType( *begin++, env, indexer );74 } // while75 }76 77 /// Replaces array types with equivalent pointer, and function types with a pointer-to-function78 const ast::Type * adjustExprType(79 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );80 81 // in CastCost.cc82 Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,83 const SymTab::Indexer & indexer, const TypeEnvironment & env );84 Cost castCost(85 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,86 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );87 88 // in ConversionCost.cc89 Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,90 const SymTab::Indexer & indexer, const TypeEnvironment & env );91 Cost conversionCost(92 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,93 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );94 95 // in AlternativeFinder.cc96 Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,97 const SymTab::Indexer & indexer, const TypeEnvironment & env );98 99 // in PtrsAssignable.cc100 int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env );101 int ptrsAssignable( const ast::Type * src, const ast::Type * dst,102 const ast::TypeEnvironment & env );103 104 // in PtrsCastable.cc105 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer );106 int ptrsCastable(107 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,108 const ast::TypeEnvironment & env );109 110 // in Unify.cc111 bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );112 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );113 114 inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {115 TypeEnvironment env;116 return typesCompatible( t1, t2, indexer, env );117 }118 119 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {120 TypeEnvironment env;121 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );122 }123 124 bool typesCompatible(125 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},126 const ast::TypeEnvironment & env = {} );127 128 bool typesCompatibleIgnoreQualifiers(129 const ast::Type *, const ast::Type *, const ast::SymbolTable &,130 const ast::TypeEnvironment & env = {} );131 132 /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.133 Type * extractResultType( FunctionType * functionType );134 /// Creates or extracts the type represented by the list of returns in a `FunctionType`.135 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );136 137 // in CommonType.cc138 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars );139 ast::ptr< ast::Type > commonType(140 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,141 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,142 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab143 );144 // in Unify.cc145 std::vector< ast::ptr< ast::Type > > flattenList(146 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env147 );148 149 // in PolyCost.cc150 int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer );151 int polyCost(152 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );153 154 // in SpecCost.cc155 int specCost( Type * type );156 int specCost( const ast::Type * type );157 158 57 // in Occurs.cc 159 58 bool occurs( const Type * type, const std::string & varName, const TypeEnvironment & env ); … … 168 67 return false; 169 68 } 170 171 // in AlternativeFinder.cc172 void referenceToRvalueConversion( Expression *& expr, Cost & cost );173 // in CandidateFinder.cpp174 const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost );175 69 176 70 /// flatten tuple type into list of types … … 218 112 } 219 113 220 221 114 return new ast::TupleType{ std::move(types) }; 222 115 } … … 227 120 return tupleFromTypes( tys.begin(), tys.end() ); 228 121 } 229 230 231 122 232 123 // in TypeEnvironment.cc -
src/SymTab/Indexer.cc
r466787a rad861ef 31 31 #include "InitTweak/InitTweak.h" // for isConstructor, isCopyFunction, isC... 32 32 #include "Mangler.h" // for Mangler 33 #include "ResolvExpr/typeops.h" // for typesCompatible 33 #include "ResolvExpr/AlternativeFinder.h" // for referenceToRvalueConversion 34 #include "ResolvExpr/Unify.h" // for typesCompatible 34 35 #include "SynTree/LinkageSpec.h" // for isMangled, isOverridable, Spec 35 36 #include "SynTree/Constant.h" // for Constant -
src/SymTab/Mangler.cc
r466787a rad861ef 439 439 private: 440 440 void mangleDecl( const ast::DeclWithType *declaration ); 441 void mangleRef( const ast::BaseInstType *refType, std::stringprefix );441 void mangleRef( const ast::BaseInstType *refType, const std::string & prefix ); 442 442 443 443 void printQualifiers( const ast::Type *type ); … … 535 535 } 536 536 537 __attribute__((unused))538 inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {539 std::vector< ast::ptr< ast::Type > > ret;540 std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),541 std::mem_fun( &ast::DeclWithType::get_type ) );542 return ret;543 }544 545 537 void Mangler_new::postvisit( const ast::FunctionType * functionType ) { 546 538 printQualifiers( functionType ); … … 558 550 } 559 551 560 void Mangler_new::mangleRef( const ast::BaseInstType * refType, std::string prefix ) { 552 void Mangler_new::mangleRef( 553 const ast::BaseInstType * refType, const std::string & prefix ) { 561 554 printQualifiers( refType ); 562 555 563 556 mangleName += prefix + std::to_string( refType->name.length() ) + refType->name; 564 557 565 if ( mangleGenericParams ) { 566 if ( ! refType->params.empty() ) { 567 mangleName += "_"; 568 for ( const ast::Expr * param : refType->params ) { 569 auto paramType = dynamic_cast< const ast::TypeExpr * >( param ); 570 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 571 maybeAccept( paramType->type.get(), *visitor ); 572 } 573 mangleName += "_"; 558 if ( mangleGenericParams && ! refType->params.empty() ) { 559 mangleName += "_"; 560 for ( const ast::Expr * param : refType->params ) { 561 auto paramType = dynamic_cast< const ast::TypeExpr * >( param ); 562 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 563 maybeAccept( paramType->type.get(), *visitor ); 574 564 } 565 mangleName += "_"; 575 566 } 576 567 } … … 656 647 } 657 648 649 // For debugging: 658 650 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) { 659 651 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) { … … 665 657 // skip if not including qualifiers 666 658 if ( typeMode ) return; 667 if ( auto ptype = dynamic_cast< const ast::FunctionType * >(type) ) { 668 if ( ! ptype->forall.empty() ) { 669 std::list< std::string > assertionNames; 670 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 671 mangleName += Encoding::forall; 672 for ( auto & decl : ptype->forall ) { 673 switch ( decl->kind ) { 674 case ast::TypeDecl::Kind::Dtype: 675 dcount++; 676 break; 677 case ast::TypeDecl::Kind::Ftype: 678 fcount++; 679 break; 680 case ast::TypeDecl::Kind::Ttype: 681 vcount++; 682 break; 683 default: 684 assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() ); 685 } // switch 686 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 687 } // for 688 for ( auto & assert : ptype->assertions ) { 689 assertionNames.push_back( ast::Pass<Mangler_new>::read( 690 assert->var.get(), 691 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) ); 692 acount++; 693 } // for 694 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_"; 695 for(const auto & a : assertionNames) mangleName += a; 696 // std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) ); 697 mangleName += "_"; 698 } // if 659 auto funcType = dynamic_cast<const ast::FunctionType *>( type ); 660 if ( funcType && !funcType->forall.empty() ) { 661 std::list< std::string > assertionNames; 662 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 663 mangleName += Encoding::forall; 664 for ( auto & decl : funcType->forall ) { 665 switch ( decl->kind ) { 666 case ast::TypeDecl::Dtype: 667 dcount++; 668 break; 669 case ast::TypeDecl::Ftype: 670 fcount++; 671 break; 672 case ast::TypeDecl::Ttype: 673 vcount++; 674 break; 675 default: 676 assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() ); 677 } // switch 678 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 679 } // for 680 for ( auto & assert : funcType->assertions ) { 681 assertionNames.push_back( ast::Pass<Mangler_new>::read( 682 assert->var.get(), 683 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) ); 684 acount++; 685 } // for 686 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_"; 687 for ( const auto & a : assertionNames ) mangleName += a; 688 mangleName += "_"; 699 689 } // if 700 690 if ( ! inFunctionType ) { -
src/SymTab/Validate.cc
r466787a rad861ef 63 63 #include "InitTweak/GenInit.h" // for fixReturnStatements 64 64 #include "InitTweak/InitTweak.h" // for isCtorDtorAssign 65 #include "ResolvExpr/typeops.h" // for typesCompatible 65 #include "ResolvExpr/typeops.h" // for extractResultType 66 #include "ResolvExpr/Unify.h" // for typesCompatible 66 67 #include "ResolvExpr/Resolver.h" // for findSingleExpression 67 68 #include "ResolvExpr/ResolveTypeof.h" // for resolveTypeof -
src/SynTree/ApplicationExpr.cc
r466787a rad861ef 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ApplicationExpr.cc .cc--7 // ApplicationExpr.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 26 26 #include "Expression.h" // for ParamEntry, ApplicationExpr, Expression 27 27 #include "InitTweak/InitTweak.h" // for getFunction 28 #include "ResolvExpr/ typeops.h"// for extractResultType28 #include "ResolvExpr/Unify.h" // for extractResultType 29 29 #include "Type.h" // for Type, PointerType, FunctionType 30 30 -
src/SynTree/BasicType.cc
r466787a rad861ef 29 29 } 30 30 31 bool BasicType::isWholeNumber() const {32 return kind == Bool ||33 kind ==Char ||34 kind == SignedChar ||35 kind == UnsignedChar ||36 kind == ShortSignedInt ||37 kind == ShortUnsignedInt ||38 kind == SignedInt ||39 kind == UnsignedInt ||40 kind == LongSignedInt ||41 kind == LongUnsignedInt ||42 kind == LongLongSignedInt ||43 kind ==LongLongUnsignedInt ||44 kind == SignedInt128 ||45 kind == UnsignedInt128;46 }47 48 31 bool BasicType::isInteger() const { 49 32 return kind <= UnsignedInt128; -
src/SynTree/Type.h
r466787a rad861ef 271 271 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 272 272 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 273 bool isWholeNumber() const;274 273 bool isInteger() const; 275 274 }; -
src/Validate/FixReturnTypes.cpp
r466787a rad861ef 20 20 #include "AST/Type.hpp" 21 21 #include "CodeGen/CodeGenerator.h" 22 #include "ResolvExpr/ typeops.h"22 #include "ResolvExpr/Unify.h" 23 23 24 24 namespace ast { -
src/Validate/ReplaceTypedef.cpp
r466787a rad861ef 20 20 #include "Common/UniqueName.h" 21 21 #include "Common/utility.h" 22 #include "ResolvExpr/ typeops.h"22 #include "ResolvExpr/Unify.h" 23 23 24 24 namespace Validate { -
tests/Makefile.am
r466787a rad861ef 88 88 io/.in/many_read.data \ 89 89 meta/fork+exec.hfa \ 90 unified_locking/mutex_test.hfa 90 concurrent/unified_locking/mutex_test.hfa \ 91 concurrent/channels/parallel_harness.hfa 91 92 92 93 dist-hook: -
tests/concurrent/futures/typed.cfa
r466787a rad861ef 5 5 thread Server { 6 6 int cnt; 7 future(int) * requests[NFUTURES];7 single_future(int) * requests[NFUTURES]; 8 8 }; 9 9 … … 24 24 void process( Server & this, int i ) { 25 25 if( this.requests[i] == 0p ) return; 26 future(int) * f = this.requests[i];26 single_future(int) * f = this.requests[i]; 27 27 this.requests[i] = 0p; 28 28 this.cnt--; … … 30 30 } 31 31 32 void call( Server & mutex this, future(int) & f ) {32 void call( Server & mutex this, single_future(int) & f ) { 33 33 for(i; NFUTURES) { 34 34 if( this.requests[i] == 0p ) { … … 70 70 71 71 void work(void) { 72 future(int) mine;72 single_future(int) mine; 73 73 call( *the_server, mine ); 74 74 wait( mine ); -
tests/concurrent/mutexstmt/locks.cfa
r466787a rad861ef 72 72 73 73 single_acquisition_lock l1; 74 linear_backoff_then_block_lock l2;74 exp_backoff_then_block_lock l2; 75 75 owner_lock l3; 76 76 -
tests/concurrent/unified_locking/locks.cfa
r466787a rad861ef 15 15 condition_variable( owner_lock ) c_o; 16 16 17 linear_backoff_then_block_lock l;18 condition_variable( linear_backoff_then_block_lock ) c_l;17 exp_backoff_then_block_lock l; 18 condition_variable( exp_backoff_then_block_lock ) c_l; 19 19 20 20 fast_block_lock f; -
tests/concurrent/unified_locking/thread_test.cfa
r466787a rad861ef 25 25 26 26 thread worker { 27 linear_backoff_then_block_lock * locks;27 exp_backoff_then_block_lock * locks; 28 28 bool improved; 29 29 }; 30 30 31 void ?{}( worker & w, linear_backoff_then_block_lock * locks, bool improved ) {31 void ?{}( worker & w, exp_backoff_then_block_lock * locks, bool improved ) { 32 32 w.locks = locks; 33 33 w.improved = improved; … … 39 39 for (int i = 0; i < workBufferSize; i += 1) buffer[i] = rand() % 1024; 40 40 unsigned int lck = rand() % lockCount; 41 linear_backoff_then_block_lock * curr_lock = &locks[lck];41 exp_backoff_then_block_lock * curr_lock = &locks[lck]; 42 42 for (unsigned int i = 0; i < num_times; i++) { 43 43 dowork(buffer, work_unlocked); … … 51 51 } 52 52 53 53 int doOne = 0; 54 54 int main(int argc, char* argv[]) { 55 55 switch (argc) { 56 case 8: 57 doOne = atoi(argv[7]); 56 58 case 7: 57 work_unlocked = atoi(argv[ 5]);59 work_unlocked = atoi(argv[6]); 58 60 case 6: 59 61 work_locked = atoi(argv[5]); 60 62 case 5: 61 num_times = atoi(argv[4]);63 total_times = atoi(argv[4]); 62 64 case 4: 63 65 lockCount = atoi(argv[3]); … … 72 74 } 73 75 processor p[threadCount]; 74 linear_backoff_then_block_lock locks[lockCount];76 exp_backoff_then_block_lock locks[lockCount]; 75 77 worker * worker_arr[taskCount]; 76 78 num_times = total_times / taskCount; 77 78 //printf("Start Test: martin lock simple\n"); 79 clock_t begin = clock(); 79 //printf("%d\n", doOne); 80 // 81 //clock_t begin = clock(); 82 if (doOne == 1) { 83 printf("Start Test: martin lock simple %d\n", num_times); 80 84 for (unsigned int i = 0; i < taskCount; i++) { 81 85 worker_arr[i] = new( locks, false ); … … 84 88 delete( worker_arr[i] ); 85 89 } 86 clock_t end = clock(); 87 double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 88 printf("norm: %f\n", time_spent); 90 } 91 //clock_t end = clock(); 92 //double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 93 //printf("norm: %f\n", time_spent); 89 94 90 95 //printf("Start Test: martin lock improved\n"); 91 begin = clock(); 96 //begin = clock(); 97 if (doOne == 2) { 92 98 for (unsigned int i = 0; i < taskCount; i++) { 93 99 worker_arr[i] = new( locks, true ); … … 96 102 delete( worker_arr[i] ); 97 103 } 98 end = clock(); 99 time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 100 printf("improved: %f\n", time_spent); 104 } 105 //end = clock(); 106 //time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 107 //printf("improved: %f\n", time_spent); 101 108 } -
tests/enum_tests/.expect/typedIntEnum.txt
r466787a rad861ef 1 0 2 1 3 1000 4 1001 5 2000 6 2001 7 2002 1 0=0 2 1=1 3 1000=1000 4 1001=1001 5 2000=2000 6 2001=2001 7 2002=2002 -
tests/enum_tests/pointerEnum.cfa
r466787a rad861ef 11 11 int main() { 12 12 E * v = First; 13 sout | "v: " | e.x;13 // sout | "v: " | e.x; 14 14 } -
tests/enum_tests/typedIntEnum.cfa
r466787a rad861ef 12 12 13 13 int main() { 14 printf(" %d\n", zero);15 printf(" %d\n", one);16 printf(" %d\n", thousand);17 printf(" %d\n", thousand_one);18 printf(" %d\n", two_thousand);19 printf(" %d\n", two_thousand_one);20 printf(" %d\n", two_thousand_two);14 printf("0=%d\n", zero); 15 printf("1=%d\n", one); 16 printf("1000=%d\n", thousand); 17 printf("1001=%d\n", thousand_one); 18 printf("2000=%d\n", two_thousand); 19 printf("2001=%d\n", two_thousand_one); 20 printf("2002=%d\n", two_thousand_two); 21 21 return 0; 22 22 }
Note: See TracChangeset
for help on using the changeset viewer.