00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __EXP_H_
00023 #define __EXP_H_
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <iostream>
00036 #include <fstream>
00037 #include <stdio.h>
00038 #include <list>
00039 #include <vector>
00040 #include <set>
00041 #include <assert.h>
00042 #include "operator.h"
00043 #include "types.h"
00044 #include "type.h"
00045
00046 #include "exphelp.h"
00047 #include "memo.h"
00048
00049 class UseSet;
00050 class DefSet;
00051 class RTL;
00052 class Statement;
00053 class BasicBlock;
00054 class LocationSet;
00055 class StatementSet;
00056 class TypeVal;
00057 class ExpVisitor;
00058 class ExpModifier;
00059 class XMLProgParser;
00060 class Proc;
00061 class UserProc;
00062 typedef BasicBlock* PBB;
00063
00064 #define DEBUG_BUFSIZE 5000 // Size of the debug print buffer
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 class Exp {
00077 protected:
00078 OPER op;
00079
00080 unsigned lexBegin, lexEnd;
00081
00082
00083 Exp(OPER op) : op(op) {}
00084
00085 public:
00086
00087 virtual ~Exp() {}
00088
00089
00090
00091 OPER getOper() const {return op;}
00092 void setOper(OPER x) {op = x;}
00093
00094 void setLexBegin(unsigned int n) { lexBegin = n; }
00095 void setLexEnd(unsigned int n) { lexEnd = n; }
00096 unsigned getLexBegin() { return lexBegin; }
00097 unsigned getLexEnd() { return lexEnd; }
00098
00099
00100 virtual void print(std::ostream& os, bool html = false) = 0;
00101
00102 void printt(std::ostream& os = std::cout);
00103 void printAsHL(std::ostream& os = std::cout);
00104 char* prints();
00105 void dump();
00106
00107 virtual void printr(std::ostream& os, bool html = false) { print(os, html);}
00108
00109 virtual void printx(int ind) = 0;
00110
00111
00112 void createDotFile(char* name);
00113 virtual void appendDotFile(std::ofstream& os) = 0;
00114
00115
00116 virtual Exp* clone() = 0;
00117
00118
00119
00120 virtual bool operator==(const Exp& o) const = 0;
00121
00122 virtual bool operator< (const Exp& o) const = 0;
00123
00124 virtual bool operator<<(const Exp& o) const
00125 {return (*this < o);}
00126
00127 virtual bool operator*=(Exp& o) = 0;
00128
00129
00130
00131 virtual int getArity() {return 0;}
00132
00133
00134
00135
00136
00137
00138 bool isFlagCall() {return op == opFlagCall;}
00139
00140 bool isFlags() {return op == opFlags || op == opFflags;}
00141
00142 bool isMainFlag() {return op >= opZF && op <= opOF;}
00143
00144 bool isRegOf() {return op == opRegOf;}
00145
00146 bool isRegOfK();
00147
00148 bool isRegN(int n);
00149
00150 bool isMemOf() {return op == opMemOf;}
00151
00152 bool isAddrOf() {return op == opAddrOf;}
00153
00154 bool isArrayIndex() {return op == opArrayIndex;}
00155
00156 bool isMemberOf() {return op == opMemberAccess;}
00157
00158 bool isTemp();
00159
00160 bool isAnull() {return op == opAnull;}
00161
00162 bool isNil() {return op == opNil;}
00163
00164 bool isPC() {return op == opPC;}
00165
00166 bool isAfpTerm();
00167
00168 bool isIntConst() {return op == opIntConst;}
00169
00170 bool isStrConst() {return op == opStrConst;}
00171
00172 char* getAnyStrConst();
00173
00174 bool isFltConst() {return op == opFltConst;}
00175
00176 bool isConst() {return op == opIntConst || op == opStrConst;}
00177
00178 bool isPostVar() {return op == opPostVar;}
00179
00180 bool isSizeCast() {return op == opSize;}
00181
00182 bool isSubscript() {return op == opSubscript;}
00183
00184
00185
00186 bool isLocal() {return op == opLocal;}
00187
00188 bool isGlobal() {return op == opGlobal;}
00189
00190 bool isTypeOf() {return op == opTypeOf;}
00191
00192 int getVarIndex();
00193
00194 virtual bool isTerminal() { return false; }
00195
00196 bool isTrue() {return op == opTrue;}
00197
00198 bool isFalse() {return op == opFalse;}
00199
00200 bool isDisjunction() {return op == opOr;}
00201
00202 bool isConjunction() {return op == opAnd;}
00203
00204 bool isBoolConst() {return op == opTrue || op == opFalse;}
00205
00206 bool isEquality() {return op == opEquals ;}
00207
00208 bool isComparison() { return op == opEquals || op == opNotEqual ||
00209 op == opGtr || op == opLess ||
00210 op == opGtrUns || op == opLessUns ||
00211 op == opGtrEq || op == opLessEq ||
00212 op == opGtrEqUns || op == opLessEqUns; }
00213
00214 bool isTypeVal() { return op == opTypeVal;}
00215
00216 bool isMachFtr() {return op == opMachFtr;}
00217
00218 bool isParam() {return op == opParam;}
00219
00220
00221 bool isLocation() { return op == opMemOf || op == opRegOf ||
00222 op == opGlobal || op == opLocal ||
00223 op == opParam; }
00224
00225
00226 bool isTypedExp() { return op == opTypedExp;}
00227
00228
00229
00230
00231
00232 virtual Exp *match(Exp *pattern);
00233
00234
00235 virtual bool match(const char *pattern, std::map<std::string, Exp*> &bindings);
00236
00237
00238
00239
00240
00241
00242
00243 virtual bool search(Exp* search, Exp*& result);
00244
00245
00246
00247 bool searchAll(Exp* search, std::list<Exp*>& result);
00248
00249
00250 Exp* searchReplace (Exp* search, Exp* replace, bool& change);
00251
00252
00253 Exp* searchReplaceAll(Exp* search, Exp* replace, bool& change, bool once = false);
00254
00255
00256 static void doSearch(Exp* search, Exp*& pSrc, std::list<Exp**>& li, bool once);
00257
00258
00259 virtual void doSearchChildren(Exp* search, std::list<Exp**>& li, bool once);
00260
00261
00262 Exp* propagateAll();
00263 Exp* propagateAllRpt(bool& changed);
00264
00265
00266
00267
00268
00269
00270
00271
00272 virtual Exp* getSubExp1() {return 0;}
00273 virtual Exp* getSubExp2() {return 0;}
00274 virtual Exp* getSubExp3() {return 0;}
00275 virtual Exp*& refSubExp1();
00276 virtual Exp*& refSubExp2();
00277 virtual Exp*& refSubExp3();
00278 virtual void setSubExp1(Exp* e) {};
00279 virtual void setSubExp2(Exp* e) {};
00280 virtual void setSubExp3(Exp* e) {};
00281
00282
00283 int getComplexityDepth(UserProc* proc);
00284
00285 int getMemDepth();
00286
00287
00288
00289
00290 Exp* getGuard();
00291
00292
00293
00294
00295
00296 void partitionTerms(std::list<Exp*>& positives, std::list<Exp*>& negatives, std::vector<int>& integers,
00297 bool negate);
00298 virtual Exp* simplifyArith() {return this;}
00299 static Exp* Accumulate(std::list<Exp*> exprs);
00300
00301 Exp* simplify();
00302 virtual Exp* polySimplify(bool& bMod) {bMod = false; return this;}
00303
00304 virtual Exp* simplifyAddr() {return this;}
00305 virtual Exp* simplifyConstraint() {return this;}
00306 Exp* fixSuccessor();
00307
00308 Exp* killFill();
00309
00310
00311 void addUsedLocs(LocationSet& used, bool memOnly = false);
00312
00313 Exp *removeSubscripts(bool& allZero);
00314
00315
00316 virtual int getNumRefs() {return 0;}
00317
00318
00319
00320 Exp* fromSSAleft(UserProc* proc, Statement* d);
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 virtual Exp* genConstraints(Exp* result);
00334
00335
00336
00337 virtual bool accept(ExpVisitor* v) = 0;
00338 virtual Exp* accept(ExpModifier* v) = 0;
00339 void fixLocationProc(UserProc* p);
00340 UserProc* findProc();
00341
00342 void setConscripts(int n, bool bClear);
00343 Exp* stripSizes();
00344
00345 Exp* expSubscriptVar(Exp* e, Statement* def );
00346
00347 Exp* expSubscriptValNull(Exp* e );
00348
00349 Exp* expSubscriptAllNull();
00350
00351
00352 Exp* bypass();
00353 void bypassComp();
00354 bool containsFlags();
00355 bool containsBadMemof(UserProc* p);
00356 bool containsMemof(UserProc* proc);
00357
00358
00359
00360 virtual Type* ascendType() {assert(0); return 0;}
00361
00362 virtual void descendType(Type* parentType, bool& ch, Statement* s) {assert(0);}
00363
00364 protected:
00365 friend class XMLProgParser;
00366 };
00367
00368
00369 std::ostream& operator<<(std::ostream& os, Exp* p);
00370
00371
00372
00373
00374 class Const : public Exp {
00375 union {
00376 int i;
00377
00378
00379 ADDRESS a;
00380 QWord ll;
00381 double d;
00382 char* p;
00383
00384 Proc* pp;
00385 } u;
00386 int conscript;
00387 Type* type;
00388 public:
00389
00390 Const(int i);
00391 Const(QWord ll);
00392 Const(ADDRESS a);
00393 Const(double d);
00394 Const(char* p);
00395 Const(Proc* p);
00396
00397 Const(Const& o);
00398
00399
00400
00401
00402 virtual Exp* clone();
00403
00404
00405 virtual bool operator==(const Exp& o) const;
00406 virtual bool operator< (const Exp& o) const;
00407 virtual bool operator*=(Exp& o);
00408
00409
00410 int getInt() {return u.i;}
00411 QWord getLong(){return u.ll;}
00412 double getFlt() {return u.d;}
00413 char* getStr() {return u.p;}
00414 ADDRESS getAddr() {return u.a;}
00415 const char* getFuncName();
00416
00417
00418 void setInt(int i) {u.i = i;}
00419 void setLong(QWord ll) {u.ll = ll;}
00420 void setFlt(double d) {u.d = d;}
00421 void setStr(char* p) {u.p = p;}
00422 void setAddr(ADDRESS a) {u.a = a;}
00423
00424
00425 Type* getType() { return type; }
00426 void setType(Type* ty) { type = ty; }
00427
00428 virtual void print(std::ostream& os, bool html = false);
00429
00430 void printNoQuotes(std::ostream& os);
00431 virtual void printx(int ind);
00432
00433
00434 virtual void appendDotFile(std::ofstream& of);
00435 virtual Exp* genConstraints(Exp* restrictTo);
00436
00437
00438 virtual bool accept(ExpVisitor* v);
00439 virtual Exp* accept(ExpModifier* v);
00440
00441 virtual bool match(const char *pattern, std::map<std::string, Exp*> &bindings);
00442
00443 int getConscript() {return conscript;}
00444 void setConscript(int cs) {conscript = cs;}
00445
00446 virtual Type* ascendType();
00447 virtual void descendType(Type* parentType, bool& ch, Statement* s);
00448
00449 protected:
00450 friend class XMLProgParser;
00451 };
00452
00453
00454
00455
00456 class Terminal : public Exp {
00457 public:
00458
00459 Terminal(OPER op);
00460 Terminal(Terminal& o);
00461
00462
00463 virtual Exp* clone();
00464
00465
00466 virtual bool operator==(const Exp& o) const;
00467 virtual bool operator< (const Exp& o) const;
00468 virtual bool operator*=(Exp& o);
00469
00470 virtual void print(std::ostream& os, bool html = false);
00471 virtual void appendDotFile(std::ofstream& of);
00472 virtual void printx(int ind);
00473
00474 virtual bool isTerminal() { return true; }
00475
00476
00477 virtual bool accept(ExpVisitor* v);
00478 virtual Exp* accept(ExpModifier* v);
00479
00480 virtual Type* ascendType();
00481 virtual void descendType(Type* parentType, bool& ch, Statement* s);
00482
00483 virtual bool match(const char *pattern, std::map<std::string, Exp*> &bindings);
00484
00485 protected:
00486 friend class XMLProgParser;
00487 };
00488
00489
00490
00491
00492 class Unary : public Exp {
00493 protected:
00494 Exp* subExp1;
00495
00496
00497 Unary(OPER op);
00498 public:
00499
00500 Unary(OPER op, Exp* e);
00501
00502 Unary(Unary& o);
00503
00504
00505 virtual Exp* clone();
00506
00507
00508 virtual bool operator==(const Exp& o) const;
00509 virtual bool operator< (const Exp& o) const;
00510 virtual bool operator*=(Exp& o);
00511
00512
00513 virtual ~Unary();
00514
00515
00516 virtual int getArity() {return 1;}
00517
00518
00519 virtual void print(std::ostream& os, bool html = false);
00520 virtual void appendDotFile(std::ofstream& of);
00521 virtual void printx(int ind);
00522
00523
00524 void setSubExp1(Exp* e);
00525 void setSubExp1ND(Exp* e) {subExp1 = e;}
00526
00527 Exp* getSubExp1();
00528
00529 Exp*& refSubExp1();
00530
00531 virtual Exp* match(Exp *pattern);
00532 virtual bool match(const char *pattern, std::map<std::string, Exp*> &bindings);
00533
00534
00535 void doSearchChildren(Exp* search, std::list<Exp**>& li, bool once);
00536
00537
00538 virtual Exp* polySimplify(bool& bMod);
00539 Exp* simplifyArith();
00540 Exp* simplifyAddr();
00541 virtual Exp* simplifyConstraint();
00542
00543
00544 virtual Exp* genConstraints(Exp* restrictTo);
00545
00546
00547 virtual bool accept(ExpVisitor* v);
00548 virtual Exp* accept(ExpModifier* v);
00549
00550 virtual Type* ascendType();
00551 virtual void descendType(Type* parentType, bool& ch, Statement* s);
00552
00553 protected:
00554 friend class XMLProgParser;
00555 };
00556
00557
00558
00559
00560 class Binary : public Unary {
00561 protected:
00562 Exp* subExp2;
00563
00564
00565 Binary(OPER op);
00566
00567 public:
00568
00569 Binary(OPER op, Exp* e1, Exp* e2);
00570
00571 Binary(Binary& o);
00572
00573
00574 virtual Exp* clone();
00575
00576
00577 virtual bool operator==(const Exp& o) const ;
00578 virtual bool operator< (const Exp& o) const ;
00579 virtual bool operator*=(Exp& o);
00580
00581
00582 virtual ~Binary();
00583
00584
00585 int getArity() {return 2;}
00586
00587
00588 virtual void print(std::ostream& os, bool html = false);
00589 virtual void printr(std::ostream& os, bool html = false);
00590 virtual void appendDotFile(std::ofstream& of);
00591 virtual void printx(int ind);
00592
00593
00594 void setSubExp2(Exp* e);
00595
00596 Exp* getSubExp2();
00597
00598 void commute();
00599
00600 Exp*& refSubExp2();
00601
00602 virtual Exp* match(Exp *pattern);
00603 virtual bool match(const char *pattern, std::map<std::string, Exp*> &bindings);
00604
00605
00606 void doSearchChildren(Exp* search, std::list<Exp**>& li, bool once);
00607
00608
00609 virtual Exp* polySimplify(bool& bMod);
00610 Exp* simplifyArith();
00611 Exp* simplifyAddr();
00612 virtual Exp* simplifyConstraint();
00613
00614
00615 virtual Exp* genConstraints(Exp* restrictTo);
00616
00617
00618 virtual bool accept(ExpVisitor* v);
00619 virtual Exp* accept(ExpModifier* v);
00620
00621 virtual Type* ascendType();
00622 virtual void descendType(Type* parentType, bool& ch, Statement* s);
00623
00624 private:
00625 Exp* constrainSub(TypeVal* typeVal1, TypeVal* typeVal2);
00626
00627 protected:
00628 friend class XMLProgParser;
00629 };
00630
00631
00632
00633
00634 class Ternary : public Binary {
00635 Exp* subExp3;
00636
00637
00638 Ternary(OPER op);
00639
00640 public:
00641
00642 Ternary(OPER op, Exp* e1, Exp* e2, Exp* e3);
00643
00644 Ternary(Ternary& o);
00645
00646
00647 virtual Exp* clone();
00648
00649
00650 virtual bool operator==(const Exp& o) const ;
00651 virtual bool operator< (const Exp& o) const ;
00652 virtual bool operator*=(Exp& o);
00653
00654
00655 virtual ~Ternary();
00656
00657
00658 int getArity() {return 3;}
00659
00660
00661 virtual void print(std::ostream& os, bool html = false);
00662 virtual void printr(std::ostream& os, bool html = false);
00663 virtual void appendDotFile(std::ofstream& of);
00664 virtual void printx(int ind);
00665
00666
00667 void setSubExp3(Exp* e);
00668
00669 Exp* getSubExp3();
00670
00671 Exp*& refSubExp3();
00672
00673
00674 void doSearchChildren(Exp* search, std::list<Exp**>& li, bool once);
00675
00676 virtual Exp* polySimplify(bool& bMod);
00677 Exp* simplifyArith();
00678 Exp* simplifyAddr();
00679
00680
00681 virtual Exp* genConstraints(Exp* restrictTo);
00682
00683
00684 virtual bool accept(ExpVisitor* v);
00685 virtual Exp* accept(ExpModifier* v);
00686
00687 virtual bool match(const char *pattern, std::map<std::string, Exp*> &bindings);
00688
00689 virtual Type* ascendType();
00690 virtual void descendType(Type* parentType, bool& ch, Statement* s);
00691
00692 protected:
00693 friend class XMLProgParser;
00694 };
00695
00696
00697
00698
00699 class TypedExp : public Unary {
00700 Type *type;
00701 public:
00702
00703 TypedExp();
00704
00705 TypedExp(Exp* e1);
00706
00707
00708
00709 TypedExp(Type* ty, Exp* e1);
00710
00711 TypedExp(TypedExp& o);
00712
00713
00714 virtual Exp* clone();
00715
00716
00717 virtual bool operator==(const Exp& o) const;
00718 virtual bool operator< (const Exp& o) const;
00719 virtual bool operator<<(const Exp& o) const;
00720 virtual bool operator*=(Exp& o);
00721
00722
00723 virtual void print(std::ostream& os, bool html = false);
00724 virtual void appendDotFile(std::ofstream& of);
00725 virtual void printx(int ind);
00726
00727
00728 virtual Type* getType() {return type;}
00729 virtual void setType(Type* ty) {type = ty;}
00730
00731
00732 virtual Exp* polySimplify(bool& bMod);
00733
00734
00735 virtual bool accept(ExpVisitor* v);
00736 virtual Exp* accept(ExpModifier* v);
00737
00738 virtual Type* ascendType();
00739 virtual void descendType(Type* parentType, bool& ch, Statement* s);
00740
00741 protected:
00742 friend class XMLProgParser;
00743 };
00744
00745
00746
00747
00748 class FlagDef : public Unary {
00749 RTL* rtl;
00750 public:
00751 FlagDef(Exp* params, RTL* rtl);
00752 virtual ~FlagDef();
00753 virtual void appendDotFile(std::ofstream& of);
00754 RTL* getRtl() { return rtl; }
00755 void setRtl(RTL* r) { rtl = r; }
00756
00757
00758 virtual bool accept(ExpVisitor* v);
00759 virtual Exp* accept(ExpModifier* v);
00760
00761 protected:
00762 friend class XMLProgParser;
00763 };
00764
00765
00766
00767
00768
00769
00770
00771 class RefExp : public Unary {
00772 Statement* def;
00773
00774 public:
00775
00776 RefExp(Exp* e, Statement* def);
00777
00778
00779 virtual Exp* clone();
00780 virtual bool operator==(const Exp& o) const;
00781 virtual bool operator< (const Exp& o) const;
00782 virtual bool operator*=(Exp& o);
00783
00784 virtual void print(std::ostream& os, bool html = false);
00785 virtual void printx(int ind);
00786
00787 Statement* getDef() {return def;}
00788 Exp* addSubscript(Statement* def) {this->def = def; return this;}
00789 void setDef(Statement* def) {this->def = def;}
00790 virtual Exp* genConstraints(Exp* restrictTo);
00791 bool references(Statement* s) {return def == s;}
00792 virtual Exp* polySimplify(bool& bMod);
00793 virtual Exp *match(Exp *pattern);
00794 virtual bool match(const char *pattern, std::map<std::string, Exp*> &bindings);
00795
00796
00797
00798 bool isImplicitDef();
00799
00800
00801 virtual bool accept(ExpVisitor* v);
00802 virtual Exp* accept(ExpModifier* v);
00803
00804 virtual Type* ascendType();
00805 virtual void descendType(Type* parentType, bool& ch, Statement* s);
00806
00807 protected:
00808 RefExp() : Unary(opSubscript), def(NULL) { }
00809 friend class XMLProgParser;
00810 };
00811
00812
00813
00814
00815
00816 class TypeVal : public Terminal {
00817 Type* val;
00818
00819 public:
00820 TypeVal(Type* ty);
00821 ~TypeVal();
00822
00823 virtual Type* getType() {return val;}
00824 virtual void setType(Type* t) {val = t;}
00825 virtual Exp* clone();
00826 virtual bool operator==(const Exp& o) const;
00827 virtual bool operator< (const Exp& o) const;
00828 virtual bool operator*=(Exp& o);
00829 virtual void print(std::ostream& os, bool html = false);
00830 virtual void printx(int ind);
00831 virtual Exp* genConstraints(Exp* restrictTo) {
00832 assert(0); return NULL;}
00833
00834
00835
00836 virtual bool accept(ExpVisitor* v);
00837 virtual Exp* accept(ExpModifier* v);
00838
00839 protected:
00840 friend class XMLProgParser;
00841 };
00842
00843 class Location : public Unary {
00844 protected:
00845 UserProc *proc;
00846
00847 public:
00848
00849 Location(OPER op, Exp* e, UserProc *proc);
00850
00851 Location(Location& o);
00852
00853 static Location* regOf(int r) {return new Location(opRegOf, new Const(r), NULL);}
00854 static Location* regOf(Exp *e) {return new Location(opRegOf, e, NULL);}
00855 static Location* memOf(Exp *e, UserProc* p = NULL) {return new Location(opMemOf, e, p);}
00856 static Location* tempOf(Exp* e) {return new Location(opTemp, e, NULL);}
00857 static Location* global(const char *nam, UserProc *p) {
00858 return new Location(opGlobal, new Const((char*)nam), p);}
00859 static Location* local(const char *nam, UserProc *p);
00860 static Location* param(const char *nam, UserProc *p = NULL) {
00861 return new Location(opParam, new Const((char*)nam), p);}
00862
00863 virtual Exp* clone();
00864
00865 void setProc(UserProc *p) { proc = p; }
00866 UserProc *getProc() { return proc; }
00867
00868 virtual Exp* polySimplify(bool& bMod);
00869 virtual void getDefinitions(LocationSet& defs);
00870
00871
00872 virtual bool accept(ExpVisitor* v);
00873 virtual Exp* accept(ExpModifier* v);
00874 virtual bool match(const char *pattern, std::map<std::string, Exp*> &bindings);
00875
00876 protected:
00877 friend class XMLProgParser;
00878 Location(OPER op) : Unary(op), proc(NULL) { }
00879 };
00880
00881 #endif // __EXP_H__