00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __BASIC_BLOCK_H__
00024 #define __BASIC_BLOCK_H__
00025
00026 #if defined(_MSC_VER)
00027 #pragma warning(disable:4290)
00028 #endif
00029
00030 #include "managed.h"
00031
00032 class Location;
00033 class HLLCode;
00034 class BasicBlock;
00035 class RTL;
00036 class Proc;
00037 class UserProc;
00038 struct SWITCH_INFO;
00039
00040 typedef BasicBlock* PBB;
00041
00042
00043
00044
00045
00046
00047
00048
00049 enum travType {
00050 UNTRAVERSED,
00051 DFS_TAG,
00052 DFS_LNUM,
00053 DFS_RNUM,
00054 DFS_CASE,
00055 DFS_PDOM,
00056 DFS_CODEGEN
00057 };
00058
00059
00060 enum structType {
00061 Loop,
00062 Cond,
00063 LoopCond,
00064 Seq
00065 };
00066
00067
00068 enum unstructType {
00069 Structured,
00070 JumpInOutLoop,
00071 JumpIntoCase
00072 };
00073
00074
00075
00076 enum condType {
00077 IfThen,
00078 IfThenElse,
00079 IfElse,
00080 Case
00081 };
00082
00083
00084 enum loopType {
00085 PreTested,
00086 PostTested,
00087 Endless
00088 };
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 enum BBTYPE {
00099 ONEWAY,
00100 TWOWAY,
00101 NWAY,
00102 CALL,
00103 RET,
00104 FALL,
00105 COMPJUMP,
00106 COMPCALL,
00107 INVALID
00108 };
00109
00110 enum SBBTYPE {
00111 NONE,
00112 PRETESTLOOP,
00113 POSTTESTLOOP,
00114 ENDLESSLOOP,
00115 JUMPINOUTLOOP,
00116 JUMPINTOCASE,
00117 IFGOTO,
00118 IFTHEN,
00119 IFTHENELSE,
00120 IFELSE,
00121 CASE
00122 };
00123
00124 typedef std::list<PBB>::iterator BB_IT;
00125
00126
00127
00128
00129 class BasicBlock {
00130
00131
00132
00133 friend class Cfg;
00134
00135 public:
00136
00137
00138
00139 BasicBlock();
00140
00141
00142
00143
00144 ~BasicBlock();
00145
00146
00147
00148
00149 BasicBlock(const BasicBlock& bb);
00150
00151
00152
00153
00154 BBTYPE getType();
00155
00156
00157
00158
00159
00160 int getLabel();
00161
00162 std::string &getLabelStr() { return m_labelStr; }
00163 void setLabelStr(std::string &s) { m_labelStr = s; }
00164 bool isLabelNeeded() { return m_labelneeded; }
00165 void setLabelNeeded(bool b) { m_labelneeded = b; }
00166 bool isCaseOption();
00167
00168
00169
00170
00171 bool isTraversed();
00172
00173
00174
00175
00176 void setTraversed(bool bTraversed);
00177
00178
00179
00180
00181
00182 void print(std::ostream& os, bool html = false);
00183 void printToLog();
00184 char* prints();
00185 void dump();
00186
00187
00188
00189
00190 void updateType(BBTYPE bbType, int iNumOutEdges);
00191
00192
00193
00194
00195
00196
00197 void setJumpReqd();
00198
00199
00200
00201
00202 bool isJumpReqd();
00203
00204
00205
00206
00207
00208
00209 ADDRESS getLowAddr();
00210 ADDRESS getHiAddr();
00211
00212
00213
00214
00215 std::list<RTL*>* getRTLs();
00216
00217 RTL* getRTLWithStatement(Statement *stmt);
00218
00219
00220
00221
00222 std::vector<PBB>& getInEdges();
00223
00224 int getNumInEdges() { return m_iNumInEdges; }
00225
00226
00227
00228
00229 std::vector<PBB>& getOutEdges();
00230
00231
00232
00233
00234 void setInEdge(int i, PBB newIn);
00235
00236
00237
00238
00239 void setOutEdge(int i, PBB newInEdge);
00240
00241
00242
00243
00244 PBB getOutEdge(unsigned int i);
00245
00246 int getNumOutEdges() { return m_iNumOutEdges; }
00247
00248
00249
00250
00251 int whichPred(PBB pred);
00252
00253
00254
00255
00256 void addInEdge(PBB newInEdge);
00257 void deleteEdge(PBB edge);
00258
00259
00260
00261
00262 void deleteInEdge(std::vector<PBB>::iterator& it);
00263 void deleteInEdge(PBB edge);
00264
00265
00266
00267
00268 ADDRESS getCallDest();
00269 Proc *getCallDestProc();
00270
00271
00272
00273
00274
00275
00276 unsigned DFTOrder(int& first, int& last);
00277
00278
00279
00280
00281
00282
00283 unsigned RevDFTOrder(int& first, int& last);
00284
00285
00286
00287
00288 static bool lessAddress(PBB bb1, PBB bb2);
00289
00290
00291
00292
00293 static bool lessFirstDFT(PBB bb1, PBB bb2);
00294
00295
00296
00297
00298 static bool lessLastDFT(PBB bb1, PBB bb2);
00299
00300
00301
00302
00303 void resetDFASets();
00304
00305 class LastStatementNotABranchError : public std::exception {
00306 public:
00307 Statement *stmt;
00308 LastStatementNotABranchError(Statement *stmt) : stmt(stmt) { }
00309 };
00310
00311 Exp *getCond() throw(LastStatementNotABranchError);
00312
00313
00314 void setCond(Exp *e) throw(LastStatementNotABranchError);
00315
00316 class LastStatementNotAGotoError : public std::exception {
00317 public:
00318 Statement *stmt;
00319 LastStatementNotAGotoError(Statement *stmt) : stmt(stmt) { }
00320 };
00321
00322 Exp* getDest() throw(LastStatementNotAGotoError);
00323
00324
00325 bool isJmpZ(PBB dest);
00326
00327
00328 BasicBlock *getLoopBody();
00329
00330
00331
00332 void simplify();
00333
00334
00335
00336
00337
00338
00339 PBB getCorrectOutEdge(ADDRESS a);
00340
00341
00342
00343
00344
00345 int m_DFTfirst;
00346 int m_DFTlast;
00347 int m_DFTrevfirst;
00348 int m_DFTrevlast;
00349
00350 private:
00351
00352
00353
00354 BasicBlock(std::list<RTL*>* pRtls, BBTYPE bbType, int iNumOutEdges);
00355
00356
00357
00358
00359
00360
00361 void setRTLs(std::list<RTL*>* rtls);
00362
00363 public:
00364
00365
00366 void generateBodyCode(HLLCode &hll, bool dup = false);
00367
00368
00369 SBBTYPE m_structType;
00370 SBBTYPE m_loopCondType;
00371 PBB m_loopHead;
00372 PBB m_caseHead;
00373 PBB m_condFollow;
00374 PBB m_loopFollow;
00375 PBB m_latchNode;
00376
00377 protected:
00378
00379 BBTYPE m_nodeType;
00380 std::list<RTL*>* m_pRtls;
00381 int m_iLabelNum;
00382 std::string m_labelStr;
00383 bool m_labelneeded;
00384 bool m_bIncomplete;
00385 bool m_bJumpReqd;
00386
00387
00388 std::vector<PBB> m_InEdges;
00389 std::vector<PBB> m_OutEdges;
00390 int m_iNumInEdges;
00391 int m_iNumOutEdges;
00392
00393
00394 bool m_iTraversed;
00395
00396
00397 LocationSet liveIn;
00398
00399 public:
00400
00401 bool isPostCall();
00402 static void doAvail(StatementSet& s, PBB inEdge);
00403 Proc* getDestProc();
00404
00405
00406
00407
00408
00409
00410 typedef std::list<RTL*>::iterator rtlit;
00411 typedef std::list<RTL*>::reverse_iterator rtlrit;
00412 typedef std::list<Exp*>::iterator elit;
00413 Statement* getFirstStmt(rtlit& rit, StatementList::iterator& sit);
00414 Statement* getNextStmt(rtlit& rit, StatementList::iterator& sit);
00415 Statement* getLastStmt(rtlrit& rit, StatementList::reverse_iterator& sit);
00416 Statement* getFirstStmt();
00417 Statement* getLastStmt();
00418 Statement* getPrevStmt(rtlrit& rit, StatementList::reverse_iterator& sit);
00419 RTL* getLastRtl() {return m_pRtls->back();}
00420
00421 void getStatements(StatementList &stmts);
00422
00423
00424
00425
00426
00427
00428 char* getStmtNumber();
00429
00430 protected:
00431
00432
00433 int ord;
00434 int revOrd;
00435 int inEdgesVisited;
00436 int numForwardInEdges;
00437 int loopStamps[2], revLoopStamps[2];
00438 travType traversed;
00439 bool hllLabel;
00440 char* labelStr;
00441 int indentLevel;
00442
00443
00444 PBB immPDom;
00445 PBB loopHead;
00446 PBB caseHead;
00447 PBB condFollow;
00448 PBB loopFollow;
00449 PBB latchNode;
00450
00451
00452 structType sType;
00453 unstructType usType;
00454 loopType lType;
00455 condType cType;
00456
00457 void setLoopStamps(int &time, std::vector<PBB> &order);
00458 void setRevLoopStamps(int &time);
00459 void setRevOrder(std::vector<PBB> &order);
00460
00461 void setLoopHead(PBB head) { loopHead = head; }
00462 PBB getLoopHead() { return loopHead; }
00463 void setLatchNode(PBB latch) { latchNode = latch; }
00464 bool isLatchNode() { return loopHead && loopHead->latchNode == this; }
00465 PBB getLatchNode() { return latchNode; }
00466 PBB getCaseHead() { return caseHead; }
00467 void setCaseHead(PBB head, PBB follow);
00468
00469 structType getStructType() { return sType; }
00470 void setStructType(structType s);
00471
00472 unstructType getUnstructType();
00473 void setUnstructType(unstructType us);
00474
00475 loopType getLoopType();
00476 void setLoopType(loopType l);
00477
00478 condType getCondType();
00479 void setCondType(condType l);
00480
00481 void setLoopFollow(PBB other) { loopFollow = other; }
00482 PBB getLoopFollow() { return loopFollow; }
00483
00484 void setCondFollow(PBB other) { condFollow = other; }
00485 PBB getCondFollow() { return condFollow; }
00486
00487
00488 bool hasBackEdgeTo(BasicBlock *dest);
00489
00490
00491 bool hasBackEdge() {
00492 for (unsigned int i = 0; i < m_OutEdges.size(); i++)
00493 if (hasBackEdgeTo(m_OutEdges[i]))
00494 return true;
00495 return false;
00496 }
00497
00498 public:
00499 bool isBackEdge(int inEdge);
00500
00501 protected:
00502
00503 bool isAncestorOf(BasicBlock *other);
00504
00505 bool inLoop(PBB header, PBB latch);
00506
00507 bool isIn(std::list<PBB> &set, PBB bb) {
00508 for (std::list<PBB>::iterator it = set.begin(); it != set.end(); it++)
00509 if (*it == bb) return true;
00510 return false;
00511 }
00512
00513 char* indent(int indLevel, int extra = 0);
00514 bool allParentsGenerated();
00515 void emitGotoAndLabel(HLLCode *hll, int indLevel, PBB dest);
00516 void WriteBB(HLLCode *hll, int indLevel);
00517
00518 public:
00519 void generateCode(HLLCode *hll, int indLevel, PBB latch, std::list<PBB> &followSet,
00520 std::list<PBB> &gotoSet, UserProc* proc);
00521
00522 void prependStmt(Statement* s, UserProc* proc);
00523
00524
00525 bool calcLiveness(ConnectionGraph& ig, UserProc* proc);
00526 void getLiveOut(LocationSet& live, LocationSet& phiLocs);
00527
00528
00529 bool decodeIndirectJmp(UserProc* proc);
00530 void processSwitch(UserProc* proc);
00531 int findNumCases();
00532
00533
00534
00535
00536 bool undoComputedBB(Statement* stmt);
00537
00538
00539
00540 bool overlappedRegProcessingDone;
00541
00542 protected:
00543 friend class XMLProgParser;
00544 void addOutEdge(PBB bb) { m_OutEdges.push_back(bb); }
00545 void addRTL(RTL *rtl) {
00546 if (m_pRtls == NULL)
00547 m_pRtls = new std::list<RTL*>;
00548 m_pRtls->push_back(rtl);
00549 }
00550 void addLiveIn(Exp *e) { liveIn.insert(e); }
00551
00552 };
00553
00554 #endif // #define __BASIC_BLOCK_H__