Changes in / [c4c8571:3f95dab]


Ignore:
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • benchmark/rmit.py

    rc4c8571 r3f95dab  
    183183                        range( 97, 145) : "24-95,120-191",
    184184                        range(145, 193) : "0-95,96-191",
    185                 },
    186                 "nasus": {
    187                         range(  1,  65) : "64-127",
    188                         range( 65, 129) : "64-127,192-255",
    189                         range(129, 193) : "64-255",
    190                         range(193, 257) : "0-255",
    191185                },
    192186        }
  • libcfa/src/concurrency/io.cfa

    rc4c8571 r3f95dab  
    241241                        else {
    242242                                const unsigned target = proc->io.target;
    243                                 /* paranoid */ verify( io.tscs[target].t.tv != ULLONG_MAX );
     243                                /* paranoid */ verify( io.tscs[target].tv != ULLONG_MAX );
    244244                                HELP: if(target < ctxs_count) {
    245245                                        const unsigned long long cutoff = calc_cutoff(ctsc, ctx->cq.id, ctxs_count, io.data, io.tscs, __shard_factor.io);
    246                                         const unsigned long long age = moving_average(ctsc, io.tscs[target].t.tv, io.tscs[target].t.ma);
     246                                        const unsigned long long age = moving_average(ctsc, io.tscs[target].tv, io.tscs[target].ma);
    247247                                        __cfadbg_print_safe(io, "Kernel I/O: Help attempt on %u from %u, age %'llu vs cutoff %'llu, %s\n", target, ctx->cq.id, age, cutoff, age > cutoff ? "yes" : "no");
    248248                                        if(age <= cutoff) break HELP;
  • libcfa/src/concurrency/io/setup.cfa

    rc4c8571 r3f95dab  
    359359        }
    360360
    361         void ^?{}( $io_arbiter & mutex this ) {}
     361        void ^?{}( $io_arbiter & this ) {}
    362362
    363363        $io_arbiter * create(void) {
  • libcfa/src/concurrency/io/types.hfa

    rc4c8571 r3f95dab  
    125125
    126126
    127         struct __attribute__((aligned(64))) $io_context {
     127        struct __attribute__((aligned(128))) $io_context {
    128128                $io_arbiter * arbiter;
    129129                processor * proc;
     
    153153        };
    154154
    155         monitor __attribute__((aligned(64))) $io_arbiter {
     155        struct __attribute__((aligned(128))) $io_arbiter {
    156156                __outstanding_io_queue pending;
    157157        };
  • libcfa/src/concurrency/kernel.hfa

    rc4c8571 r3f95dab  
    8383
    8484// Wrapper around kernel threads
    85 struct __attribute__((aligned(64))) processor {
     85struct __attribute__((aligned(128))) processor {
    8686        // Cluster from which to get threads
    8787        struct cluster * cltr;
     
    171171
    172172// Intrusives lanes which are used by the ready queue
    173 union __attribute__((aligned(64))) __intrusive_lane_t;
     173struct __attribute__((aligned(128))) __intrusive_lane_t;
    174174void  ?{}(__intrusive_lane_t & this);
    175175void ^?{}(__intrusive_lane_t & this);
    176176
    177177// Aligned timestamps which are used by the ready queue and io subsystem
    178 union __attribute__((aligned(64))) __timestamp_t {
    179         struct {
    180                 volatile unsigned long long tv;
    181                 volatile unsigned long long ma;
    182         } t;
    183         char __padding[192];
    184 };
    185 
    186 static inline void  ?{}(__timestamp_t & this) { this.t.tv = 0; this.t.ma = 0; }
     178struct __attribute__((aligned(128))) __timestamp_t {
     179        volatile unsigned long long tv;
     180        volatile unsigned long long ma;
     181};
     182
     183static inline void  ?{}(__timestamp_t & this) { this.tv = 0; this.ma = 0; }
    187184static inline void ^?{}(__timestamp_t &) {}
    188185
     
    215212//-----------------------------------------------------------------------------
    216213// Cluster
    217 struct __attribute__((aligned(64))) cluster {
     214struct __attribute__((aligned(128))) cluster {
    218215        struct {
    219216                struct {
  • libcfa/src/concurrency/kernel/cluster.cfa

    rc4c8571 r3f95dab  
    229229                        for( idx ; lanes_count ) {
    230230                                __intrusive_lane_t & sl = readyQ.data[idx];
    231                                 assert(!readyQ.data[idx].l.lock);
     231                                assert(!readyQ.data[idx].lock);
    232232
    233233                                        if(is_empty(sl)) {
    234                                                 assert( sl.l.anchor.next == 0p );
    235                                                 assert( sl.l.anchor.ts   == MAX );
    236                                                 assert( mock_head(sl)  == sl.l.prev );
     234                                                assert( sl.anchor.next == 0p );
     235                                                assert( sl.anchor.ts   == MAX );
     236                                                assert( mock_head(sl)  == sl.prev );
    237237                                        } else {
    238                                                 assert( sl.l.anchor.next != 0p );
    239                                                 assert( sl.l.anchor.ts   != MAX );
    240                                                 assert( mock_head(sl)  != sl.l.prev );
     238                                                assert( sl.anchor.next != 0p );
     239                                                assert( sl.anchor.ts   != MAX );
     240                                                assert( mock_head(sl)  != sl.prev );
    241241                                        }
    242242                        }
     
    249249static inline void fix(__intrusive_lane_t & ll) {
    250250        if(is_empty(ll)) {
    251                 verify(ll.l.anchor.next == 0p);
    252                 ll.l.prev = mock_head(ll);
     251                verify(ll.anchor.next == 0p);
     252                ll.prev = mock_head(ll);
    253253        }
    254254}
     
    299299        tscs = alloc(count, tscs`realloc);
    300300        for(i; count) {
    301                 tscs[i].t.tv = rdtscl();
    302                 tscs[i].t.ma = 0;
     301                tscs[i].tv = rdtscl();
     302                tscs[i].ma = 0;
    303303        }
    304304}
     
    400400                for( idx; ncount ~ ocount) {
    401401                        // Lock is not strictly needed but makes checking invariants much easier
    402                         __attribute__((unused)) bool locked = __atomic_try_acquire(&readyQ.data[idx].l.lock);
     402                        __attribute__((unused)) bool locked = __atomic_try_acquire(&readyQ.data[idx].lock);
    403403                        verify(locked);
    404404
     
    418418
    419419                        // Unlock the lane
    420                         __atomic_unlock(&readyQ.data[idx].l.lock);
     420                        __atomic_unlock(&readyQ.data[idx].lock);
    421421
    422422                        // TODO print the queue statistics here
     
    467467}
    468468
    469 #define nested_offsetof(type, field) ((off_t)(&(((type*)0)-> field)))
    470 
    471469// Ctor
    472470void ?{}( __intrusive_lane_t & this ) {
    473         this.l.lock = false;
    474         this.l.prev = mock_head(this);
    475         this.l.anchor.next = 0p;
    476         this.l.anchor.ts   = MAX;
     471        this.lock = false;
     472        this.prev = mock_head(this);
     473        this.anchor.next = 0p;
     474        this.anchor.ts   = MAX;
    477475        #if !defined(__CFA_NO_STATISTICS__)
    478                 this.l.cnt  = 0;
     476                this.cnt  = 0;
    479477        #endif
    480478
    481479        // We add a boat-load of assertions here because the anchor code is very fragile
    482         /* paranoid */ _Static_assert( offsetof( thread$, link ) == nested_offsetof(__intrusive_lane_t, l.anchor) );
    483         /* paranoid */ verify( offsetof( thread$, link ) == nested_offsetof(__intrusive_lane_t, l.anchor) );
    484         /* paranoid */ verify( ((uintptr_t)( mock_head(this) ) + offsetof( thread$, link )) == (uintptr_t)(&this.l.anchor) );
    485         /* paranoid */ verify( &mock_head(this)->link.next == &this.l.anchor.next );
    486         /* paranoid */ verify( &mock_head(this)->link.ts   == &this.l.anchor.ts   );
     480        /* paranoid */ _Static_assert( offsetof( thread$, link ) == offsetof(__intrusive_lane_t, anchor) );
     481        /* paranoid */ verify( offsetof( thread$, link ) == offsetof(__intrusive_lane_t, anchor) );
     482        /* paranoid */ verify( ((uintptr_t)( mock_head(this) ) + offsetof( thread$, link )) == (uintptr_t)(&this.anchor) );
     483        /* paranoid */ verify( &mock_head(this)->link.next == &this.anchor.next );
     484        /* paranoid */ verify( &mock_head(this)->link.ts   == &this.anchor.ts   );
    487485        /* paranoid */ verify( mock_head(this)->link.next == 0p );
    488486        /* paranoid */ verify( mock_head(this)->link.ts   == MAX );
    489         /* paranoid */ verify( mock_head(this) == this.l.prev );
    490         /* paranoid */ verify( __alignof__(__intrusive_lane_t) == 64 );
    491         /* paranoid */ verify( __alignof__(this) == 64 );
    492         /* paranoid */ verifyf( ((intptr_t)(&this) % 64) == 0, "Expected address to be aligned %p %% 64 == %zd", &this, ((intptr_t)(&this) % 64) );
    493 }
    494 
    495 #undef nested_offsetof
     487        /* paranoid */ verify( mock_head(this) == this.prev );
     488        /* paranoid */ verify( __alignof__(__intrusive_lane_t) == 128 );
     489        /* paranoid */ verify( __alignof__(this) == 128 );
     490        /* paranoid */ verifyf( ((intptr_t)(&this) % 128) == 0, "Expected address to be aligned %p %% 128 == %zd", &this, ((intptr_t)(&this) % 128) );
     491}
    496492
    497493// Dtor is trivial
    498494void ^?{}( __intrusive_lane_t & this ) {
    499495        // Make sure the list is empty
    500         /* paranoid */ verify( this.l.anchor.next == 0p );
    501         /* paranoid */ verify( this.l.anchor.ts   == MAX );
    502         /* paranoid */ verify( mock_head(this)    == this.l.prev );
     496        /* paranoid */ verify( this.anchor.next == 0p );
     497        /* paranoid */ verify( this.anchor.ts   == MAX );
     498        /* paranoid */ verify( mock_head(this)  == this.prev );
    503499}
    504500
  • libcfa/src/concurrency/kernel/cluster.hfa

    rc4c8571 r3f95dab  
    3939        if (ts_next == ULLONG_MAX) return;
    4040        unsigned long long now = rdtscl();
    41         unsigned long long pma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED);
    42         __atomic_store_n(&tscs[ idx ].t.tv, ts_next, __ATOMIC_RELAXED);
    43         __atomic_store_n(&tscs[ idx ].t.ma, moving_average(now, ts_prev, pma), __ATOMIC_RELAXED);
     41        unsigned long long pma = __atomic_load_n(&tscs[ idx ].ma, __ATOMIC_RELAXED);
     42        __atomic_store_n(&tscs[ idx ].tv, ts_next, __ATOMIC_RELAXED);
     43        __atomic_store_n(&tscs[ idx ].ma, moving_average(now, ts_prev, pma), __ATOMIC_RELAXED);
    4444}
    4545
     
    6161                if(ptsc != ULLONG_MAX) {
    6262                        /* paranoid */ verify( start + i < count );
    63                         unsigned long long tsc = moving_average(ctsc, ptsc, tscs[start + i].t.ma);
     63                        unsigned long long tsc = moving_average(ctsc, ptsc, tscs[start + i].ma);
    6464                        if(tsc > max) max = tsc;
    6565                }
  • libcfa/src/concurrency/kernel/fwd.hfa

    rc4c8571 r3f95dab  
    3535extern "C" {
    3636        extern "Cforall" {
    37                 extern __attribute__((aligned(64))) thread_local struct KernelThreadData {
     37                extern __attribute__((aligned(128))) thread_local struct KernelThreadData {
    3838                        struct thread$          * volatile this_thread;
    3939                        struct processor        * volatile this_processor;
  • libcfa/src/concurrency/kernel/private.hfa

    rc4c8571 r3f95dab  
    8888#elif defined(CFA_HAVE_LINUX_RSEQ_H)
    8989        extern "Cforall" {
    90                 extern __attribute__((aligned(64))) thread_local volatile struct rseq __cfaabi_rseq;
     90                extern __attribute__((aligned(128))) thread_local volatile struct rseq __cfaabi_rseq;
    9191        }
    9292#else
  • libcfa/src/concurrency/kernel/startup.cfa

    rc4c8571 r3f95dab  
    152152#elif defined(CFA_HAVE_LINUX_RSEQ_H)
    153153        extern "Cforall" {
    154                 __attribute__((aligned(64))) thread_local volatile struct rseq __cfaabi_rseq @= {
     154                __attribute__((aligned(128))) thread_local volatile struct rseq __cfaabi_rseq @= {
    155155                        .cpu_id : RSEQ_CPU_ID_UNINITIALIZED,
    156156                };
  • libcfa/src/concurrency/ready_queue.cfa

    rc4c8571 r3f95dab  
    8181                                /* paranoid */ verify( i < lanes_count );
    8282                                // If we can't lock it retry
    83                         } while( !__atomic_try_acquire( &readyQ.data[i].l.lock ) );
     83                        } while( !__atomic_try_acquire( &readyQ.data[i].lock ) );
    8484                } else {
    8585                        do {
    8686                                i = __tls_rand() % lanes_count;
    87                         } while( !__atomic_try_acquire( &readyQ.data[i].l.lock ) );
     87                        } while( !__atomic_try_acquire( &readyQ.data[i].lock ) );
    8888                }
    8989        } else {
     
    9393                        /* paranoid */ verify( i < lanes_count );
    9494                        // If we can't lock it retry
    95                 } while( !__atomic_try_acquire( &readyQ.data[i].l.lock ) );
     95                } while( !__atomic_try_acquire( &readyQ.data[i].lock ) );
    9696        }
    9797
     
    100100
    101101        // Unlock and return
    102         __atomic_unlock( &readyQ.data[i].l.lock );
     102        __atomic_unlock( &readyQ.data[i].lock );
    103103
    104104        #if !defined(__CFA_NO_STATISTICS__)
     
    136136        else {
    137137                const unsigned target = proc->rdq.target;
    138                 __cfadbg_print_safe(ready_queue, "Kernel : %u considering helping %u, tcsc %llu\n", this, target, readyQ.tscs[target].t.tv);
    139                 /* paranoid */ verify( readyQ.tscs[target].t.tv != ULLONG_MAX );
     138                __cfadbg_print_safe(ready_queue, "Kernel : %u considering helping %u, tcsc %llu\n", this, target, readyQ.tscs[target].tv);
     139                /* paranoid */ verify( readyQ.tscs[target].tv != ULLONG_MAX );
    140140                if(target < lanes_count) {
    141141                        const unsigned long long cutoff = calc_cutoff(ctsc, proc->rdq.id, lanes_count, cltr->sched.readyQ.data, cltr->sched.readyQ.tscs, __shard_factor.readyq);
    142                         const unsigned long long age = moving_average(ctsc, readyQ.tscs[target].t.tv, readyQ.tscs[target].t.ma);
     142                        const unsigned long long age = moving_average(ctsc, readyQ.tscs[target].tv, readyQ.tscs[target].ma);
    143143                        __cfadbg_print_safe(ready_queue, "Kernel : Help attempt on %u from %u, age %'llu vs cutoff %'llu, %s\n", target, this, age, cutoff, age > cutoff ? "yes" : "no");
    144144                        if(age > cutoff) {
     
    188188
    189189        // If we can't get the lock retry
    190         if( !__atomic_try_acquire(&lane.l.lock) ) {
     190        if( !__atomic_try_acquire(&lane.lock) ) {
    191191                return 0p;
    192192        }
     
    194194        // If list is empty, unlock and retry
    195195        if( is_empty(lane) ) {
    196                 __atomic_unlock(&lane.l.lock);
     196                __atomic_unlock(&lane.lock);
    197197                return 0p;
    198198        }
     
    206206        /* paranoid */ verify(thrd);
    207207        /* paranoid */ verify(ts_next);
    208         /* paranoid */ verify(lane.l.lock);
     208        /* paranoid */ verify(lane.lock);
    209209
    210210        // Unlock and return
    211         __atomic_unlock(&lane.l.lock);
     211        __atomic_unlock(&lane.lock);
    212212
    213213        // Update statistics
  • libcfa/src/concurrency/ready_subqueue.hfa

    rc4c8571 r3f95dab  
    66
    77// Intrusives lanes which are used by the relaxed ready queue
    8 union __attribute__((aligned(64))) __intrusive_lane_t {
    9         struct {
    10                 struct thread$ * prev;
     8struct __attribute__((aligned(128))) __intrusive_lane_t {
     9        struct thread$ * prev;
    1110
    12                 // spin lock protecting the queue
    13                 volatile bool lock;
     11        // spin lock protecting the queue
     12        volatile bool lock;
    1413
    15                 __thread_desc_link anchor;
     14        __thread_desc_link anchor;
    1615
    17                 #if !defined(__CFA_NO_STATISTICS__)
    18                         unsigned cnt;
    19                 #endif
    20         } l;
    21         char __padding[192];
     16        #if !defined(__CFA_NO_STATISTICS__)
     17                unsigned cnt;
     18        #endif
    2219};
    2320
     
    2522static inline thread$ * mock_head(const __intrusive_lane_t & this) {
    2623        thread$ * rhead = (thread$ *)(
    27                 (uintptr_t)( &this.l.anchor ) - __builtin_offsetof( thread$, link )
     24                (uintptr_t)( &this.anchor ) - __builtin_offsetof( thread$, link )
    2825        );
    2926        return rhead;
     
    3330// returns true of lane was empty before push, false otherwise
    3431static inline void push( __intrusive_lane_t & this, thread$ * node ) {
    35         /* paranoid */ verify( this.l.lock );
     32        /* paranoid */ verify( this.lock );
    3633        /* paranoid */ verify( node->link.next == 0p );
    3734        /* paranoid */ verify( __atomic_load_n(&node->link.ts, __ATOMIC_RELAXED) == MAX  );
    38         /* paranoid */ verify( this.l.prev->link.next == 0p );
    39         /* paranoid */ verify( __atomic_load_n(&this.l.prev->link.ts, __ATOMIC_RELAXED)   == MAX  );
    40         if( this.l.anchor.next == 0p ) {
    41                 /* paranoid */ verify( this.l.anchor.next == 0p );
    42                 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) == MAX );
    43                 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != 0  );
    44                 /* paranoid */ verify( this.l.prev == mock_head( this ) );
     35        /* paranoid */ verify( this.prev->link.next == 0p );
     36        /* paranoid */ verify( __atomic_load_n(&this.prev->link.ts, __ATOMIC_RELAXED)   == MAX  );
     37        if( this.anchor.next == 0p ) {
     38                /* paranoid */ verify( this.anchor.next == 0p );
     39                /* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) == MAX );
     40                /* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != 0  );
     41                /* paranoid */ verify( this.prev == mock_head( this ) );
    4542        } else {
    46                 /* paranoid */ verify( this.l.anchor.next != 0p );
    47                 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != MAX );
    48                 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != 0  );
    49                 /* paranoid */ verify( this.l.prev != mock_head( this ) );
     43                /* paranoid */ verify( this.anchor.next != 0p );
     44                /* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != MAX );
     45                /* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != 0  );
     46                /* paranoid */ verify( this.prev != mock_head( this ) );
    5047        }
    5148
    5249        // Get the relevant nodes locally
    53         this.l.prev->link.next = node;
    54         __atomic_store_n(&this.l.prev->link.ts, rdtscl(), __ATOMIC_RELAXED);
    55         this.l.prev = node;
     50        this.prev->link.next = node;
     51        __atomic_store_n(&this.prev->link.ts, rdtscl(), __ATOMIC_RELAXED);
     52        this.prev = node;
    5653        #if !defined(__CFA_NO_STATISTICS__)
    57                 this.l.cnt++;
     54                this.cnt++;
    5855        #endif
    5956}
     
    6360// returns true of lane was empty before push, false otherwise
    6461static inline [* thread$, unsigned long long] pop( __intrusive_lane_t & this ) {
    65         /* paranoid */ verify( this.l.lock );
    66         /* paranoid */ verify( this.l.anchor.next != 0p );
    67         /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != MAX );
    68         /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != 0   );
     62        /* paranoid */ verify( this.lock );
     63        /* paranoid */ verify( this.anchor.next != 0p );
     64        /* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != MAX );
     65        /* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != 0   );
    6966
    7067        // Get the relevant nodes locally
    71         thread$ * node = this.l.anchor.next;
    72         this.l.anchor.next = node->link.next;
    73         __atomic_store_n(&this.l.anchor.ts, __atomic_load_n(&node->link.ts, __ATOMIC_RELAXED), __ATOMIC_RELAXED);
    74         bool is_empty = this.l.anchor.next == 0p;
     68        thread$ * node = this.anchor.next;
     69        this.anchor.next = node->link.next;
     70        __atomic_store_n(&this.anchor.ts, __atomic_load_n(&node->link.ts, __ATOMIC_RELAXED), __ATOMIC_RELAXED);
     71        bool is_empty = this.anchor.next == 0p;
    7572        node->link.next = 0p;
    7673        __atomic_store_n(&node->link.ts, ULLONG_MAX, __ATOMIC_RELAXED);
    7774        #if !defined(__CFA_NO_STATISTICS__)
    78                 this.l.cnt--;
     75                this.cnt--;
    7976        #endif
    8077
    8178        // Update head time stamp
    82         if(is_empty) this.l.prev = mock_head( this );
     79        if(is_empty) this.prev = mock_head( this );
    8380
    84         unsigned long long ats = __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED);
     81        unsigned long long ats = __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED);
    8582        /* paranoid */ verify( node->link.next == 0p );
    8683        /* paranoid */ verify( __atomic_load_n(&node->link.ts , __ATOMIC_RELAXED) == MAX );
     
    9390// Check whether or not list is empty
    9491static inline bool is_empty(__intrusive_lane_t & this) {
    95         return this.l.anchor.next == 0p;
     92        return this.anchor.next == 0p;
    9693}
    9794
     
    9996static inline unsigned long long ts(__intrusive_lane_t & this) {
    10097        // Cannot verify 'emptiness' here since it may not be locked
    101         /* paranoid */ verify(this.l.anchor.ts != 0);
    102         /* paranoid */ static_assert(__atomic_always_lock_free(sizeof(this.l.anchor.ts), &this.l.anchor.ts));
    103         return __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED);
     98        /* paranoid */ verify(this.anchor.ts != 0);
     99        /* paranoid */ static_assert(__atomic_always_lock_free(sizeof(this.anchor.ts), &this.anchor.ts));
     100        return __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED);
    104101}
  • libcfa/src/concurrency/stats.hfa

    rc4c8571 r3f95dab  
    132132        #endif
    133133
    134         struct __attribute__((aligned(64))) __stats_t {
     134        struct __attribute__((aligned(128))) __stats_t {
    135135                __stats_readyQ_t ready;
    136136                #if defined(CFA_HAVE_LINUX_IO_URING_H)
  • src/AST/Decl.hpp

    rc4c8571 r3f95dab  
    143143        FunctionDecl( const CodeLocation & loc, const std::string & name, std::vector<ptr<TypeDecl>>&& forall,
    144144                std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
    145                 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall,
     145                CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
    146146                std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false);
    147147
     
    149149                std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions,
    150150                std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
    151                 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall,
     151                CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
    152152                std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false);
    153153
  • src/GenPoly/SpecializeNew.cpp

    rc4c8571 r3f95dab  
    230230        if ( auto tuple = type.as<ast::TupleType>() ) {
    231231                std::vector<ast::ptr<ast::Expr>> exprs;
    232                 for ( const ast::ptr<ast::Type> & t : *tuple ) {
     232                for ( const ast::Type * t : *tuple ) {
    233233                        exprs.push_back( structureArg( location, t, begin, end ) );
    234234                }
     
    248248                        if (typeMap.count(typeInst->base)) {
    249249                                ast::TypeInstType * newInst = mutate(typeInst);
    250                                 auto const & pair = typeMap[typeInst->base];
    251                                 newInst->expr_id = pair.first;
    252                                 newInst->formal_usage = pair.second;
     250                                newInst->expr_id = typeMap[typeInst->base].first;
     251                                newInst->formal_usage = typeMap[typeInst->base].second;
    253252                                return newInst;
    254253                        }
     
    463462        if ( specialized != expr->arg ) {
    464463                // Assume that the specialization incorporates the cast.
     464                std::cerr << expr <<std::endl;
    465465                return specialized;
    466466        } else {
  • src/InitTweak/InitTweak.cc

    rc4c8571 r3f95dab  
    2727#include "AST/Stmt.hpp"
    2828#include "AST/Type.hpp"
    29 #include "CodeGen/OperatorTable.h" // for isConstructor, isDestructor, isCto...
    3029#include "Common/PassVisitor.h"
    3130#include "Common/SemanticError.h"  // for SemanticError
     
    771770                        std::list< Expression * > callExprs;
    772771                        collectCtorDtorCalls( stmt, callExprs );
     772                        // if ( callExprs.empty() ) return false; // xxx - do I still need this check?
    773773                        return std::all_of( callExprs.begin(), callExprs.end(), pred);
    774774                }
     
    901901                        } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( func ) ) {
    902902                                return varExpr->get_var()->get_name();
    903                         } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( func ) ) {
     903                        }       else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( func ) ) {
    904904                                return funcName( castExpr->get_arg() );
    905905                        } else if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( func ) ) {
     
    923923                        } else if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( func ) ) {
    924924                                return varExpr->var->name;
    925                         } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( func ) ) {
     925                        }       else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( func ) ) {
    926926                                return funcName( castExpr->arg );
    927927                        } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( func ) ) {
     
    991991
    992992        Type * isPointerType( Type * type ) {
    993                 return getPointerBase( type ) ? type : nullptr;
     993                if ( getPointerBase( type ) ) return type;
     994                else return nullptr;
    994995        }
    995996
     
    10131014                                src = new AddressExpr( src );
    10141015                        }
     1016                        // src = new CastExpr( src, new ReferenceType( noQualifiers, src->result->stripReferences()->clone() ) );
    10151017                }
    10161018                return new ApplicationExpr( VariableExpr::functionPointer( assign ), { dst, src } );
     
    11651167        }
    11661168
     1169        bool isConstructor( const std::string & str ) { return str == "?{}"; }
     1170        bool isDestructor( const std::string & str ) { return str == "^?{}"; }
     1171        bool isAssignment( const std::string & str ) { return str == "?=?"; }
     1172        bool isCtorDtor( const std::string & str ) { return isConstructor( str ) || isDestructor( str ); }
     1173        bool isCtorDtorAssign( const std::string & str ) { return isCtorDtor( str ) || isAssignment( str ); }
     1174
    11671175        const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ) {
    11681176                const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( decl );
     
    11841192
    11851193bool isAssignment( const ast::FunctionDecl * decl ) {
    1186         return CodeGen::isAssignment( decl->name ) && isCopyFunction( decl );
     1194        return isAssignment( decl->name ) && isCopyFunction( decl );
    11871195}
    11881196
    11891197bool isDestructor( const ast::FunctionDecl * decl ) {
    1190         return CodeGen::isDestructor( decl->name );
     1198        return isDestructor( decl->name );
    11911199}
    11921200
    11931201bool isDefaultConstructor( const ast::FunctionDecl * decl ) {
    1194         return CodeGen::isConstructor( decl->name ) && 1 == decl->params.size();
     1202        return isConstructor( decl->name ) && 1 == decl->params.size();
    11951203}
    11961204
    11971205bool isCopyConstructor( const ast::FunctionDecl * decl ) {
    1198         return CodeGen::isConstructor( decl->name ) && 2 == decl->params.size();
     1206        return isConstructor( decl->name ) && 2 == decl->params.size();
    11991207}
    12001208
     
    12141222        }
    12151223        const FunctionDecl * isDestructor( const Declaration * decl ) {
    1216                 if ( CodeGen::isDestructor( decl->name ) ) {
     1224                if ( isDestructor( decl->name ) ) {
    12171225                        return dynamic_cast< const FunctionDecl * >( decl );
    12181226                }
     
    12201228        }
    12211229        const FunctionDecl * isDefaultConstructor( const Declaration * decl ) {
    1222                 if ( CodeGen::isConstructor( decl->name ) ) {
     1230                if ( isConstructor( decl->name ) ) {
    12231231                        if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) {
    12241232                                if ( func->type->parameters.size() == 1 ) {
  • src/SymTab/Autogen.cc

    rc4c8571 r3f95dab  
    258258        }
    259259
    260         /// Given type T, generate type of default ctor/dtor, i.e. function type void (*) (T &).
     260        ///
    261261        ast::FunctionDecl * genDefaultFunc(const CodeLocation loc, const std::string fname, const ast::Type * paramType, bool maybePolymorphic) {
    262262                std::vector<ast::ptr<ast::TypeDecl>> typeParams;
    263263                if (maybePolymorphic) typeParams = getGenericParams(paramType);
    264264                auto dstParam = new ast::ObjectDecl(loc, "_dst", new ast::ReferenceType(paramType), nullptr, {}, ast::Linkage::Cforall);
    265                 return new ast::FunctionDecl(loc, fname, std::move(typeParams), {dstParam}, {}, new ast::CompoundStmt(loc), {}, ast::Linkage::Cforall);
     265                return new ast::FunctionDecl(loc, fname, std::move(typeParams), {dstParam}, {}, new ast::CompoundStmt(loc));
    266266        }
    267267
Note: See TracChangeset for help on using the changeset viewer.