# HG changeset patch # User mjsousa # Date 1418823996 0 # Node ID c9eeb67ba939abbf917f8658f60e0cbb3ba94034 # Parent 5f4dfe6670dabf11abc3da334de25b53f5bacc8d Small code re-organization of how const values are stored in symbol_c (can now be accessed through member functions, instead of macros) diff -r 5f4dfe6670da -r c9eeb67ba939 absyntax/absyntax.cc --- a/absyntax/absyntax.cc Sun Dec 14 19:15:29 2014 +0000 +++ b/absyntax/absyntax.cc Wed Dec 17 13:46:36 2014 +0000 @@ -44,6 +44,7 @@ + /* The base class of all symbols */ symbol_c::symbol_c( int first_line, int first_column, const char *ffile, long int first_order, @@ -59,10 +60,6 @@ this->parent = NULL; this->datatype = NULL; this->scope = NULL; - this->const_value._real64.status = cs_undefined; - this->const_value._int64.status = cs_undefined; - this->const_value._uint64.status = cs_undefined; - this->const_value._bool.status = cs_undefined; } diff -r 5f4dfe6670da -r c9eeb67ba939 absyntax/absyntax.hh --- a/absyntax/absyntax.hh Sun Dec 14 19:15:29 2014 +0000 +++ b/absyntax/absyntax.hh Wed Dec 17 13:46:36 2014 +0000 @@ -93,9 +93,50 @@ - - - +/*** constant folding ***/ +/* During stage 3 (semantic analysis/checking) we will be doing constant folding. + * That algorithm will anotate the abstract syntax tree with the result of operations + * on literals (i.e. 44 + 55 will store the result 99). + * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT, + * or an ANY_BIT, we need to handle all possibilities, and determine the result of the + * operation assuming each type. + * For this reason, we have one entry for each possible type, with some expressions + * having more than one entry filled in! + */ +class const_value_c { + public: + typedef enum { cs_undefined, /* not defined/not yet evaluated --> const_value is not valid! */ + cs_non_const, /* we have determined that expression is not a const value --> const_value is not valid! */ + cs_const_value, /* const value is valid */ + cs_overflow /* result produced overflow or underflow --> const_value is not valid! */ + } const_status_t; + + template class const_value__ { + const_status_t status; + value_type value; + + public: + const_value__(void): status(cs_undefined), value(0) {}; + + value_type get(void) {return value;} + void set(value_type value_) {status = cs_const_value; value = value_;} + void set_overflow(void) {status = cs_overflow ;} + void set_nonconst(void) {status = cs_non_const ;} + bool is_valid (void) {return (status == cs_const_value);} + bool is_overflow (void) {return (status == cs_overflow );} + bool is_nonconst (void) {return (status == cs_non_const );} + bool is_zero (void) {return (is_valid() && (get() == 0));} + }; + + const_value__< int64_t> _int64; /* status is initialised to UNDEFINED */ + const_value__ _uint64; /* status is initialised to UNDEFINED */ + const_value__ _real64; /* status is initialised to UNDEFINED */ + const_value__ _bool; /* status is initialised to UNDEFINED */ + + /* default constructor and destructor */ + const_value_c(void) {}; + ~const_value_c(void) {}; +}; @@ -142,33 +183,8 @@ symbol_c *scope; /*** constant folding ***/ - /* During stage 3 (semantic analysis/checking) we will be doing constant folding. - * That algorithm will anotate the abstract syntax tree with the result of operations - * on literals (i.e. 44 + 55 will store the result 99). - * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT, - * or an ANY_BIT, we need to handle all possibilities, and determine the result of the - * operation assuming each type. - * For this reason, we have one entry for each possible type, with some expressions - * having more than one entry filled in! - */ - typedef enum { cs_undefined, /* not defined/not yet evaluated --> const_value is not valid! */ - cs_non_const, /* we have determined that expression is not a const value --> const_value is not valid! */ - cs_const_value, /* const value is valid */ - cs_overflow /* result produced overflow or underflow --> const_value is not valid! */ - } const_status_t; - - typedef struct const_value_real64_s {const_status_t status; real64_t value; const_value_real64_s (): status(cs_undefined), value(0.0) {} } const_value_real64_t; - typedef struct const_value_int64_s {const_status_t status; int64_t value; const_value_int64_s (): status(cs_undefined), value(0) {} } const_value_int64_t; - typedef struct const_value_uint64_s {const_status_t status; uint64_t value; const_value_uint64_s (): status(cs_undefined), value(0) {} } const_value_uint64_t; - typedef struct const_value_bool_s {const_status_t status; bool value; const_value_bool_s (): status(cs_undefined), value(false) {} } const_value_bool_t; - - typedef struct { - const_value_real64_t _real64; /* status is initialised to UNDEFINED */ - const_value_int64_t _int64; /* status is initialised to UNDEFINED */ - const_value_uint64_t _uint64; /* status is initialised to UNDEFINED */ - const_value_bool_t _bool; /* status is initialised to UNDEFINED */ - } const_value_t; - const_value_t const_value; + /* If the symbol has a constant numerical value, this will be set to that value by constant_folding_c */ + const_value_c const_value; /*** Enumeration datatype checking ***/ /* Not all symbols will contain the following anotations, which is why they are not declared here in symbol_c diff -r 5f4dfe6670da -r c9eeb67ba939 absyntax_utils/debug_ast.cc --- a/absyntax_utils/debug_ast.cc Sun Dec 14 19:15:29 2014 +0000 +++ b/absyntax_utils/debug_ast.cc Wed Dec 17 13:46:36 2014 +0000 @@ -118,7 +118,7 @@ fprintf(stderr, "}\t"); /* print the const values... */ - fprintf(stderr, " constv{f=%f, i=%"PRId64", u=%"PRIu64", b=%d}\t", symbol->const_value._real64.value, symbol->const_value._int64.value, symbol->const_value._uint64.value, symbol->const_value._bool.value?1:0); + fprintf(stderr, " constv{f=%f, i=%"PRId64", u=%"PRIu64", b=%d}\t", symbol->const_value._real64.get(), symbol->const_value._int64.get(), symbol->const_value._uint64.get(), symbol->const_value._bool.get()?1:0); } diff -r 5f4dfe6670da -r c9eeb67ba939 stage3/array_range_check.cc --- a/stage3/array_range_check.cc Sun Dec 14 19:15:29 2014 +0000 +++ b/stage3/array_range_check.cc Wed Dec 17 13:46:36 2014 +0000 @@ -68,8 +68,9 @@ warning_found = true; \ } -#define GET_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.value) -#define VALID_CVALUE(dtype, symbol) (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status) + +#define GET_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.get()) +#define VALID_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.is_valid()) /* The cmp_unsigned_signed function compares two numbers u and s. * It returns an integer indicating the relationship between the numbers: diff -r 5f4dfe6670da -r c9eeb67ba939 stage3/constant_folding.cc --- a/stage3/constant_folding.cc Sun Dec 14 19:15:29 2014 +0000 +++ b/stage3/constant_folding.cc Wed Dec 17 13:46:36 2014 +0000 @@ -186,15 +186,16 @@ -#define SET_CVALUE(dtype, symbol, new_value) {((symbol)->const_value._##dtype.value) = new_value; ((symbol)->const_value._##dtype.status) = symbol_c::cs_const_value;} -#define GET_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.value) -#define SET_OVFLOW(dtype, symbol) ((symbol)->const_value._##dtype.status) = symbol_c::cs_overflow -#define SET_NONCONST(dtype, symbol) ((symbol)->const_value._##dtype.status) = symbol_c::cs_non_const - -#define VALID_CVALUE(dtype, symbol) (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status) -#define IS_OVFLOW(dtype, symbol) (symbol_c::cs_overflow == (symbol)->const_value._##dtype.status) -#define IS_NONCONST(dtype, symbol) (symbol_c::cs_non_const == (symbol)->const_value._##dtype.status) -#define ISZERO_CVALUE(dtype, symbol) ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0)) +#define SET_CVALUE(dtype, symbol, new_value) ((symbol)->const_value._##dtype.set(new_value)) +#define GET_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.get()) +#define SET_OVFLOW(dtype, symbol) ((symbol)->const_value._##dtype.set_overflow()) +#define SET_NONCONST(dtype, symbol) ((symbol)->const_value._##dtype.set_nonconst()) + +#define VALID_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.is_valid()) +#define IS_OVFLOW(dtype, symbol) ((symbol)->const_value._##dtype.is_overflow()) +#define IS_NONCONST(dtype, symbol) ((symbol)->const_value._##dtype.is_nonconst()) +#define ISZERO_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.is_zero()) + #define ISEQUAL_CVALUE(dtype, symbol1, symbol2) \ (VALID_CVALUE(dtype, symbol1) && VALID_CVALUE(dtype, symbol2) && (GET_CVALUE(dtype, symbol1) == GET_CVALUE(dtype, symbol2))) @@ -225,18 +226,16 @@ * - constant * constant = non_const (if not equal) */ #define COMPUTE_MEET_SEMILATTICE(dtype, c1, c2, resValue) {\ - if (( c1._##dtype.value != c2._##dtype.value && c2._##dtype.status == symbol_c::cs_const_value &&\ - c1._##dtype.status == symbol_c::cs_const_value) ||\ - ( c1._##dtype.status == symbol_c::cs_non_const && c2._##dtype.status == symbol_c::cs_const_value ) ||\ - ( c2._##dtype.status == symbol_c::cs_non_const && c1._##dtype.status == symbol_c::cs_const_value )) {\ - resValue._##dtype.status = symbol_c::cs_non_const;\ + if (( c1._##dtype.get() != c2._##dtype.get() && c2._##dtype.is_valid() && c1._##dtype.is_valid()) ||\ + ( c1._##dtype.is_nonconst() && c2._##dtype.is_valid() ) ||\ + ( c2._##dtype.is_nonconst() && c1._##dtype.is_valid() )) {\ + resValue._##dtype.set_nonconst();\ } else {\ - resValue._##dtype.status = symbol_c::cs_const_value;\ - resValue._##dtype.value = c1._##dtype.value;\ + resValue._##dtype.set(c1._##dtype.get());\ }\ } -typedef std::map map_values_t; +typedef std::map map_values_t; static map_values_t values; @@ -734,11 +733,11 @@ itr = m1.begin(); for ( ; itr != m1.end(); ++itr) { std::string name = itr->first; - symbol_c::const_value_t value; + const_value_c value; if (m2.count(name) > 0) { - symbol_c::const_value_t c1 = itr->second; - symbol_c::const_value_t c2 = m2[name]; + const_value_c c1 = itr->second; + const_value_c c2 = m2[name]; COMPUTE_MEET_SEMILATTICE (real64, c1, c2, value); COMPUTE_MEET_SEMILATTICE (uint64, c1, c2, value); COMPUTE_MEET_SEMILATTICE ( int64, c1, c2, value); @@ -1581,7 +1580,7 @@ symbol->beg_expression->accept(*this); symbol->end_expression->accept(*this); varName = get_var_name_c::get_name(symbol->control_variable)->value; - values[varName]._int64.status = symbol_c::cs_non_const; + values[varName]._int64.status = const_value_c::cs_non_const; /* Optimize dead code */ if (NULL != symbol->by_expression) { diff -r 5f4dfe6670da -r c9eeb67ba939 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Sun Dec 14 19:15:29 2014 +0000 +++ b/stage3/fill_candidate_datatypes.cc Wed Dec 17 13:46:36 2014 +0000 @@ -68,11 +68,10 @@ #include #include -#define GET_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.value) -#define VALID_CVALUE(dtype, symbol) (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status) -#define IS_OVERFLOW(dtype, symbol) (symbol_c::cs_overflow == (symbol)->const_value._##dtype.status) - - + +#define GET_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.get()) +#define VALID_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.is_valid()) +#define IS_OVERFLOW(dtype, symbol) ((symbol)->const_value._##dtype.is_overflow()) /* set to 1 to see debug info during execution */ diff -r 5f4dfe6670da -r c9eeb67ba939 stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Sun Dec 14 19:15:29 2014 +0000 +++ b/stage4/generate_c/generate_c.cc Wed Dec 17 13:46:36 2014 +0000 @@ -53,8 +53,8 @@ /* Macros to access the constant value of each expression (if it exists) from the annotation introduced to the symbol_c object by constant_folding_c in stage3! */ -#define VALID_CVALUE(dtype, symbol) (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status) -#define GET_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.value) +#define VALID_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.is_valid()) +#define GET_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.get())