Changeset ad861ef


Ignore:
Timestamp:
Jan 20, 2023, 1:25:37 PM (2 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
79a6b17, cd5eb4b
Parents:
466787a (diff), a0d1f1c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

Files:
19 added
3 deleted
51 edited
27 moved

Legend:

Unmodified
Added
Removed
  • configure.ac

    r466787a rad861ef  
    226226AC_PROG_YACC
    227227if test "${YACC}" = "yacc" ; then echo "Error: bison required." ; exit 1 ; fi
    228 AC_PROG_LEX
     228AC_PROG_LEX(yywrap)
    229229if test "${LEX}" = "lex" ; then echo "Error: flex required." ; exit 1 ; fi
    230 AC_PROG_LIBTOOL
     230LT_INIT
    231231AC_PROG_INSTALL
    232232
     
    284284                tools/Makefile
    285285                tools/prettyprinter/Makefile
     286                benchmark/Cargo.toml
    286287        ])
    287 
    288         AC_OUTPUT(benchmark/Cargo.toml)
    289288])
    290289
    291290AC_CONFIG_LINKS([tests/test.py:tests/test.py])
    292 
    293 AC_OUTPUT(tests/config.py)
     291AC_CONFIG_FILES([tests/config.py])
     292
     293AC_OUTPUT
    294294
    295295# Final text
  • libcfa/configure.ac

    r466787a rad861ef  
    122122AC_PROG_CC
    123123AM_PROG_AS
    124 AC_PROG_LIBTOOL
     124LT_INIT
    125125AC_PROG_INSTALL
    126126AC_PROG_MAKE_SET
     
    246246AC_CONFIG_HEADERS(prelude/defines.hfa)
    247247
    248 AC_OUTPUT()
     248AC_OUTPUT
    249249
    250250# Final text
  • libcfa/src/Makefile.am

    r466787a rad861ef  
    113113        concurrency/once.hfa \
    114114        concurrency/kernel/fwd.hfa \
    115         concurrency/mutex_stmt.hfa
     115        concurrency/mutex_stmt.hfa \
     116    concurrency/select.hfa \
     117    concurrency/channel.hfa
    116118
    117119inst_thread_headers_src = \
  • libcfa/src/concurrency/clib/cfathread.cfa

    r466787a rad861ef  
    439439        // Mutex
    440440        struct cfathread_mutex {
    441                 linear_backoff_then_block_lock impl;
     441                exp_backoff_then_block_lock impl;
    442442        };
    443443        int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict) __attribute__((nonnull (1))) { *mut = new(); return 0; }
     
    454454        // Condition
    455455        struct cfathread_condition {
    456                 condition_variable(linear_backoff_then_block_lock) impl;
     456                condition_variable(exp_backoff_then_block_lock) impl;
    457457        };
    458458        int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict) __attribute__((nonnull (1))) { *cond = new(); return 0; }
  • libcfa/src/concurrency/future.hfa

    r466787a rad861ef  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // io/types.hfa --
    8 //
    9 // Author           : Thierry Delisle & Peiran Hong
     7// concurrency/future.hfa --
     8//
     9// Author           : Thierry Delisle & Peiran Hong & Colby Parsons
    1010// Created On       : Wed Jan 06 17:33:18 2021
    1111// Last Modified By :
     
    1414//
    1515
    16 #pragma once
     16// #pragma once
    1717
    1818#include "bits/locks.hfa"
    1919#include "monitor.hfa"
    20 
     20#include "select.hfa"
     21
     22//----------------------------------------------------------------------------
     23// future
     24// I don't use future_t here since I need to use a lock for this future
     25//  since it supports multiple consumers
     26//  future_t is lockfree and uses atomics which aren't needed given we use locks here
    2127forall( T ) {
     28    // enum(int) { FUTURE_EMPTY = 0, FUTURE_FULFILLED = 1 }; // Enums seem to be broken so feel free to add this back afterwards
     29
     30    // temporary enum replacement
     31    const int FUTURE_EMPTY = 0;
     32    const int FUTURE_FULFILLED = 1;
     33
    2234        struct future {
     35                int state;
     36                T result;
     37                dlist( select_node ) waiters;
     38        futex_mutex lock;
     39        };
     40
     41    struct future_node {
     42        inline select_node;
     43        T * my_result;
     44    };
     45
     46    // C_TODO: perhaps allow exceptions to be inserted like uC++?
     47
     48        static inline {
     49
     50        void ?{}( future_node(T) & this, thread$ * blocked_thread, T * my_result ) {
     51            ((select_node &)this){ blocked_thread };
     52            this.my_result = my_result;
     53        }
     54
     55        void ?{}(future(T) & this) {
     56                        this.waiters{};
     57            this.state = FUTURE_EMPTY;
     58            this.lock{};
     59                }
     60
     61                // Reset future back to original state
     62                void reset(future(T) & this) with(this)
     63        {
     64            lock( lock );
     65            if( ! waiters`isEmpty )
     66                abort("Attempting to reset a future with blocked waiters");
     67            state = FUTURE_EMPTY;
     68            unlock( lock );
     69        }
     70
     71                // check if the future is available
     72        // currently no mutual exclusion because I can't see when you need this call to be synchronous or protected
     73                bool available( future(T) & this ) { return this.state; }
     74
     75
     76        // memcpy wrapper to help copy values
     77        void copy_T( T & from, T & to ) {
     78            memcpy((void *)&to, (void *)&from, sizeof(T));
     79        }
     80
     81        // internal helper to signal waiters off of the future
     82        void _internal_flush( future(T) & this ) with(this) {
     83            while( ! waiters`isEmpty ) {
     84                select_node &s = try_pop_front( waiters );
     85
     86                if ( s.race_flag == 0p )
     87                    // poke in result so that woken threads do not need to reacquire any locks
     88                    // *(((future_node(T) &)s).my_result) = result;
     89                    copy_T( result, *(((future_node(T) &)s).my_result) );
     90                else if ( !install_select_winner( s, &this ) ) continue;
     91               
     92                // only unpark if future is not selected
     93                // or if it is selected we only unpark if we win the race
     94                unpark( s.blocked_thread );
     95            }
     96        }
     97
     98                // Fulfil the future, returns whether or not someone was unblocked
     99                bool fulfil( future(T) & this, T & val ) with(this) {
     100            lock( lock );
     101            if( state != FUTURE_EMPTY )
     102                abort("Attempting to fulfil a future that has already been fulfilled");
     103
     104            copy_T( val, result );
     105
     106            bool ret_val = ! waiters`isEmpty;
     107            state = FUTURE_FULFILLED;
     108                        _internal_flush( this );
     109            unlock( lock );
     110            return ret_val;
     111                }
     112
     113                // Wait for the future to be fulfilled
     114                // Also return whether the thread had to block or not
     115                [T, bool] get( future(T) & this ) with( this ) {
     116            lock( lock );
     117            T ret_val;
     118            if( state == FUTURE_FULFILLED ) {
     119                copy_T( result, ret_val );
     120                unlock( lock );
     121                return [ret_val, false];
     122            }
     123
     124            future_node(T) node = { active_thread(), &ret_val };
     125            insert_last( waiters, ((select_node &)node) );
     126            unlock( lock );
     127            park( );
     128
     129                        return [ret_val, true];
     130                }
     131
     132                // Wait for the future to be fulfilled
     133                T get( future(T) & this ) {
     134                        [T, bool] tt;
     135                        tt = get(this);
     136                        return tt.0;
     137                }
     138
     139        // Gets value if it is available and returns [ val, true ]
     140        // otherwise returns [ default_val, false]
     141        // will not block
     142        [T, bool] try_get( future(T) & this ) with(this) {
     143            lock( lock );
     144            T ret_val;
     145            if( state == FUTURE_FULFILLED ) {
     146                copy_T( result, ret_val );
     147                unlock( lock );
     148                return [ret_val, true];
     149            }
     150            unlock( lock );
     151           
     152            return [ret_val, false];
     153        }
     154
     155        void * register_select( future(T) & this, select_node & s ) with(this) {
     156            lock( lock );
     157
     158            // future not ready -> insert select node and return 0p
     159            if( state == FUTURE_EMPTY ) {
     160                insert_last( waiters, s );
     161                unlock( lock );
     162                return 0p;
     163            }
     164
     165            // future ready and we won race to install it as the select winner return 1p
     166            if ( install_select_winner( s, &this ) ) {
     167                unlock( lock );
     168                return 1p;
     169            }
     170
     171            unlock( lock );
     172            // future ready and we lost race to install it as the select winner
     173            return 2p;
     174        }
     175
     176        void unregister_select( future(T) & this, select_node & s ) with(this) {
     177            lock( lock );
     178            if ( s`isListed ) remove( s );
     179            unlock( lock );
     180        }
     181               
     182        }
     183}
     184
     185//--------------------------------------------------------------------------------------------------------
     186// These futures below do not support select statements so they may not be as useful as 'future'
     187//  however the 'single_future' is cheap and cheerful and is most likely more performant than 'future'
     188//  since it uses raw atomics and no locks afaik
     189//
     190// As far as 'multi_future' goes I can't see many use cases as it will be less performant than 'future'
     191//  since it is monitor based and also is not compatible with select statements
     192//--------------------------------------------------------------------------------------------------------
     193
     194forall( T ) {
     195        struct single_future {
    23196                inline future_t;
    24197                T result;
     
    27200        static inline {
    28201                // Reset future back to original state
    29                 void reset(future(T) & this) { reset( (future_t&)this ); }
     202                void reset(single_future(T) & this) { reset( (future_t&)this ); }
    30203
    31204                // check if the future is available
    32                 bool available( future(T) & this ) { return available( (future_t&)this ); }
     205                bool available( single_future(T) & this ) { return available( (future_t&)this ); }
    33206
    34207                // Mark the future as abandoned, meaning it will be deleted by the server
    35208                // This doesn't work beause of the potential need for a destructor
    36                 void abandon( future(T) & this );
     209                void abandon( single_future(T) & this );
    37210
    38211                // Fulfil the future, returns whether or not someone was unblocked
    39                 thread$ * fulfil( future(T) & this, T result ) {
     212                thread$ * fulfil( single_future(T) & this, T result ) {
    40213                        this.result = result;
    41214                        return fulfil( (future_t&)this );
     
    44217                // Wait for the future to be fulfilled
    45218                // Also return whether the thread had to block or not
    46                 [T, bool] wait( future(T) & this ) {
     219                [T, bool] wait( single_future(T) & this ) {
    47220                        bool r = wait( (future_t&)this );
    48221                        return [this.result, r];
     
    50223
    51224                // Wait for the future to be fulfilled
    52                 T wait( future(T) & this ) {
     225                T wait( single_future(T) & this ) {
    53226                        [T, bool] tt;
    54227                        tt = wait(this);
  • libcfa/src/concurrency/locks.hfa

    r466787a rad861ef  
    3838#include <unistd.h>
    3939
    40 // undef to make a number of the locks not reacquire upon waking from a condlock
    41 #define REACQ 1
     40// C_TODO: cleanup this and locks.cfa
     41// - appropriate separation of interface and impl
     42// - clean up unused/unneeded locks
     43// - change messy big blocking lock from inheritance to composition to remove need for flags
    4244
    4345//-----------------------------------------------------------------------------
     
    249251static inline void on_notify(clh_lock & this, struct thread$ * t ) { unpark(t); }
    250252static inline size_t on_wait(clh_lock & this) { unlock(this); return 0; }
    251 static inline void on_wakeup(clh_lock & this, size_t recursion ) {
    252         #ifdef REACQ
    253         lock(this);
    254         #endif
    255 }
    256 
    257 
    258 //-----------------------------------------------------------------------------
    259 // Linear backoff Spinlock
    260 struct linear_backoff_then_block_lock {
     253static inline void on_wakeup(clh_lock & this, size_t recursion ) { lock(this); }
     254
     255
     256//-----------------------------------------------------------------------------
     257// Exponential backoff then block lock
     258struct exp_backoff_then_block_lock {
    261259        // Spin lock used for mutual exclusion
    262260        __spinlock_t spinlock;
     
    269267};
    270268
    271 static inline void  ?{}( linear_backoff_then_block_lock & this ) {
     269static inline void  ?{}( exp_backoff_then_block_lock & this ) {
    272270        this.spinlock{};
    273271        this.blocked_threads{};
    274272        this.lock_value = 0;
    275273}
    276 static inline void ^?{}( linear_backoff_then_block_lock & this ) {}
    277 // static inline void ?{}( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
    278 // static inline void ?=?( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
    279 
    280 static inline bool internal_try_lock(linear_backoff_then_block_lock & this, size_t & compare_val) with(this) {
     274static inline void ^?{}( exp_backoff_then_block_lock & this ) {}
     275// static inline void ?{}( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;
     276// static inline void ?=?( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;
     277
     278static inline bool internal_try_lock(exp_backoff_then_block_lock & this, size_t & compare_val) with(this) {
    281279        if (__atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {
    282280                return true;
     
    285283}
    286284
    287 static inline bool try_lock(linear_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }
    288 
    289 static inline bool try_lock_contention(linear_backoff_then_block_lock & this) with(this) {
     285static inline bool try_lock(exp_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }
     286
     287static inline bool try_lock_contention(exp_backoff_then_block_lock & this) with(this) {
    290288        if (__atomic_exchange_n(&lock_value, 2, __ATOMIC_ACQUIRE) == 0) {
    291289                return true;
     
    294292}
    295293
    296 static inline bool block(linear_backoff_then_block_lock & this) with(this) {
     294static inline bool block(exp_backoff_then_block_lock & this) with(this) {
    297295        lock( spinlock __cfaabi_dbg_ctx2 ); // TODO change to lockfree queue (MPSC)
    298296        if (lock_value != 2) {
     
    306304}
    307305
    308 static inline void lock(linear_backoff_then_block_lock & this) with(this) {
     306static inline void lock(exp_backoff_then_block_lock & this) with(this) {
    309307        size_t compare_val = 0;
    310308        int spin = 4;
     
    324322}
    325323
    326 static inline void unlock(linear_backoff_then_block_lock & this) with(this) {
     324static inline void unlock(exp_backoff_then_block_lock & this) with(this) {
    327325    if (__atomic_exchange_n(&lock_value, 0, __ATOMIC_RELEASE) == 1) return;
    328326        lock( spinlock __cfaabi_dbg_ctx2 );
     
    332330}
    333331
    334 static inline void on_notify(linear_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); }
    335 static inline size_t on_wait(linear_backoff_then_block_lock & this) { unlock(this); return 0; }
    336 static inline void on_wakeup(linear_backoff_then_block_lock & this, size_t recursion ) {
    337         #ifdef REACQ
    338         lock(this);
    339         #endif
    340 }
     332static inline void on_notify(exp_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); }
     333static inline size_t on_wait(exp_backoff_then_block_lock & this) { unlock(this); return 0; }
     334static inline void on_wakeup(exp_backoff_then_block_lock & this, size_t recursion ) { lock(this); }
    341335
    342336//-----------------------------------------------------------------------------
     
    390384
    391385static inline void on_notify(fast_block_lock & this, struct thread$ * t ) with(this) {
    392         #ifdef REACQ
    393                 lock( lock __cfaabi_dbg_ctx2 );
    394                 insert_last( blocked_threads, *t );
    395                 unlock( lock );
    396         #else
    397                 unpark(t);
    398         #endif
     386    lock( lock __cfaabi_dbg_ctx2 );
     387    insert_last( blocked_threads, *t );
     388    unlock( lock );
    399389}
    400390static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; }
     
    553543}
    554544static inline size_t on_wait(spin_queue_lock & this) { unlock(this); return 0; }
    555 static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) {
    556         #ifdef REACQ
    557         lock(this);
    558         #endif
    559 }
     545static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { lock(this); }
    560546
    561547
     
    598584static inline void on_notify(mcs_block_spin_lock & this, struct thread$ * t ) { unpark(t); }
    599585static inline size_t on_wait(mcs_block_spin_lock & this) { unlock(this); return 0; }
    600 static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {
    601         #ifdef REACQ
    602         lock(this);
    603         #endif
    604 }
     586static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {lock(this); }
    605587
    606588//-----------------------------------------------------------------------------
     
    640622
    641623static inline void on_notify(block_spin_lock & this, struct thread$ * t ) with(this.lock) {
    642   #ifdef REACQ
    643624        // first we acquire internal fast_block_lock
    644625        lock( lock __cfaabi_dbg_ctx2 );
     
    652633        unlock( lock );
    653634
    654   #endif
    655635        unpark(t);
    656        
    657636}
    658637static inline size_t on_wait(block_spin_lock & this) { unlock(this); return 0; }
    659638static inline void on_wakeup(block_spin_lock & this, size_t recursion ) with(this) {
    660   #ifdef REACQ
    661639        // now we acquire the entire block_spin_lock upon waking up
    662640        while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause();
    663641        __atomic_store_n(&held, true, __ATOMIC_RELEASE);
    664642        unlock( lock ); // Now we release the internal fast_spin_lock
    665   #endif
    666643}
    667644
  • src/AST/Expr.cpp

    r466787a rad861ef  
    3030#include "Common/SemanticError.h"
    3131#include "GenPoly/Lvalue.h"        // for referencesPermissable
    32 #include "ResolvExpr/typeops.h"    // for extractResultType
     32#include "ResolvExpr/Unify.h"      // for extractResultType
    3333#include "Tuples/Tuples.h"         // for makeTupleType
    3434
  • src/AST/Node.hpp

    r466787a rad861ef  
    1919#include <cstddef>     // for nullptr_t
    2020#include <iosfwd>
    21 #include <type_traits> // for remove_reference
    2221
    2322#include "Common/ErrorObjects.h"  // for SemanticErrorException
     
    3635        Node(const Node&) : strong_count(0), weak_count(0) {}
    3736        Node(Node&&) : strong_count(0), weak_count(0) {}
    38         Node& operator= (const Node&) = delete;
    39         Node& operator= (Node&&) = delete;
     37        Node& operator=(const Node&) = delete;
     38        Node& operator=(Node&&) = delete;
    4039        virtual ~Node() {}
    4140
  • src/AST/SymbolTable.cpp

    r466787a rad861ef  
    2222#include "Inspect.hpp"
    2323#include "Type.hpp"
    24 #include "CodeGen/OperatorTable.h"  // for isCtorDtorAssign
     24#include "CodeGen/OperatorTable.h"         // for isCtorDtorAssign
    2525#include "Common/SemanticError.h"
    2626#include "Common/Stats/Counter.h"
     
    2828#include "InitTweak/InitTweak.h"
    2929#include "ResolvExpr/Cost.h"
    30 #include "ResolvExpr/typeops.h"
     30#include "ResolvExpr/CandidateFinder.hpp"  // for referenceToRvalueConversion
     31#include "ResolvExpr/Unify.h"
    3132#include "SymTab/Mangler.h"
    3233
  • src/CodeGen/CodeGenerator.cc

    r466787a rad861ef  
    273273        }
    274274
     275        template<typename pass_type>
     276        inline void genEnumInitializer( PassVisitor<pass_type> * visitor, Type * baseType, std::ostream & output,
     277        Initializer * init, long long * cur_val, Options options) {
     278                auto baseTypeAsBasic = baseType ? dynamic_cast<BasicType *>( baseType ) : nullptr;
     279                if ( init ) { // If value has an explicit initiazatior
     280                        output << " = ";
     281                        output << "(" << genType(baseType, "", options) << ")";
     282                        init->accept( *visitor );
     283                        if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // if it is an integral type and initilizer offered,
     284                        // need to update the cur_val
     285                                Expression* expr = ((SingleInit *)(init))->value;
     286                                while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { // unwrap introduced cast
     287                                        expr = temp->arg;
     288                                }
     289                                *cur_val = ((ConstantExpr *)expr)->constant.get_ival()+1;
     290                        }
     291                } else if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // integral implicitly init to cur_val + 1
     292                        output << " = " << "(" << genType(baseType, "", options) << ")";
     293                        output << (*cur_val)++;
     294                }
     295        }
     296
    275297        void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
    276298                extension( enumDecl );
    277299                std::list< Declaration* > &memb = enumDecl->get_members();
    278300                if (enumDecl->base && ! memb.empty()) {
    279                         unsigned long long last_val = -1; // if the first enum value has no explicit initializer,
    280                         // as other
     301                        long long cur_val = 0;
    281302                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    282303                                ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
    283304                                assert( obj );
    284305                                output << "static ";
    285                                 output << genType(enumDecl->base, "", options) << " const ";
    286                                 output << mangleName( obj ) << " ";
    287                                 output << " = ";
    288                                 output << "(" << genType(enumDecl->base, "", options) << ")";
    289                                 if ( (BasicType *)(enumDecl->base) && ((BasicType *)(enumDecl->base))->isWholeNumber() ) {
    290                                         if ( obj->get_init() ) {
    291                                                 obj->get_init()->accept( *visitor );
    292                                                 Expression* expr = ((SingleInit *)(obj->init))->value;
    293                                                 while ( auto temp = dynamic_cast<CastExpr *>(expr) ) {
    294                                                         expr = temp->arg;
    295                                                 }
    296                                                 last_val = ((ConstantExpr *)expr)->constant.get_ival();
    297                                         } else {
    298                                                 output << ++last_val;
    299                                         } // if
    300                                 } else {
    301                                         if ( obj->get_init() ) {
    302                                                 obj->get_init()->accept( *visitor );
    303                                         } else {
    304                                                 // Should not reach here!
    305                                         }
    306                                 }
     306                                output << genType(enumDecl->base, mangleName( obj ), options);
     307                                genEnumInitializer( visitor, enumDecl->base, output, obj->get_init(), &cur_val, options);
    307308                                output << ";" << endl;
    308309                        } // for
  • src/CodeGen/GenType.cc

    r466787a rad861ef  
    255255        void GenType::postvisit( EnumInstType * enumInst ) {
    256256                if ( enumInst->baseEnum && enumInst->baseEnum->base ) {
    257                         typeString = genType(enumInst->baseEnum->base, "", options) + typeString;
     257                        typeString = genType(enumInst->baseEnum->base, typeString, options);
    258258                } else {
    259259                        typeString = enumInst->name + " " + typeString;
  • src/GenPoly/Box.cc

    r466787a rad861ef  
    1414//
    1515
     16#include "Box.h"
     17
    1618#include <algorithm>                     // for mismatch
    1719#include <cassert>                       // for assert, strict_dynamic_cast
     
    2325#include <string>                        // for string, allocator, basic_string
    2426#include <utility>                       // for pair
    25 
    26 #include "Box.h"
    2727
    2828#include "CodeGen/OperatorTable.h"
     
    3737#include "InitTweak/InitTweak.h"         // for getFunctionName, isAssignment
    3838#include "Lvalue.h"                      // for generalizedLvalue
    39 #include "ResolvExpr/typeops.h"          // for typesCompatible
     39#include "ResolvExpr/Unify.h"            // for typesCompatible
    4040#include "ScopedSet.h"                   // for ScopedSet, ScopedSet<>::iter...
    4141#include "ScrubTyVars.h"                 // for ScrubTyVars
     
    911911
    912912                        for ( FunctionType const * const funType : functions ) {
    913                                 FunctionType *originalFunction = funType->clone();
    914                                 FunctionType *realFunction = funType->clone();
    915                                 std::string mangleName = SymTab::Mangler::mangle( realFunction );
     913                                std::string mangleName = SymTab::Mangler::mangle( funType );
    916914
    917915                                // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this
    918916                                // pre-substitution parameter function type.
    919917                                // The second part of the insert result is "is the value new".
    920                                 if ( adaptersDone.insert( mangleName ).second ) {
    921 
    922                                         // apply substitution to type variables to figure out what the adapter's type should look like
    923                                         assert( env );
    924                                         env->apply( realFunction );
    925                                         mangleName = SymTab::Mangler::mangle( realFunction );
    926                                         mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
    927 
    928                                         typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
    929                                         AdapterIter adapter = adapters.find( mangleName );
    930                                         if ( adapter == adapters.end() ) {
    931                                                 // adapter has not been created yet in the current scope, so define it
    932                                                 FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars );
    933                                                 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    934                                                 adapter = answer.first;
    935                                                 stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) );
    936                                         } // if
    937                                         assert( adapter != adapters.end() );
    938 
    939                                         // add the appropriate adapter as a parameter
    940                                         appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
     918                                if ( !adaptersDone.insert( mangleName ).second ) continue;
     919
     920                                // Apply substitution to type variables to figure out what the adapter's type should look like.
     921                                assert( env );
     922                                FunctionType *realType = funType->clone();
     923                                env->apply( realType );
     924                                mangleName = SymTab::Mangler::mangle( realType );
     925                                mangleName += makePolyMonoSuffix( funType, exprTyVars );
     926
     927                                typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
     928                                AdapterIter adapter = adapters.find( mangleName );
     929                                if ( adapter == adapters.end() ) {
     930                                        // Adapter has not been created yet in the current scope, so define it.
     931                                        FunctionDecl *newAdapter = makeAdapter( funType, realType, mangleName, exprTyVars );
     932                                        std::pair< AdapterIter, bool > answer = adapters.insert( mangleName, newAdapter );
     933                                        adapter = answer.first;
     934                                        stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) );
    941935                                } // if
     936                                assert( adapter != adapters.end() );
     937
     938                                // Add the appropriate adapter as a parameter.
     939                                appExpr->args.push_front( new VariableExpr( adapter->second ) );
    942940                        } // for
    943941                } // passAdapters
  • src/GenPoly/GenPoly.cc

    r466787a rad861ef  
    2424#include <vector>                       // for vector
    2525
     26#include "AST/Expr.hpp"
    2627#include "AST/Type.hpp"
     28#include "AST/TypeSubstitution.hpp"
    2729#include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::const_it...
    2830#include "ResolvExpr/typeops.h"         // for flatten
     
    490492                }
    491493
     494                /// Flattens a list of types.
     495                // There is another flattenList in Unify.
    492496                void flattenList( vector<ast::ptr<ast::Type>> const & src,
    493497                                vector<ast::ptr<ast::Type>> & out ) {
  • src/GenPoly/InstantiateGeneric.cc

    r466787a rad861ef  
    2828#include "GenPoly.h"                   // for isPolyType, typesPolyCompatible
    2929#include "InitTweak/InitTweak.h"
    30 #include "ResolvExpr/typeops.h"
     30#include "ResolvExpr/AdjustExprType.hpp"  // for adjustExprType
     31#include "ResolvExpr/Unify.h"          // for typesCompatible
    3132#include "ScopedSet.h"                 // for ScopedSet, ScopedSet<>::iterator
    3233#include "ScrubTyVars.h"               // for ScrubTyVars
  • src/GenPoly/InstantiateGenericNew.cpp

    r466787a rad861ef  
    3232#include "GenPoly/GenPoly.h"           // for isPolyType, typesPolyCompatible
    3333#include "GenPoly/ScrubTyVars.h"       // for scrubAll
    34 #include "ResolvExpr/typeops.h"        // for typesCompatible
     34#include "ResolvExpr/AdjustExprType.hpp"  // for adjustExprType
     35#include "ResolvExpr/Unify.h"          // for typesCompatible
    3536
    3637namespace GenPoly {
  • src/InitTweak/FixInit.cc

    r466787a rad861ef  
    3939#include "InitTweak.h"                 // for getFunctionName, getCallArg
    4040#include "ResolvExpr/Resolver.h"       // for findVoidExpression
    41 #include "ResolvExpr/typeops.h"        // for typesCompatible
     41#include "ResolvExpr/Unify.h"          // for typesCompatible
    4242#include "SymTab/Autogen.h"            // for genImplicitCall
    4343#include "SymTab/Indexer.h"            // for Indexer
  • src/InitTweak/FixInitNew.cpp

    r466787a rad861ef  
    2626#include "GenPoly/GenPoly.h"           // for getFunctionType
    2727#include "ResolvExpr/Resolver.h"       // for findVoidExpression
    28 #include "ResolvExpr/typeops.h"        // for typesCompatible
     28#include "ResolvExpr/Unify.h"          // for typesCompatible
    2929#include "SymTab/Autogen.h"            // for genImplicitCall
    3030#include "SymTab/Indexer.h"            // for Indexer
  • src/InitTweak/InitTweak.cc

    r466787a rad861ef  
    3535#include "GenPoly/GenPoly.h"       // for getFunctionType
    3636#include "InitTweak.h"
    37 #include "ResolvExpr/typeops.h"    // for typesCompatibleIgnoreQualifiers
     37#include "ResolvExpr/Unify.h"      // for typesCompatibleIgnoreQualifiers
    3838#include "SymTab/Autogen.h"
    3939#include "SymTab/Indexer.h"        // for Indexer
  • src/Parser/TypeData.cc

    r466787a rad861ef  
    933933                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
    934934                } else if ( !cur->initializer ) {
    935                         if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) {
     935                        if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) {
    936936                                SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
    937937                        }
  • src/ResolvExpr/AlternativeFinder.cc

    r466787a rad861ef  
    1414//
    1515
     16#include "AlternativeFinder.h"
     17
    1618#include <algorithm>               // for copy
    1719#include <cassert>                 // for strict_dynamic_cast, assert, assertf
     
    2628
    2729#include "CompilationState.h"      // for resolvep
     30#include "AdjustExprType.hpp"      // for adjustExprType
    2831#include "Alternative.h"           // for AltList, Alternative
    29 #include "AlternativeFinder.h"
    3032#include "AST/Expr.hpp"
    3133#include "AST/SymbolTable.hpp"
    3234#include "AST/Type.hpp"
     35#include "CastCost.hpp"            // for castCost
    3336#include "Common/SemanticError.h"  // for SemanticError
    3437#include "Common/utility.h"        // for deleteAll, printAll, CodeLocation
     38#include "ConversionCost.h"        // for conversionCost
    3539#include "Cost.h"                  // for Cost, Cost::zero, operator<<, Cost...
    3640#include "ExplodedActual.h"        // for ExplodedActual
    3741#include "InitTweak/InitTweak.h"   // for getFunctionName
     42#include "PolyCost.hpp"            // for polyCost
    3843#include "RenameVars.h"            // for RenameVars, global_renamer
    3944#include "ResolveAssertions.h"     // for resolveAssertions
    4045#include "ResolveTypeof.h"         // for resolveTypeof
    4146#include "Resolver.h"              // for resolveStmtExpr
     47#include "SpecCost.hpp"            // for specCost
    4248#include "SymTab/Indexer.h"        // for Indexer
    4349#include "SymTab/Mangler.h"        // for Mangler
     
    5157#include "Tuples/Explode.h"        // for explode
    5258#include "Tuples/Tuples.h"         // for isTtype, handleTupleAssignment
     59#include "typeops.h"               // for combos
    5360#include "Unify.h"                 // for unify
    54 #include "typeops.h"               // for adjustExprType, polyCost, castCost
    5561
    5662#define PRINT( text ) if ( resolvep ) { text }
  • src/ResolvExpr/AlternativeFinder.h

    r466787a rad861ef  
    3434namespace ResolvExpr {
    3535        struct ArgPack;
     36
     37        Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
     38                const SymTab::Indexer & indexer, const TypeEnvironment & env );
     39
     40        void referenceToRvalueConversion( Expression *& expr, Cost & cost );
    3641
    3742        /// First index is which argument, second index is which alternative for that argument,
  • src/ResolvExpr/CandidateFinder.cpp

    r466787a rad861ef  
    2323#include <vector>
    2424
     25#include "AdjustExprType.hpp"
    2526#include "Candidate.hpp"
     27#include "CastCost.hpp"           // for castCost
    2628#include "CompilationState.h"
     29#include "ConversionCost.h"       // for conversionCast
    2730#include "Cost.h"
    2831#include "ExplodedArg.hpp"
     32#include "PolyCost.hpp"
    2933#include "RenameVars.h"           // for renameTyVars
    3034#include "Resolver.h"
    3135#include "ResolveTypeof.h"
    3236#include "SatisfyAssertions.hpp"
    33 #include "typeops.h"              // for adjustExprType, conversionCost, polyCost, specCost
     37#include "SpecCost.hpp"
     38#include "typeops.h"              // for combos
    3439#include "Unify.h"
    3540#include "AST/Expr.hpp"
  • src/ResolvExpr/CandidateFinder.hpp

    r466787a rad861ef  
    6363        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
    6464
     65/// Create an expression that preforms reference to rvalue conversion on
     66/// the given expression and update the cost of the expression.
     67const ast::Expr * referenceToRvalueConversion(
     68        const ast::Expr * expr, Cost & cost );
     69
    6570} // namespace ResolvExpr
    6671
  • src/ResolvExpr/CastCost.cc

    r466787a rad861ef  
    1313// Update Count     : 9
    1414//
     15
     16#include "CastCost.hpp"
    1517
    1618#include <cassert>                       // for assert
     
    2224#include "ConversionCost.h"              // for ConversionCost
    2325#include "Cost.h"                        // for Cost, Cost::infinity
     26#include "ResolvExpr/ConversionCost.h"   // for conversionCost
     27#include "ResolvExpr/PtrsCastable.hpp"   // for ptrsCastable
    2428#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment, EqvClass
     29#include "ResolvExpr/typeops.h"          // for ptrsCastable
     30#include "ResolvExpr/Unify.h"            // for typesCompatibleIgnoreQualifiers
    2531#include "SymTab/Indexer.h"              // for Indexer
    2632#include "SynTree/Declaration.h"         // for TypeDecl, NamedTypeDecl
    2733#include "SynTree/Type.h"                // for PointerType, Type, TypeInstType
    28 #include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
    2934
    3035#if 0
  • src/ResolvExpr/CommonType.cc

    r466787a rad861ef  
    1313// Update Count     : 24
    1414//
     15
     16#include "CommonType.hpp"
    1517
    1618#include <cassert>                       // for strict_dynamic_cast
  • src/ResolvExpr/ConversionCost.cc

    r466787a rad861ef  
    2222#include "ResolvExpr/Cost.h"             // for Cost
    2323#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
    24 #include "ResolvExpr/Unify.h"
     24#include "ResolvExpr/Unify.h"            // for typesCompatibleIgnoreQualifiers
     25#include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
    2526#include "SymTab/Indexer.h"              // for Indexer
    2627#include "SynTree/Declaration.h"         // for TypeDecl, NamedTypeDecl
    2728#include "SynTree/Type.h"                // for Type, BasicType, TypeInstType
    28 #include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
    2929
    3030
  • src/ResolvExpr/ConversionCost.h

    r466787a rad861ef  
    3232namespace ResolvExpr {
    3333        class TypeEnvironment;
     34
     35        Cost conversionCost(
     36                const Type * src, const Type * dest, bool srcIsLvalue,
     37                const SymTab::Indexer & indexer, const TypeEnvironment & env );
    3438
    3539        typedef std::function<Cost(const Type *, const Type *, bool,
     
    8084        const ast::SymbolTable &, const ast::TypeEnvironment &)>;
    8185
     86Cost conversionCost(
     87        const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
     88        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
     89
     90Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,
     91        bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env,
     92        PtrsCalculation func );
     93
    8294#warning when the old ConversionCost is removed, get ride of the _new suffix.
    8395class ConversionCost_new : public ast::WithShortCircuiting {
     
    119131};
    120132
    121 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,
    122         bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env,
    123         PtrsCalculation func );
    124 
    125133} // namespace ResolvExpr
    126134
  • src/ResolvExpr/PtrsAssignable.cc

    r466787a rad861ef  
    1414//
    1515
    16 #include "typeops.h"
     16#include "PtrsAssignable.hpp"
    1717
    1818#include "AST/Pass.hpp"
  • src/ResolvExpr/PtrsCastable.cc

    r466787a rad861ef  
    1414//
    1515
     16#include "PtrsCastable.hpp"
     17
    1618#include "AST/Decl.hpp"
    1719#include "AST/Pass.hpp"
     
    1921#include "AST/TypeEnvironment.hpp"
    2022#include "Common/PassVisitor.h"
     23#include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
    2124#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
    2225#include "SymTab/Indexer.h"              // for Indexer
     
    2427#include "SynTree/Type.h"                // for TypeInstType, Type, BasicType
    2528#include "SynTree/Visitor.h"             // for Visitor
    26 #include "typeops.h"                     // for ptrsAssignable
    2729
    2830namespace ResolvExpr {
     
    291293                return objectCast( src, env, symtab );
    292294        } else {
    293                 ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab };
    294                 src->accept( ptrs );
    295                 return ptrs.core.result;
     295                return ast::Pass<PtrsCastable_new>::read( src, dst, env, symtab );
    296296        }
    297297}
  • src/ResolvExpr/RenameVars.cc

    r466787a rad861ef  
    8383
    8484                const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
    85                         // rename
    8685                        auto it = idMap.find( type->name );
    87                         if ( it != idMap.end() ) {
    88                                 // unconditionally mutate because map will *always* have different name
    89                                 ast::TypeInstType * mut = ast::shallowCopy( type );
    90                                 // reconcile base node since some copies might have been made
    91                                 mut->base = it->second.base;
    92                                 mut->formal_usage = it->second.formal_usage;
    93                                 mut->expr_id = it->second.expr_id;
    94                     type = mut;
    95                         }
    96 
    97                         return type;
     86                        if ( it == idMap.end() ) return type;
     87
     88                        // Unconditionally mutate because map will *always* have different name.
     89                        ast::TypeInstType * mut = ast::shallowCopy( type );
     90                        // Reconcile base node since some copies might have been made.
     91                        mut->base = it->second.base;
     92                        mut->formal_usage = it->second.formal_usage;
     93                        mut->expr_id = it->second.expr_id;
     94                        return mut;
    9895                }
    9996
     
    187184
    188185const ast::Type * renameTyVars( const ast::Type * t, RenameMode mode, bool reset ) {
    189         // ast::Type *tc = ast::deepCopy(t);
    190186        ast::Pass<RenameVars_new> renamer;
    191187        renamer.core.mode = mode;
  • src/ResolvExpr/ResolveAssertions.cc

    r466787a rad861ef  
    2626#include <vector>                   // for vector
    2727
     28#include "AdjustExprType.hpp"       // for adjustExprType
    2829#include "Alternative.h"            // for Alternative, AssertionItem, AssertionList
    2930#include "Common/FilterCombos.h"    // for filterCombos
     
    3132#include "Common/utility.h"         // for sort_mins
    3233#include "GenPoly/GenPoly.h"        // for getFunctionType
     34#include "ResolvExpr/AlternativeFinder.h"  // for computeConversionCost
    3335#include "ResolvExpr/RenameVars.h"  // for renameTyVars
     36#include "SpecCost.hpp"             // for specCost
    3437#include "SymTab/Indexer.h"         // for Indexer
    3538#include "SymTab/Mangler.h"         // for Mangler
    3639#include "SynTree/Expression.h"     // for InferredParams
    3740#include "TypeEnvironment.h"        // for TypeEnvironment, etc.
    38 #include "typeops.h"                // for adjustExprType, specCost
    3941#include "Unify.h"                  // for unify
    4042
  • src/ResolvExpr/SatisfyAssertions.cpp

    r466787a rad861ef  
    2323#include <vector>
    2424
     25#include "AdjustExprType.hpp"
    2526#include "Candidate.hpp"
    2627#include "CandidateFinder.hpp"
     28#include "CommonType.hpp"
    2729#include "Cost.h"
    2830#include "RenameVars.h"
     31#include "SpecCost.hpp"
    2932#include "typeops.h"
    3033#include "Unify.h"
  • src/ResolvExpr/Unify.cc

    r466787a rad861ef  
    3333#include "AST/TypeEnvironment.hpp"
    3434#include "Common/PassVisitor.h"     // for PassVisitor
     35#include "CommonType.hpp"           // for commonType
    3536#include "FindOpenVars.h"           // for findOpenVars
     37#include "SpecCost.hpp"             // for SpecCost
    3638#include "SynTree/LinkageSpec.h"    // for C
    3739#include "SynTree/Constant.h"       // for Constant
     
    4345#include "Tuples/Tuples.h"          // for isTtype
    4446#include "TypeEnvironment.h"        // for EqvClass, AssertionSet, OpenVarSet
    45 #include "typeops.h"                // for flatten, occurs, commonType
     47#include "typeops.h"                // for flatten, occurs
    4648
    4749namespace ast {
     
    5052
    5153namespace SymTab {
    52 class Indexer;
     54        class Indexer;
    5355}  // namespace SymTab
    5456
     
    5658
    5759namespace ResolvExpr {
     60
     61// Template Helpers:
     62template< typename Iterator1, typename Iterator2 >
     63bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
     64        for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     65                Type *commonType = 0;
     66                if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
     67                        return false;
     68                } // if
     69                commonTypes.push_back( commonType );
     70        } // for
     71        return ( list1Begin == list1End && list2Begin == list2End );
     72}
     73
     74template< typename Iterator1, typename Iterator2 >
     75bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     76        std::list< Type* > commonTypes;
     77        if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions,  openVars, indexer, commonTypes ) ) {
     78                deleteAll( commonTypes );
     79                return true;
     80        } else {
     81                return false;
     82        } // if
     83}
    5884
    5985        struct Unify_old : public WithShortCircuiting {
  • src/ResolvExpr/Unify.h

    r466787a rad861ef  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 13:09:04 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Mon Jun 18 11:58:00 2018
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Jan 17 11:12:00 2023
     13// Update Count     : 5
    1414//
    1515
     
    3737
    3838namespace ResolvExpr {
    39         bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
    40         bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
    41         bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
    42         bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common );
    4339
    44         template< typename Iterator1, typename Iterator2 >
    45         bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
    46                 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    47                         Type *commonType = 0;
    48                         if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    49                                 return false;
    50                         } // if
    51                         commonTypes.push_back( commonType );
    52                 } // for
    53                 if ( list1Begin != list1End || list2Begin != list2End ) {
    54                         return false;
    55                 } else {
    56                         return true;
    57                 } // if
    58         }
     40bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
     41bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
     42bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
     43bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common );
    5944
    60         template< typename Iterator1, typename Iterator2 >
    61         bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    62                 std::list< Type* > commonTypes;
    63                 if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
    64                         deleteAll( commonTypes );
    65                         return true;
    66                 } else {
    67                         return false;
    68                 } // if
    69         }
     45bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     46bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
    7047
    71         bool unify(
    72                 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    73                 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    74                 ast::OpenVarSet & open, const ast::SymbolTable & symtab );
     48inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
     49        TypeEnvironment env;
     50        return typesCompatible( t1, t2, indexer, env );
     51}
    7552
    76         bool unify(
    77                 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    78                 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    79                 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
     53inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
     54        TypeEnvironment env;
     55        return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
     56}
    8057
    81         bool unifyExact(
    82                 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    83                 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    84                 WidenMode widen, const ast::SymbolTable & symtab );
     58bool unify(
     59        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     60        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     61        ast::OpenVarSet & open, const ast::SymbolTable & symtab );
    8562
    86         bool unifyInexact(
    87                 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    88                 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    89                 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
    90                 ast::ptr<ast::Type> & common );
     63bool unify(
     64        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     65        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     66        ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
     67
     68bool unifyExact(
     69        const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
     70        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     71        WidenMode widen, const ast::SymbolTable & symtab );
     72
     73bool unifyInexact(
     74        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     75        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     76        const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
     77        ast::ptr<ast::Type> & common );
     78
     79bool typesCompatible(
     80        const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
     81        const ast::TypeEnvironment & env = {} );
     82
     83bool typesCompatibleIgnoreQualifiers(
     84        const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
     85        const ast::TypeEnvironment & env = {} );
     86
     87/// Creates the type represented by the list of returnVals in a FunctionType.
     88/// The caller owns the return value.
     89Type * extractResultType( FunctionType * functionType );
     90/// Creates or extracts the type represented by returns in a `FunctionType`.
     91ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );
     92
     93std::vector<ast::ptr<ast::Type>> flattenList(
     94        const std::vector<ast::ptr<ast::Type>> & src, ast::TypeEnvironment & env
     95);
    9196
    9297} // namespace ResolvExpr
  • src/ResolvExpr/WidenMode.h

    r466787a rad861ef  
    1919        struct WidenMode {
    2020                WidenMode( bool first, bool second ): first( first ), second( second ) {}
    21                
     21
    2222                WidenMode &operator|=( const WidenMode &other ) {
    2323                        first |= other.first; second |= other.second; return *this;
     
    3535                        WidenMode newWM( *this ); newWM &= other; return newWM;
    3636                }
    37                
     37
    3838                operator bool() { return first && second; }
    3939
  • src/ResolvExpr/module.mk

    r466787a rad861ef  
    1717SRC_RESOLVEXPR = \
    1818      ResolvExpr/AdjustExprType.cc \
     19      ResolvExpr/AdjustExprType.hpp \
    1920      ResolvExpr/Alternative.cc \
    2021      ResolvExpr/AlternativeFinder.cc \
     
    2627      ResolvExpr/Candidate.hpp \
    2728      ResolvExpr/CastCost.cc \
     29      ResolvExpr/CastCost.hpp \
    2830      ResolvExpr/CommonType.cc \
     31      ResolvExpr/CommonType.hpp \
    2932      ResolvExpr/ConversionCost.cc \
    3033      ResolvExpr/ConversionCost.h \
     
    4043      ResolvExpr/Occurs.cc \
    4144      ResolvExpr/PolyCost.cc \
     45      ResolvExpr/PolyCost.hpp \
    4246      ResolvExpr/PtrsAssignable.cc \
     47      ResolvExpr/PtrsAssignable.hpp \
    4348      ResolvExpr/PtrsCastable.cc \
     49      ResolvExpr/PtrsCastable.hpp \
    4450      ResolvExpr/RenameVars.cc \
    4551      ResolvExpr/RenameVars.h \
     
    5460      ResolvExpr/SatisfyAssertions.hpp \
    5561      ResolvExpr/SpecCost.cc \
     62      ResolvExpr/SpecCost.hpp \
    5663      ResolvExpr/TypeEnvironment.cc \
    5764      ResolvExpr/TypeEnvironment.h \
  • src/ResolvExpr/typeops.h

    r466787a rad861ef  
    1010// Created On       : Sun May 17 07:28:22 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Oct  1 09:45:00 2019
    13 // Update Count     : 6
     12// Last Modified On : Wed Jan 18 11:54:00 2023
     13// Update Count     : 7
    1414//
    1515
     
    1818#include <vector>
    1919
    20 #include "Cost.h"
    21 #include "TypeEnvironment.h"
    22 #include "WidenMode.h"
    23 #include "AST/Fwd.hpp"
    24 #include "AST/Node.hpp"
    25 #include "AST/SymbolTable.hpp"
    2620#include "AST/Type.hpp"
    27 #include "AST/TypeEnvironment.hpp"
    28 #include "SynTree/SynTree.h"
    2921#include "SynTree/Type.h"
    3022
     
    3426
    3527namespace ResolvExpr {
     28        class TypeEnvironment;
     29
    3630        // combos: takes a list of sets and returns a set of lists representing every possible way of forming a list by
    3731        // picking one element out of each set
     
    6155        }
    6256
    63         // in AdjustExprType.cc
    64         /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
    65         void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
    66 
    67         /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer
    68         void adjustExprType( Type *& type );
    69 
    70         template< typename ForwardIterator >
    71         void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) {
    72                 while ( begin != end ) {
    73                         adjustExprType( *begin++, env, indexer );
    74                 } // while
    75         }
    76 
    77         /// Replaces array types with equivalent pointer, and function types with a pointer-to-function
    78         const ast::Type * adjustExprType(
    79                 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );
    80 
    81         // in CastCost.cc
    82         Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
    83                 const SymTab::Indexer & indexer, const TypeEnvironment & env );
    84         Cost castCost(
    85                 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
    86                 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
    87 
    88         // in ConversionCost.cc
    89         Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
    90                 const SymTab::Indexer & indexer, const TypeEnvironment & env );
    91         Cost conversionCost(
    92                 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
    93                 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
    94 
    95         // in AlternativeFinder.cc
    96         Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
    97                 const SymTab::Indexer & indexer, const TypeEnvironment & env );
    98 
    99         // in PtrsAssignable.cc
    100         int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env );
    101         int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
    102                 const ast::TypeEnvironment & env );
    103 
    104         // in PtrsCastable.cc
    105         int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer );
    106         int ptrsCastable(
    107                 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    108                 const ast::TypeEnvironment & env );
    109 
    110         // in Unify.cc
    111         bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
    112         bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
    113 
    114         inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
    115                 TypeEnvironment env;
    116                 return typesCompatible( t1, t2, indexer, env );
    117         }
    118 
    119         inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
    120                 TypeEnvironment env;
    121                 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
    122         }
    123 
    124         bool typesCompatible(
    125                 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
    126                 const ast::TypeEnvironment & env = {} );
    127 
    128         bool typesCompatibleIgnoreQualifiers(
    129                 const ast::Type *, const ast::Type *, const ast::SymbolTable &,
    130                 const ast::TypeEnvironment & env = {} );
    131 
    132         /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.
    133         Type * extractResultType( FunctionType * functionType );
    134         /// Creates or extracts the type represented by the list of returns in a `FunctionType`.
    135         ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );
    136 
    137         // in CommonType.cc
    138         Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars );
    139         ast::ptr< ast::Type > commonType(
    140                 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
    141                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    142                         const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab
    143         );
    144         // in Unify.cc
    145         std::vector< ast::ptr< ast::Type > > flattenList(
    146                 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env
    147         );
    148 
    149         // in PolyCost.cc
    150         int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
    151         int polyCost(
    152                 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
    153 
    154         // in SpecCost.cc
    155         int specCost( Type * type );
    156         int specCost( const ast::Type * type );
    157 
    15857        // in Occurs.cc
    15958        bool occurs( const Type * type, const std::string & varName, const TypeEnvironment & env );
     
    16867                return false;
    16968        }
    170 
    171         // in AlternativeFinder.cc
    172         void referenceToRvalueConversion( Expression *& expr, Cost & cost );
    173         // in CandidateFinder.cpp
    174         const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost );
    17569
    17670        /// flatten tuple type into list of types
     
    218112                }
    219113
    220 
    221114                return new ast::TupleType{ std::move(types) };
    222115        }
     
    227120                return tupleFromTypes( tys.begin(), tys.end() );
    228121        }
    229 
    230        
    231122
    232123        // in TypeEnvironment.cc
  • src/SymTab/Indexer.cc

    r466787a rad861ef  
    3131#include "InitTweak/InitTweak.h"   // for isConstructor, isCopyFunction, isC...
    3232#include "Mangler.h"               // for Mangler
    33 #include "ResolvExpr/typeops.h"    // for typesCompatible
     33#include "ResolvExpr/AlternativeFinder.h"  // for referenceToRvalueConversion
     34#include "ResolvExpr/Unify.h"      // for typesCompatible
    3435#include "SynTree/LinkageSpec.h"   // for isMangled, isOverridable, Spec
    3536#include "SynTree/Constant.h"      // for Constant
  • src/SymTab/Mangler.cc

    r466787a rad861ef  
    439439                  private:
    440440                        void mangleDecl( const ast::DeclWithType *declaration );
    441                         void mangleRef( const ast::BaseInstType *refType, std::string prefix );
     441                        void mangleRef( const ast::BaseInstType *refType, const std::string & prefix );
    442442
    443443                        void printQualifiers( const ast::Type *type );
     
    535535                }
    536536
    537                 __attribute__((unused))
    538                 inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {
    539                         std::vector< ast::ptr< ast::Type > > ret;
    540                         std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
    541                                                         std::mem_fun( &ast::DeclWithType::get_type ) );
    542                         return ret;
    543                 }
    544 
    545537                void Mangler_new::postvisit( const ast::FunctionType * functionType ) {
    546538                        printQualifiers( functionType );
     
    558550                }
    559551
    560                 void Mangler_new::mangleRef( const ast::BaseInstType * refType, std::string prefix ) {
     552                void Mangler_new::mangleRef(
     553                                const ast::BaseInstType * refType, const std::string & prefix ) {
    561554                        printQualifiers( refType );
    562555
    563556                        mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
    564557
    565                         if ( mangleGenericParams ) {
    566                                 if ( ! refType->params.empty() ) {
    567                                         mangleName += "_";
    568                                         for ( const ast::Expr * param : refType->params ) {
    569                                                 auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
    570                                                 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
    571                                                 maybeAccept( paramType->type.get(), *visitor );
    572                                         }
    573                                         mangleName += "_";
     558                        if ( mangleGenericParams && ! refType->params.empty() ) {
     559                                mangleName += "_";
     560                                for ( const ast::Expr * param : refType->params ) {
     561                                        auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
     562                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
     563                                        maybeAccept( paramType->type.get(), *visitor );
    574564                                }
     565                                mangleName += "_";
    575566                        }
    576567                }
     
    656647                }
    657648
     649                // For debugging:
    658650                __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
    659651                        for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
     
    665657                        // skip if not including qualifiers
    666658                        if ( typeMode ) return;
    667                         if ( auto ptype = dynamic_cast< const ast::FunctionType * >(type) ) {
    668                                 if ( ! ptype->forall.empty() ) {
    669                                         std::list< std::string > assertionNames;
    670                                         int dcount = 0, fcount = 0, vcount = 0, acount = 0;
    671                                         mangleName += Encoding::forall;
    672                                         for ( auto & decl : ptype->forall ) {
    673                                                 switch ( decl->kind ) {
    674                                                   case ast::TypeDecl::Kind::Dtype:
    675                                                         dcount++;
    676                                                         break;
    677                                                   case ast::TypeDecl::Kind::Ftype:
    678                                                         fcount++;
    679                                                         break;
    680                                                   case ast::TypeDecl::Kind::Ttype:
    681                                                         vcount++;
    682                                                         break;
    683                                                   default:
    684                                                         assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() );
    685                                                 } // switch
    686                                                 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
    687                                         } // for
    688                                         for ( auto & assert : ptype->assertions ) {
    689                                                 assertionNames.push_back( ast::Pass<Mangler_new>::read(
    690                                                         assert->var.get(),
    691                                                         mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) );
    692                                                 acount++;
    693                                         } // for
    694                                         mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
    695                                         for(const auto & a : assertionNames) mangleName += a;
    696 //                                      std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
    697                                         mangleName += "_";
    698                                 } // if
     659                        auto funcType = dynamic_cast<const ast::FunctionType *>( type );
     660                        if ( funcType && !funcType->forall.empty() ) {
     661                                std::list< std::string > assertionNames;
     662                                int dcount = 0, fcount = 0, vcount = 0, acount = 0;
     663                                mangleName += Encoding::forall;
     664                                for ( auto & decl : funcType->forall ) {
     665                                        switch ( decl->kind ) {
     666                                        case ast::TypeDecl::Dtype:
     667                                                dcount++;
     668                                                break;
     669                                        case ast::TypeDecl::Ftype:
     670                                                fcount++;
     671                                                break;
     672                                        case ast::TypeDecl::Ttype:
     673                                                vcount++;
     674                                                break;
     675                                        default:
     676                                                assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() );
     677                                        } // switch
     678                                        varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
     679                                } // for
     680                                for ( auto & assert : funcType->assertions ) {
     681                                        assertionNames.push_back( ast::Pass<Mangler_new>::read(
     682                                                assert->var.get(),
     683                                                mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) );
     684                                        acount++;
     685                                } // for
     686                                mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
     687                                for ( const auto & a : assertionNames ) mangleName += a;
     688                                mangleName += "_";
    699689                        } // if
    700690                        if ( ! inFunctionType ) {
  • src/SymTab/Validate.cc

    r466787a rad861ef  
    6363#include "InitTweak/GenInit.h"         // for fixReturnStatements
    6464#include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
    65 #include "ResolvExpr/typeops.h"        // for typesCompatible
     65#include "ResolvExpr/typeops.h"        // for extractResultType
     66#include "ResolvExpr/Unify.h"          // for typesCompatible
    6667#include "ResolvExpr/Resolver.h"       // for findSingleExpression
    6768#include "ResolvExpr/ResolveTypeof.h"  // for resolveTypeof
  • src/SynTree/ApplicationExpr.cc

    r466787a rad861ef  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ApplicationExpr.cc.cc --
     7// ApplicationExpr.cc --
    88//
    99// Author           : Richard C. Bilson
     
    2626#include "Expression.h"          // for ParamEntry, ApplicationExpr, Expression
    2727#include "InitTweak/InitTweak.h" // for getFunction
    28 #include "ResolvExpr/typeops.h"  // for extractResultType
     28#include "ResolvExpr/Unify.h"    // for extractResultType
    2929#include "Type.h"                // for Type, PointerType, FunctionType
    3030
  • src/SynTree/BasicType.cc

    r466787a rad861ef  
    2929}
    3030
    31 bool BasicType::isWholeNumber() const {
    32         return kind == Bool ||
    33                 kind ==Char ||
    34                 kind == SignedChar ||
    35                 kind == UnsignedChar ||
    36                 kind == ShortSignedInt ||
    37                 kind == ShortUnsignedInt ||
    38                 kind == SignedInt ||
    39                 kind == UnsignedInt ||
    40                 kind == LongSignedInt ||
    41                 kind == LongUnsignedInt ||
    42                 kind == LongLongSignedInt ||
    43                 kind ==LongLongUnsignedInt ||
    44                 kind == SignedInt128 ||
    45                 kind == UnsignedInt128;
    46 }
    47 
    4831bool BasicType::isInteger() const {
    4932        return kind <= UnsignedInt128;
  • src/SynTree/Type.h

    r466787a rad861ef  
    271271        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    272272        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    273         bool isWholeNumber() const;
    274273        bool isInteger() const;
    275274};
  • src/Validate/FixReturnTypes.cpp

    r466787a rad861ef  
    2020#include "AST/Type.hpp"
    2121#include "CodeGen/CodeGenerator.h"
    22 #include "ResolvExpr/typeops.h"
     22#include "ResolvExpr/Unify.h"
    2323
    2424namespace ast {
  • src/Validate/ReplaceTypedef.cpp

    r466787a rad861ef  
    2020#include "Common/UniqueName.h"
    2121#include "Common/utility.h"
    22 #include "ResolvExpr/typeops.h"
     22#include "ResolvExpr/Unify.h"
    2323
    2424namespace Validate {
  • tests/Makefile.am

    r466787a rad861ef  
    8888        io/.in/many_read.data \
    8989        meta/fork+exec.hfa \
    90         unified_locking/mutex_test.hfa
     90        concurrent/unified_locking/mutex_test.hfa \
     91    concurrent/channels/parallel_harness.hfa
    9192
    9293dist-hook:
  • tests/concurrent/futures/typed.cfa

    r466787a rad861ef  
    55thread Server {
    66        int cnt;
    7         future(int) * requests[NFUTURES];
     7        single_future(int) * requests[NFUTURES];
    88};
    99
     
    2424void process( Server & this, int i ) {
    2525        if( this.requests[i] == 0p ) return;
    26         future(int) * f = this.requests[i];
     26        single_future(int) * f = this.requests[i];
    2727        this.requests[i] = 0p;
    2828        this.cnt--;
     
    3030}
    3131
    32 void call( Server & mutex this, future(int) & f ) {
     32void call( Server & mutex this, single_future(int) & f ) {
    3333        for(i; NFUTURES) {
    3434                if( this.requests[i] == 0p ) {
     
    7070
    7171void work(void) {
    72         future(int) mine;
     72        single_future(int) mine;
    7373        call( *the_server, mine );
    7474        wait( mine );
  • tests/concurrent/mutexstmt/locks.cfa

    r466787a rad861ef  
    7272
    7373single_acquisition_lock l1;
    74 linear_backoff_then_block_lock l2;
     74exp_backoff_then_block_lock l2;
    7575owner_lock l3;
    7676
  • tests/concurrent/unified_locking/locks.cfa

    r466787a rad861ef  
    1515condition_variable( owner_lock ) c_o;
    1616
    17 linear_backoff_then_block_lock l;
    18 condition_variable( linear_backoff_then_block_lock ) c_l;
     17exp_backoff_then_block_lock l;
     18condition_variable( exp_backoff_then_block_lock ) c_l;
    1919
    2020fast_block_lock f;
  • tests/concurrent/unified_locking/thread_test.cfa

    r466787a rad861ef  
    2525
    2626thread worker {
    27     linear_backoff_then_block_lock * locks;
     27    exp_backoff_then_block_lock * locks;
    2828    bool improved;
    2929};
    3030
    31 void ?{}( worker & w, linear_backoff_then_block_lock * locks, bool improved ) {
     31void ?{}( worker & w, exp_backoff_then_block_lock * locks, bool improved ) {
    3232        w.locks = locks;
    3333    w.improved = improved;
     
    3939    for (int i = 0; i < workBufferSize; i += 1) buffer[i] = rand() % 1024;
    4040    unsigned int lck = rand() % lockCount;
    41     linear_backoff_then_block_lock * curr_lock = &locks[lck];
     41    exp_backoff_then_block_lock * curr_lock = &locks[lck];
    4242    for (unsigned int i = 0; i < num_times; i++) {
    4343        dowork(buffer, work_unlocked);
     
    5151}
    5252
    53 
     53int doOne = 0;
    5454int main(int argc, char* argv[]) {
    5555    switch (argc) {
     56        case 8:
     57            doOne = atoi(argv[7]);
    5658        case 7:
    57             work_unlocked = atoi(argv[5]);
     59            work_unlocked = atoi(argv[6]);
    5860        case 6:
    5961            work_locked = atoi(argv[5]);
    6062        case 5:
    61             num_times = atoi(argv[4]);
     63            total_times = atoi(argv[4]);
    6264        case 4:
    6365            lockCount = atoi(argv[3]);
     
    7274    }
    7375        processor p[threadCount];
    74     linear_backoff_then_block_lock locks[lockCount];
     76    exp_backoff_then_block_lock locks[lockCount];
    7577    worker * worker_arr[taskCount];
    7678    num_times = total_times  / taskCount;
    77 
    78         //printf("Start Test: martin lock simple\n");
    79         clock_t begin = clock();
     79    //printf("%d\n", doOne);
     80        //
     81        //clock_t begin = clock();
     82    if (doOne == 1) {
     83        printf("Start Test: martin lock simple %d\n", num_times);
    8084        for (unsigned int i = 0; i < taskCount; i++) {
    8185        worker_arr[i] = new( locks, false );
     
    8488        delete( worker_arr[i] );
    8589    }
    86         clock_t end = clock();
    87         double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    88         printf("norm: %f\n", time_spent);
     90    }
     91        //clock_t end = clock();
     92        //double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
     93        //printf("norm: %f\n", time_spent);
    8994
    9095    //printf("Start Test: martin lock improved\n");
    91         begin = clock();
     96        //begin = clock();
     97    if (doOne == 2) {
    9298        for (unsigned int i = 0; i < taskCount; i++) {
    9399        worker_arr[i] = new( locks, true );
     
    96102        delete( worker_arr[i] );
    97103    }
    98         end = clock();
    99         time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    100         printf("improved: %f\n", time_spent);
     104    }
     105        //end = clock();
     106        //time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
     107        //printf("improved: %f\n", time_spent);
    101108}
  • tests/enum_tests/.expect/typedIntEnum.txt

    r466787a rad861ef  
    1 0
    2 1
    3 1000
    4 1001
    5 2000
    6 2001
    7 2002
     10=0
     21=1
     31000=1000
     41001=1001
     52000=2000
     62001=2001
     72002=2002
  • tests/enum_tests/pointerEnum.cfa

    r466787a rad861ef  
    1111int main() {
    1212    E * v = First;
    13     sout | "v: " | e.x;
     13    // sout | "v: " | e.x;
    1414}
  • tests/enum_tests/typedIntEnum.cfa

    r466787a rad861ef  
    1212
    1313int main() {
    14     printf("%d\n", zero);
    15     printf("%d\n", one);
    16     printf("%d\n", thousand);
    17     printf("%d\n", thousand_one);
    18     printf("%d\n", two_thousand);
    19     printf("%d\n", two_thousand_one);
    20     printf("%d\n", two_thousand_two);
     14    printf("0=%d\n", zero);
     15    printf("1=%d\n", one);
     16    printf("1000=%d\n", thousand);
     17    printf("1001=%d\n", thousand_one);
     18    printf("2000=%d\n", two_thousand);
     19    printf("2001=%d\n", two_thousand_one);
     20    printf("2002=%d\n", two_thousand_two);
    2121    return 0;
    2222}
Note: See TracChangeset for help on using the changeset viewer.