Changeset 3e1cd17


Ignore:
Timestamp:
Apr 12, 2024, 8:51:19 AM (12 months ago)
Author:
Peter A. Buhr <pabuhr@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
1 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified libcfa/src/concurrency/kernel/cluster.cfa

    r21e6da5 r3e1cd17  
    341341        // Make sure that everything is consistent
    342342        /* paranoid */ check_readyQ( cltr );
    343         /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) );
     343//      /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) );
    344344
    345345        __cfadbg_print_safe(ready_queue, "Kernel : Growing ready queue done\n");
     
    416416                fix_times(readyQ.tscs, ncount);
    417417        }
     418
    418419        cltr->sched.caches = alloc( target, cltr->sched.caches`realloc );
    419420
     
    428429
    429430        // Make sure that everything is consistent
    430         /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) );
     431//      /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) );
    431432        /* paranoid */ check_readyQ( cltr );
    432433
  • TabularUnified libcfa/src/concurrency/kernel/startup.cfa

    r21e6da5 r3e1cd17  
    672672        uint_fast32_t last_size = ready_mutate_lock();
    673673
    674                 // Adjust the ready queue size
    675                 ready_queue_shrink( &this );
     674        // Adjust the ready queue size
     675        ready_queue_shrink( &this );
    676676
    677677        // Unlock the RWlock
     
    682682        /* paranoid */ verify( this.sched.readyQ.tscs == 0p );
    683683        /* 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 );
    686686
    687687        enable_interrupts( false ); // Don't poll, could be in main cluster
  • TabularUnified libcfa/src/heap.cfa

    r21e6da5 r3e1cd17  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan  3 21:30:54 2024
    13 // Update Count     : 1619
     12// Last Modified On : Sun Apr  7 21:54:29 2024
     13// Update Count     : 1644
    1414//
    1515
     
    114114
    115115
    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.
    117117inline __attribute__((always_inline))
    118118static size_t Bsearchl( unsigned int key, const unsigned int vals[], size_t dim ) {
     
    190190                unsigned int realloc_calls, realloc_0_calls;
    191191                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;
    193193                unsigned long long int free_storage_request, free_storage_alloc;
    194194                unsigned int return_pulls, return_pushes;
     
    232232                struct Header {                                                                 // header
    233233                        union Kind {
    234                                 struct RealHeader {
     234                                struct RealHeader {                                             // 4-byte word => 8-byte header, 8-byte word => 16-byte header
    235235                                        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
    246241                                        };
     242                                        size_t size;                                            // allocation size in bytes
    247243                                } real; // RealHeader
    248244
     
    261257
    262258        struct CALIGN FreeHeader {
    263                 size_t blockSize CALIGN;                                                // size of allocations on this list
    264259                #ifdef OWNERSHIP
    265260                #ifdef RETURNSPIN
     
    271266                Storage * freeList;                                                             // thread free list
    272267                Heap * homeManager;                                                             // heap owner (free storage to bucket, from bucket to heap)
     268                size_t blockSize;                                                               // size of allocations on this list
    273269        }; // FreeHeader
    274270
     
    369365static __thread size_t PAD1 CALIGN TLSMODEL __attribute__(( unused )); // protect false sharing
    370366static __thread Heap * heapManager CALIGN TLSMODEL;
    371 static  __thread bool heapManagerBootFlag CALIGN TLSMODEL = false;
     367static __thread bool heapManagerBootFlag CALIGN TLSMODEL = false;
    372368static __thread size_t PAD2 CALIGN TLSMODEL __attribute__(( unused )); // protect further false sharing
    373369
     
    595591
    596592#ifdef __STATISTICS__
    597 static HeapStatistics stats;                                                    // zero filled
    598 
    599593#define prtFmt \
    600594        "\nHeap statistics: (storage request / allocation)\n" \
     
    607601        "  resize    >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n" \
    608602        "  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" \
    610604        "  return    pulls %'u; pushes %'u; storage %'llu / %'llu bytes\n" \
    611605        "  sbrk      calls %'u; storage %'llu bytes\n" \
     
    627621                        resize_calls, resize_0_calls, resize_storage_request, resize_storage_alloc,
    628622                        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,
    630624                        return_pulls, return_pushes, return_storage_request, return_storage_alloc,
    631625                        sbrk_calls, sbrk_storage,
     
    650644        "<total type=\"resize\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \
    651645        "<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" \
    653647        "<total type=\"return\" pulls=\"%'u;\" 0 pushes=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \
    654648        "<total type=\"sbrk\" count=\"%'u;\" size=\"%'llu\"/> bytes\n" \
     
    670664                        resize_calls, resize_0_calls, resize_storage_request, resize_storage_alloc,
    671665                        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,
    673667                        return_pulls, return_pushes, return_storage_request, return_storage_alloc,
    674668                        sbrk_calls, sbrk_storage,
     
    799793        } else {
    800794                fakeHeader( header, alignment );
    801                 if ( unlikely( MmappedBit( header ) ) ) {               // mmapped ?
     795                if ( unlikely( MmappedBit( header ) ) ) {               // mmapped storage ?
    802796                        verify( addr < heapBegin || heapEnd < addr );
    803797                        size = ClearStickyBits( header->kind.real.blockSize ); // mmap size
     798                        freeHead = 0p;                                                          // prevent uninitialized warning
    804799                        return true;
    805800                } // if
     
    904899
    905900
    906 #define BOOT_HEAP_MANAGER \
    907         if ( unlikely( ! heapMasterBootFlag ) ) { \
    908                 heapManagerCtor(); /* trigger for first heap */ \
    909         } /* if */
    910 
    911901#ifdef __STATISTICS__
    912902#define STAT_NAME __counter
    913903#define STAT_PARM , unsigned int STAT_NAME
    914904#define STAT_ARG( name ) , name
    915 #define STAT_0_CNT( counter ) stats.counters[counter].calls_0 += 1
     905#define STAT_0_CNT( counter ) heapManager->stats.counters[counter].calls_0 += 1
    916906#else
    917907#define STAT_NAME
     
    921911#endif // __STATISTICS__
    922912
    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 */
    927927#else
    928 #define __NULL_0_ALLOC__
     928#define __NULL_0_ALLOC__( counter, ... )
    929929#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__
    930940
    931941#define PROLOG( counter, ... ) \
    932942        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__ )
    941945
    942946#define SCRUB_SIZE 1024lu
     
    948952        PROLOG( STAT_NAME );
    949953
    950         verify( heapManager );
    951954        Heap.Storage * block;                                                           // pointer to new block of storage
    952955
     
    956959
    957960        #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;
    959967        stats.counters[STAT_NAME].request += size;
    960968        #endif // __STATISTICS__
     
    10781086
    10791087static 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
    10801092        verify( addr );
    10811093
     
    10911103        #endif // __STATISTICS__ || __CFA_DEBUG__
    10921104
     1105        // Do not move these down because heap can be null!
    10931106        #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
    10941113        stats.free_storage_request += rsize;
    10951114        stats.free_storage_alloc += size;
     
    11171136                } // if
    11181137        } else {
     1138                assert( freeHead );
    11191139                #ifdef __CFA_DEBUG__
    11201140                // memset is NOT always inlined!
     
    13211341        // call to malloc(), alloc(), calloc() or realloc(). If the area pointed to was moved, a free(oaddr) is done.
    13221342        void * resize( void * oaddr, size_t size ) libcfa_public {
    1323           if ( unlikely( oaddr == 0p ) ) {                              // => malloc( size )
     1343          if ( unlikely( oaddr == 0p ) ) {                                      // => malloc( size )
    13241344                        return doMalloc( size STAT_ARG( RESIZE ) );
    13251345                } // if
     
    13331353
    13341354                size_t odsize = DataStorage( bsize, oaddr, header ); // data storage available in bucket
    1335                 // same size, DO NOT preserve STICKY PROPERTIES.
     1355                // same size, DO NOT PRESERVE STICKY PROPERTIES.
    13361356                if ( oalign == libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
    13371357                        ClearZeroFillBit( header );                                     // no alignment and turn off 0 fill
     
    13461366                } // if
    13471367
    1348                 // change size, DO NOT preserve STICKY PROPERTIES.
     1368                // change size, DO NOT PRESERVE STICKY PROPERTIES.
    13491369                doFree( oaddr );                                                                // free previous storage
    13501370
     
    13561376        // the old and new sizes.
    13571377        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 );
    13581381          if ( unlikely( oaddr == 0p ) ) {                                      // => malloc( size )
    13591382                  return doMalloc( size STAT_ARG( REALLOC ) );
     
    14981521                } // if
    14991522
    1500                 #ifdef __STATISTICS__
    1501                 incCalls( FREE );
    1502                 #endif // __STATISTICS__
    1503 
    15041523                doFree( addr );                                                                 // handles heapManager == nullptr
    15051524        } // free
     
    15791598                #endif // __STATISTICS__
    15801599        } // malloc_stats_clear
    1581 
    15821600
    15831601        // Changes the file descriptor where malloc_stats() writes statistics.
     
    17001718        } // if
    17011719
    1702         // change size, DO NOT preserve STICKY PROPERTIES.
     1720        // change size, DO NOT PRESERVE STICKY PROPERTIES.
    17031721        doFree( oaddr );                                                                        // free previous storage
    17041722        return memalignNoStats( nalign, size STAT_ARG( RESIZE ) ); // create new aligned area
     
    17071725
    17081726void * 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 );
    17091730  if ( unlikely( oaddr == 0p ) ) {                                              // => malloc( size )
    17101731                return memalignNoStats( nalign, size STAT_ARG( REALLOC ) );
  • TabularUnified libcfa/src/heap.hfa

    r21e6da5 r3e1cd17  
    1010// Created On       : Tue May 26 11:23:55 2020
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 11 11:18:18 2023
    13 // Update Count     : 24
     12// Last Modified On : Mon Apr  1 09:36:20 2024
     13// Update Count     : 25
    1414//
    1515
     
    4646} // extern "C"
    4747
     48// New allocation operations.
    4849void * resize( void * oaddr, size_t alignment, size_t size );
    4950void * realloc( void * oaddr, size_t alignment, size_t size );
     
    5152
    5253// Local Variables: //
    53 // mode: c //
    5454// tab-width: 4 //
    5555// End: //
  • TabularUnified libcfa/src/stdlib.hfa

    r21e6da5 r3e1cd17  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Mar 17 08:25:31 2024
    13 // Update Count     : 796
     12// Last Modified On : Fri Apr 12 07:39:15 2024
     13// Update Count     : 812
    1414//
    1515
     
    109109        1. Replace the current forall-block that contains defintions of S_fill and S_realloc with following:
    110110                forall( T & | sized(T) ) {
    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 *; };
     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 *; };
    114114                }
    115115
    116116        2. Replace all current postfix-fill functions with following for updated S_fill:
    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; }
     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; }
    120120
    121121        3. Replace the alloc_internal$ function which is outside ttype forall-block with following function:
     
    148148*/
    149149
    150 typedef struct S_align                  { inline size_t;  } T_align;
    151 typedef struct S_resize                 { inline void *;  }     T_resize;
     150typedef struct S_align { inline size_t;  } T_align;
     151typedef struct S_resize { inline void *;  }     T_resize;
    152152
    153153forall( T & ) {
    154         struct S_fill           { char tag; char c; size_t size; T * at; char t[50]; };
    155         struct S_realloc        { inline T *; };
     154        struct S_fill { char tag; char c; size_t size; T * at; char t[50]; };
     155        struct S_realloc { inline T *; };
    156156}
    157157
    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 
     158static inline T_align ?`align( size_t a ) { return (T_align){a}; }
     159static inline T_resize ?`resize( void * a )     { return (T_resize){a}; }
     160
     161extern "C" ssize_t write(int fd, const void *buf, size_t count);
    161162static inline forall( T & | sized(T) ) {
    162163        S_fill(T) ?`fill ( T t ) {
     
    169170                return ret;
    170171        }
    171         S_fill(T)               ?`fill ( zero_t ) = void; // FIX ME: remove this once ticket 214 is resolved
    172         S_fill(T)               ?`fill ( T * a )                                { return (S_fill(T)){ 'T', '0', 0, a }; } // FIX ME: remove this once ticket 214 is resolved
    173         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}; }
    177178
    178179        T * alloc_internal$( void * Resize, T * Realloc, size_t Align, size_t Dim, S_fill(T) Fill ) {
     
    182183
    183184                if ( Resize ) {
    184                         ptr = (T*) (void *) resize( (void *)Resize, Align, Dim * size );
     185                        ptr = (T*)(void *)resize( (void *)Resize, Align, Dim * size );
    185186                } else if ( Realloc ) {
    186187                        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 );
    188189                } else {
    189                         ptr = (T *) (void *) memalign( Align, Dim * size );
     190                        ptr = (T *)(void *) memalign( Align, Dim * size );
    190191                }
    191192
  • TabularUnified src/Parser/StatementNode.cc

    r21e6da5 r3e1cd17  
    122122        ast::Expr * cond = nullptr;
    123123        if ( ctl->condition ) {
    124                 // compare the provided condition against 0
    125                 cond = notZeroExpr( maybeMoveBuild( ctl->condition ) );
     124                cond = maybeMoveBuild( ctl->condition );
    126125        } else {
    127126                for ( ast::ptr<ast::Stmt> & stmt : inits ) {
     
    129128                        auto declStmt = stmt.strict_as<ast::DeclStmt>();
    130129                        auto dwt = declStmt->decl.strict_as<ast::DeclWithType>();
    131                         ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) );
     130                        ast::Expr * nze = new ast::VariableExpr( dwt->location, dwt );
    132131                        cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze;
    133132                }
     
    200199        // do-while cannot have declarations in the contitional, so init is always empty
    201200        return new ast::WhileDoStmt( location,
    202                 notZeroExpr( maybeMoveBuild( ctl ) ),
     201                maybeMoveBuild( ctl ),
    203202                buildMoveSingle( stmt ),
    204203                buildMoveOptional( else_ ),
     
    213212
    214213        ast::Expr * astcond = nullptr;                                          // maybe empty
    215         astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) );
     214        astcond = maybeMoveBuild( forctl->condition );
    216215
    217216        ast::Expr * astincr = nullptr;                                          // maybe empty
     
    330329        clause->target = maybeBuild( targetExpr );
    331330        clause->stmt = maybeMoveBuild( stmt );
    332         clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     331        clause->when_cond = maybeMoveBuild( when );
    333332
    334333        ExpressionNode * next = targetExpr->next;
     
    345344ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
    346345        existing->else_stmt = maybeMoveBuild( stmt );
    347         existing->else_cond = notZeroExpr( maybeMoveBuild( when ) );
     346        existing->else_cond = maybeMoveBuild( when );
    348347
    349348        (void)location;
     
    354353        existing->timeout_time = maybeMoveBuild( timeout );
    355354        existing->timeout_stmt = maybeMoveBuild( stmt );
    356         existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) );
     355        existing->timeout_cond = maybeMoveBuild( when );
    357356
    358357        (void)location;
     
    362361ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
    363362        ast::WhenClause * clause = new ast::WhenClause( loc );
    364         clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     363        clause->when_cond = maybeMoveBuild( when );
    365364        clause->stmt = maybeMoveBuild( stmt );
    366365        clause->target = maybeMoveBuild( targetExpr );
     
    369368ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation & loc, ExpressionNode * when, StatementNode * stmt ) {
    370369        ast::WhenClause * clause = new ast::WhenClause( loc );
    371         clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     370        clause->when_cond = maybeMoveBuild( when );
    372371        clause->stmt = maybeMoveBuild( stmt );
    373372        return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause );
     
    508507
    509508        ast::Expr * astcond = nullptr;                                          // maybe empty
    510         astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) );
     509        astcond = maybeMoveBuild( forctl->condition );
    511510
    512511        ast::Expr * astincr = nullptr;                                          // maybe empty
  • TabularUnified src/Parser/module.mk

    r21e6da5 r3e1cd17  
    3131       Parser/parser.yy \
    3232       Parser/ParserTypes.h \
    33        Parser/parserutility.cc \
    3433       Parser/parserutility.h \
    3534       Parser/RunParser.cpp \
  • TabularUnified src/Parser/parserutility.h

    r21e6da5 r3e1cd17  
    1717
    1818#include "AST/Copy.hpp"            // for shallowCopy
    19 namespace ast {
    20         class Expr;
    21 }
    22 
    23 ast::Expr * notZeroExpr( const ast::Expr *orig );
    2419
    2520template< typename T >
  • TabularUnified src/ResolvExpr/CandidateFinder.cpp

    r21e6da5 r3e1cd17  
    4646#include "AST/Type.hpp"
    4747#include "Common/utility.h"       // for move, copy
    48 #include "Parser/parserutility.h" // for notZeroExpr
    4948#include "SymTab/Mangler.h"
    5049#include "Tuples/Tuples.h"        // for handleTupleAssignment
     
    15871586        void Finder::postvisit( const ast::LogicalExpr * logicalExpr ) {
    15881587                CandidateFinder finder1( context, tenv );
    1589                 ast::ptr<ast::Expr> arg1 = notZeroExpr( logicalExpr->arg1 );
     1588                ast::ptr<ast::Expr> arg1 = createCondExpr( logicalExpr->arg1 );
    15901589                finder1.find( arg1, ResolveMode::withAdjustment() );
    15911590                if ( finder1.candidates.empty() ) return;
    15921591
    15931592                CandidateFinder finder2( context, tenv );
    1594                 ast::ptr<ast::Expr> arg2 = notZeroExpr( logicalExpr->arg2 );
     1593                ast::ptr<ast::Expr> arg2 = createCondExpr( logicalExpr->arg2 );
    15951594                finder2.find( arg2, ResolveMode::withAdjustment() );
    15961595                if ( finder2.candidates.empty() ) return;
     
    16181617        void Finder::postvisit( const ast::ConditionalExpr * conditionalExpr ) {
    16191618                // candidates for condition
    1620                 ast::ptr<ast::Expr> arg1 = notZeroExpr( conditionalExpr->arg1 );
     1619                ast::ptr<ast::Expr> arg1 = createCondExpr( conditionalExpr->arg1 );
    16211620                CandidateFinder finder1( context, tenv );
    16221621                finder1.find( arg1, ResolveMode::withAdjustment() );
     
    22012200}
    22022201
     2202const 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
    22032218} // namespace ResolvExpr
    22042219
  • TabularUnified src/ResolvExpr/CandidateFinder.hpp

    r21e6da5 r3e1cd17  
    7070        const ast::Expr * expr, Cost & cost );
    7171
     72/// Wrap an expression to convert the result to a conditional result.
     73const ast::Expr * createCondExpr( const ast::Expr * expr );
     74
    7275} // namespace ResolvExpr
    7376
  • TabularUnified src/ResolvExpr/Resolver.cc

    r21e6da5 r3e1cd17  
    340340        }
    341341
     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
    342350        /// check if a type is a character type
    343351        bool isCharType( const ast::Type * t ) {
     
    356364                return it != end;
    357365        }
    358 }
     366} // anonymous namespace
    359367
    360368class Resolver final
     
    729737const ast::IfStmt * Resolver::previsit( const ast::IfStmt * ifStmt ) {
    730738        return ast::mutate_field(
    731                 ifStmt, &ast::IfStmt::cond, findIntegralExpression( ifStmt->cond, context ) );
     739                ifStmt, &ast::IfStmt::cond, findCondExpression( ifStmt->cond, context ) );
    732740}
    733741
    734742const ast::WhileDoStmt * Resolver::previsit( const ast::WhileDoStmt * whileDoStmt ) {
    735743        return ast::mutate_field(
    736                 whileDoStmt, &ast::WhileDoStmt::cond, findIntegralExpression( whileDoStmt->cond, context ) );
     744                whileDoStmt, &ast::WhileDoStmt::cond, findCondExpression( whileDoStmt->cond, context ) );
    737745}
    738746
     
    740748        if ( forStmt->cond ) {
    741749                forStmt = ast::mutate_field(
    742                         forStmt, &ast::ForStmt::cond, findIntegralExpression( forStmt->cond, context ) );
     750                        forStmt, &ast::ForStmt::cond, findCondExpression( forStmt->cond, context ) );
    743751        }
    744752
     
    10751083
    10761084                // Resolve the conditions as if it were an IfStmt, statements normally
    1077                 clause2->when_cond = findSingleExpression( clause.when_cond, context );
     1085                clause2->when_cond = findCondExpression( clause.when_cond, context );
    10781086                clause2->stmt = clause.stmt->accept( *visitor );
    10791087
     
    10891097                        new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
    10901098                auto timeout_time = findSingleExpression( stmt->timeout_time, target, context );
    1091                 auto timeout_cond = findSingleExpression( stmt->timeout_cond, context );
     1099                auto timeout_cond = findCondExpression( stmt->timeout_cond, context );
    10921100                auto timeout_stmt = stmt->timeout_stmt->accept( *visitor );
    10931101
     
    11021110        if ( stmt->else_stmt ) {
    11031111                // resolve the condition like IfStmt, stmts normally
    1104                 auto else_cond = findSingleExpression( stmt->else_cond, context );
     1112                auto else_cond = findCondExpression( stmt->else_cond, context );
    11051113                auto else_stmt = stmt->else_stmt->accept( *visitor );
    11061114
Note: See TracChangeset for help on using the changeset viewer.