| Polaris: Expression.h Source File | ||
|
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members
Expression.hGo 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 |
||
|