stage3/constant_folding.cc
author Mario de Sousa <msousa@fe.up.pt>
Thu, 03 Jan 2013 18:23:07 +0000
changeset 793 268bf4ca5fa1
parent 783 3bd2704d9ba9
child 786 c370918ca7fb
child 787 6e2671e0f1a8
permissions -rw-r--r--
grand merge
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     1
/*
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     2
 *  matiec - a compiler for the programming languages defined in IEC 61131-3
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     3
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     4
 *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     5
 *  Copyright (C) 2012       Manuele Conti (conti.ma@alice.it)
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     6
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     7
 *  This program is free software: you can redistribute it and/or modify
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     8
 *  it under the terms of the GNU General Public License as published by
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     9
 *  the Free Software Foundation, either version 3 of the License, or
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    10
 *  (at your option) any later version.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    11
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    12
 *  This program is distributed in the hope that it will be useful,
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    15
 *  GNU General Public License for more details.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    16
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    17
 *  You should have received a copy of the GNU General Public License
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    18
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    19
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    20
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    21
 * This code is made available on the understanding that it will not be
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    22
 * used in safety-critical situations without a full and competent review.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    23
 */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    24
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    25
/*
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    26
 * An IEC 61131-3 compiler.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    27
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    28
 * Based on the
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    29
 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    30
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    31
 */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    32
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    33
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    34
640
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    35
/* TODO: 
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    36
 *         - Add support for comparison (= and !=) of enumeration literals!
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    37
 *              We will need to add another const_value entry to the symbol_c, containing the 
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    38
 *              possible enumeration value of the enum constant!
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    39
 *              Doing this will allow us to more easily implement a constant_propagation_c later on!
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    40
 *
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    41
 *         - Add support for comparison (= and !=) of the exact same variable
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    42
 *                (e.g. if (int_v = int_v) then ...)
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    43
 */
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
    44
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    45
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    46
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    47
/* Do constant folding...
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    48
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    49
 * I.e., Determine the value of all expressions in which only constant values (i.e. literals) are used.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    50
 * The (constant) result of each operation is stored (annotated) in the respective operation symbol 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    51
 * (e.g.: add_expression_c) in the abstract syntax tree,
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    52
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    53
 * For example:
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    54
 *       2 + 3         -> the constant value '5'    is stored in the add_expression_c symbol.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    55
 *       22.2 - 5.0    -> the constant value '17.2' is stored in the add_expression_c symbol.
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    56
 *       etc...
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    57
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    58
 *
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    59
 * NOTE 1 
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    60
 *      Some operations and constants can have multiple data types. For example,
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    61
 *        1 AND 0
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    62
 *      may be either a BOOL, BYTE, WORD or LWORD.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    63
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    64
 *      The same happens with 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    65
 *        1 + 2
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    66
 *      which may be signed (e.g. INT) or unsigned (UINT)
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    67
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    68
 *      For the above reason, instead of storing a single constant value, we actually store 4:
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    69
 *        - bool
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    70
 *        - uint64
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    71
 *        -  int64
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    72
 *        - real64
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    73
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    74
 *      Additionally, since the result of an operation may result in an overflow, we actually
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    75
 *      store the result inside a struct (defined in absyntax.hh)
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    76
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    77
 *             ** During stage 3 (semantic analysis/checking) we will be doing constant folding.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    78
 *              * That algorithm will anotate the abstract syntax tree with the result of operations
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    79
 *              * on literals (i.e. 44 + 55 will store the result 99).
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    80
 *              * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT,
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    81
 *              * or an ANY_BIT, we need to handle all possibilities, and determine the result of the
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    82
 *              * operation assuming each type.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    83
 *              * For this reason, we have one entry for each possible type, with some expressions
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    84
 *              * having more than one entry filled in!
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    85
 *              **
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    86
 *             typedef enum { cs_undefined,   // not defined --> const_value is not valid!
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    87
 *                            cs_const_value, // const value is valid
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    88
 *                            cs_overflow     // result produced overflow or underflow --> const_value is not valid!
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    89
 *                          } const_status_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    90
 *    
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    91
 *             typedef struct {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    92
 *                 const_status_t status;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    93
 *                 real64_t       value; 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    94
 *             } const_value_real64_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    95
 *             const_value_real64_t *const_value_real64; // when NULL --> UNDEFINED
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    96
 *             
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    97
 *             typedef struct {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    98
 *                 const_status_t status;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    99
 *                 int64_t        value; 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   100
 *             } const_value_int64_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   101
 *             const_value_int64_t *const_value_int64; // when NULL --> UNDEFINED
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   102
 *             
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   103
 *             typedef struct {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   104
 *                 const_status_t status;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   105
 *                 uint64_t       value; 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   106
 *             } const_value_uint64_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   107
 *             const_value_uint64_t *const_value_uint64; // when NULL --> UNDEFINED
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   108
 *             
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   109
 *             typedef struct {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   110
 *                 const_status_t status;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   111
 *                 bool           value; 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   112
 *             } const_value_bool_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   113
 *             const_value_bool_t *const_value_bool; // when NULL --> UNDEFINED
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   114
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   115
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   116
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   117
 * NOTE 2 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   118
 *    This file does not print out any error messages!
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   119
 *    We cannot really print out error messages when we find an overflow. Since each operation
781
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   120
 *    (symbol in the abstract syntax tree for that operation) will have up to 4 constant results,
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   121
 *    it may happen that some of them overflow, while other do not.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   122
 *    We must wait for data type checking to determine the exact data type of each expression
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   123
 *    before we can decide whether or not we should print out an overflow error message.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   124
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   125
 *    For this reason, this visitor merely annotates the abstract syntax tree, and leaves the
781
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   126
 *    actually printing of errors for the print_datatype_errors_c class!
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   127
 *
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   128
 * NOTE 3
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   129
 *    Constant Folding class is extended with a implementation constant propagation algorithm
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   130
 *    by Mario de Sousa.
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   131
 *    Main idea is not to implement a general constant propagation algorithm but to reinterpret it
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   132
 *    for visitor classes.
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   133
 *    We declared a hash map, it contains a variables list linked with current constant values.
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   134
 *    During expression evaluation we can retrieve a constant value to symbolic variables getting it from the map.
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   135
 *    Also at join source points we use a meet semilattice rules to merge current values between a block
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   136
 *    and adjacent block.
577547327f67 Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents: 780
diff changeset
   137
 *
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   138
 */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   139
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   140
#include "constant_folding.hh"
565
8acbddf75333 Fix a few bugs of previous commit.
Mario de Sousa <msousa@fe.up.pt>
parents: 564
diff changeset
   141
#include <stdlib.h> /* required for malloc() */
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   142
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   143
#include <string.h>  /* required for strlen() */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   144
// #include <stdlib.h>  /* required for atoi() */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   145
#include <errno.h>   /* required for errno */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   146
607
be9ba3531afb cleaning up code. Changing HUGE_VAL to INFINITY.
Mario de Sousa <msousa@fe.up.pt>
parents: 604
diff changeset
   147
#include "../main.hh" // required for uint8_t, real_64_t, ..., and the macros NAN, INFINITY, INT8_MAX, REAL32_MAX, ... */
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   148
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   149
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   150
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   151
568
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   152
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   153
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   154
#define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   155
#define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   156
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   157
#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   158
  if (current_display_error_level >= error_level) {                                                                         \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   159
    fprintf(stderr, "%s:%d-%d..%d-%d: error: ",                                                                             \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   160
            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   161
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   162
    fprintf(stderr, __VA_ARGS__);                                                                                           \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   163
    fprintf(stderr, "\n");                                                                                                  \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   164
    error_count++;                                                                                                     \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   165
  }                                                                                                                         \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   166
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   167
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   168
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   169
#define STAGE3_WARNING(symbol1, symbol2, ...) {                                                                             \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   170
    fprintf(stderr, "%s:%d-%d..%d-%d: warning: ",                                                                           \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   171
            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   172
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   173
    fprintf(stderr, __VA_ARGS__);                                                                                           \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   174
    fprintf(stderr, "\n");                                                                                                  \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   175
    warning_found = true;                                                                                                   \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   176
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   177
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   178
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   179
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   180
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   181
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   182
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   183
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   184
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   185
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   186
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   187
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   188
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   189
#define SET_CVALUE(dtype, symbol, new_value) {((symbol)->const_value._##dtype.value) = new_value; ((symbol)->const_value._##dtype.status) = symbol_c::cs_const_value;}
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   190
#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.value)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   191
#define SET_OVFLOW(dtype, symbol)             ((symbol)->const_value._##dtype.status) = symbol_c::cs_overflow
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   192
#define SET_NONCONST(dtype, symbol)           ((symbol)->const_value._##dtype.status) = symbol_c::cs_non_const
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   193
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   194
#define VALID_CVALUE(dtype, symbol)           (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status)
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   195
#define IS_OVFLOW(dtype, symbol)              (symbol_c::cs_overflow    == (symbol)->const_value._##dtype.status)
648
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   196
#define IS_NONCONST(dtype, symbol)            (symbol_c::cs_non_const   == (symbol)->const_value._##dtype.status)
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   197
#define ISZERO_CVALUE(dtype, symbol)          ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0))
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   198
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   199
#define ISEQUAL_CVALUE(dtype, symbol1, symbol2) \
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   200
	(VALID_CVALUE(dtype, symbol1) && VALID_CVALUE(dtype, symbol2) && (GET_CVALUE(dtype, symbol1) == GET_CVALUE(dtype, symbol2))) 
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   201
648
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   202
#define DO_BINARY_OPER(oper_type, operation, res_type, operand1, operand2) {                                              \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   203
	if      (VALID_CVALUE(oper_type, operand1) && VALID_CVALUE(oper_type, operand2))                                  \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   204
		{SET_CVALUE(res_type, symbol, GET_CVALUE(oper_type, operand1) operation GET_CVALUE(oper_type, operand2));}\
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   205
	else if (IS_OVFLOW   (oper_type, operand1) || IS_OVFLOW   (oper_type, operand2))                                  \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   206
		{SET_OVFLOW(res_type, symbol);}  /* does it really make sense to set OVFLOW when restype is boolean??  */ \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   207
	else if (IS_NONCONST (oper_type, operand1) || IS_NONCONST (oper_type, operand2))                                  \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   208
		{SET_NONCONST(res_type, symbol);}                                                                         \
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   209
}
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   210
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   211
#define DO_UNARY_OPER(dtype, operation, operand) {                                                                        \
648
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   212
	if      (VALID_CVALUE(dtype, operand))                                                                            \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   213
		{SET_CVALUE(dtype, symbol, operation GET_CVALUE(dtype, operand));}                                        \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   214
	else if (IS_OVFLOW   (dtype, operand))                                                                            \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   215
		{SET_OVFLOW(dtype, symbol);}                                                                              \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   216
	else if (IS_NONCONST (dtype, operand))                                                                            \
5ca2aabb8bcb More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents: 643
diff changeset
   217
		{SET_NONCONST(dtype, symbol);}                                                                            \
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   218
}
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   219
776
96a1199d0739 Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents: 774
diff changeset
   220
/* Constant Propagation: Rules for Meet from "Cooper K., Torczon L. - Engineering a Compiler, Second Edition - 2011"
96a1199d0739 Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents: 774
diff changeset
   221
 * at 9.3 Static Single-Assignment Form  page 517
96a1199d0739 Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents: 774
diff changeset
   222
 * - any * undefined = any
96a1199d0739 Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents: 774
diff changeset
   223
 * - any * non_const = non_const
96a1199d0739 Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents: 774
diff changeset
   224
 * - constant * constant = constant  (if equal)
96a1199d0739 Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents: 774
diff changeset
   225
 * - constant * constant = non_const (if not equal)
774
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   226
 */
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   227
#define COMPUTE_MEET_SEMILATTICE(dtype, c1, c2, resValue) {\
776
96a1199d0739 Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents: 774
diff changeset
   228
		if (( c1._##dtype.value  != c2._##dtype.value && c2._##dtype.status == symbol_c::cs_const_value &&\
96a1199d0739 Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents: 774
diff changeset
   229
              c1._##dtype.status == symbol_c::cs_const_value) ||\
774
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   230
		    ( c1._##dtype.status == symbol_c::cs_non_const && c2._##dtype.status == symbol_c::cs_const_value ) ||\
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   231
		    ( c2._##dtype.status == symbol_c::cs_non_const && c1._##dtype.status == symbol_c::cs_const_value  )) {\
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   232
			resValue._##dtype.status = symbol_c::cs_non_const;\
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   233
		} else {\
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   234
			resValue._##dtype.status = symbol_c::cs_const_value;\
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   235
			resValue._##dtype.value  = c1._##dtype.value;\
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   236
		}\
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   237
}
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   238
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   239
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   240
static std::map <std::string, symbol_c::const_value_t> values;
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   241
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   242
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   243
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   244
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   245
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   246
/***            convert string to numerical value                    ***/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   247
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   248
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   249
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   250
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   251
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   252
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   253
  /* To allow the compiler to be portable, we cannot assume that int64_t is mapped onto long long int,
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   254
   * so we cannot call strtoll() and strtoull() in extract_int64() and extract_uint64().
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   255
   *
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   256
   * So, we create our own strtouint64() and strtoint64() functions.
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   257
   * (We actually call them matiec_strtoint64() so they will not clash with any function
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   258
   *  that may be added to the standard library in the future).
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   259
   * We actually create several of each, and let the compiler choose which is the correct one,
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   260
   * by having it resolve the call to the overloaded function. For the C++ compiler to be able
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   261
   * to resolve this ambiguity, we need to add a dummy parameter to each function!
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   262
   *
640
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
   263
   * TODO: support platforms (where the compiler will run) in which int64_t is mapped onto int !!
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
   264
   *       Is this really needed?
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
   265
   *       Currently, when trying to compile matiec on sych a platform, the C++ compiler will not
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
   266
   *       find any apropriate matiec_strtoint64() to call, so matiec will not be able to be compiled.
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
   267
   *       If you need this, you are welcome to fix it yourself...
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   268
   */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   269
static  int64_t matiec_strtoint64 (         long      int *dummy, const char *nptr, char **endptr, int base) {return strtol  (nptr, endptr, base);}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   270
static  int64_t matiec_strtoint64 (         long long int *dummy, const char *nptr, char **endptr, int base) {return strtoll (nptr, endptr, base);}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   271
  
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   272
static uint64_t matiec_strtouint64(unsigned long      int *dummy, const char *nptr, char **endptr, int base) {return strtoul (nptr, endptr, base);}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   273
static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   274
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   275
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   276
/* extract the value of an integer from an integer_c object !! */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   277
/* NOTE: it must ignore underscores! */
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   278
/* NOTE: To follow the basic structure used throughout the compiler's code, we should really be
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   279
 * writing this as a visitor_c (and do away with the dynamic casts!), but since we only have 3 distinct 
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   280
 * symbol class types to handle, it is probably easier to read if we write it as a standard function... 
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   281
 */
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   282
int64_t extract_int64_value(symbol_c *sym, bool *overflow) {
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   283
  int64_t      ret;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   284
  std::string  str = "";
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   285
  char        *endptr;
735
0304ff59fd7f Fix some important clang++ warnings.
Manuele Conti <conti.ma@alice.it>
parents: 690
diff changeset
   286
  const char  *value = NULL;
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   287
  int          base;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   288
  integer_c         *integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   289
  hex_integer_c     *hex_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   290
  octal_integer_c   *octal_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   291
  binary_integer_c  *binary_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   292
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   293
   if       ((integer        = dynamic_cast<integer_c *>(sym))        != NULL) {value = integer       ->value + 0; base = 10;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   294
   else  if ((hex_integer    = dynamic_cast<hex_integer_c *>(sym))    != NULL) {value = hex_integer   ->value + 3; base = 16;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   295
   else  if ((octal_integer  = dynamic_cast<octal_integer_c *>(sym))  != NULL) {value = octal_integer ->value + 2; base =  8;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   296
   else  if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base =  2;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   297
   else  ERROR;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   298
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   299
  for(unsigned int i = 0; i < strlen(value); i++)
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   300
    if (value[i] != '_')  str += value[i];
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   301
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   302
  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   303
  ret = matiec_strtoint64((int64_t *)NULL, str.c_str(), &endptr, base);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   304
  if (overflow != NULL)
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   305
    *overflow = (errno == ERANGE);
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   306
  if (((errno != 0) && (errno != ERANGE)) || (*endptr != '\0'))
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   307
    ERROR;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   308
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   309
  return ret;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   310
}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   311
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   312
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   313
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   314
uint64_t extract_uint64_value(symbol_c *sym, bool *overflow) {
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   315
  uint64_t     ret;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   316
  std::string  str = "";
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   317
  char        *endptr;
735
0304ff59fd7f Fix some important clang++ warnings.
Manuele Conti <conti.ma@alice.it>
parents: 690
diff changeset
   318
  const char  *value = NULL;
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   319
  int          base;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   320
  integer_c         *integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   321
  hex_integer_c     *hex_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   322
  octal_integer_c   *octal_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   323
  binary_integer_c  *binary_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   324
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   325
   if       ((integer        = dynamic_cast<integer_c *>(sym))        != NULL) {value = integer       ->value + 0; base = 10;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   326
   else  if ((hex_integer    = dynamic_cast<hex_integer_c *>(sym))    != NULL) {value = hex_integer   ->value + 3; base = 16;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   327
   else  if ((octal_integer  = dynamic_cast<octal_integer_c *>(sym))  != NULL) {value = octal_integer ->value + 2; base =  8;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   328
   else  if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base =  2;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   329
   else  ERROR;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   330
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   331
  for(unsigned int i = 0; i < strlen(value); i++)
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   332
    if (value[i] != '_')  str += value[i];
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   333
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   334
  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   335
  ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, base);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   336
  if (overflow != NULL)
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   337
    *overflow = (errno == ERANGE);
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   338
  if (((errno != 0) && (errno != ERANGE)) || (*endptr != '\0'))
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   339
    ERROR;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   340
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   341
  return ret;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   342
}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   343
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   344
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   345
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   346
/* extract the value of a real from an real_c object !! */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   347
/* NOTE: it must ignore underscores! */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   348
/* From iec_bison.yy
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   349
 *  real:
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   350
 *   real_token		{$$ = new real_c($1, locloc(@$));}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   351
 * | fixed_point_token	{$$ = new real_c($1, locloc(@$));}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   352
 *
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   353
 * From iec_flex.ll
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   354
 * {real}			{yylval.ID=strdup(yytext); return real_token;}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   355
 * {fixed_point}		{yylval.ID=strdup(yytext); return fixed_point_token;}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   356
 *
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   357
 * real		{integer}\.{integer}{exponent}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   358
 * fixed_point		{integer}\.{integer}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   359
 * exponent        [Ee]([+-]?){integer}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   360
 * integer         {digit}((_?{digit})*)
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   361
 */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   362
real64_t extract_real_value(symbol_c *sym, bool *overflow) {
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   363
  std::string str = "";
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   364
  real_c *real_sym;
633
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   365
  fixed_point_c *fixed_point_sym;
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   366
  char   *endptr;
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   367
  real64_t ret;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   368
633
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   369
  if ((real_sym = dynamic_cast<real_c *>(sym)) != NULL) {
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   370
	for(unsigned int i = 0; i < strlen(real_sym->value); i++)
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   371
      if (real_sym->value[i] != '_') str += real_sym->value[i];
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   372
  }
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   373
  else if ((fixed_point_sym = dynamic_cast<fixed_point_c *>(sym)) != NULL) {
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   374
    for(unsigned int i = 0; i < strlen(fixed_point_sym->value); i++)
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   375
      if (fixed_point_sym->value[i] != '_') str += fixed_point_sym->value[i];
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   376
  }
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   377
  else ERROR;
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   378
    
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   379
  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   380
  #if    (real64_t  == float)
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   381
    ret = strtof(str.c_str(),  &endptr);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   382
  #elif  (real64_t  == double)
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   383
    ret = strtod(str.c_str(),  &endptr);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   384
  #elif  (real64_t  == long_double)
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   385
    ret = strtold(str.c_str(), &endptr);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   386
  #else 
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   387
    #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting!
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   388
  #endif
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   389
  if (overflow != NULL)
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   390
    *overflow = (errno == ERANGE);
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   391
  if (((errno != 0) && (errno != ERANGE)) || (*endptr != '\0'))
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   392
    ERROR;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   393
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   394
  return ret;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   395
}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   396
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   397
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   398
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   399
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   400
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   401
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   402
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   403
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   404
/***        Functions to check for overflow situation                ***/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   405
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   406
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   407
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   408
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   409
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   410
/* NOTE:
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   411
 *   Most of the conditions to detect overflows on signed and unsigned integer operations were adapted from
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   412
 *   https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow?showComments=false
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   413
 *   https://www.securecoding.cert.org/confluence/display/seccode/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   414
 */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   415
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   416
/* NOTE: If at all possible, all overflow tests are done by pre-condition tests, i.e. tests that 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   417
 *       can be run _before_ the operation is executed, and therefore without accessing the result!
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   418
 *
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   419
 *       The exception is for real/floating point values, that simply test if the result is NaN (not a number).
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   420
 */
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   421
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   422
/* res = a + b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   423
static void CHECK_OVERFLOW_uint64_SUM(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   424
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   425
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   426
	/* Test by post-condition: If sum is smaller than either operand => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   427
	// if (GET_CVALUE(uint64, res) < GET_CVALUE(uint64, a))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   428
	/* Test by pre-condition: If (UINT64_MAX - a) < b => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   429
	if ((UINT64_MAX - GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   430
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   431
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   432
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   433
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   434
/* res = a - b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   435
static void CHECK_OVERFLOW_uint64_SUB(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   436
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   437
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   438
	/* Test by post-condition: If diference is larger than a => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   439
	// if (GET_CVALUE(uint64, res) > GET_CVALUE(uint64, a))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   440
	/* Test by pre-condition: if b > a => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   441
	if (GET_CVALUE(uint64, b) > GET_CVALUE(uint64, a))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   442
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   443
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   444
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   445
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   446
/* res = a * b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   447
static void CHECK_OVERFLOW_uint64_MUL(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   448
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   449
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   450
	/* Test by pre-condition: If (UINT64_MAX / a) < b => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   451
	if ((UINT64_MAX / GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   452
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   453
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   454
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   455
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   456
/* res = a / b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   457
static void CHECK_OVERFLOW_uint64_DIV(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   458
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   459
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   460
	if (GET_CVALUE(uint64, b) == 0) /* division by zero! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   461
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   462
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   463
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   464
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   465
/* res = a MOD b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   466
static void CHECK_OVERFLOW_uint64_MOD(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   467
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   468
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   469
	/* no overflow condition exists, including division by zero, which IEC 61131-3 considers legal for MOD operation! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   470
	if (false) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   471
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   472
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   473
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   474
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   475
/* res = - a */
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   476
static void CHECK_OVERFLOW_uint64_NEG(symbol_c *res, symbol_c *a) {
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   477
	/* The only legal operation is res = -0, everything else is an overflow! */
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   478
	if (VALID_CVALUE(uint64, a) && (GET_CVALUE(uint64, a) != 0))
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   479
		SET_OVFLOW(uint64, res);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   480
}
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   481
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   482
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   483
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   484
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   485
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   486
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   487
/* res = a + b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   488
static void CHECK_OVERFLOW_int64_SUM(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   489
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   490
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   491
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   492
	int64_t b = GET_CVALUE(int64, b_ptr);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   493
	/* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   494
	if (((b > 0) && (a > (INT64_MAX - b)))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   495
	 || ((b < 0) && (a < (INT64_MIN - b))))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   496
		SET_OVFLOW(int64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   497
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   498
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   499
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   500
/* res = a - b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   501
static void CHECK_OVERFLOW_int64_SUB(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   502
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   503
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   504
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   505
	int64_t b = GET_CVALUE(int64, b_ptr);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   506
	/* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   507
	if (((b > 0) && (a < (INT64_MIN + b)))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   508
	 || ((b < 0) && (a > (INT64_MAX + b))))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   509
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   510
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   511
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   512
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   513
/* res = a * b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   514
static void CHECK_OVERFLOW_int64_MUL(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   515
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   516
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   517
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   518
	int64_t b = GET_CVALUE(int64, b_ptr);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   519
	if (   ( (a > 0) &&  (b > 0) &&             (a > (INT64_MAX / b))) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   520
	    || ( (a > 0) && !(b > 0) &&             (b < (INT64_MIN / a))) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   521
	    || (!(a > 0) &&  (b > 0) &&             (a < (INT64_MIN / b))) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   522
	    || (!(a > 0) && !(b > 0) && (a != 0) && (b < (INT64_MAX / a))))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   523
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   524
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   525
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   526
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   527
/* res = a / b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   528
static void CHECK_OVERFLOW_int64_DIV(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   529
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   530
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   531
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   532
	int64_t b = GET_CVALUE(int64, b_ptr);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   533
	if ((b == 0) || ((a == INT64_MIN) && (b == -1)))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   534
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   535
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   536
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   537
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   538
/* res = a MOD b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   539
static void CHECK_OVERFLOW_int64_MOD(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   540
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   541
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   542
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   543
	int64_t b = GET_CVALUE(int64, b_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   544
	/* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   545
	 *  IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   546
	 *
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   547
	 * Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division,
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   548
	 * so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!!
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   549
	 *
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   550
	 * On the other hand, division by 0 is OK!!
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   551
	 */
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   552
	if ((a == INT64_MIN) && (b == -1))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   553
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   554
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   555
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   556
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   557
/* res = - a */
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   558
static void CHECK_OVERFLOW_int64_NEG(symbol_c *res, symbol_c *a) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   559
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   560
		return;
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   561
	if (GET_CVALUE(int64, a) == INT64_MIN)
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   562
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   563
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   564
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   565
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   566
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   567
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   568
static void CHECK_OVERFLOW_real64(symbol_c *res_ptr) {
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   569
	if (!VALID_CVALUE(real64, res_ptr))
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   570
		return;
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   571
	real64_t res = GET_CVALUE(real64, res_ptr);
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   572
	/* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   573
	/* The IEC 61131-3 clearly states in section '2.5.1.5.2 Numerical functions':
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   574
	 * "It is an error if the result of evaluation of one of these [numerical] functions exceeds the range of values
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   575
	 *  specified for the data type of the function output, or if division by zero is attempted."
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   576
	 * For this reason, any operation that has as a result a positive or negative inifinity, is also an error!
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   577
	 */
607
be9ba3531afb cleaning up code. Changing HUGE_VAL to INFINITY.
Mario de Sousa <msousa@fe.up.pt>
parents: 604
diff changeset
   578
	if ((isnan(res)) || (res == INFINITY) || (res == -INFINITY))
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   579
		SET_OVFLOW(real64, res_ptr);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   580
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   581
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   582
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   583
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   584
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   585
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   586
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   587
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   588
/***        Functions to execute operations on the const values      ***/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   589
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   590
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   591
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   592
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   593
/* static void *handle_cmp(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2, OPERATION) */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   594
#define handle_cmp(symbol, oper1, oper2, operation) {               \
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   595
	if ((NULL == oper1) || (NULL == oper2)) return NULL;        \
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   596
	DO_BINARY_OPER(  bool, operation, bool, oper1, oper2);     \
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   597
	DO_BINARY_OPER(uint64, operation, bool, oper1, oper2);     \
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   598
	DO_BINARY_OPER( int64, operation, bool, oper1, oper2);     \
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   599
	DO_BINARY_OPER(real64, operation, bool, oper1, oper2);     \
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   600
	return NULL;                                                \
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   601
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   602
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   603
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   604
/* NOTE: the MOVE standard function is equivalent to the ':=' in ST syntax */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   605
static void *handle_move(symbol_c *to, symbol_c *from) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   606
	if (NULL == from) return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   607
	to->const_value = from->const_value;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   608
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   609
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   610
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   611
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   612
/* unary negation (multiply by -1) */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   613
static void *handle_neg(symbol_c *symbol, symbol_c *oper) {
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   614
	if (NULL == oper) return NULL;
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   615
	/* NOTE: The oper may never be an integer/real literal, '-1' and '-2.2' are stored as an neg_integer_c/neg_real_c instead.
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   616
	 *       Because of this, we MUST NOT handle the INT_MIN special situation that is handled in neg_integer_c visitor!
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   617
	 *
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   618
	 *       VAR v1, v2, v3 : UINT; END_VAR;
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   619
	 *       v1 =  9223372036854775808 ; (* |INT64_MIN| == -INT64_MIN *)   <------ LEGAL
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   620
	 *       v2 =  -(-v1);                                                 <------ ILLEGAL (since it -v1 is overflow!)
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   621
	 *       v2 =  -(-9223372036854775808 );                               <------ MUST also be ILLEGAL 
640
ffa02cf2b335 Add some comments.
Mario de Sousa <msousa@fe.up.pt>
parents: 621
diff changeset
   622
	 */
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   623
	DO_UNARY_OPER(uint64, -, oper);	CHECK_OVERFLOW_uint64_NEG(symbol, oper);  /* handle the uint_v := -0 situation! */
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   624
	DO_UNARY_OPER( int64, -, oper);	CHECK_OVERFLOW_int64_NEG (symbol, oper);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   625
	DO_UNARY_OPER(real64, -, oper);	CHECK_OVERFLOW_real64(symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   626
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   627
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   628
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   629
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   630
/* unary boolean negation (NOT) */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   631
static void *handle_not(symbol_c *symbol, symbol_c *oper) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   632
	if (NULL == oper) return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   633
	DO_UNARY_OPER(  bool, !, oper);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   634
	DO_UNARY_OPER(uint64, ~, oper);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   635
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   636
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   637
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   638
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   639
static void *handle_or (symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   640
	if ((NULL == oper1) || (NULL == oper2)) return NULL;
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   641
	DO_BINARY_OPER(  bool, ||, bool  , oper1, oper2);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   642
	DO_BINARY_OPER(uint64, | , uint64, oper1, oper2);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   643
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   644
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   645
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   646
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   647
static void *handle_xor(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   648
	if ((NULL == oper1) || (NULL == oper2)) return NULL;
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   649
	DO_BINARY_OPER(  bool, ^, bool  , oper1, oper2);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   650
	DO_BINARY_OPER(uint64, ^, uint64, oper1, oper2);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   651
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   652
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   653
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   654
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   655
static void *handle_and(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   656
	if ((NULL == oper1) || (NULL == oper2)) return NULL;
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   657
	DO_BINARY_OPER(  bool, &&, bool, oper1, oper2);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   658
	DO_BINARY_OPER(uint64, & , uint64, oper1, oper2);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   659
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   660
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   661
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   662
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   663
static void *handle_add(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   664
	if ((NULL == oper1) || (NULL == oper2)) return NULL;
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   665
	DO_BINARY_OPER(uint64, +, uint64, oper1, oper2);   CHECK_OVERFLOW_uint64_SUM(symbol, oper1, oper2);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   666
	DO_BINARY_OPER( int64, +,  int64, oper1, oper2);   CHECK_OVERFLOW_int64_SUM (symbol, oper1, oper2);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   667
	DO_BINARY_OPER(real64, +, real64, oper1, oper2);   CHECK_OVERFLOW_real64    (symbol);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   668
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   669
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   670
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   671
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   672
static void *handle_sub(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   673
	if ((NULL == oper1) || (NULL == oper2)) return NULL;
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   674
	DO_BINARY_OPER(uint64, -, uint64, oper1, oper2);   CHECK_OVERFLOW_uint64_SUB(symbol, oper1, oper2);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   675
	DO_BINARY_OPER( int64, -,  int64, oper1, oper2);   CHECK_OVERFLOW_int64_SUB (symbol, oper1, oper2);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   676
	DO_BINARY_OPER(real64, -, real64, oper1, oper2);   CHECK_OVERFLOW_real64    (symbol);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   677
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   678
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   679
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   680
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   681
static void *handle_mul(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   682
	if ((NULL == oper1) || (NULL == oper2)) return NULL;
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   683
	DO_BINARY_OPER(uint64, *, uint64, oper1, oper2);   CHECK_OVERFLOW_uint64_MUL(symbol, oper1, oper2);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   684
	DO_BINARY_OPER( int64, *,  int64, oper1, oper2);   CHECK_OVERFLOW_int64_MUL (symbol, oper1, oper2);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   685
	DO_BINARY_OPER(real64, *, real64, oper1, oper2);   CHECK_OVERFLOW_real64    (symbol);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   686
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   687
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   688
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   689
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   690
static void *handle_div(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   691
	if ((NULL == oper1) || (NULL == oper2)) return NULL;
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   692
	if (ISZERO_CVALUE(uint64, oper2))  {SET_OVFLOW(uint64, symbol);} else {DO_BINARY_OPER(uint64, /, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_DIV(symbol, oper1, oper2);};
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   693
	if (ISZERO_CVALUE( int64, oper2))  {SET_OVFLOW( int64, symbol);} else {DO_BINARY_OPER( int64, /,  int64, oper1, oper2); CHECK_OVERFLOW_int64_DIV (symbol, oper1, oper2);};
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   694
	if (ISZERO_CVALUE(real64, oper2))  {SET_OVFLOW(real64, symbol);} else {DO_BINARY_OPER(real64, /, real64, oper1, oper2); CHECK_OVERFLOW_real64(symbol);};
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   695
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   696
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   697
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   698
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   699
static void *handle_mod(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   700
	if ((NULL == oper1) || (NULL == oper2)) return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   701
	/* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   702
	 *  IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   703
	 *
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   704
	 * Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division,
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   705
	 * so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!!
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   706
	 */
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   707
	if (ISZERO_CVALUE(uint64, oper2))  {SET_CVALUE(uint64, symbol, 0);} else {DO_BINARY_OPER(uint64, %, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_MOD(symbol, oper1, oper2);};
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   708
	if (ISZERO_CVALUE( int64, oper2))  {SET_CVALUE( int64, symbol, 0);} else {DO_BINARY_OPER( int64, %,  int64, oper1, oper2); CHECK_OVERFLOW_int64_MOD (symbol, oper1, oper2);};
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   709
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   710
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   711
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   712
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   713
static void *handle_pow(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   714
	/* NOTE: If the const_value in symbol->r_exp is within the limits of both int64 and uint64, then we do both operations.
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   715
	 *       That is OK, as the result should be identicial (we do create an unnecessary CVALUE variable, but who cares?).
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   716
	 *       If only one is valid, then that is the oper we will do!
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   717
	 */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   718
	if (VALID_CVALUE(real64, oper1) && VALID_CVALUE( int64, oper2))
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   719
		SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, oper1), GET_CVALUE( int64, oper2)));
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   720
	if (VALID_CVALUE(real64, oper1) && VALID_CVALUE(uint64, oper2))
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   721
		SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, oper1), GET_CVALUE(uint64, oper2)));
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   722
	CHECK_OVERFLOW_real64(symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   723
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   724
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   725
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   726
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   727
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   728
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   729
/***        Helper functions for handling IL instruction lists.      ***/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   730
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   731
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   732
/***********************************************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   733
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   734
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   735
/* If the cvalues of all the prev_il_intructions have the same VALID value, then set the local cvalue to that value, otherwise, set it to NONCONST! */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   736
#define intersect_prev_CVALUE_(dtype, symbol) {                                                                   \
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   737
	symbol->const_value._##dtype = symbol->prev_il_instruction[0]->const_value._##dtype;                      \
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   738
	for (unsigned int i = 1; i < symbol->prev_il_instruction.size(); i++) {                                   \
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   739
		if (!ISEQUAL_CVALUE(dtype, symbol, symbol->prev_il_instruction[i]))                               \
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   740
			{SET_NONCONST(dtype, symbol); break;}                                                     \
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   741
	}                                                                                                         \
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   742
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   743
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   744
static void intersect_prev_cvalues(il_instruction_c *symbol) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   745
	if (symbol->prev_il_instruction.empty())
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   746
		return;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   747
	intersect_prev_CVALUE_(real64, symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   748
	intersect_prev_CVALUE_(uint64, symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   749
	intersect_prev_CVALUE_( int64, symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   750
	intersect_prev_CVALUE_(  bool, symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   751
}
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   752
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   753
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   754
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   755
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   756
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   757
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   758
/***        The constant_folding_c                                   ***/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   759
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   760
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   761
/***********************************************************************/
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   762
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   763
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   764
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   765
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   766
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   767
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   768
constant_folding_c::constant_folding_c(symbol_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   769
    error_count = 0;
568
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   770
    warning_found = false;
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   771
    current_display_error_level = 0;
661
f537c3315f83 Minor changes needed to build with pedantic flag.
Manuele Conti <conti.ma@alice.it>
parents: 648
diff changeset
   772
    il_operand = NULL;
f537c3315f83 Minor changes needed to build with pedantic flag.
Manuele Conti <conti.ma@alice.it>
parents: 648
diff changeset
   773
    search_varfb_instance_type = NULL;
f537c3315f83 Minor changes needed to build with pedantic flag.
Manuele Conti <conti.ma@alice.it>
parents: 648
diff changeset
   774
    prev_il_instruction = NULL;
568
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   775
    
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   776
    /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   777
    symbol_c null_symbol;
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   778
    if (! (std::numeric_limits<real64_t>::is_iec559) )
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   779
        STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 60559 floating point numbers. "
568
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   780
                                                   "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals "
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   781
                                                   "(i.e. constant folding) may themselves be erroneous, although are most probably correct."
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   782
                                                   "However, more likely is the possible existance of overflow/underflow errors that are not detected.");
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   783
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   784
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   785
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   786
constant_folding_c::~constant_folding_c(void) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   787
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   788
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   789
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   790
int constant_folding_c::get_error_count() {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   791
	return error_count;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   792
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   793
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   794
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   795
/*********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   796
/* B 1.2 - Constants */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   797
/*********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   798
/******************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   799
/* B 1.2.1 - Numeric Literals */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   800
/******************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   801
void *constant_folding_c::visit(real_c *symbol) {
576
8368ec909825 Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents: 575
diff changeset
   802
	bool overflow;
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   803
	SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow));
576
8368ec909825 Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents: 575
diff changeset
   804
	if (overflow) SET_OVFLOW(real64, symbol);
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   805
	return NULL;
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   806
}
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   807
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   808
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   809
void *constant_folding_c::visit(integer_c *symbol) {
587
1ecf916cc397 Fix extract_integer_value.
Manuele Conti <conti.ma@alice.it>
parents: 579
diff changeset
   810
	bool overflow;
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   811
	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
588
3d72d09bd40f Add missing set overflow flag.
Manuele Conti <conti.ma@alice.it>
parents: 587
diff changeset
   812
	if (overflow) SET_OVFLOW(int64, symbol);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   813
	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
588
3d72d09bd40f Add missing set overflow flag.
Manuele Conti <conti.ma@alice.it>
parents: 587
diff changeset
   814
	if (overflow) SET_OVFLOW(uint64, symbol);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   815
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   816
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   817
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   818
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   819
void *constant_folding_c::visit(neg_real_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   820
	symbol->exp->accept(*this);
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   821
	DO_UNARY_OPER(real64, -, symbol->exp); CHECK_OVERFLOW_real64(symbol);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   822
	if (IS_OVFLOW(real64, symbol->exp)) SET_OVFLOW(real64, symbol);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   823
	return NULL;
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   824
}
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   825
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   826
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   827
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   828
/* | '-' integer	{$$ = new neg_integer_c($2, locloc(@$));} */
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   829
void *constant_folding_c::visit(neg_integer_c *symbol) {
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   830
	symbol->exp->accept(*this);
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   831
	/* Note that due to syntax restrictions, the value of symbol->exp will always be positive. 
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   832
	 * However, the following code does not depend on that restriction.
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   833
	 */
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   834
	/* The remainder of the code (for example, data type checking) considers the neg_integer_c as a leaf of the
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   835
	 * abstract syntax tree, and therefore simply ignores the values of neg_integer_c->exp.
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   836
	 * For this reason only, and in only this situation, we must guarantee that any 'overflow' situation in 
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   837
	 * the cvalue of neg_integer_c->exp is also reflected back to this neg_integer_c symbol.
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   838
	 * For the rest of the code we do NOT do this, as it would gurantee that a single overflow deep inside
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   839
	 * an expression would imply that the expression itself would also be set to 'overflow' condition.
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   840
	 * This in turn would then have the compiler produce a whole load of error messages where they are not wanted!
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   841
	 */
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   842
	DO_UNARY_OPER(uint64, -, symbol->exp); CHECK_OVERFLOW_uint64_NEG(symbol, symbol->exp);  /* handle the uintv := -0 situation */
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   843
	if (IS_OVFLOW(uint64, symbol->exp)) SET_OVFLOW(uint64, symbol);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   844
	DO_UNARY_OPER( int64, -, symbol->exp); CHECK_OVERFLOW_int64_NEG (symbol, symbol->exp);
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   845
	if (IS_OVFLOW( int64, symbol->exp)) SET_OVFLOW( int64, symbol);
590
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   846
	/* NOTE 1: INT64_MIN = -(INT64_MAX + 1)   ---> assuming two's complement representation!!!
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   847
	 * NOTE 2: if the user happens to want INT_MIN, that value will first be parsed as a positive integer, before being negated here.
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   848
	 * However, the positive value cannot be stored inside an int64! So, in this case, we will get the value from the uint64 cvalue.
643
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   849
	 *
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   850
	 * This same situation is usually considered an overflow (check handle_neg() function). However, here we have a special
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   851
	 * situation. If we do not allow this, then the user would never the able to use the following code:
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   852
	 *  VAR v : LINT; END_VAR
1cc0e1ca2aad Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 640
diff changeset
   853
	 *    v := -9223372036854775809 ; (* - |INT64_MIN| == INT64_MIN *)
590
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   854
	 */
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   855
	// if (INT64_MIN == -INT64_MAX - 1) // We do not really need to check that the platform uses two's complement
621
e3616f6b6959 Remove remaining signed/unsigned comparison error messages when compiling.
Mario de Sousa <msousa@fe.up.pt>
parents: 612
diff changeset
   856
	if (VALID_CVALUE(uint64, symbol->exp) && (GET_CVALUE(uint64, symbol->exp) == (uint64_t)INT64_MAX+1)) {
590
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   857
		SET_CVALUE(int64, symbol, INT64_MIN);
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   858
	}
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   859
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   860
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   861
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   862
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   863
void *constant_folding_c::visit(binary_integer_c *symbol) {
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   864
	bool overflow;
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   865
	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   866
	if (overflow) SET_OVFLOW(int64, symbol);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   867
	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   868
	if (overflow) SET_OVFLOW(uint64, symbol);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   869
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   870
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   871
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   872
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   873
void *constant_folding_c::visit(octal_integer_c *symbol) {
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   874
	bool overflow;
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   875
	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   876
	if (overflow) SET_OVFLOW(int64, symbol);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   877
	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   878
	if (overflow) SET_OVFLOW(uint64, symbol);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   879
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   880
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   881
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   882
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   883
void *constant_folding_c::visit(hex_integer_c *symbol) {
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   884
	bool overflow;
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   885
	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   886
	if (overflow) SET_OVFLOW(int64, symbol);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   887
	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   888
	if (overflow) SET_OVFLOW(uint64, symbol);
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   889
	return NULL;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   890
}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   891
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   892
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   893
/*
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   894
integer_literal:
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   895
  integer_type_name '#' signed_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   896
| integer_type_name '#' binary_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   897
| integer_type_name '#' octal_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   898
| integer_type_name '#' hex_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   899
*/
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   900
// SYM_REF2(integer_literal_c, type, value)
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   901
void *constant_folding_c::visit(integer_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   902
	symbol->value->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   903
	DO_UNARY_OPER( int64, /* none */, symbol->value);
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   904
	DO_UNARY_OPER(uint64, /* none */, symbol->value);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   905
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   906
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   907
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   908
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   909
void *constant_folding_c::visit(real_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   910
	symbol->value->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   911
	DO_UNARY_OPER(real64, /* none */, symbol->value);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   912
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   913
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   914
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   915
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   916
void *constant_folding_c::visit(bit_string_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   917
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   918
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   919
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   920
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   921
void *constant_folding_c::visit(boolean_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   922
	symbol->value->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   923
	DO_UNARY_OPER(bool, /* none */, symbol->value);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   924
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   925
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   926
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   927
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   928
void *constant_folding_c::visit(boolean_true_c *symbol) {
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   929
	SET_CVALUE(bool, symbol, true);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   930
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   931
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   932
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   933
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   934
void *constant_folding_c::visit(boolean_false_c *symbol) {
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   935
	SET_CVALUE(bool, symbol, false);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   936
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   937
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   938
633
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   939
/************************/
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   940
/* B 1.2.3.1 - Duration */
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   941
/********* **************/
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   942
void *constant_folding_c::visit(fixed_point_c *symbol) {
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   943
	bool overflow;
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   944
	SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow));
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   945
	if (overflow) SET_OVFLOW(real64, symbol);
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   946
	return NULL;
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
   947
}
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   948
774
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   949
/*********************/
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   950
/* B 1.4 - Variables */
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   951
/*********************/
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   952
void *constant_folding_c::visit(symbolic_variable_c *symbol) {
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   953
	std::string varName;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   954
783
3bd2704d9ba9 Remove redundant class for get variable name.
Manuele Conti <conti.ma@alice.it>
parents: 782
diff changeset
   955
	varName = get_var_name_c::get_name(symbol->var_name)->value;
774
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   956
	if (values.count(varName) > 0) {
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   957
		symbol->const_value = values[varName];
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   958
	}
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   959
	return NULL;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   960
}
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   961
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   962
/**********************/
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   963
/* B 1.5.3 - Programs */
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   964
/**********************/
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   965
void *constant_folding_c::visit(program_declaration_c *symbol) {
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   966
	symbol_c *var_name;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   967
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   968
	values.clear(); /* Clear global map */
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   969
	search_var_instance_decl_c search_var_instance_decl(symbol);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   970
	function_param_iterator_c fpi(symbol);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   971
	while((var_name = fpi.next()) != NULL) {
783
3bd2704d9ba9 Remove redundant class for get variable name.
Manuele Conti <conti.ma@alice.it>
parents: 782
diff changeset
   972
		std::string varName = get_var_name_c::get_name(var_name)->value;
774
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   973
		symbol_c   *varDecl = search_var_instance_decl.get_decl(var_name);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   974
		values[varName] = varDecl->const_value;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   975
	}
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   976
	/* Add all variables declared into Values map and put them to initial value */
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   977
	symbol->function_block_body->accept(*this);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   978
	return NULL;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
   979
}
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   980
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   981
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   982
/****************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   983
/* B.2 - Language IL (Instruction List) */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   984
/****************************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   985
/***********************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   986
/* B 2.1 Instructions and Operands */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   987
/***********************************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   988
/* Not needed, since we inherit from iterator_visitor_c */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   989
/*| instruction_list il_instruction */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   990
// SYM_LIST(instruction_list_c)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   991
// void *constant_folding_c::visit(instruction_list_c *symbol) {}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   992
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   993
/* | label ':' [il_incomplete_instruction] eol_list */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   994
// SYM_REF2(il_instruction_c, label, il_instruction)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   995
// void *visit(instruction_list_c *symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   996
void *constant_folding_c::visit(il_instruction_c *symbol) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   997
	if (NULL == symbol->il_instruction) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   998
		/* This empty/null il_instruction does not change the value of the current/default IL variable.
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
   999
		 * So it inherits the candidate_datatypes from it's previous IL instructions!
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1000
		 */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1001
		intersect_prev_cvalues(symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1002
	} else {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1003
		il_instruction_c fake_prev_il_instruction = *symbol;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1004
		intersect_prev_cvalues(&fake_prev_il_instruction);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1005
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1006
		if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1007
		else                                          prev_il_instruction = &fake_prev_il_instruction;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1008
		symbol->il_instruction->accept(*this);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1009
		prev_il_instruction = NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1010
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1011
		/* This object has (inherits) the same cvalues as the il_instruction */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1012
		symbol->const_value = symbol->il_instruction->const_value;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1013
	}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1014
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1015
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1016
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1017
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1018
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1019
void *constant_folding_c::visit(il_simple_operation_c *symbol) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1020
	/* determine the cvalue of the operand */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1021
	if (NULL != symbol->il_operand) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1022
		symbol->il_operand->accept(*this);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1023
	}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1024
	/* determine the cvalue resulting from executing the il_operator... */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1025
	il_operand = symbol->il_operand;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1026
	symbol->il_simple_operator->accept(*this);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1027
	il_operand = NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1028
	/* This object has (inherits) the same cvalues as the il_instruction */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1029
	symbol->const_value = symbol->il_simple_operator->const_value;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1030
	return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1031
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1032
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1033
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1034
/* TODO: handle function invocations... */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1035
/* | function_name [il_operand_list] */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1036
/* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1037
// SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1038
// void *constant_folding_c::visit(il_function_call_c *symbol) {}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1039
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1040
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1041
/* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1042
// SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1043
void *constant_folding_c::visit(il_expression_c *symbol) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1044
  symbol_c *prev_il_instruction_backup = prev_il_instruction;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1045
  
690
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1046
  /* Stage2 will insert an artificial (and equivalent) LD <il_operand> to the simple_instr_list if necessary. We can therefore ignore the 'il_operand' entry! */
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1047
  // if (NULL != symbol->il_operand)
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1048
  //   symbol->il_operand->accept(*this);
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1049
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1050
  if(symbol->simple_instr_list != NULL)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1051
    symbol->simple_instr_list->accept(*this);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1052
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1053
  /* Now do the operation,  */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1054
  il_operand = symbol->simple_instr_list;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1055
  prev_il_instruction = prev_il_instruction_backup;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1056
  symbol->il_expr_operator->accept(*this);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1057
  il_operand = NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1058
  
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1059
  /* This object has (inherits) the same cvalues as the il_instruction */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1060
  symbol->const_value = symbol->il_expr_operator->const_value;
690
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1061
  
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1062
  /* Since stage2 will insert an artificial (and equivalent) LD <il_operand> to the simple_instr_list when an 'il_operand' exists, we know
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1063
   * that if (symbol->il_operand != NULL), then the first IL instruction in the simple_instr_list will be the equivalent and artificial
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1064
   * 'LD <il_operand>' IL instruction.
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1065
   * Just to be cosistent, we will copy the constant info back into the il_operand, even though this should not be necessary!
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1066
   */
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1067
  if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to!
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1068
  if  (NULL != symbol->il_operand)
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1069
    symbol->il_operand->const_value = ((list_c *)symbol->simple_instr_list)->elements[0]->const_value;
6156ee2b4e32 Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents: 667
diff changeset
  1070
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1071
  return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1072
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1073
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1074
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1075
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1076
void *constant_folding_c::visit(il_jump_operation_c *symbol) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1077
  /* recursive call to fill const values... */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1078
  il_operand = NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1079
  symbol->il_jump_operator->accept(*this);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1080
  il_operand = NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1081
  /* This object has (inherits) the same cvalues as the il_jump_operator */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1082
  symbol->const_value = symbol->il_jump_operator->const_value;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1083
  return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1084
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1085
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1086
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1087
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1088
/* FB calls leave the value in the accumulator unchanged */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1089
/*   il_call_operator prev_declared_fb_name
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1090
 * | il_call_operator prev_declared_fb_name '(' ')'
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1091
 * | il_call_operator prev_declared_fb_name '(' eol_list ')'
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1092
 * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1093
 * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1094
 */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1095
/* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1096
// SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1097
void *constant_folding_c::visit(il_fb_call_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1098
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1099
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1100
/* TODO: handle function invocations... */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1101
/* | function_name '(' eol_list [il_param_list] ')' */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1102
/* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1103
// SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1104
// void *constant_folding_c::visit(il_formal_funct_call_c *symbol) {return NULL;}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1105
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1106
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1107
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1108
/* Not needed, since we inherit from iterator_visitor_c */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1109
//  void *constant_folding_c::visit(il_operand_list_c *symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1110
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1111
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1112
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1113
/* | simple_instr_list il_simple_instruction */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1114
/* This object is referenced by il_expression_c objects */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1115
void *constant_folding_c::visit(simple_instr_list_c *symbol) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1116
  if (symbol->n <= 0)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1117
    return NULL;  /* List is empty! Nothing to do. */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1118
    
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1119
  for(int i = 0; i < symbol->n; i++)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1120
    symbol->elements[i]->accept(*this);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1121
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1122
  /* This object has (inherits) the same cvalues as the il_jump_operator */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1123
  symbol->const_value = symbol->elements[symbol->n-1]->const_value;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1124
  return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1125
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1126
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1127
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1128
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1129
// SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1130
void *constant_folding_c::visit(il_simple_instruction_c *symbol) {
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1131
  if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1132
  if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1133
  else                                          prev_il_instruction = symbol->prev_il_instruction[0];
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1134
  symbol->il_simple_instruction->accept(*this);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1135
  prev_il_instruction = NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1136
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1137
  /* This object has (inherits) the same cvalues as the il_jump_operator */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1138
  symbol->const_value = symbol->il_simple_instruction->const_value;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1139
  return NULL;
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1140
}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1141
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1142
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1143
/*
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1144
    void *visit(il_param_list_c *symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1145
    void *visit(il_param_assignment_c *symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1146
    void *visit(il_param_out_assignment_c *symbol);
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1147
*/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1148
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1149
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1150
/*******************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1151
/* B 2.2 Operators */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1152
/*******************/
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1153
void *constant_folding_c::visit(   LD_operator_c *symbol) {return handle_move(symbol, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1154
void *constant_folding_c::visit(  LDN_operator_c *symbol) {return handle_not (symbol, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1155
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1156
/* NOTE: we are implementing a constant folding algorithm, not a constant propagation algorithm.
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1157
 *       For the constant propagation algorithm, the correct implementation of ST(N)_operator_c would be...
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1158
 */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1159
//void *constant_folding_c::visit(   ST_operator_c *symbol) {return handle_move(il_operand, symbol);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1160
//void *constant_folding_c::visit(  STN_operator_c *symbol) {return handle_not (il_operand, symbol);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1161
void *constant_folding_c::visit(   ST_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1162
void *constant_folding_c::visit(  STN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1163
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1164
/* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand>
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1165
 *              NOT [<il_operand>]
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1166
 *       However, it does not define the semantic of the NOT operation when the <il_operand> is specified.
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1167
 *       We therefore consider it an error if an il_operand is specified! This error will be caught elsewhere!
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1168
 */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1169
void *constant_folding_c::visit(  NOT_operator_c *symbol) {return handle_not(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1170
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1171
/* NOTE: Since we are only implementing a constant folding algorithm, and not a constant propagation algorithm,
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1172
 *       the following IL instructions do not change/set the value of the il_operand!
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1173
 */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1174
void *constant_folding_c::visit(    S_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1175
void *constant_folding_c::visit(    R_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1176
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1177
/* FB calls leave the value in the accumulator unchanged */
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1178
void *constant_folding_c::visit(   S1_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1179
void *constant_folding_c::visit(   R1_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1180
void *constant_folding_c::visit(  CLK_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1181
void *constant_folding_c::visit(   CU_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1182
void *constant_folding_c::visit(   CD_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1183
void *constant_folding_c::visit(   PV_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1184
void *constant_folding_c::visit(   IN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1185
void *constant_folding_c::visit(   PT_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1186
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1187
void *constant_folding_c::visit(  AND_operator_c *symbol) {return handle_and (symbol, prev_il_instruction, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1188
void *constant_folding_c::visit(   OR_operator_c *symbol) {return handle_or  (symbol, prev_il_instruction, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1189
void *constant_folding_c::visit(  XOR_operator_c *symbol) {return handle_xor (symbol, prev_il_instruction, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1190
void *constant_folding_c::visit( ANDN_operator_c *symbol) {       handle_and (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1191
void *constant_folding_c::visit(  ORN_operator_c *symbol) {       handle_or  (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1192
void *constant_folding_c::visit( XORN_operator_c *symbol) {       handle_xor (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1193
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1194
void *constant_folding_c::visit(  ADD_operator_c *symbol) {return handle_add (symbol, prev_il_instruction, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1195
void *constant_folding_c::visit(  SUB_operator_c *symbol) {return handle_sub (symbol, prev_il_instruction, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1196
void *constant_folding_c::visit(  MUL_operator_c *symbol) {return handle_mul (symbol, prev_il_instruction, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1197
void *constant_folding_c::visit(  DIV_operator_c *symbol) {return handle_div (symbol, prev_il_instruction, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1198
void *constant_folding_c::visit(  MOD_operator_c *symbol) {return handle_mod (symbol, prev_il_instruction, il_operand);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1199
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1200
void *constant_folding_c::visit(   GT_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, > );}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1201
void *constant_folding_c::visit(   GE_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, >=);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1202
void *constant_folding_c::visit(   EQ_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, ==);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1203
void *constant_folding_c::visit(   LT_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, < );}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1204
void *constant_folding_c::visit(   LE_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, <=);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1205
void *constant_folding_c::visit(   NE_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, !=);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1206
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1207
void *constant_folding_c::visit(  CAL_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1208
void *constant_folding_c::visit(  RET_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1209
void *constant_folding_c::visit(  JMP_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1210
void *constant_folding_c::visit( CALC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1211
void *constant_folding_c::visit(CALCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1212
void *constant_folding_c::visit( RETC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1213
void *constant_folding_c::visit(RETCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1214
void *constant_folding_c::visit( JMPC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1215
void *constant_folding_c::visit(JMPCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1216
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1217
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
  1218
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
  1219
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
  1220
/***************************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
  1221
/* B.3 - Language ST (Structured Text) */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
  1222
/***************************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
  1223
/***********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
  1224
/* B 3.1 - Expressions */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
  1225
/***********************/
612
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1226
void *constant_folding_c::visit(    or_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_or (symbol, symbol->l_exp, symbol->r_exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1227
void *constant_folding_c::visit(   xor_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_xor(symbol, symbol->l_exp, symbol->r_exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1228
void *constant_folding_c::visit(   and_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_and(symbol, symbol->l_exp, symbol->r_exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1229
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1230
void *constant_folding_c::visit(   equ_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, ==);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1231
void *constant_folding_c::visit(notequ_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, !=);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1232
void *constant_folding_c::visit(    lt_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, < );}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1233
void *constant_folding_c::visit(    gt_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, > );}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1234
void *constant_folding_c::visit(    le_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, <=);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1235
void *constant_folding_c::visit(    ge_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, >=);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1236
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1237
void *constant_folding_c::visit(   add_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_add(symbol, symbol->l_exp, symbol->r_exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1238
void *constant_folding_c::visit(   sub_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_sub(symbol, symbol->l_exp, symbol->r_exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1239
void *constant_folding_c::visit(   mul_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_mul(symbol, symbol->l_exp, symbol->r_exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1240
void *constant_folding_c::visit(   div_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_div(symbol, symbol->l_exp, symbol->r_exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1241
void *constant_folding_c::visit(   mod_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_mod(symbol, symbol->l_exp, symbol->r_exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1242
void *constant_folding_c::visit( power_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_pow(symbol, symbol->l_exp, symbol->r_exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1243
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1244
void *constant_folding_c::visit(   neg_expression_c *symbol) {symbol->  exp->accept(*this); return handle_neg(symbol, symbol->exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1245
void *constant_folding_c::visit(   not_expression_c *symbol) {symbol->  exp->accept(*this); return handle_not(symbol, symbol->exp);}
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1246
c062ff18d04f Constant folding for IL.
Mario de Sousa <msousa@fe.up.pt>
parents: 607
diff changeset
  1247
/* TODO: handle function invocations... */
633
73b56dc69e61 Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents: 621
diff changeset
  1248
// void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {}
774
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1249
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1250
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1251
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1252
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1253
/*********************************/
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1254
/* B 3.2.1 Assignment Statements */
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1255
/*********************************/
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1256
void *constant_folding_c::visit(assignment_statement_c *symbol) {
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1257
	std::string varName;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1258
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1259
	symbol->r_exp->accept(*this);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1260
	symbol->l_exp->const_value = symbol->r_exp->const_value;
783
3bd2704d9ba9 Remove redundant class for get variable name.
Manuele Conti <conti.ma@alice.it>
parents: 782
diff changeset
  1261
	varName = get_var_name_c::get_name(symbol->l_exp)->value;
774
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1262
	values[varName] = symbol->l_exp->const_value;
780
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1263
774
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1264
	return NULL;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1265
}
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1266
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1267
/********************************/
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1268
/* B 3.2.3 Selection Statements */
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1269
/********************************/
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1270
void *constant_folding_c::visit(if_statement_c *symbol) {
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1271
	std::map <std::string, symbol_c::const_value_t> values_incoming;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1272
	std::map <std::string, symbol_c::const_value_t> values_statement_result;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1273
	std::map <std::string, symbol_c::const_value_t> values_elsestatement_result;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1274
	std::map <std::string, symbol_c::const_value_t>::iterator itr;
780
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1275
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1276
	/* Optimize dead code */
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1277
	symbol->expression->accept(*this);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1278
	if (VALID_CVALUE(bool, symbol->expression) && GET_CVALUE(bool, symbol->expression) == false)
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1279
		return NULL;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1280
774
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1281
	values_incoming = values; /* save incoming status */
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1282
	symbol->statement_list->accept(*this);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1283
	values_statement_result = values;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1284
	if (NULL != symbol->else_statement_list) {
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1285
		values = values_incoming;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1286
		symbol->else_statement_list->accept(*this);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1287
		values_elsestatement_result = values;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1288
	} else
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1289
		values_elsestatement_result = values_incoming;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1290
	values.clear();
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1291
	itr = values_statement_result.begin();
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1292
	for ( ; itr != values_statement_result.end(); ++itr) {
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1293
		std::string name = itr->first;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1294
		symbol_c::const_value_t value;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1295
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1296
		if (values_elsestatement_result.count(name) > 0) {
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1297
			symbol_c::const_value_t c1 = itr->second;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1298
			symbol_c::const_value_t c2 = values_elsestatement_result[name];
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1299
			COMPUTE_MEET_SEMILATTICE (real64, c1, c2, value);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1300
			COMPUTE_MEET_SEMILATTICE (uint64, c1, c2, value);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1301
			COMPUTE_MEET_SEMILATTICE ( int64, c1, c2, value);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1302
			COMPUTE_MEET_SEMILATTICE (  bool, c1, c2, value);
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1303
		} else
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1304
			value = values_statement_result[name];
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1305
		values[name] = value;
979af2009d88 Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents: 735
diff changeset
  1306
	}
780
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1307
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1308
	return NULL;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1309
}
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1310
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1311
/********************************/
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1312
/* B 3.2.4 Iteration Statements */
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1313
/********************************/
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1314
void *constant_folding_c::visit(for_statement_c *symbol) {
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1315
	std::map <std::string, symbol_c::const_value_t> values_incoming;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1316
	std::map <std::string, symbol_c::const_value_t> values_statement_result;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1317
	std::map <std::string, symbol_c::const_value_t>::iterator itr;
782
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1318
	std::string varName;
780
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1319
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1320
	values_incoming = values; /* save incoming status */
782
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1321
	symbol->beg_expression->accept(*this);
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1322
	symbol->end_expression->accept(*this);
783
3bd2704d9ba9 Remove redundant class for get variable name.
Manuele Conti <conti.ma@alice.it>
parents: 782
diff changeset
  1323
	varName =  get_var_name_c::get_name(symbol->control_variable)->value;
782
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1324
	values[varName] = symbol->beg_expression->const_value;
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1325
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1326
	/* Optimize dead code */
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1327
	if (VALID_CVALUE(int64, symbol->beg_expression) && VALID_CVALUE(int64, symbol->end_expression) &&
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1328
		  GET_CVALUE(int64, symbol->beg_expression) >    GET_CVALUE(int64, symbol->end_expression))
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1329
		return NULL;
c8cd69801b7e Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents: 781
diff changeset
  1330
780
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1331
	symbol->statement_list->accept(*this);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1332
	values_statement_result = values;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1333
	values.clear();
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1334
	itr = values_statement_result.begin();
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1335
	for ( ; itr != values_statement_result.end(); ++itr) {
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1336
		std::string name = itr->first;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1337
		symbol_c::const_value_t value;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1338
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1339
		if (values_incoming.count(name) > 0) {
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1340
			symbol_c::const_value_t c1 = itr->second;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1341
			symbol_c::const_value_t c2 = values_incoming[name];
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1342
			COMPUTE_MEET_SEMILATTICE (real64, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1343
			COMPUTE_MEET_SEMILATTICE (uint64, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1344
			COMPUTE_MEET_SEMILATTICE ( int64, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1345
			COMPUTE_MEET_SEMILATTICE (  bool, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1346
		} else
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1347
			value = values_statement_result[name];
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1348
		values[name] = value;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1349
	}
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1350
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1351
	return NULL;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1352
}
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1353
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1354
void *constant_folding_c::visit(while_statement_c *symbol) {
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1355
	std::map <std::string, symbol_c::const_value_t> values_incoming;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1356
	std::map <std::string, symbol_c::const_value_t> values_statement_result;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1357
	std::map <std::string, symbol_c::const_value_t>::iterator itr;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1358
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1359
	/* Optimize dead code */
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1360
	symbol->expression->accept(*this);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1361
	if (VALID_CVALUE(bool, symbol->expression) && GET_CVALUE(bool, symbol->expression) == false)
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1362
		return NULL;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1363
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1364
	values_incoming = values; /* save incoming status */
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1365
	symbol->statement_list->accept(*this);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1366
	values_statement_result = values;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1367
	values.clear();
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1368
	itr = values_statement_result.begin();
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1369
	for ( ; itr != values_statement_result.end(); ++itr) {
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1370
		std::string name = itr->first;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1371
		symbol_c::const_value_t value;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1372
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1373
		if (values_incoming.count(name) > 0) {
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1374
			symbol_c::const_value_t c1 = itr->second;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1375
			symbol_c::const_value_t c2 = values_incoming[name];
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1376
			COMPUTE_MEET_SEMILATTICE (real64, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1377
			COMPUTE_MEET_SEMILATTICE (uint64, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1378
			COMPUTE_MEET_SEMILATTICE ( int64, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1379
			COMPUTE_MEET_SEMILATTICE (  bool, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1380
		} else
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1381
			value = values_statement_result[name];
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1382
		values[name] = value;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1383
	}
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1384
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1385
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1386
	return NULL;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1387
}
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1388
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1389
void *constant_folding_c::visit(repeat_statement_c *symbol) {
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1390
	std::map <std::string, symbol_c::const_value_t> values_incoming;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1391
	std::map <std::string, symbol_c::const_value_t> values_statement_result;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1392
	std::map <std::string, symbol_c::const_value_t>::iterator itr;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1393
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1394
	/* Optimize dead code */
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1395
	symbol->expression->accept(*this);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1396
	if (VALID_CVALUE(bool, symbol->expression) && GET_CVALUE(bool, symbol->expression) == false)
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1397
		return NULL;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1398
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1399
	values_incoming = values; /* save incoming status */
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1400
	symbol->statement_list->accept(*this);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1401
	values_statement_result = values;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1402
	values.clear();
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1403
	itr = values_statement_result.begin();
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1404
	for ( ; itr != values_statement_result.end(); ++itr) {
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1405
		std::string name = itr->first;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1406
		symbol_c::const_value_t value;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1407
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1408
		if (values_incoming.count(name) > 0) {
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1409
			symbol_c::const_value_t c1 = itr->second;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1410
			symbol_c::const_value_t c2 = values_incoming[name];
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1411
			COMPUTE_MEET_SEMILATTICE (real64, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1412
			COMPUTE_MEET_SEMILATTICE (uint64, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1413
			COMPUTE_MEET_SEMILATTICE ( int64, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1414
			COMPUTE_MEET_SEMILATTICE (  bool, c1, c2, value);
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1415
		} else
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1416
			value = values_statement_result[name];
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1417
		values[name] = value;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1418
	}
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1419
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1420
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1421
	return NULL;
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1422
}
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1423
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1424
9fbdf8a7430e Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents: 776
diff changeset
  1425