Polaris: Expression.h Source File

Expression.h

Go to the documentation of this file.
00001 ///
00002 #ifndef _EXPRESSION_H
00003 #define _EXPRESSION_H
00004 ///
00005 /// \class Expression 
00006 /// \brief the base class for all expressions
00007 /// \defgroup Polaris
00008 /// \ingroup Polaris
00009 ///  Expression
00010 /// \see Expression/Expression.h
00011 /// \see Expression/Expression.h
00012 /// \see Expression/expr_funcs.h
00013 /// \see Expression/Expression.cc
00014 ///
00015 /// \endcode
00016 /// \section Overview Overview
00017 /// Class Expression is the base type for all expressions.  This class,
00018 /// and its subclasses, offer facilities for the creation, comparison
00019 /// and simplification of expressions.
00020 ///
00021 /// \endcode
00022 /// \section Description Description
00023 /// The Expression class is an abstract base class for all expressions
00024 /// that may occur in a Fortran program.  Since it is abstract,
00025 /// Expression objects cannot be created, only subclasses of
00026 /// Expressions.
00027 ///
00028 /// All classes in the Expresion heirarchy share some common fields.
00029 /// The two most important of these fields are op() and type().
00030 /// The op() field returns the kind of expression (e.g. + or *)
00031 /// while the type() field returns the type of the expresion
00032 /// (e.g. INTEGER or REAL).  The op() field is needed to determine
00033 /// which subclass the current Expression object belongs to,
00034 /// and hence what methods it will or will not accept.
00035 ///
00036 /// The classes in the Expression heirarchy also share some common
00037 /// methods.  The clone() method returns a copy of the expression.
00038 /// The method arg_list() returns a reference to a List of
00039 /// subexpressions in the expression.  The function simplify()
00040 /// simplifies takes an expression and returns a simplified version
00041 /// of it.  There also exists a collection of comparison methods
00042 /// (operator ==(), compare(), and match()) which compare two
00043 /// expressions.
00044 ///
00045 /// To ease the construction of expressions, a collection of
00046 /// functions have been provided which creates a properly typed
00047 /// expression from the given arguments.  See expr_funcs.h 
00048 /// for a description of these functions.
00049 ///
00050 /// \endcode
00051 /// \section Expression Expression creation
00052 /// Unlike most other classes in Polaris, new Expression objects are
00053 /// usually created by calling one of the functions in expr_func.h,
00054 /// rather than calling the constructors directly.  It is strongly
00055 /// recommended that the user call these functions rather than the
00056 /// constructors, since these functions will also properly initialize
00057 /// the type and op (expression class) fields of the created
00058 /// expressions.
00059 ///
00060 /// A few examples of the creation of some common expressions is
00061 /// shown below.  The left-hand-side of these examples are C++ code
00062 /// which creates the expression on the right-hand-side.
00063 /// The variables var1 and var2 are assumed to be Symbol objects.
00064 /// The variable max is assumed to be the symbol for the MAX intrinsic.
00065 /// \code
00066 ///   constant(2)  -->  2
00067 ///   id(var1)  -->  var1
00068 ///   add(id(var1), constant(3))  -->  var1 + 3
00069 ///   add(expr_list(id(var1), id(var2), constant(3))) --> var1 + var2 + 3
00070 ///   sub(id(var1), constant(1))  -->  var1 - 1
00071 ///   mul(id(var1), constant(2))  -->  var1 * 2
00072 ///   mul(expr_list(id(var1), id(var2), constant(3))) --> var1 * var2 * 3
00073 ///   div(id(var1), constant(4))  -->  var1 / 4
00074 ///   array_reference(id(var1), comma(id(var2), constant(3)))  -->  var1[var2,3]
00075 ///   intrinsic_call(max, comma(id(var1), constant(2)))  -->  MAX(var1, 2)
00076 ///
00077 /// \endcode
00078 /// \section Expression Expression simplification
00079 /// One of the most common operations performed on expressions is
00080 /// expression simplification by means of the simplify() function.  The
00081 /// simplifier is capable of performing constant folding, symbolic
00082 /// simplification of integer division expressions, distribution, and
00083 /// the combining or cancellation of like terms.  When done, arithmetic
00084 /// expressions should be in a sum of products form and logical
00085 /// expressions should be in conjuctive normal form.
00086 ///
00087 /// More specifically, the simplifier can perform the following
00088 /// optimizations:
00089 /// \code
00090 ///  - Constant folding of +, -, *, /, **, ABS, MAX, MIN, MOD, .AND.,
00091 ///    .OR., NOT., and relational operators.
00092 ///    (e.g.  2 * 3 + 4  --> 10,  3 .LE. 0  -->  .FALSE.)
00093 ///  - Convert subtraction expressions into addition expressions.
00094 ///    (e.g.  a - b  -->  a + (-1)*b).
00095 ///  - Convert unary minus into multiplication by -1.
00096 ///    (e.g.  -b  --> (-1)*b)
00097 ///  - Elimination of unary plus and unnecessary parentheses.
00098 ///    (e.g. +b  -->  b,  ((a) + ((b)))  -->  a + b)
00099 ///  - Association of args of +, *, .AND, .OR., MIN, and MAX operators.
00100 ///    (e.g. (a + (b + (c + d)))  -->  a + b + c + d,
00101 ///          MAX(a, MAX(b, c))  -->  MAX(a, b, c))
00102 ///  - Distribution of multiplication expressions to form sums of
00103 ///    products.
00104 ///    (e.g. (a + b)*(c + d)  -->  a*c + a*d + b*c + b*d)
00105 ///  - Combination of terms.
00106 ///    (e.g. a + b + 2*a - b  --> 3*a,
00107 ///          a*(a**2)  -->  a**3,
00108 ///          MIN(a + 2, a + 5, 0)  -->  MIN(a + 2, 0))
00109 ///  - Symbolic simplification of division expressions, where the
00110 ///    denominator is an integer, variable, or an multiplication
00111 ///    expression containing integers or variables.
00112 ///    (e.g.  (a*b)/(b*c)  -->  a/c,  (4*a + 10)/6  -->  (2*a + 5)/3)
00113 ///  - Divisible terms are pulled out of division expressions with
00114 ///    integer denominators.
00115 ///    (e.g.  (8*a + 10*b)/5   -->  (8*a)/5 + 2*b)
00116 ///  - Similar facilities for modulo expressions.
00117 ///    (e.g.  MOD(a*b, b*c)  -->  b*MOD(a, c),
00118 ///           MOD(4*a + 10, 6)  -->  2*MOD(2*a + 5, 3),
00119 ///           MOD(8*a + 10*b, 5)  -->  MOD(8*a, 5))
00120 ///  - Recognition of division expressions whose integer denominator
00121 ///    evenly divides the numerator.
00122 ///    (e.g.  2*((i**2 - i)/2)  -->  i**2 + (-1)*i,
00123 ///           (i**2 + i)/2 - (i**2 - i)/2  -->  i)
00124 ///  - Recognition of expressions containing Infinity.
00125 ///    (e.g.  Infty + 1  -->  Infty,  MIN(Infty, a)  -->  a)
00126 ///  - Distribution/removal of .NOT. operations
00127 ///    (e.g.  .NOT. (a .OR. b)  -->  .NOT. a .AND. .NOT. b,
00128 ///           .NOT. (a .LT. b)  -->  a .GE. b)
00129 ///  - Distribution of .OR. expressions into conjunctive normal form.
00130 ///    (e.g.  (a .AND. b) .OR. (c .AND. d)
00131 ///           -->  (a.OR.c).AND.(a.OR.d).AND.(b.OR.c).AND.(b.OR.d))
00132 ///  - Combination of logical operators
00133 ///    (e.g.  (a .LE. b) .AND. (a .LE. b+1)  -->  a .LE. b
00134 ///           (a .LE. b) .AND. (a .GE. b)  -->  a .EQ. b
00135 ///           (a .LE. b) .AND. (a .GT. b)  -->  .FALSE.
00136 ///           c .AND. c  --> c,  c .AND. .NOT.c  -->  .FALSE.)
00137 ///
00138 /// \endcode
00139 /// Some of the optimizations that the simplifier CANNOT do are:
00140 /// \code
00141 ///  - Constant folding of real or complex expressions.
00142 ///  - Factoring of arbitrary expressions.
00143 ///    (e.g. (n*n + 2*n + 1)/(n + 1)  -->  n + 1)
00144 ///  - Simplification across subterms of logical expressions in
00145 ///    conjunctive normal form.
00146 ///    (e.g. (A .OR. B) .AND. A  --> A,
00147 ///          (A .OR. B) .AND. .NOT.A and .NOT.B  -->  .FALSE.)
00148 ///
00149 /// \endcode
00150 /// \section Examples Examples
00151 /// Here is an example of an function that substitutes all
00152 /// occurrences of a given variable with a given expression.
00153 /// This example performs two of the most common operations
00154 /// upon expressions; visiting all subexpressions of an expression,
00155 /// and modifying selective parts of an expression.
00156 ///
00157 /// \code
00158 ///    Expression *
00159 ///    subst_var(Expression *expr, const Symbol &var,
00160 ///              const Expression &value)
00161 ///    {
00162 ///        if (expr->op() == ID_OP) {
00163 ///            if (&expr->symbol() == &var) {
00164 ///                delete expr;
00165 ///                return value.clone();
00166 ///            }
00167 ///        }
00168 ///        else {
00169 ///            Iterator<Expression> iter = expr->arg_list();
00170 ///
00171 ///            for ( ; iter.valid(); ++iter)
00172 ///                iter.assign() = subst_var(iter.pull(), var, value);
00173 ///        }
00174 ///
00175 ///        return expr;
00176 ///    }
00177 ///
00178 /// \endcode
00179 /// \section Known Known bugs or limitations
00180 /// The operator = () methods only copy the arguments of the
00181 /// current class.  None of the superclass's arguments are copied.
00182 /// Use at your own risk.
00183 ///
00184 /// Currently, the simplifier only recognizes the intrinsics
00185 /// MIN, MAX, ABS, and MOD.  It will not recognize the related
00186 /// intrinsics such as MIN0 and MAX1.
00187 ///
00188 /// Currently, the method structures_ok() is not implemented.
00189 ///
00190 class ProgramUnit;
00191 class Symbol;
00192 class Statement;
00193 class ExprTable;
00194 class Expression;
00195 class ExtraInfo;
00196 class String;
00197 class Symtab;
00198 class DDgraph;
00199 class Format;
00200 class VDL;
00201 
00202 #ifdef POLARIS_GNU_PRAGMAS
00203 #pragma interface
00204 #endif
00205 
00206 #include "ClassNames.h"
00207 #include <strstream.h>
00208 
00209 #include "../Type.h"
00210 #include "../Collection/List.h"
00211 #include "../Collection/Iterator.h"
00212 #include "../BinRep.h"
00213 #include "../Collection/RefList.h"
00214 #include "../Boolean.h"
00215 
00216 #include "ExprSignature.h"
00217 #include "replace.h"
00218 
00219 typedef unsigned char Arc_type;
00220 
00221 ///< Types of operators
00222 
00223 enum OP_TYPE {
00224     DELETED_EXPRESSION_OP = 0, ///< Indicates this expression has been deleted
00225 
00226     INTEGER_CONSTANT_OP,       ///< IntConstExpr.h          1
00227     REAL_CONSTANT_OP,          ///< RealConstExpr.h         1.0
00228     STRING_CONSTANT_OP,        ///< StringConstExpr.h       'foo'
00229     LOGICAL_CONSTANT_OP,       ///< LogicalConstExpr.h      .TRUE.
00230     HOLLERITH_CONSTANT_OP,     ///< HollerithConstExpr.h    H3foo
00231     COMPLEX_OP,                ///< ComplexExpr.h           (0., 1.)
00232     ARRAY_REF_OP,              ///< ArrayRefExpr.h          a(i)
00233     SUBSTRING_OP,              ///< SubStringExpr.h         'foo'(1:3)
00234     FUNCTION_CALL_OP,          ///< FunctionCallExpr.h      foo(n)
00235     INTRINSIC_CALL_OP,         ///< IntrinsicCallExpr.h     MIN(a, b)
00236     LAMBDA_CALL_OP,            ///< LambdaCallExpr.h        (#1 + #2)(a, b)
00237     ARG_OP,                    ///< ArgNumberExpr.h         #1
00238     RETURN_OP,                 ///< ReturnStarExpr.h        *1
00239     LABEL_OP,                  ///< LabelExpr.h             100
00240     IO_STAR_OP,                ///< IOStarExpr.h            *
00241     FORMAT_OP,                 ///< FormatExpr.h            100
00242     ID_OP,                     ///< IDExpr.h                n
00243     U_PLUS_OP,                 ///< UnaryExpr.h             +a
00244     U_MINUS_OP,                ///< UnaryExpr.h             -a
00245     NOT_OP,                    ///< UnaryExpr.h             .NOT. a
00246     EQ_OP,                     ///< BinaryExpr.h            a .EQ. b
00247     NE_OP,                     ///< BinaryExpr.h            a .NE. b
00248     LT_OP,                     ///< BinaryExpr.h            a .LT. b
00249     LE_OP,                     ///< BinaryExpr.h            a .LE. b
00250     GT_OP,                     ///< BinaryExpr.h            a .GT. b
00251     GE_OP,                     ///< BinaryExpr.h            a .GE. b
00252     SUB_OP,                    ///< BinaryExpr.h            a - b
00253     DIV_OP,                    ///< BinaryExpr.h            a / b
00254     INTDIV_OP,                 ///< BinaryExpr.h            a /# b
00255     RATDIV_OP,                 ///< BinaryExpr.h            a /% b
00256     EXP_OP,                    ///< BinaryExpr.h            a ** b
00257     CONCAT_OP,                 ///< NonBinaryExpr.h         a // b
00258     ADD_OP,                    ///< NonBinaryExpr.h         a + b + c
00259     MULT_OP,                   ///< NonBinaryExpr.h         a * b * c
00260     OR_OP,                     ///< NonBinaryExpr.h         a .OR. b .OR. c
00261     AND_OP,                    ///< NonBinaryExpr.h         a .AND. b .AND. c
00262     EQV_OP,                    ///< NonBinaryExpr.h         a .EQV. b .EQV. c
00263     NEQV_OP,                   ///< NonBinaryExpr.h         a .NEQV. b .NEQV. c
00264     DO_OP,                     ///< DoExpr.h                (a(i) i=1,100)
00265     EQUAL_OP,                  ///< EqualExpr.h             i=1,100
00266     COMMA_OP,                  ///< CommaExpr.h             a, b, c
00267     COLON_OP,                  ///< NonBinaryExpr.h         a:b:c
00268     PAREN_OP,                  ///< UnaryExpr.h             (a)
00269     OMEGA_OP,                  ///< OmegeExpr.h             
00270     REPSTAR_OP,                ///< BinaryExpr.h            1.0 * 100
00271                                ///<  (Repeat factor for DATA statement constants)
00272     TABLE_ENTRY,               ///< TableExpr.h   (Only for expr table entries)
00273     STMT_LABEL_OP,             ///< StmtLabelExpr.h         StmtLabel("S35")
00274                                ///<  (Used only internally for Stmt conversion)
00275     KEY_OP,                    ///< KeyExpr.h               MASK=A
00276     KEYPAIR_OP,                ///< BinaryExpr.h            MASK=A
00277     INFINITY_OP,               ///< InfinityExpr.h          Inf
00278 
00279     ALPHA_OP,                  ///< GSAExpr.h               ALPHA(...)
00280     GAMMA_OP,                  ///< GSAExpr.h               GAMMA(a .LT. b, c, d)
00281     MU_OP,                     ///< GSAExpr.h               MU(c, d)
00282     THETA_OP,                  ///< GSAExpr.h               GAMMA(c, d)
00283     ETA_OP,                    ///< GSAExpr.h               ETA(i .GT. n, c, d)
00284     BETA_OP,                   ///< Guobin: Added for array SSA
00285 
00286     DISTRIBUTE_OP,             ///<_ Distribution           A(2:BLOCK(5),:BLOCK)
00287 
00288     RANGE_OP,                  ///< Used to represent a range    [1:N]
00289 
00290     ///< Wild Card Types
00291 
00292     ANY_EXPR_SUBSET_WC, ///< MUST be first wildcard type!!!!
00293     
00294     FORBOL_EXPR_WC,            ///< Used only by Forbol
00295     FORBOL_STMT_WC,            ///< Used only by Forbol
00296     FORBOL_EXPR_PMF_WC,        ///< Used only by Forbol
00297     FORBOL_STMT_PMF_WC,        ///< Used only by Forbol
00298     FORBOL_BLOCK_PMF_WC,       ///< Used only by Forbol
00299     
00300     AND_WC,
00301     OR_WC,
00302     NOT_WC,
00303     CONTAINS_WC,
00304     SUCH_THAT_WC,
00305     ANY_WC,
00306     ANY_EXPR_OF_TYPE_WC,
00307     ANY_CONST_WC,
00308     ANY_INT_CONST_WC,
00309     ANY_HOLLERITH_CONST_WC,
00310     ANY_LOGICAL_CONST_WC,
00311     ANY_REAL_CONST_WC,
00312     ANY_STRING_CONST_WC,
00313     ANY_ARRAY_REF_WC,
00314     ANY_BINARY_WC,
00315     ANY_COMMA_WC,
00316     ANY_COMPLEX_WC,
00317     ANY_ID_WC,
00318     ANY_FUNCTION_CALL_WC,
00319     ANY_INTRINSIC_CALL_WC,
00320     ANY_NON_BINARY_WC,
00321     ANY_SUBSTRING_WC,
00322     ANY_UNARY_WC,
00323     ANY_INT_WC,
00324     ANY_REAL_WC,
00325 
00326     ///< This last one is simply for consistency checking by the compiler.
00327     ///< It should not be used externally.
00328 
00329     NUM_OP_TYPES
00330 };
00331 
00332 class Expression : public Listable {
00333     friend class _find_info;
00334     friend class DDgraph;
00335     friend ostream & operator << (ostream &, const Expression &);
00336 
00337  public:
00338     inline Expression(OP_TYPE optype, const Type & exptype);
00339     ///< Create an expression of the given kind and type.
00340 
00341     inline Expression(const Expression & e);
00342     virtual ~Expression();
00343     
00344     virtual Expression *clone() const = 0;
00345     ///< Return a copy of myself.
00346 
00347     virtual Listable *listable_clone() const;
00348     ///< Like clone(), except returned object is of type Listable.
00349 
00350     inline OP_TYPE  op() const;
00351     inline void     op(const OP_TYPE o);
00352     ///< Reference the Expression's operation type.
00353 
00354     inline const Type   & type() const;
00355     inline Type   * type_ref() const;
00356     ///< Return the type of the Expression.
00357     inline void     type(const Type &exptype);
00358     ///< Change the type of the Expression.
00359 
00360     virtual Boolean     args_are_non_null() const;
00361     ///< Return true if the unary or binary expression doesn't have any
00362     ///< non-NULL subexpression arguments.
00363 
00364     virtual const List<Expression> &arg_list() const;
00365     virtual List<Expression> &arg_list();
00366     ///< Return a reference to list of all expression arguments of
00367     ///< myself.
00368 
00369     virtual const RefList<Expression> *arg_refs() const;
00370     ///< Return a list of references to all expression arguments of
00371     ///< myself.  This method is outdated.  Use arg_list() instead.
00372 
00373     BinRep         *overflow_ref() const;
00374     ///< Return a reference to my overflow field.
00375 
00376     virtual void    relink_eptrs(ProgramUnit & p);
00377     ///< Change the pointers in Expression elements
00378     ///< (IDExprs) to point into the given ProgramUnit.
00379 
00380     inline Boolean is_wildcard() const;
00381     ///< Returns True iff this Expression is some kind of wildcard
00382     ///< (note that this is NOT a check for whether or not
00383     ///< an Expression contains a wildcard, but rather whether
00384     ///< the top level itself IS a wildcard)
00385 
00386     virtual Boolean is_side_effect_free(void) const;
00387     ///< Return True if expression is side-effect free.  That is,
00388     ///< if the expression does not contain any function calls.
00389 
00390     friend Expression *sym_factors(const Expression &sum_of_prods, List<Expression> &factors);
00391     ///< Factor the given sum-of-products expression and return a list
00392     ///< of factors (ID_OPs), and also the Expression resulting from
00393     ///< dividing sum_of_prods by the factors as the function result.
00394 
00395     friend Expression *simplify(Expression *);
00396     ///< Simplify the given expression, and return the simplified
00397     ///< result.  Ownership of the given expression is passed to the
00398     ///< simplify routine, which may modify or delete it.
00399 
00400     virtual Expression *member_ref(const Symbol *);
00401     ///< If Expression is an variable with the given name or a
00402     ///< multiplication expression containing such a variable. return
00403     ///< the IDExpr representing that variable.  Otherwise, return
00404     ///< NULL.
00405 
00406     virtual const Symbol *base_variable_ref() const;
00407     virtual Symbol *base_variable_ref();
00408     ///< If the expression is an array reference, identifier, or
00409     ///< substring, return the Symbol name of that expression.
00410     ///< Otherwise, return NULL.
00411 
00412     friend Boolean  is_evenly_divisible(const Expression &expr, int divisor);
00413     ///< Return true if the given expression is evenly divisible by the
00414     ///< given integer for any value assigned to any variable in the
00415     ///< given expression.  Note: This function assumes that the
00416     ///< expression has already been simplified.
00417 
00418     inline Boolean  operator == (const Expression & e) const;
00419     inline Boolean  operator == (Expression & e);
00420     ///< Compare two expressions by structure (including the possibility
00421     ///< of wildcards).  If two subexpressions are otherwise equal but
00422     ///< may have side effects, they are considered UNEQUAL.
00423     ///< cf. match() Note: There are two reasons that neither 'e' nor
00424     ///< this method are declared 'const': 1) The matching algorithm
00425     ///< involves sorting nonbinary arguments and assigning value
00426     ///< numbers (otherwise no restructuring takes place), 2) if
00427     ///< wildcards are present with hooks, it is possible to
00428     ///< destructively access parts of either expression after a match
00429     ///< has been found.
00430 
00431     inline Boolean  operator != (Expression & e);
00432     ///< Returns true iff operator==() returns false
00433 
00434     inline Boolean  match(Expression & e);
00435     ///< Compare two expressions by structure (including the possibility
00436     ///< of wildcards).  If two expressions are equal in structure, they
00437     ///< are considered equal REGARDLESS of whether or not either may
00438     ///< contain side effects (this is in contrast to the way in which
00439     ///< operator==() operators).  For instance, if `a' is an Expression
00440     ///< * representing the Fortran expression `FUN(1)' and `b' is an
00441     ///< Expression * representing the Fortran expression `FUN(1)', then
00442     ///< the C++ expression
00443     ///<
00444     ///<   *a == *b
00445     ///<
00446     ///< will return False while
00447     ///<
00448     ///<   a->match(*b)
00449     ///<
00450     ///< will return True.  In all other respects, match() is equivalent
00451     ///< to operator==().
00452 
00453     friend void        _remove_duplicates(List<Expression>&);
00454 
00455     inline const ExprSignature & signature() const;
00456     ///< Return a reference to the signature for this Expressions.
00457     ///< Signatures are used by the simplifier and comparison operators
00458     ///< to compare expressions.  If two expressions have different
00459     ///< signatures, then the two expressions are different.
00460 
00461     virtual const ExprSignature & update_signature();
00462     ///< Update my signature and return it.  It is assumed that the
00463     ///< signatures of my subexpressions are correct.  Also call
00464     ///< _clear() on all wildcard descendants.
00465 
00466     const ExprSignature & create_signature();
00467     ///< Update my signature and all my subexpression's signatures, then
00468     ///< return my new signature.
00469 
00470     const ExprSignature & standardize();
00471     ///< Put myself and all my subexpressions in standard form update my
00472     ///< signature and all my subexpression's signatures, then return my
00473     ///< new signature.  (An expression is in standard form if all
00474     ///< commutative subexpressions have their arguments placed in a
00475     ///< canonical form.)
00476 
00477     int             compare(const Expression &ex) const; 
00478     ///< Return either -1, 0, or 1, indicating that the other expression
00479     ///< is less than, equal, or greater than myself.  The less than or
00480     ///< greater than relationship has no relation to the symbolic
00481     ///< meaning of the expresion.  (For example, this function may
00482     ///< indicate that x + 1 < x < x + 2.)
00483 
00484     virtual int     node_compare(const Expression &ex) const; 
00485     ///< Assuming that the the two expressions have the same operation
00486     ///< and expression type, return either -1, 0, or 1, indicating that
00487     ///< the other expression is less than, equal, or greater than
00488     ///< myself.
00489 
00490     virtual void    print(ostream &) const;
00491     ///< Print out myself.
00492 
00493     virtual void    print_debug(ostream & o, Boolean debug) const = 0;
00494     ///< debug indicates whether it should contain extra fields
00495 
00496     virtual int     structures_OK() const = 0;
00497     ///< Return 1 if my structures are in a valid state.
00498 
00499     virtual void    convert(BinRep &, Symtab &) = 0;
00500     ///< Read in the values of my fields and my subexpressions from the
00501     ///< given BinRep object.  Convert(BinRep) expects the BinRep to be
00502     ///< referencing an expression set of the same type as the
00503     ///< expression. On return, all data from the expression set has
00504     ///< been inserted into the appropriate fields in the expression
00505     ///< object. NOTE that this converts the expression to an
00506     ///< intermediate form which may contain TableExpr objects.
00507  
00508     virtual int     exchange_expr( VDL & vdl );
00509     ///< Create a node in the "expression" member and return the index.
00510 
00511     Expression     *tableEntry(int);
00512     ///< TableEntry takes an integer and returns a pointer to an
00513     ///< Expression object which represents another entry in the
00514     ///< expression table.  This intermediate table-entry expression
00515     ///< object is an intermediate form which is only used in converting
00516     ///< expressions from table form to expression object form and
00517     ///< should not be used to represent actual expressions.
00518 
00519     virtual const String & str_data() const;
00520     virtual String & str_data();
00521     virtual const char *data_ref() const;
00522     virtual void    data(const char *);
00523     ///< Methods specified in derived class StringExpr.h and its
00524     ///< subclasses.
00525 
00526     virtual int     value() const;
00527     virtual void    value(int);
00528     ///< Methods specified in derived classes ArgNumberExpr.h and
00529     ///< IntConstExpr.h
00530 
00531     virtual const Expression & array() const;
00532     virtual Expression & array();
00533     virtual void    array(Expression *);
00534     virtual const Expression & subscript() const;
00535     virtual Expression & subscript();
00536     virtual void    subscript(Expression *);
00537     ///< Methods specified in derived class ArrayRefExpr.h
00538 
00539     virtual const Expression & left_guarded() const;
00540     virtual Expression & left_guarded();
00541     virtual void    left(Expression *);
00542     virtual Boolean left_valid() const;
00543     virtual Expression *grab_left();
00544     virtual const Expression & right_guarded() const;
00545     virtual Expression & right_guarded();
00546     virtual void    right(Expression *);
00547     virtual Boolean right_valid() const;
00548     virtual Expression *grab_right();
00549     ///< Methods specified in derived class BinaryExpr.h
00550 
00551     virtual const Expression & real_part() const;
00552     virtual Expression & real_part();
00553     virtual void    real_part(Expression *);
00554     virtual const Expression & imaginary_part() const;
00555     virtual Expression & imaginary_part();
00556     virtual void    imaginary_part(Expression *);
00557     ///< Methods specified in derived class ComplexExpr.h
00558 
00559     virtual const Expression & iolist() const;
00560     virtual Expression & iolist();
00561     virtual void    iolist(Expression *);
00562     virtual const Expression & iterator() const;
00563     virtual Expression & iterator();
00564     virtual void    iterator(Expression *);
00565     ///< Methods specified in derived class DoExpr.h
00566 
00567     virtual const Expression & index_id() const;
00568     virtual Expression & index_id();
00569     virtual void    index_id(Expression *);
00570     virtual const Expression & iteration_space() const;
00571     virtual Expression & iteration_space();
00572     virtual void    iteration_space(Expression *);
00573     ///< Methods specified in derived class EqualExpr.h
00574     
00575     virtual const Format & format() const;
00576     virtual Format & format();
00577     virtual void    format(Format & format);
00578     ///< Methods specified in derived class FormatExpr.h
00579     
00580     virtual const Expression & function() const;
00581     virtual Expression & function();
00582     virtual void    function(Expression *);
00583     ///< Methods specified in derived class FunctionCallExpr.h
00584 
00585     virtual const Expression & parameters_guarded() const;
00586     virtual Expression & parameters_guarded();
00587     virtual void    parameters(Expression *);
00588     virtual Boolean parameters_valid() const;
00589     ///< Methods specified in derived classes FunctionCallExpr.h
00590     ///< IntrinsicCallExpr.h, and LambdaCallExpr.h
00591 
00592     virtual const Symbol & symbol() const;
00593     virtual Symbol & symbol();
00594     virtual void    symbol(const Symbol &);
00595     virtual const Expression & substituted_guarded() const;
00596     virtual Expression & substituted_guarded();
00597     virtual void    substituted(Expression *);
00598     virtual Boolean substituted_valid() const;
00599     virtual Expression * grab_substituted();
00600     ///< Methods specified in derived class IDExpr.h
00601 
00602     virtual int     sign() const;
00603     virtual void    sign(int s);
00604     ///< Methods specified in derived class InfinityExpr.h
00605        
00606     virtual const Expression & intrinsic() const;
00607     virtual Expression & intrinsic();
00608     virtual void    intrinsic(Expression *);
00609     ///< Methods specified in derived class IntrinsicExpr.h
00610     
00611     virtual void    stmt(Statement & stmt);
00612     virtual const Statement & stmt() const;
00613     virtual Statement & stmt();
00614     ///< Methods specified in derived class LabelExpr.h
00615     
00616     virtual const Expression & lambda_expr() const;
00617     virtual Expression & lambda_expr();
00618     virtual void    lambda_expr(Expression *);
00619     ///< Methods specified in derived class LambdaCallExpr.h
00620 
00621     virtual void    gate(Expression *);
00622     virtual const Expression &gate() const;
00623     virtual Expression &gate();
00624     ///< Methods specified in derived class GSAExpr.h
00625 
00626     virtual void    string(Expression *);
00627     virtual const Expression & string() const;
00628     virtual Expression & string();
00629     virtual void    bound(Expression *);
00630     virtual const Expression & bound() const;
00631     virtual Expression & bound();
00632     ///< Methods specified in derived class SubStringExpr.h
00633 
00634     virtual int     entry() const;
00635     virtual void    entry(int);
00636     ///< Methods specified in derived class TableExpr.h
00637     
00638     virtual const Expression & expr_guarded() const;
00639     virtual Expression & expr_guarded();
00640     virtual void    expr(Expression *);
00641     virtual Boolean expr_valid() const;
00642     virtual Expression *grab_expr();
00643     ///< Methods specified in derived class UnaryExpr.h
00644 
00645 public:
00646     ///< These should really be protected, but some compilers have
00647     ///< compatibility problems if they're not public
00648 
00649     inline void _backup();
00650     virtual void _backup_aux();
00651     ///< Backs up an expression tree match, resetting matches made by
00652     ///< wildcards.
00653   
00654     inline ExprSignature & _signature_live();
00655     virtual Expression *_fold_top(void);
00656     virtual Expression *_divides_evenly(const Symbol *);
00657     virtual Expression *_divide_by_int(int &);
00658     virtual int         _gcd(void) const;
00659     virtual Expression *_distribute_top(void);
00660     virtual Boolean _args_are_equal(Expression &, 
00661                                     Boolean consider_side_effects);
00662     virtual Expression *_combine_top();
00663     ///< Methods used for simplification.
00664 
00665     Boolean         _wildcard_is_equal_to(Expression &,
00666                                           Boolean consider_side_effects);
00667 
00668     ///< hack -- the following was originally protected, but _fb_EXPR_Wildcard
00669     ///< lines 39 and 53 can't access it (even though _fb_EXPR_Wildcard
00670     ///< publically inherits Wildcard, which in turn publically inherits
00671     ///< Expression.  Bill P.
00672     virtual Boolean _match(Expression & e, Boolean consider_side_effects);
00673 
00674 private:
00675     void            _ref_error(const char *) const;
00676 
00677  protected:
00678     ///< ------------- Helper functions ------------
00679     void            get_type(BinRep & typebin, const char *exprname);
00680     void            make_overflow(Iterator<BinRep> & iter, const char *exname);
00681     void            empty_overflow();
00682     
00683 
00684     OP_TYPE         _op;        ///< Type of the Expressions operator
00685 
00686     Type            _type;      ///< Type and size of the Expression
00687                                 ///< (ex.INTEGER_TYPE)
00688     
00689     Boolean         _is_wildcard;
00690 
00691     ExprSignature   _signature; ///< Used for simplification
00692 
00693     BinRep         *_overflow;  ///< Any overflow information
00694 
00695     friend Expression * _replace_or_traverse(Expression *,
00696     /*&*/                                    Expression &,
00697     /*&*/                                    ReplaceOptions &options);
00698 
00699     friend Expression *_replace_or_traverse_aux(Expression *,
00700     /*&*/                                       Expression *,
00701     /*&*/                                       Expression &,
00702     /*&*/                                       ReplaceOptions &options);
00703 };
00704 
00705 void reset_simplifier_opts();
00706 void set_simplifier_opts();
00707 
00708 #include "expr_funcs.h"
00709 
00710 inline
00711 Expression::Expression(OP_TYPE optype, const Type & exptype) 
00712 {
00713     #ifdef CLASS_INSTANCE_REGISTRY
00714     register_instance(EXPRESSION, sizeof(Expression), this);
00715     #endif
00716 
00717     _op = optype;
00718     _type = exptype;
00719     _overflow = NULL;
00720     _is_wildcard = False;
00721 }
00722 
00723 inline
00724 Expression::Expression(const Expression & e) 
00725 {
00726     #ifdef CLASS_INSTANCE_REGISTRY
00727     register_instance(EXPRESSION, sizeof(Expression), this);
00728     #endif
00729 
00730     _op = e._op;
00731     _type = e._type;
00732     _signature = e._signature;
00733     _overflow = (e._overflow ? new BinRep(*e._overflow) : 0);
00734     _is_wildcard = e._is_wildcard;
00735 }
00736 
00737 inline OP_TYPE
00738 Expression::op() const
00739 {
00740     return _op;
00741 }
00742 
00743 inline void
00744 Expression::op(const OP_TYPE o)
00745 {
00746     _op = o;
00747 }
00748 
00749 inline Boolean
00750 Expression::is_wildcard() const 
00751 {
00752     return _is_wildcard;
00753 }
00754 
00755 inline const Type &
00756 Expression::type() const
00757 {
00758     return _type;
00759 }
00760 
00761 inline void
00762 Expression::type(const Type &exptype) 
00763 {
00764     _type = exptype;
00765 }
00766 
00767 inline Type *
00768 Expression::type_ref() const
00769 {
00770     Type * t = new Type(_type);
00771     return t;
00772 }
00773 
00774 
00775 inline BinRep *
00776 Expression::overflow_ref() const
00777 {
00778     return _overflow;
00779 }
00780 
00781 inline Boolean
00782 Expression::operator != (Expression & e) 
00783 {
00784     return !(*this == e);
00785 }
00786 
00787 inline Boolean
00788 Expression::match(Expression & e)
00789 {
00790     return _match(e, False);
00791 }
00792 
00793 inline Boolean
00794 Expression::operator == (const Expression & e) const
00795 {
00796   if (_op!=e._op){
00797     return 0;
00798   }
00799   ///< First simple heuristic.
00800   if (_op==NE_OP && e._op==NE_OP 
00801       || _op==EQ_OP && e._op==EQ_OP){
00802     if (_type.data_type()==INTEGER_TYPE &&
00803     e._type.data_type()==INTEGER_TYPE){
00804       Boolean res=
00805     (CASTAWAY(Expression *)this)->_match(CASTAWAY(Expression &)e, True);
00806       if (res){
00807     return res;
00808       } else {
00809     Expression* mul(Expression * expr1, Expression * expr2);
00810     Expression* constant(int value);
00811     Expression* negl=simplify(mul(constant(-1), 
00812                       e.left_guarded().clone()));
00813     Expression* negr=simplify(mul(constant(-1), 
00814                       e.right_guarded().clone()));
00815     if (*negl==left_guarded() &&
00816         *negr==right_guarded()){
00817       delete negl;
00818       delete negr;
00819       return 1;
00820     } else {
00821       delete negl;
00822       delete negr;
00823       return 0;
00824     }
00825       }
00826     }
00827   }
00828 
00829   ///< Now the general comparison checker.
00830     return (CASTAWAY(Expression *)this)->_match(CASTAWAY(Expression &)e, True);
00831 }
00832 
00833 inline Boolean
00834 Expression::operator == (Expression & e)
00835 {
00836     return _match(e, True);
00837 }
00838 
00839 inline ExprSignature &
00840 Expression::_signature_live()
00841 {
00842     return _signature;
00843 }
00844 
00845 inline const ExprSignature &
00846 Expression::signature() const
00847 {
00848     return _signature;
00849 }
00850 
00851 ///< Precondition:  signature is correct
00852 
00853 inline void
00854 Expression::_backup() {
00855     ///< We only need to call the virtual function if there are wildcards
00856     ///< somewhere in the current node or descendants
00857     if (_signature.has_wildcard())
00858         _backup_aux();
00859 }
00860 
00861 #endif
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:52 2005