Changeset 3e1cd17
- Timestamp:
- Apr 12, 2024, 8:51:19 AM (12 months ago)
- Branches:
- master
- Children:
- b1b3df5
- Parents:
- 21e6da5 (diff), b78c54f (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:
-
- 1 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified libcfa/src/concurrency/kernel/cluster.cfa ¶
r21e6da5 r3e1cd17 341 341 // Make sure that everything is consistent 342 342 /* paranoid */ check_readyQ( cltr ); 343 /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) );343 // /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) ); 344 344 345 345 __cfadbg_print_safe(ready_queue, "Kernel : Growing ready queue done\n"); … … 416 416 fix_times(readyQ.tscs, ncount); 417 417 } 418 418 419 cltr->sched.caches = alloc( target, cltr->sched.caches`realloc ); 419 420 … … 428 429 429 430 // Make sure that everything is consistent 430 /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) );431 // /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) ); 431 432 /* paranoid */ check_readyQ( cltr ); 432 433 -
TabularUnified libcfa/src/concurrency/kernel/startup.cfa ¶
r21e6da5 r3e1cd17 672 672 uint_fast32_t last_size = ready_mutate_lock(); 673 673 674 675 674 // Adjust the ready queue size 675 ready_queue_shrink( &this ); 676 676 677 677 // Unlock the RWlock … … 682 682 /* paranoid */ verify( this.sched.readyQ.tscs == 0p ); 683 683 /* paranoid */ verify( this.sched.readyQ.count == 0 ); 684 /* paranoid */ verify( this.sched.io.tscs == 0p );685 /* paranoid */ verify( this.sched.caches == 0p );684 // /* paranoid */ verify( this.sched.io.tscs == 0p ); 685 // /* paranoid */ verify( this.sched.caches == 0p ); 686 686 687 687 enable_interrupts( false ); // Don't poll, could be in main cluster -
TabularUnified libcfa/src/heap.cfa ¶
r21e6da5 r3e1cd17 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jan 3 21:30:54202413 // Update Count : 16 1912 // Last Modified On : Sun Apr 7 21:54:29 2024 13 // Update Count : 1644 14 14 // 15 15 … … 114 114 115 115 116 // generic Bsearchl does not inline, so substitute with hand-coded binary-search.116 // CFA generic Bsearchl does not inline, so substitute with hand-coded binary-search. 117 117 inline __attribute__((always_inline)) 118 118 static size_t Bsearchl( unsigned int key, const unsigned int vals[], size_t dim ) { … … 190 190 unsigned int realloc_calls, realloc_0_calls; 191 191 unsigned long long int realloc_storage_request, realloc_storage_alloc; 192 unsigned int free_calls, free_null_ calls;192 unsigned int free_calls, free_null_0_calls; 193 193 unsigned long long int free_storage_request, free_storage_alloc; 194 194 unsigned int return_pulls, return_pushes; … … 232 232 struct Header { // header 233 233 union Kind { 234 struct RealHeader { 234 struct RealHeader { // 4-byte word => 8-byte header, 8-byte word => 16-byte header 235 235 union { 236 struct { // 4-byte word => 8-byte header, 8-byte word => 16-byte header 237 union { 238 // 2nd low-order bit => zero filled, 3rd low-order bit => mmapped 239 // FreeHeader * home; // allocated block points back to home locations (must overlay alignment) 240 void * home; // allocated block points back to home locations (must overlay alignment) 241 size_t blockSize; // size for munmap (must overlay alignment) 242 Storage * next; // freed block points to next freed block of same size 243 }; 244 size_t size; // allocation size in bytes 245 }; 236 // 2nd low-order bit => zero filled, 3rd low-order bit => mmapped 237 // FreeHeader * home; // allocated block points back to home locations (must overlay alignment) 238 void * home; // allocated block points back to home locations (must overlay alignment) 239 size_t blockSize; // size for munmap (must overlay alignment) 240 Storage * next; // freed block points to next freed block of same size 246 241 }; 242 size_t size; // allocation size in bytes 247 243 } real; // RealHeader 248 244 … … 261 257 262 258 struct CALIGN FreeHeader { 263 size_t blockSize CALIGN; // size of allocations on this list264 259 #ifdef OWNERSHIP 265 260 #ifdef RETURNSPIN … … 271 266 Storage * freeList; // thread free list 272 267 Heap * homeManager; // heap owner (free storage to bucket, from bucket to heap) 268 size_t blockSize; // size of allocations on this list 273 269 }; // FreeHeader 274 270 … … 369 365 static __thread size_t PAD1 CALIGN TLSMODEL __attribute__(( unused )); // protect false sharing 370 366 static __thread Heap * heapManager CALIGN TLSMODEL; 371 static 367 static __thread bool heapManagerBootFlag CALIGN TLSMODEL = false; 372 368 static __thread size_t PAD2 CALIGN TLSMODEL __attribute__(( unused )); // protect further false sharing 373 369 … … 595 591 596 592 #ifdef __STATISTICS__ 597 static HeapStatistics stats; // zero filled598 599 593 #define prtFmt \ 600 594 "\nHeap statistics: (storage request / allocation)\n" \ … … 607 601 " resize >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n" \ 608 602 " realloc >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n" \ 609 " free !null calls %'u; null calls %'u; storage %'llu / %'llu bytes\n" \603 " free !null calls %'u; null/0 calls %'u; storage %'llu / %'llu bytes\n" \ 610 604 " return pulls %'u; pushes %'u; storage %'llu / %'llu bytes\n" \ 611 605 " sbrk calls %'u; storage %'llu bytes\n" \ … … 627 621 resize_calls, resize_0_calls, resize_storage_request, resize_storage_alloc, 628 622 realloc_calls, realloc_0_calls, realloc_storage_request, realloc_storage_alloc, 629 free_calls, free_null_ calls, free_storage_request, free_storage_alloc,623 free_calls, free_null_0_calls, free_storage_request, free_storage_alloc, 630 624 return_pulls, return_pushes, return_storage_request, return_storage_alloc, 631 625 sbrk_calls, sbrk_storage, … … 650 644 "<total type=\"resize\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \ 651 645 "<total type=\"realloc\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \ 652 "<total type=\"free\" !null=\"%'u;\" 0 null =\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \646 "<total type=\"free\" !null=\"%'u;\" 0 null/0=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \ 653 647 "<total type=\"return\" pulls=\"%'u;\" 0 pushes=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \ 654 648 "<total type=\"sbrk\" count=\"%'u;\" size=\"%'llu\"/> bytes\n" \ … … 670 664 resize_calls, resize_0_calls, resize_storage_request, resize_storage_alloc, 671 665 realloc_calls, realloc_0_calls, realloc_storage_request, realloc_storage_alloc, 672 free_calls, free_null_ calls, free_storage_request, free_storage_alloc,666 free_calls, free_null_0_calls, free_storage_request, free_storage_alloc, 673 667 return_pulls, return_pushes, return_storage_request, return_storage_alloc, 674 668 sbrk_calls, sbrk_storage, … … 799 793 } else { 800 794 fakeHeader( header, alignment ); 801 if ( unlikely( MmappedBit( header ) ) ) { // mmapped ?795 if ( unlikely( MmappedBit( header ) ) ) { // mmapped storage ? 802 796 verify( addr < heapBegin || heapEnd < addr ); 803 797 size = ClearStickyBits( header->kind.real.blockSize ); // mmap size 798 freeHead = 0p; // prevent uninitialized warning 804 799 return true; 805 800 } // if … … 904 899 905 900 906 #define BOOT_HEAP_MANAGER \907 if ( unlikely( ! heapMasterBootFlag ) ) { \908 heapManagerCtor(); /* trigger for first heap */ \909 } /* if */910 911 901 #ifdef __STATISTICS__ 912 902 #define STAT_NAME __counter 913 903 #define STAT_PARM , unsigned int STAT_NAME 914 904 #define STAT_ARG( name ) , name 915 #define STAT_0_CNT( counter ) stats.counters[counter].calls_0 += 1905 #define STAT_0_CNT( counter ) heapManager->stats.counters[counter].calls_0 += 1 916 906 #else 917 907 #define STAT_NAME … … 921 911 #endif // __STATISTICS__ 922 912 923 // Uncomment to get allocation addresses for a 0-sized allocation rather than a null pointer. 924 //#define __NONNULL_0_ALLOC__ 925 #if ! defined( __NONNULL_0_ALLOC__ ) 926 #define __NULL_0_ALLOC__ unlikely( size == 0 ) || /* 0 BYTE ALLOCATION RETURNS NULL POINTER */ 913 #define BOOT_HEAP_MANAGER \ 914 if ( unlikely( ! heapMasterBootFlag ) ) { \ 915 heapManagerCtor(); /* trigger for first heap */ \ 916 } /* if */ \ 917 verify( heapManager ); 918 919 #define __NONNULL_0_ALLOC__ /* Uncomment to return non-null address for malloc( 0 ). */ 920 #ifndef __NONNULL_0_ALLOC__ 921 #define __NULL_0_ALLOC__( counter, ... ) /* 0 byte allocation returns null pointer */ \ 922 if ( unlikely( size == 0 ) ) { \ 923 STAT_0_CNT( counter ); \ 924 __VA_ARGS__; /* call routine, if specified */ \ 925 return 0p; \ 926 } /* if */ 927 927 #else 928 #define __NULL_0_ALLOC__ 928 #define __NULL_0_ALLOC__( counter, ... ) 929 929 #endif // __NONNULL_0_ALLOC__ 930 931 #ifdef __DEBUG__ 932 #define __OVERFLOW_MALLOC__( ... ) \ 933 if ( unlikely( size > ULONG_MAX - sizeof(Heap.Storage) ) ) { /* error check */ \ 934 __VA_ARGS__; /* call routine, if specified */ \ 935 return 0p; \ 936 } /* if */ 937 #else 938 #define __OVERFLOW_MALLOC__( ... ) 939 #endif // __DEBUG__ 930 940 931 941 #define PROLOG( counter, ... ) \ 932 942 BOOT_HEAP_MANAGER; \ 933 if ( \ 934 __NULL_0_ALLOC__ \ 935 unlikely( size > ULONG_MAX - sizeof(Heap.Storage) ) ) { /* error check */ \ 936 STAT_0_CNT( counter ); \ 937 __VA_ARGS__; \ 938 return 0p; \ 939 } /* if */ 940 943 __NULL_0_ALLOC__( counter, __VA_ARGS__ ) \ 944 __OVERFLOW_MALLOC__( __VA_ARGS__ ) 941 945 942 946 #define SCRUB_SIZE 1024lu … … 948 952 PROLOG( STAT_NAME ); 949 953 950 verify( heapManager );951 954 Heap.Storage * block; // pointer to new block of storage 952 955 … … 956 959 957 960 #ifdef __STATISTICS__ 958 stats.counters[STAT_NAME].calls += 1; 961 #ifdef __NONNULL_0_ALLOC__ 962 if ( unlikely( size == 0 ) ) // malloc( 0 ) ? 963 stats.counters[STAT_NAME].calls_0 += 1; 964 else 965 #endif // __NONNULL_0_ALLOC__ 966 stats.counters[STAT_NAME].calls += 1; 959 967 stats.counters[STAT_NAME].request += size; 960 968 #endif // __STATISTICS__ … … 1078 1086 1079 1087 static void doFree( void * addr ) libcfa_nopreempt with( *heapManager ) { 1088 // char buf[64]; 1089 // int len = sprintf( buf, "doFree addr %p\n", addr ); 1090 // write( 2, buf, len ); 1091 1080 1092 verify( addr ); 1081 1093 … … 1091 1103 #endif // __STATISTICS__ || __CFA_DEBUG__ 1092 1104 1105 // Do not move these down because heap can be null! 1093 1106 #ifdef __STATISTICS__ 1107 #ifdef __NONNULL_0_ALLOC__ 1108 if ( unlikely( rsize == 0 ) ) // malloc( 0 ) ? 1109 stats.free_null_0_calls += 1; 1110 else 1111 #endif // __NONNULL_0_ALLOC__ 1112 heapManager->stats.free_calls += 1; // count free amd implicit frees from resize/realloc 1094 1113 stats.free_storage_request += rsize; 1095 1114 stats.free_storage_alloc += size; … … 1117 1136 } // if 1118 1137 } else { 1138 assert( freeHead ); 1119 1139 #ifdef __CFA_DEBUG__ 1120 1140 // memset is NOT always inlined! … … 1321 1341 // call to malloc(), alloc(), calloc() or realloc(). If the area pointed to was moved, a free(oaddr) is done. 1322 1342 void * resize( void * oaddr, size_t size ) libcfa_public { 1323 if ( unlikely( oaddr == 0p ) ) { // => malloc( size )1343 if ( unlikely( oaddr == 0p ) ) { // => malloc( size ) 1324 1344 return doMalloc( size STAT_ARG( RESIZE ) ); 1325 1345 } // if … … 1333 1353 1334 1354 size_t odsize = DataStorage( bsize, oaddr, header ); // data storage available in bucket 1335 // same size, DO NOT preserveSTICKY PROPERTIES.1355 // same size, DO NOT PRESERVE STICKY PROPERTIES. 1336 1356 if ( oalign == libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size 1337 1357 ClearZeroFillBit( header ); // no alignment and turn off 0 fill … … 1346 1366 } // if 1347 1367 1348 // change size, DO NOT preserveSTICKY PROPERTIES.1368 // change size, DO NOT PRESERVE STICKY PROPERTIES. 1349 1369 doFree( oaddr ); // free previous storage 1350 1370 … … 1356 1376 // the old and new sizes. 1357 1377 void * realloc( void * oaddr, size_t size ) libcfa_public { 1378 // char buf[64]; 1379 // int len = sprintf( buf, "realloc1 oaddr %p size %d\n", oaddr, size ); 1380 // write( 2, buf, len ); 1358 1381 if ( unlikely( oaddr == 0p ) ) { // => malloc( size ) 1359 1382 return doMalloc( size STAT_ARG( REALLOC ) ); … … 1498 1521 } // if 1499 1522 1500 #ifdef __STATISTICS__1501 incCalls( FREE );1502 #endif // __STATISTICS__1503 1504 1523 doFree( addr ); // handles heapManager == nullptr 1505 1524 } // free … … 1579 1598 #endif // __STATISTICS__ 1580 1599 } // malloc_stats_clear 1581 1582 1600 1583 1601 // Changes the file descriptor where malloc_stats() writes statistics. … … 1700 1718 } // if 1701 1719 1702 // change size, DO NOT preserveSTICKY PROPERTIES.1720 // change size, DO NOT PRESERVE STICKY PROPERTIES. 1703 1721 doFree( oaddr ); // free previous storage 1704 1722 return memalignNoStats( nalign, size STAT_ARG( RESIZE ) ); // create new aligned area … … 1707 1725 1708 1726 void * realloc( void * oaddr, size_t nalign, size_t size ) libcfa_public { 1727 // char buf[64]; 1728 // int len = sprintf( buf, "realloc2 oaddr %p size %d\n", oaddr, size ); 1729 // write( 2, buf, len ); 1709 1730 if ( unlikely( oaddr == 0p ) ) { // => malloc( size ) 1710 1731 return memalignNoStats( nalign, size STAT_ARG( REALLOC ) ); -
TabularUnified libcfa/src/heap.hfa ¶
r21e6da5 r3e1cd17 10 10 // Created On : Tue May 26 11:23:55 2020 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 11 11:18:18 202313 // Update Count : 2 412 // Last Modified On : Mon Apr 1 09:36:20 2024 13 // Update Count : 25 14 14 // 15 15 … … 46 46 } // extern "C" 47 47 48 // New allocation operations. 48 49 void * resize( void * oaddr, size_t alignment, size_t size ); 49 50 void * realloc( void * oaddr, size_t alignment, size_t size ); … … 51 52 52 53 // Local Variables: // 53 // mode: c //54 54 // tab-width: 4 // 55 55 // End: // -
TabularUnified libcfa/src/stdlib.hfa ¶
r21e6da5 r3e1cd17 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Mar 17 08:25:31202413 // Update Count : 79612 // Last Modified On : Fri Apr 12 07:39:15 2024 13 // Update Count : 812 14 14 // 15 15 … … 109 109 1. Replace the current forall-block that contains defintions of S_fill and S_realloc with following: 110 110 forall( T & | sized(T) ) { 111 union U_fill 112 struct S_fill 113 struct S_realloc 111 union U_fill { char c; T * a; T t; }; 112 struct S_fill { char tag; U_fill(T) fill; }; 113 struct S_realloc { inline T *; }; 114 114 } 115 115 116 116 2. Replace all current postfix-fill functions with following for updated S_fill: 117 S_fill(T) ?`fill( char a ) 118 S_fill(T) ?`fill( T a ){ S_fill(T) ret = {'t'}; memcpy(&ret.fill.t, &a, sizeof(T)); return ret; }119 S_fill(T) ?`fill( T a[], size_t nmemb ){ S_fill(T) ret = {'a', nmemb}; ret.fill.a = a; return ret; }117 S_fill(T) ?`fill( char a ) { S_fill(T) ret = {'c'}; ret.fill.c = a; return ret; } 118 S_fill(T) ?`fill( T a ) { S_fill(T) ret = {'t'}; memcpy(&ret.fill.t, &a, sizeof(T)); return ret; } 119 S_fill(T) ?`fill( T a[], size_t nmemb ) { S_fill(T) ret = {'a', nmemb}; ret.fill.a = a; return ret; } 120 120 121 121 3. Replace the alloc_internal$ function which is outside ttype forall-block with following function: … … 148 148 */ 149 149 150 typedef struct S_align 151 typedef struct S_resize 150 typedef struct S_align { inline size_t; } T_align; 151 typedef struct S_resize { inline void *; } T_resize; 152 152 153 153 forall( T & ) { 154 struct S_fill 155 struct S_realloc 154 struct S_fill { char tag; char c; size_t size; T * at; char t[50]; }; 155 struct S_realloc { inline T *; }; 156 156 } 157 157 158 static inline T_align ?`align ( size_t a ) { return (T_align){a}; } 159 static inline T_resize ?`resize ( void * a ) { return (T_resize){a}; } 160 158 static inline T_align ?`align( size_t a ) { return (T_align){a}; } 159 static inline T_resize ?`resize( void * a ) { return (T_resize){a}; } 160 161 extern "C" ssize_t write(int fd, const void *buf, size_t count); 161 162 static inline forall( T & | sized(T) ) { 162 163 S_fill(T) ?`fill ( T t ) { … … 169 170 return ret; 170 171 } 171 S_fill(T) 172 S_fill(T) ?`fill ( T * a ){ return (S_fill(T)){ 'T', '0', 0, a }; } // FIX ME: remove this once ticket 214 is resolved173 S_fill(T) ?`fill ( char c ){ return (S_fill(T)){ 'c', c }; }174 S_fill(T) ?`fill ( T a[], size_t nmemb ){ return (S_fill(T)){ 'a', '0', nmemb * sizeof(T), a }; }175 176 S_realloc(T) ?`realloc ( T * a ){ return (S_realloc(T)){a}; }172 S_fill(T) ?`fill ( zero_t ) = void; // FIX ME: remove this once ticket 214 is resolved 173 S_fill(T) ?`fill ( T * a ) { return (S_fill(T)){ 'T', '0', 0, a }; } // FIX ME: remove this once ticket 214 is resolved 174 S_fill(T) ?`fill ( char c ) { return (S_fill(T)){ 'c', c }; } 175 S_fill(T) ?`fill ( T a[], size_t nmemb ) { return (S_fill(T)){ 'a', '0', nmemb * sizeof(T), a }; } 176 177 S_realloc(T) ?`realloc ( T * a ) { return (S_realloc(T)){a}; } 177 178 178 179 T * alloc_internal$( void * Resize, T * Realloc, size_t Align, size_t Dim, S_fill(T) Fill ) { … … 182 183 183 184 if ( Resize ) { 184 ptr = (T*) (void *)resize( (void *)Resize, Align, Dim * size );185 ptr = (T*)(void *)resize( (void *)Resize, Align, Dim * size ); 185 186 } else if ( Realloc ) { 186 187 if ( Fill.tag != '0' ) copy_end = min(malloc_size( Realloc ), Dim * size ); 187 ptr = (T *) (void *)realloc( (void *)Realloc, Align, Dim * size );188 ptr = (T *)(void *)realloc( (void *)Realloc, Align, Dim * size ); 188 189 } else { 189 ptr = (T *) 190 ptr = (T *)(void *) memalign( Align, Dim * size ); 190 191 } 191 192 -
TabularUnified src/Parser/StatementNode.cc ¶
r21e6da5 r3e1cd17 122 122 ast::Expr * cond = nullptr; 123 123 if ( ctl->condition ) { 124 // compare the provided condition against 0 125 cond = notZeroExpr( maybeMoveBuild( ctl->condition ) ); 124 cond = maybeMoveBuild( ctl->condition ); 126 125 } else { 127 126 for ( ast::ptr<ast::Stmt> & stmt : inits ) { … … 129 128 auto declStmt = stmt.strict_as<ast::DeclStmt>(); 130 129 auto dwt = declStmt->decl.strict_as<ast::DeclWithType>(); 131 ast::Expr * nze = n otZeroExpr( new ast::VariableExpr( dwt->location, dwt ));130 ast::Expr * nze = new ast::VariableExpr( dwt->location, dwt ); 132 131 cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze; 133 132 } … … 200 199 // do-while cannot have declarations in the contitional, so init is always empty 201 200 return new ast::WhileDoStmt( location, 202 notZeroExpr( maybeMoveBuild( ctl )),201 maybeMoveBuild( ctl ), 203 202 buildMoveSingle( stmt ), 204 203 buildMoveOptional( else_ ), … … 213 212 214 213 ast::Expr * astcond = nullptr; // maybe empty 215 astcond = notZeroExpr( maybeMoveBuild( forctl->condition ));214 astcond = maybeMoveBuild( forctl->condition ); 216 215 217 216 ast::Expr * astincr = nullptr; // maybe empty … … 330 329 clause->target = maybeBuild( targetExpr ); 331 330 clause->stmt = maybeMoveBuild( stmt ); 332 clause->when_cond = notZeroExpr( maybeMoveBuild( when ));331 clause->when_cond = maybeMoveBuild( when ); 333 332 334 333 ExpressionNode * next = targetExpr->next; … … 345 344 ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) { 346 345 existing->else_stmt = maybeMoveBuild( stmt ); 347 existing->else_cond = notZeroExpr( maybeMoveBuild( when ));346 existing->else_cond = maybeMoveBuild( when ); 348 347 349 348 (void)location; … … 354 353 existing->timeout_time = maybeMoveBuild( timeout ); 355 354 existing->timeout_stmt = maybeMoveBuild( stmt ); 356 existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ));355 existing->timeout_cond = maybeMoveBuild( when ); 357 356 358 357 (void)location; … … 362 361 ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 363 362 ast::WhenClause * clause = new ast::WhenClause( loc ); 364 clause->when_cond = notZeroExpr( maybeMoveBuild( when ));363 clause->when_cond = maybeMoveBuild( when ); 365 364 clause->stmt = maybeMoveBuild( stmt ); 366 365 clause->target = maybeMoveBuild( targetExpr ); … … 369 368 ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation & loc, ExpressionNode * when, StatementNode * stmt ) { 370 369 ast::WhenClause * clause = new ast::WhenClause( loc ); 371 clause->when_cond = notZeroExpr( maybeMoveBuild( when ));370 clause->when_cond = maybeMoveBuild( when ); 372 371 clause->stmt = maybeMoveBuild( stmt ); 373 372 return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause ); … … 508 507 509 508 ast::Expr * astcond = nullptr; // maybe empty 510 astcond = notZeroExpr( maybeMoveBuild( forctl->condition ));509 astcond = maybeMoveBuild( forctl->condition ); 511 510 512 511 ast::Expr * astincr = nullptr; // maybe empty -
TabularUnified src/Parser/module.mk ¶
r21e6da5 r3e1cd17 31 31 Parser/parser.yy \ 32 32 Parser/ParserTypes.h \ 33 Parser/parserutility.cc \34 33 Parser/parserutility.h \ 35 34 Parser/RunParser.cpp \ -
TabularUnified src/Parser/parserutility.h ¶
r21e6da5 r3e1cd17 17 17 18 18 #include "AST/Copy.hpp" // for shallowCopy 19 namespace ast {20 class Expr;21 }22 23 ast::Expr * notZeroExpr( const ast::Expr *orig );24 19 25 20 template< typename T > -
TabularUnified src/ResolvExpr/CandidateFinder.cpp ¶
r21e6da5 r3e1cd17 46 46 #include "AST/Type.hpp" 47 47 #include "Common/utility.h" // for move, copy 48 #include "Parser/parserutility.h" // for notZeroExpr49 48 #include "SymTab/Mangler.h" 50 49 #include "Tuples/Tuples.h" // for handleTupleAssignment … … 1587 1586 void Finder::postvisit( const ast::LogicalExpr * logicalExpr ) { 1588 1587 CandidateFinder finder1( context, tenv ); 1589 ast::ptr<ast::Expr> arg1 = notZeroExpr( logicalExpr->arg1 );1588 ast::ptr<ast::Expr> arg1 = createCondExpr( logicalExpr->arg1 ); 1590 1589 finder1.find( arg1, ResolveMode::withAdjustment() ); 1591 1590 if ( finder1.candidates.empty() ) return; 1592 1591 1593 1592 CandidateFinder finder2( context, tenv ); 1594 ast::ptr<ast::Expr> arg2 = notZeroExpr( logicalExpr->arg2 );1593 ast::ptr<ast::Expr> arg2 = createCondExpr( logicalExpr->arg2 ); 1595 1594 finder2.find( arg2, ResolveMode::withAdjustment() ); 1596 1595 if ( finder2.candidates.empty() ) return; … … 1618 1617 void Finder::postvisit( const ast::ConditionalExpr * conditionalExpr ) { 1619 1618 // candidates for condition 1620 ast::ptr<ast::Expr> arg1 = notZeroExpr( conditionalExpr->arg1 );1619 ast::ptr<ast::Expr> arg1 = createCondExpr( conditionalExpr->arg1 ); 1621 1620 CandidateFinder finder1( context, tenv ); 1622 1621 finder1.find( arg1, ResolveMode::withAdjustment() ); … … 2201 2200 } 2202 2201 2202 const ast::Expr * createCondExpr( const ast::Expr * expr ) { 2203 assert( expr ); 2204 return new ast::CastExpr( expr->location, 2205 ast::UntypedExpr::createCall( expr->location, 2206 "?!=?", 2207 { 2208 expr, 2209 new ast::ConstantExpr( expr->location, 2210 new ast::ZeroType(), "0", std::make_optional( 0ull ) 2211 ), 2212 } 2213 ), 2214 new ast::BasicType( ast::BasicType::SignedInt ) 2215 ); 2216 } 2217 2203 2218 } // namespace ResolvExpr 2204 2219 -
TabularUnified src/ResolvExpr/CandidateFinder.hpp ¶
r21e6da5 r3e1cd17 70 70 const ast::Expr * expr, Cost & cost ); 71 71 72 /// Wrap an expression to convert the result to a conditional result. 73 const ast::Expr * createCondExpr( const ast::Expr * expr ); 74 72 75 } // namespace ResolvExpr 73 76 -
TabularUnified src/ResolvExpr/Resolver.cc ¶
r21e6da5 r3e1cd17 340 340 } 341 341 342 ast::ptr< ast::Expr > findCondExpression( 343 const ast::Expr * untyped, const ResolveContext & context 344 ) { 345 if ( nullptr == untyped ) return untyped; 346 ast::ptr<ast::Expr> condExpr = createCondExpr( untyped ); 347 return findIntegralExpression( condExpr, context ); 348 } 349 342 350 /// check if a type is a character type 343 351 bool isCharType( const ast::Type * t ) { … … 356 364 return it != end; 357 365 } 358 } 366 } // anonymous namespace 359 367 360 368 class Resolver final … … 729 737 const ast::IfStmt * Resolver::previsit( const ast::IfStmt * ifStmt ) { 730 738 return ast::mutate_field( 731 ifStmt, &ast::IfStmt::cond, find IntegralExpression( ifStmt->cond, context ) );739 ifStmt, &ast::IfStmt::cond, findCondExpression( ifStmt->cond, context ) ); 732 740 } 733 741 734 742 const ast::WhileDoStmt * Resolver::previsit( const ast::WhileDoStmt * whileDoStmt ) { 735 743 return ast::mutate_field( 736 whileDoStmt, &ast::WhileDoStmt::cond, find IntegralExpression( whileDoStmt->cond, context ) );744 whileDoStmt, &ast::WhileDoStmt::cond, findCondExpression( whileDoStmt->cond, context ) ); 737 745 } 738 746 … … 740 748 if ( forStmt->cond ) { 741 749 forStmt = ast::mutate_field( 742 forStmt, &ast::ForStmt::cond, find IntegralExpression( forStmt->cond, context ) );750 forStmt, &ast::ForStmt::cond, findCondExpression( forStmt->cond, context ) ); 743 751 } 744 752 … … 1075 1083 1076 1084 // Resolve the conditions as if it were an IfStmt, statements normally 1077 clause2->when_cond = find SingleExpression( clause.when_cond, context );1085 clause2->when_cond = findCondExpression( clause.when_cond, context ); 1078 1086 clause2->stmt = clause.stmt->accept( *visitor ); 1079 1087 … … 1089 1097 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt }; 1090 1098 auto timeout_time = findSingleExpression( stmt->timeout_time, target, context ); 1091 auto timeout_cond = find SingleExpression( stmt->timeout_cond, context );1099 auto timeout_cond = findCondExpression( stmt->timeout_cond, context ); 1092 1100 auto timeout_stmt = stmt->timeout_stmt->accept( *visitor ); 1093 1101 … … 1102 1110 if ( stmt->else_stmt ) { 1103 1111 // resolve the condition like IfStmt, stmts normally 1104 auto else_cond = find SingleExpression( stmt->else_cond, context );1112 auto else_cond = findCondExpression( stmt->else_cond, context ); 1105 1113 auto else_stmt = stmt->else_stmt->accept( *visitor ); 1106 1114
Note: See TracChangeset
for help on using the changeset viewer.