diff --git a/include/BasicBlock.h b/include/BasicBlock.h index 3860ee0..ffbb7a4 100644 --- a/include/BasicBlock.h +++ b/include/BasicBlock.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include "icode.h" #include "types.h" #include "graph.h" //#include "icode.h" @@ -12,22 +14,21 @@ struct Function; class CIcodeRec; struct BB; +struct LOCAL_ID; struct interval; -struct ICODE; -typedef std::list::iterator iICODE; -typedef std::list::reverse_iterator riICODE; -typedef union + +struct TYPEADR_TYPE { uint32_t ip; /* Out edge icode address */ BB * BBptr; /* Out edge pointer to next BB */ interval *intPtr; /* Out edge ptr to next interval*/ -} TYPEADR_TYPE; +}; struct BB : public llvm::ilist_node { private: BB(const BB&); - BB() : nodeType(0),traversed(0), + BB() : nodeType(0),traversed(DFS_NONE), numHlIcodes(0),flg(0), inEdges(0), edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0), @@ -38,10 +39,14 @@ private: } //friend class SymbolTableListTraits; - iICODE range_start; - iICODE range_end; + typedef boost::iterator_range rCODE; + rCODE instructions; public: + struct ValidFunctor + { + bool operator()(BB *p) {return p->valid();} + }; iICODE begin(); iICODE end() const; riICODE rbegin(); @@ -50,7 +55,7 @@ public: ICODE &back(); size_t size(); uint8_t nodeType; /* Type of node */ - int traversed; /* Boolean: traversed yet? */ + eDFS traversed; /* last traversal id is held here traversed yet? */ int numHlIcodes; /* No. of high-level icodes */ uint32_t flg; /* BB flags */ @@ -94,8 +99,9 @@ public: int caseTail; /* tail node for the case */ int index; /* Index, used in several ways */ -static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0); -static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Function * parent); + static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0); + static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Function * parent); + static BB * Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent); void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow); void mergeFallThrough(CIcodeRec &Icode); void dfsNumbering(std::vector &dfsLast, int *first, int *last); @@ -105,10 +111,19 @@ static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Functio /// const Function *getParent() const { return Parent; } Function *getParent() { return Parent; } - void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc); - BB *rmJMP(int marker, BB *pBB); - void genDU1(); + void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc); + BB * rmJMP(int marker, BB *pBB); + void genDU1(); + int findBBExps(LOCAL_ID &locals, Function *f); + bool valid() {return 0==(flg & INVALID_BB); } + bool wasTraversedAtLevel(int l) const {return traversed==l;} + ICODE * writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond); + void addOutEdge(uint32_t ip) // TODO: fix this + { + edges[0].ip = ip; + } private: + bool isEndOfPath(int latch_node_idx) const; Function *Parent; }; diff --git a/include/Procedure.h b/include/Procedure.h index d3b67b1..5a105ca 100644 --- a/include/Procedure.h +++ b/include/Procedure.h @@ -124,6 +124,9 @@ public: r->name = nm; return r; } + bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;} + bool hasRegArgs() const { return (flg & REG_ARGS)!=0;} + bool isLibrary() const { return (flg & PROC_ISLIB)!=0;} void compoundCond(); void writeProcComments(); void lowLevelAnalysis(); @@ -140,10 +143,8 @@ public: void process_operands(ICODE &pIcode, STATE *pstate); boolT process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph); boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate); - void displayCFG(); void freeCFG(); void codeGen(std::ostream &fs); - void displayStats(); void mergeFallThrough(BB *pBB); void structIfs(); void structLoops(derSeq *derivedG); @@ -151,20 +152,25 @@ public: void controlFlowAnalysis(); void newRegArg(iICODE picode, iICODE ticode); void writeProcComments(std::ostream &ostr); + + void displayCFG(); + void displayStats(); + void processHliCall(COND_EXPR *exp, iICODE picode); + +protected: + bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b); bool Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB); bool Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB); bool Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB); bool Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB); void replaceInEdge(BB* where, BB* which, BB* with); - protected: - bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b); + void processExpPush(int &numHlIcodes, iICODE picode); // TODO: replace those with friend visitor ? void propLongReg(int loc_ident_idx, const ID &pLocId); void propLongStk(int i, const ID &pLocId); void propLongGlb(int i, const ID &pLocId); void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong); - void processHliCall(COND_EXPR *exp, iICODE picode); int findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE iter); int findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg); @@ -176,6 +182,6 @@ public: void findIdioms(); void propLong(); void genLiveKtes(); - uint8_t findDerivedSeq (derSeq &derivedGi); + uint8_t findDerivedSeq (derSeq &derivedGi); bool nextOrderGraph(derSeq &derivedGi); }; diff --git a/include/ast.h b/include/ast.h index 2aec461..58372d9 100644 --- a/include/ast.h +++ b/include/ast.h @@ -85,7 +85,7 @@ public: static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du); static COND_EXPR *boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op); static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx); - static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym); + static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym); public: virtual COND_EXPR *clone() const; void release(); @@ -105,8 +105,8 @@ public: virtual ~COND_EXPR() {} public: virtual COND_EXPR *inverse() const; // return new COND_EXPR that is invarse of this - virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc); - virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym); + virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locId); + virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym); virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx); virtual hlType expType(Function *pproc) const; }; @@ -124,7 +124,7 @@ struct BinaryOperator : public COND_EXPR static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r); virtual COND_EXPR *inverse(); virtual COND_EXPR *clone(); - virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc); + virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locs); virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym); virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx); @@ -158,7 +158,7 @@ struct UnaryOperator : public COND_EXPR COND_EXPR *unaryExp; virtual COND_EXPR *inverse(); virtual COND_EXPR *clone(); - virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc); + virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locs); static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr) { UnaryOperator *newExp = new UnaryOperator(); diff --git a/include/bundle.h b/include/bundle.h index 86fc5c3..fd09809 100644 --- a/include/bundle.h +++ b/include/bundle.h @@ -30,6 +30,7 @@ public: } strTable decl; /* Declarations */ strTable code; /* C code */ + int current_indent; }; diff --git a/include/graph.h b/include/graph.h index 941a41e..714b0ed 100644 --- a/include/graph.h +++ b/include/graph.h @@ -28,6 +28,7 @@ enum eBBKind /* Depth-first traversal constants */ enum eDFS { + DFS_NONE, DFS_DISP=1, /* Display graph pass */ DFS_MERGE=2, /* Merge nodes pass */ DFS_NUM=3, /* DFS numbering pass */ diff --git a/include/icode.h b/include/icode.h index 234b873..9828494 100644 --- a/include/icode.h +++ b/include/icode.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "Enums.h" #include "state.h" // State depends on INDEXBASE, but later need STATE //enum condId; @@ -26,6 +27,7 @@ struct ICODE; struct bundle; typedef std::list::iterator iICODE; typedef std::list::reverse_iterator riICODE; +typedef boost::iterator_range rCODE; /* uint8_t and uint16_t registers */ @@ -58,6 +60,7 @@ struct CallType : public HlTypeSupport void allocStkArgs (int num); bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc); void placeStkArg(COND_EXPR *exp, int pos); + virtual COND_EXPR * toId(); public: bool removeRegFromLong(eReg regi, LOCAL_ID *locId) { @@ -285,6 +288,18 @@ protected: HLTYPE m_hl; bool invalid; /* Has no HIGH_LEVEL equivalent */ public: + template + struct FlagFilter + { + bool operator()(ICODE *ic) {return ic->ll()->testFlags(FLAG);} + bool operator()(ICODE &ic) {return ic.ll()->testFlags(FLAG);} + }; + template + struct TypeFilter + { + bool operator()(ICODE *ic) {return ic->type==HIGH_LEVEL;} + bool operator()(ICODE &ic) {return ic.type==HIGH_LEVEL;} + }; /* Def/Use of registers and stack variables */ struct DU_ICODE { @@ -399,6 +414,7 @@ public: ICODE * addIcode(ICODE *pIcode); void SetInBB(int start, int end, BB* pnewBB); + void SetInBB(rCODE &rang, BB* pnewBB); bool labelSrch(uint32_t target, uint32_t &pIndex); iterator labelSrch(uint32_t target); ICODE * GetIcode(int ip); diff --git a/include/locident.h b/include/locident.h index 0673a3d..ae79506 100644 --- a/include/locident.h +++ b/include/locident.h @@ -18,6 +18,7 @@ /* Type definition */ // this array has to stay in-order of addition i.e. not std::set > // TODO: why ? +struct COND_EXPR; struct ICODE; typedef std::list::iterator iICODE; struct IDX_ARRAY : public std::vector @@ -104,6 +105,10 @@ struct ID struct LOCAL_ID { std::vector id_arr; +protected: + int newLongIdx(int16_t seg, int16_t offH, int16_t offL, uint8_t regi, hlType t); + int newLongGlb(int16_t seg, int16_t offH, int16_t offL, hlType t); + int newLongStk(hlType t, int offH, int offL); public: LOCAL_ID() { @@ -122,10 +127,10 @@ public: void flagByteWordId(int off); void propLongId(uint8_t regL, uint8_t regH, const char *name); size_t csym() const {return id_arr.size();} -protected: - int newLongIdx(int16_t seg, int16_t offH, int16_t offL, uint8_t regi, hlType t); - int newLongGlb(int16_t seg, int16_t offH, int16_t offL, hlType t); - int newLongStk(hlType t, int offH, int offL); + void newRegArg(iICODE picode, iICODE ticode) const; + void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const; + void forwardSubs(COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const; + COND_EXPR *createId(const ID *retVal, iICODE ix_); }; diff --git a/include/symtab.h b/include/symtab.h index 386723c..a5ccaf6 100644 --- a/include/symtab.h +++ b/include/symtab.h @@ -50,7 +50,7 @@ struct STKSYM : public SymbolCommon void setArgName(int i) { char buf[32]; - sprintf (buf, "arg%ld", i); + sprintf (buf, "arg%d", i); name = buf; } }; diff --git a/src/BasicBlock.cpp b/src/BasicBlock.cpp index 702cedf..d3c8e7a 100644 --- a/src/BasicBlock.cpp +++ b/src/BasicBlock.cpp @@ -1,10 +1,13 @@ #include #include - +#include +#include +#include #include "BasicBlock.h" #include "Procedure.h" #include "dcc.h" using namespace std; +using namespace boost; BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore) { @@ -12,29 +15,27 @@ BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore) pnewBB->Parent = parent; return pnewBB; } - -BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function *parent) +/** + * @arg start - basic block starts here, might be parent->Icode.end() + * @arg fin - last of basic block's instructions +*/ +BB *BB::Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent) { BB* pnewBB; - pnewBB = new BB; pnewBB->nodeType = _nodeType; /* Initialise */ pnewBB->immedDom = NO_DOM; pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail = - pnewBB->latchNode= pnewBB->loopFollow = NO_NODE; - pnewBB->range_start = parent->Icode.begin(); - pnewBB->range_end = parent->Icode.begin(); - if(start!=-1) + pnewBB->latchNode= pnewBB->loopFollow = NO_NODE; + pnewBB->instructions = make_iterator_range(start,fin); + if(start==parent->Icode.end()) { - advance(pnewBB->range_start,start); - advance(pnewBB->range_end,ip+1); + pnewBB->instructions = make_iterator_range(parent->Icode.end(),parent->Icode.end()); } else { - pnewBB->range_end = parent->Icode.end(); - pnewBB->range_end = parent->Icode.end(); + pnewBB->instructions.advance_end(1); // 1 after fin, to create range where fin is inclusive } - if (numOutEdges) pnewBB->edges.resize(numOutEdges); @@ -42,16 +43,32 @@ BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function * * real code basic blocks (ie. not interval bbs) */ if(parent) { - if (start >= 0) - parent->Icode.SetInBB(start, ip, pnewBB); + if (start != parent->Icode.end()) + parent->Icode.SetInBB(pnewBB->instructions, pnewBB); parent->heldBBs.push_back(pnewBB); parent->m_cfg.push_back(pnewBB); pnewBB->Parent = parent; } - if (start != -1) /* Only for code BB's */ + if ( start != parent->Icode.end() ) /* Only for code BB's */ stats.numBBbef++; return pnewBB; } +BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function *parent) +{ + iICODE st(parent->Icode.begin()); + iICODE fin(parent->Icode.begin()); + if(start==-1) + { + st = parent->Icode.end(); + fin = parent->Icode.end(); + } + else + { + advance(st,start); + advance(fin,ip); + } + return Create(st,fin,_nodeType,numOutEdges,parent); +} static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call", "loop", "repeat", "interval", "cycleHead", @@ -67,7 +84,12 @@ void BB::display() printf("start = %ld, length = %ld, #out edges = %ld\n", begin()->loc_ip, size(), edges.size()); for (size_t i = 0; i < edges.size(); i++) - printf(" outEdge[%2d] = %ld\n",i, edges[i].BBptr->begin()->loc_ip); + { + if(edges[i].BBptr==0) + printf(" outEdge[%2d] = Unlinked out edge to %d\n",i, edges[i].ip); + else + printf(" outEdge[%2d] = %d\n",i, edges[i].BBptr->begin()->loc_ip); + } } /***************************************************************************** * displayDfs - Displays the CFG using a depth first traversal @@ -131,11 +153,63 @@ void BB::displayDfs() * current procedure. * indLevel: indentation level - used for formatting. * numLoc: last # assigned to local variables */ +ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond) +{ + latch = pProc->m_dfsLast[this->latchNode]; + std::ostringstream ostr; + ICODE* picode; + switch (loopType) + { + case WHILE_TYPE: + picode = &this->back(); + + /* Check for error in while condition */ + if (picode->hl()->opcode != HLI_JCOND) + reportError (WHILE_FAIL); + + /* Check if condition is more than 1 HL instruction */ + if (numHlIcodes > 1) + { + /* Write the code for this basic block */ + writeBB(ostr,indLevel, pProc, numLoc); + repCond = true; + } + + /* Condition needs to be inverted if the loop body is along + * the THEN path of the header node */ + if (edges[ELSE].BBptr->dfsLastNum == loopFollow) + { + picode->hl()->replaceExpr(picode->hl()->expr()->inverse()); + } + { + string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc); + ostr << "\n"<invalidate(); + break; + + case REPEAT_TYPE: + ostr << "\n"<back(); + picode->invalidate(); + break; + + case ENDLESS_TYPE: + ostr << "\n"<m_dfsLast[_ifFollow])) return; - if (traversed == DFS_ALPHA) + if (wasTraversedAtLevel(DFS_ALPHA)) return; traversed = DFS_ALPHA; /* Check for start of loop */ repCond = false; latch = NULL; - _loopType = loopType; - if (_loopType) + if (loopType) { - latch = pProc->m_dfsLast[this->latchNode]; - std::ostringstream ostr; - switch (_loopType) - { - case WHILE_TYPE: - picode = &this->back(); - - /* Check for error in while condition */ - if (picode->hl()->opcode != HLI_JCOND) - reportError (WHILE_FAIL); - - /* Check if condition is more than 1 HL instruction */ - if (numHlIcodes > 1) - { - /* Write the code for this basic block */ - writeBB(ostr,indLevel, pProc, numLoc); - repCond = true; - } - - /* Condition needs to be inverted if the loop body is along - * the THEN path of the header node */ - if (edges[ELSE].BBptr->dfsLastNum == loopFollow) - { - picode->hl()->replaceExpr(picode->hl()->expr()->inverse()); - } - { - string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc); - ostr << "\n"<invalidate(); - break; - - case REPEAT_TYPE: - ostr << "\n"<back(); - picode->invalidate(); - break; - - case ENDLESS_TYPE: - ostr << "\n"<dfsLastNum == loopFollow) @@ -238,7 +266,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, /* Loop epilogue: generate the loop trailer */ indLevel--; - if (_loopType == WHILE_TYPE) + if (loopType == WHILE_TYPE) { std::ostringstream ostr; /* Check if there is need to repeat other statements involved @@ -250,9 +278,9 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, ostr <hl()->opcode != HLI_JCOND) reportError (REPEAT_FAIL); @@ -275,7 +303,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, else /* no loop, process nodeType of the graph */ { - if (_nodeType == TWO_BRANCH) /* if-then[-else] */ + if (nodeType == TWO_BRANCH) /* if-then[-else] */ { stats.numHLIcode++; indLevel++; @@ -344,8 +372,11 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, else /* fall, call, 1w */ { succ = edges[0].BBptr; /* fall-through edge */ + assert(succ->size()>0); if (succ->traversed != DFS_ALPHA) + { succ->writeCode (indLevel, pProc,numLoc, _latchNode,_ifFollow); + } } } } @@ -361,7 +392,7 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc) /* Generate code for each hlicode that is not a HLI_JCOND */ - for(ICODE &pHli : *this) + for(ICODE &pHli : instructions) { if ((pHli.type == HIGH_LEVEL) && ( pHli.valid() )) //TODO: use filtering range here. { @@ -379,33 +410,34 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc) iICODE BB::begin() { - return range_start; + return instructions.begin();//range_start; } iICODE BB::end() const { - return range_end; + return instructions.end();//range_end } ICODE &BB::back() { - return *rbegin(); + return instructions.back();//*rbegin(); } size_t BB::size() { - return distance(range_start,range_end); + + return distance(instructions.begin(),instructions.end()); } ICODE &BB::front() { - return *begin(); + return instructions.front();//*begin(); } riICODE BB::rbegin() { - return riICODE(end()); + return riICODE( instructions.end() ); } riICODE BB::rend() { - return riICODE(begin()); + return riICODE( instructions.begin() ); } diff --git a/src/ast.cpp b/src/ast.cpp index 2176b15..95a4792 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -823,7 +823,7 @@ void COND_EXPR::changeBoolOp (condOp newOp) /* Inserts the expression exp into the tree at the location specified by the * register regi */ -bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,LOCAL_ID *locsym) +bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym) { if (tree == NULL) @@ -836,7 +836,7 @@ bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, } return false; } -COND_EXPR *COND_EXPR::insertSubTreeReg (COND_EXPR *_expr, eReg regi,LOCAL_ID *locsym) +COND_EXPR *COND_EXPR::insertSubTreeReg (COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym) { eReg treeReg; diff --git a/src/control.cpp b/src/control.cpp index e59cfbc..4eab9cd 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -2,14 +2,16 @@ * Description : Performs control flow analysis on the CFG * (C) Cristina Cifuentes ********************************************************************/ +#include #include #include #include -#include "dcc.h" #include #include #include +#include "dcc.h" + //typedef struct list { // int nodeIdx; // struct list *next; @@ -577,6 +579,7 @@ bool Function::Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB) hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR)); /* Replace in-edge to obb from t to pbb */ + auto iter=find(obb->inEdges.begin(),obb->inEdges.end(),thenBB); if(iter!=obb->inEdges.end()) *iter = pbb; diff --git a/src/dataflow.cpp b/src/dataflow.cpp index ff01835..5885235 100644 --- a/src/dataflow.cpp +++ b/src/dataflow.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,13 @@ struct ExpStack COND_EXPR * pop(); int numElem(); boolT empty(); + void processExpPush(int &numHlIcodes, iICODE picode) + { + push(picode->hl()->expr()); + picode->invalidate(); + numHlIcodes--; + } + }; /*************************************************************************** * Expression stack functions @@ -266,6 +274,8 @@ void Function::genLiveKtes () * Propagates register usage information to the procedure call. */ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) { + using namespace boost::adaptors; + using namespace boost::assign; BB * pbb=0; /* pointer to current basic block */ Function * pcallee; /* invoked subroutine */ //ICODE *ticode /* icode that invokes a subroutine */ @@ -282,14 +292,10 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) { /* Process nodes in reverse postorder order */ change = false; - //for (i = numBBs; i > 0; i--) - //boost::RandomAccessContainerConcept; - - for(auto iBB=m_dfsLast.rbegin(); iBB!=m_dfsLast.rend(); ++iBB) + auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) ); + for( BB * _pbb : valid_reversed_bbs) { - pbb = *iBB;//m_dfsLast[i-1]; - if (pbb->flg & INVALID_BB) /* Do not process invalid BBs */ - continue; + pbb = _pbb;//*iBB;//m_dfsLast[i-1]; /* Get current liveIn() and liveOut() sets */ prevLiveIn = pbb->liveIn; @@ -307,7 +313,6 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) auto picode = pbb->rbegin(); /* icode of function return */ if (picode->hl()->opcode == HLI_RET) { - //pbb->back().loc_ip picode->hl()->expr(COND_EXPR::idID (&retVal, &localId, (++pbb->rbegin()).base())); picode->du.use = in_liveOut; } @@ -393,6 +398,7 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) void BB::genDU1() { + using namespace boost::adaptors; eReg regi; /* Register that was defined */ int k, defRegIdx, useIdx; iICODE picode, ticode,lastInst; @@ -404,10 +410,13 @@ void BB::genDU1() */ assert(0!=Parent); lastInst = this->end(); - for (picode = this->begin(); picode != lastInst; picode++) + ICODE::TypeFilter zq; + auto all_high_levels = instructions | filtered(zq); + printf("\n"); + for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode) { - if (picode->type != HIGH_LEVEL) - continue; +// if (picode->type != HIGH_LEVEL) +// continue; regi = rUNDEF; defRegIdx = 0; // foreach defined register @@ -428,10 +437,10 @@ void BB::genDU1() continue; if ((regi == rSI) && (flg & SI_REGVAR)) continue; - if (distance(picode,lastInst)>1) /* several instructions */ + if (distance(picode,all_high_levels.end())>1) /* several instructions */ { useIdx = 0; - for (auto ricode = ++iICODE(picode); ricode != lastInst; ricode++) + for (auto ricode = ++iICODE(picode.base()); ricode != lastInst; ricode++) { ticode=ricode; if (ricode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes @@ -503,9 +512,9 @@ void BB::genDU1() /* Backpatch any uses of this instruction, within * the same BB, if the instruction was invalidated */ - for (auto back_patch_at = riICODE(picode); back_patch_at != rend(); back_patch_at++) + for (auto back_patch_at = riICODE(picode.base()); back_patch_at != rend(); back_patch_at++) { - back_patch_at->du1.remove(0,picode); + back_patch_at->du1.remove(0,picode.base()); } } else /* liveOut */ @@ -536,18 +545,15 @@ void Function::genDU1 () /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs * of picode. */ -static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, - iICODE ticode, LOCAL_ID *locsym, int &numHlIcodes) +void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const { - boolT res; + bool res; if (rhs == NULL) /* In case expression popped is NULL */ return; /* Insert on rhs of ticode, if possible */ - res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs,rhs, - locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, - locsym); + res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this); if (res) { picode->invalidate(); @@ -556,9 +562,7 @@ static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, else { /* Try to insert it on lhs of ticode*/ - res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs,rhs, - locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, - locsym); + res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this); if (res) { picode->invalidate(); @@ -599,7 +603,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE /* Returns whether the elements of the expression rhs are all x-clear from * instruction f up to instruction t. */ -bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, Function * pproc) +bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID & locId) { iICODE i; boolT res; @@ -610,7 +614,7 @@ bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, Function * pproc) case IDENTIFIER: if (expr.ident.idType == REGISTER) { - regi= pproc->localId.id_arr[expr.ident.idNode.regiIdx].id.regi; + regi= locId.id_arr[expr.ident.idNode.regiIdx].id.regi; for (i = ++iICODE(f); (i != lastBBinst) && (i!=t); i++) if ((i->type == HIGH_LEVEL) && ( i->valid() )) { @@ -631,38 +635,38 @@ bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, Function * pproc) case BOOLEAN_OP: if(0==rhs()) return false; - res = rhs()->xClear ( f, t, lastBBinst, pproc); + res = rhs()->xClear ( f, t, lastBBinst, locId); if (res == false) return false; if(0==lhs()) return false; - return lhs()->xClear ( f, t, lastBBinst, pproc); + return lhs()->xClear ( f, t, lastBBinst, locId); case NEGATION: case ADDRESSOF: case DEREFERENCE: if(0==expr.unaryExp) return false; - return expr.unaryExp->xClear ( f, t, lastBBinst, pproc); + return expr.unaryExp->xClear ( f, t, lastBBinst, locId); } /* eos */ return false; } -bool UnaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc) +bool UnaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locs) { if(0==unaryExp) return false; - return unaryExp->xClear ( f, t, lastBBinst, pproc); + return unaryExp->xClear ( f, t, lastBBinst, locs); } -bool BinaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc) +bool BinaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locs) { if(0==m_rhs) return false; - if ( ! m_rhs->xClear (f, t, lastBBinst, pproc) ) + if ( ! m_rhs->xClear (f, t, lastBBinst, locs) ) return false; if(0==m_lhs) return false; - return m_lhs->xClear (f, t, lastBBinst, pproc); + return m_lhs->xClear (f, t, lastBBinst, locs); } /* Checks the type of the formal argument as against to the actual argument, * whenever possible, and then places the actual argument on the procedure's @@ -712,37 +716,39 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, int num /** Eliminates extraneous intermediate icode instructions when finding * expressions. Generates new hlIcodes in the form of expression trees. * For HLI_CALL hlIcodes, places the arguments in the argument list. */ -void Function::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) +void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const { boolT res; - switch (ticode->hl()->opcode) { + HLTYPE &p_hl(*picode->hl()); + HLTYPE &t_hl(*ticode->hl()); + switch (t_hl.opcode) + { case HLI_ASSIGN: if(isLong) { - forwardSubsLong (picode->hl()->asgn.lhs->expr.ident.idNode.longIdx, - picode->hl()->asgn.rhs, picode,ticode, + forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx, + p_hl.asgn.rhs, picode,ticode, &numHlIcodes); } else - forwardSubs (picode->hl()->asgn.lhs, picode->hl()->asgn.rhs, - picode, ticode, &localId, numHlIcodes); + this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes); break; case HLI_JCOND: case HLI_PUSH: case HLI_RET: if(isLong) { res = COND_EXPR::insertSubTreeLongReg ( - picode->hl()->asgn.rhs, - &ticode->hl()->exp.v, - picode->hl()->asgn.lhs->expr.ident.idNode.longIdx); + p_hl.asgn.rhs, + &t_hl.exp.v, + p_hl.asgn.lhs->expr.ident.idNode.longIdx); } else { res = COND_EXPR::insertSubTreeReg ( - ticode->hl()->exp.v, - picode->hl()->asgn.rhs, - localId.id_arr[picode->hl()->asgn.lhs->expr.ident.idNode.regiIdx].id.regi, - &localId); + t_hl.exp.v, + p_hl.asgn.rhs, + id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi, + this); } if (res) { @@ -821,274 +827,282 @@ void Function::processHliCall(COND_EXPR *_exp, iICODE picode) } } -void Function::findExps() + +int BB::findBBExps(LOCAL_ID &locals,Function *fnc) { - int i, numHlIcodes; - iICODE - picode, // Current icode */ - ticode; // Target icode */ - BB * pbb; // Current and next basic block */ - boolT res; + bool res; + + ID *_retVal; // function return value COND_EXPR *_exp, // expression pointer - for HLI_POP and HLI_CALL */ *lhs; // exp ptr for return value of a HLI_CALL */ - //STKFRAME * args; // pointer to arguments - for HLI_CALL */ - uint8_t regi; // register(s) to be forward substituted */ - ID *_retVal; // function return value - - /* Initialize expression stack */ - g_exp_stk.init(); - - _exp = 0; - /* Traverse tree in dfsLast order */ - for (i = 0; i < numBBs; i++) + iICODE ticode; // Target icode */ + HLTYPE *ti_hl=0; + uint8_t regi; + numHlIcodes = 0; + // register(s) to be forward substituted */ + for (iICODE picode = begin(); picode != end(); picode++) { - /* Process one BB */ - pbb = m_dfsLast[i]; - if (pbb->flg & INVALID_BB) + if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() )) continue; - numHlIcodes = 0; - for (picode = pbb->begin(); picode != pbb->end(); picode++) + HLTYPE &_icHl(*picode->hl()); + numHlIcodes++; + if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */ { - if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() )) - continue; - numHlIcodes++; - if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */ + /* Check for only one use of this register. If this is + * the last definition of the register in this BB, check + * that it is not liveOut from this basic block */ + if (picode->du1.numUses(0)==1) { - /* Check for only one use of this register. If this is - * the last definition of the register in this BB, check - * that it is not liveOut from this basic block */ - if (picode->du1.numUses(0)==1) + /* Check that this register is not liveOut, if it + * is the last definition of the register */ + regi = picode->du1.regi[0]; + + /* Check if we can forward substitute this register */ + switch (_icHl.opcode) { - /* Check that this register is not liveOut, if it - * is the last definition of the register */ - regi = picode->du1.regi[0]; - - /* Check if we can forward substitute this register */ - switch (picode->hl()->opcode) - { - case HLI_ASSIGN: - /* Replace rhs of current icode into target + case HLI_ASSIGN: + /* Replace rhs of current icode into target * icode expression */ + + ticode = picode->du1.idx[0].uses.front(); + if ((picode->du.lastDefRegi & duReg[regi]).any() && + ((ticode->hl()->opcode != HLI_CALL) && + (ticode->hl()->opcode != HLI_RET))) + continue; + + if (_icHl.asgn.rhs->xClear (picode, + picode->du1.idx[0].uses[0], + end(), locals)) + { + locals.processTargetIcode(picode, numHlIcodes, ticode,false); + } + break; + + case HLI_POP: + ticode = picode->du1.idx[0].uses.front(); + ti_hl = ticode->hl(); + if ((picode->du.lastDefRegi & duReg[regi]).any() && + ((ti_hl->opcode != HLI_CALL) && + (ti_hl->opcode != HLI_RET))) + continue; + + _exp = g_exp_stk.pop(); /* pop last exp pushed */ + switch (ticode->hl()->opcode) { + case HLI_ASSIGN: + locals.forwardSubs(_icHl.expr(), _exp, picode, ticode, numHlIcodes); + break; + + case HLI_JCOND: case HLI_PUSH: case HLI_RET: + res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, + _exp, + locals.id_arr[_icHl.expr()->expr.ident.idNode.regiIdx].id.regi, + &locals); + if (res) + { + picode->invalidate(); + numHlIcodes--; + } + break; + + /****case HLI_CALL: /* register arguments + newRegArg (pProc, picode, ticode); + picode->invalidate(); + numHlIcodes--; + break; */ + } /* eos */ + break; + + case HLI_CALL: + ticode = picode->du1.idx[0].uses.front(); + ti_hl = ticode->hl(); + _retVal = &_icHl.call.proc->retVal; + switch (ti_hl->opcode) + { + case HLI_ASSIGN: + assert(ti_hl->asgn.rhs); + _exp = _icHl.call.toId(); + res = COND_EXPR::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals); + if (! res) + COND_EXPR::insertSubTreeReg (ti_hl->asgn.lhs, _exp,_retVal->id.regi, &locals); + //TODO: HERE missing: 2 regs + picode->invalidate(); + numHlIcodes--; + break; + + case HLI_PUSH: case HLI_RET: + ti_hl->expr( _icHl.call.toId() ); + picode->invalidate(); + numHlIcodes--; + break; + + case HLI_JCOND: + _exp = _icHl.call.toId(); + res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals); + if (res) /* was substituted */ + { + picode->invalidate(); + numHlIcodes--; + } + else /* cannot substitute function */ + { + //picode->loc_ip + lhs = COND_EXPR::idID(_retVal,&locals,picode); + picode->setAsgn(lhs, _exp); + } + break; + } /* eos */ + break; + } /* eos */ + } + } + + else if (picode->du1.numRegsDef == 2) /* long regs */ + { + /* Check for only one use of these registers */ + if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1)) + { + regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this + + switch (_icHl.opcode) + { + case HLI_ASSIGN: + /* Replace rhs of current icode into target + * icode expression */ + if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) + { + ticode = picode->du1.idx[0].uses.front(); + if ((picode->du.lastDefRegi & duReg[regi]).any() && + ((ticode->hl()->opcode != HLI_CALL) && + (ticode->hl()->opcode != HLI_RET))) + continue; + locals.processTargetIcode(picode, numHlIcodes, ticode,true); + } + break; + + case HLI_POP: + if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) + { ticode = picode->du1.idx[0].uses.front(); if ((picode->du.lastDefRegi & duReg[regi]).any() && ((ticode->hl()->opcode != HLI_CALL) && (ticode->hl()->opcode != HLI_RET))) continue; - if (picode->hl()->asgn.rhs->xClear (picode, - picode->du1.idx[0].uses[0], pbb->end(), this)) - { - processTargetIcode(picode, numHlIcodes, ticode,false); - } - break; - - case HLI_POP: - ticode = picode->du1.idx[0].uses.front(); - if ((picode->du.lastDefRegi & duReg[regi]).any() && - ((ticode->hl()->opcode != HLI_CALL) && - (ticode->hl()->opcode != HLI_RET))) - continue; - - _exp = g_exp_stk.pop(); /* pop last exp pushed */ + _exp = g_exp_stk.pop(); /* pop last exp pushed */ switch (ticode->hl()->opcode) { case HLI_ASSIGN: - forwardSubs (picode->hl()->expr(), _exp, - picode, ticode, &localId, - numHlIcodes); + forwardSubsLong (_icHl.expr()->expr.ident.idNode.longIdx, + _exp, picode, ticode, &numHlIcodes); break; - - case HLI_JCOND: case HLI_PUSH: case HLI_RET: - res = COND_EXPR::insertSubTreeReg (ticode->hl()->exp.v, - _exp, - localId.id_arr[picode->hl()->expr()->expr.ident.idNode.regiIdx].id.regi, - &localId); + case HLI_JCOND: case HLI_PUSH: + res = COND_EXPR::insertSubTreeLongReg (_exp, + &ticode->hl()->exp.v, + _icHl.asgn.lhs->expr.ident.idNode.longIdx); if (res) { picode->invalidate(); numHlIcodes--; } break; - - /****case HLI_CALL: /* register arguments - newRegArg (pProc, picode, ticode); - picode->invalidate(); - numHlIcodes--; - break; */ - } /* eos */ - break; - - case HLI_CALL: - ticode = picode->du1.idx[0].uses.front(); - HLTYPE *ti_hl(ticode->hl()); - _retVal = &picode->hl()->call.proc->retVal; - switch (ti_hl->opcode) { - case HLI_ASSIGN: - assert(ti_hl->asgn.rhs); - _exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args); - res = COND_EXPR::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &localId); - if (! res) - COND_EXPR::insertSubTreeReg (ti_hl->asgn.lhs, _exp,_retVal->id.regi, &localId); - //TODO: HERE missing: 2 regs - picode->invalidate(); - numHlIcodes--; - break; - - case HLI_PUSH: case HLI_RET: - ti_hl->expr( COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args) ); - picode->invalidate(); - numHlIcodes--; - break; - - case HLI_JCOND: - _exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args); - res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &localId); - if (res) /* was substituted */ - { - picode->invalidate(); - numHlIcodes--; - } - else /* cannot substitute function */ - { - //picode->loc_ip - lhs = COND_EXPR::idID(_retVal,&localId,picode); - picode->setAsgn(lhs, _exp); - } + case HLI_CALL: /*** missing ***/ break; } /* eos */ - break; - } /* eos */ - } - } + } + break; - else if (picode->du1.numRegsDef == 2) /* long regs */ - { - /* Check for only one use of these registers */ - if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1)) - { - regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this + case HLI_CALL: /* check for function return */ + ticode = picode->du1.idx[0].uses.front(); + switch (ticode->hl()->opcode) + { + case HLI_ASSIGN: + _exp = _icHl.call.toId(); + ticode->hl()->asgn.lhs = + COND_EXPR::idLong(&locals, DST, ticode,HIGH_FIRST, picode, eDEF, ++iICODE(ticode)); + ticode->hl()->asgn.rhs = _exp; + picode->invalidate(); + numHlIcodes--; + break; - switch (picode->hl()->opcode) { - case HLI_ASSIGN: - /* Replace rhs of current icode into target - * icode expression */ - if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) - { - ticode = picode->du1.idx[0].uses.front(); - if ((picode->du.lastDefRegi & duReg[regi]).any() && - ((ticode->hl()->opcode != HLI_CALL) && - (ticode->hl()->opcode != HLI_RET))) - continue; - processTargetIcode(picode, numHlIcodes, ticode,true); - } - break; + case HLI_PUSH: case HLI_RET: + ticode->hl()->expr( _icHl.call.toId() ); + picode->invalidate(); + numHlIcodes--; + break; - case HLI_POP: - if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) - { - ticode = picode->du1.idx[0].uses.front(); - if ((picode->du.lastDefRegi & duReg[regi]).any() && - ((ticode->hl()->opcode != HLI_CALL) && - (ticode->hl()->opcode != HLI_RET))) - continue; - - _exp = g_exp_stk.pop(); /* pop last exp pushed */ - switch (ticode->hl()->opcode) { - case HLI_ASSIGN: - forwardSubsLong (picode->hl()->expr()->expr.ident.idNode.longIdx, - _exp, picode, ticode, &numHlIcodes); - break; - case HLI_JCOND: case HLI_PUSH: - res = COND_EXPR::insertSubTreeLongReg (_exp, - &ticode->hl()->exp.v, - picode->hl()->asgn.lhs->expr.ident.idNode.longIdx); - if (res) - { - picode->invalidate(); - numHlIcodes--; - } - break; - case HLI_CALL: /*** missing ***/ - break; - } /* eos */ - } - break; - - case HLI_CALL: /* check for function return */ - ticode = picode->du1.idx[0].uses.front(); - switch (ticode->hl()->opcode) - { - case HLI_ASSIGN: - _exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args); - ticode->hl()->asgn.lhs = - COND_EXPR::idLong(&localId, DST, ticode,HIGH_FIRST, picode, eDEF, ++iICODE(ticode)); - ticode->hl()->asgn.rhs = _exp; + case HLI_JCOND: + _exp = _icHl.call.toId(); + _retVal = &picode->hl()->call.proc->retVal; + res = COND_EXPR::insertSubTreeLongReg (_exp, + &ticode->hl()->exp.v, + locals.newLongReg ( _retVal->type, _retVal->id.longId.h, + _retVal->id.longId.l, picode)); + if (res) /* was substituted */ + { picode->invalidate(); numHlIcodes--; - break; - - case HLI_PUSH: case HLI_RET: - ticode->hl()->expr( COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args) ); - picode->invalidate(); - numHlIcodes--; - break; - - case HLI_JCOND: - _exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args); - _retVal = &picode->hl()->call.proc->retVal; - res = COND_EXPR::insertSubTreeLongReg (_exp, - &ticode->hl()->exp.v, - localId.newLongReg ( _retVal->type, _retVal->id.longId.h, - _retVal->id.longId.l, picode)); - if (res) /* was substituted */ - { - picode->invalidate(); - numHlIcodes--; - } - else /* cannot substitute function */ - { - lhs = COND_EXPR::idID(_retVal,&localId,picode/*picode->loc_ip*/); - picode->setAsgn(lhs, _exp); - } - break; - } /* eos */ - } /* eos */ - } + } + else /* cannot substitute function */ + { + lhs = locals.createId(_retVal,picode); + picode->setAsgn(lhs, _exp); + } + break; + } /* eos */ + } /* eos */ } + } + /* HLI_PUSH doesn't define any registers, only uses registers. + * Push the associated expression to the register on the local + * expression stack */ + else if (_icHl.opcode == HLI_PUSH) + { + g_exp_stk.processExpPush(numHlIcodes, picode); + } + else if(picode->du1.numRegsDef!=0) + printf("Num def %d\n",picode->du1.numRegsDef); - /* HLI_PUSH doesn't define any registers, only uses registers. - * Push the associated expression to the register on the local - * expression stack */ - else if (picode->hl()->opcode == HLI_PUSH) + /* For HLI_CALL instructions that use arguments from the stack, + * pop them from the expression stack and place them on the + * procedure's argument list */ + if(_icHl.opcode == HLI_CALL) + { + if ( not _icHl.call.proc->hasRegArgs()) { - g_exp_stk.push(picode->hl()->expr()); - picode->invalidate(); - numHlIcodes--; - } - - /* For HLI_CALL instructions that use arguments from the stack, - * pop them from the expression stack and place them on the - * procedure's argument list */ - - if ((picode->hl()->opcode == HLI_CALL) && ! (picode->hl()->call.proc->flg & REG_ARGS)) - { - processHliCall(_exp, picode); + fnc->processHliCall(_exp, picode); } /* If we could not substitute the result of a function, * assign it to the corresponding registers */ - if ((picode->hl()->opcode == HLI_CALL) && - ((picode->hl()->call.proc->flg & PROC_ISLIB) != - PROC_ISLIB) && (not picode->du1.used(0)) && - (picode->du1.numRegsDef > 0)) + if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0)) { - _exp = COND_EXPR::idFunc (picode->hl()->call.proc, picode->hl()->call.args); - lhs = COND_EXPR::idID (&picode->hl()->call.proc->retVal, &localId, picode); + _exp = COND_EXPR::idFunc (_icHl.call.proc, _icHl.call.args); + lhs = COND_EXPR::idID (&_icHl.call.proc->retVal, &locals, picode); picode->setAsgn(lhs, _exp); } } + } + /* Store number of high-level icodes in current basic block */ + +} + +void Function::findExps() +{ + //int i, numHlIcodes; + //STKFRAME * args; // pointer to arguments - for HLI_CALL */ + + /* Initialize expression stack */ + g_exp_stk.init(); + + /* Traverse tree in dfsLast order */ +// for (i = 0; i < numBBs; i++) + for(BB *pbb : m_dfsLast) + { + /* Process one BB */ +// pbb = m_dfsLast[i]; + if (not pbb->valid()) + continue; + pbb->findBBExps( this->localId, this); - /* Store number of high-level icodes in current basic block */ - pbb->numHlIcodes = numHlIcodes; } } @@ -1126,25 +1140,21 @@ void Function::dataFlow(std::bitset<32> &_liveOut) if(isAL && isAH) { isAx = true; - printf("**************************************************************************** dataFlow Join discovered Ax\n"); isAH=isAL=false; } if(isDL && isDH) { isDx = true; - printf("**************************************************************************** dataFlow Join discovered Dx\n"); isDH=isDL=false; } if(isBL && isBH) { isBx = true; - printf("**************************************************************************** dataFlow Join discovered Dx\n"); isBH=isBL=false; } if(isCL && isCH) { isCx = true; - printf("**************************************************************************** dataFlow Join discovered Dx\n"); isCH=isCL=false; } @@ -1173,7 +1183,6 @@ void Function::dataFlow(std::bitset<32> &_liveOut) } else if(isAL||isBL||isCL||isDL) { - printf("**************************************************************************** AL/DL return \n"); retVal.type = TYPE_BYTE_SIGN; retVal.loc = REG_FRAME; if (isAL) diff --git a/src/graph.cpp b/src/graph.cpp index 5b05db9..29c61e4 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -30,23 +30,26 @@ void Function::createCFG() * 6) End of procedure */ int i; - int ip, start; + int ip; BB * psBB; BB * pBB; iICODE pIcode = Icode.begin(); - + iICODE iStart = Icode.begin(); stats.numBBbef = stats.numBBaft = 0; - for (ip = start = 0; pIcode!=Icode.end(); ip++, pIcode++) + for (; pIcode!=Icode.end(); ++pIcode) { + iICODE nextIcode = ++iICODE(pIcode); LLInst *ll = pIcode->ll(); /* Stick a NOWHERE_NODE on the end if we terminate * with anything other than a ret, jump or terminate */ - if (ip + 1 == Icode.size() and + if (nextIcode == Icode.end() and (not ll->testFlags(TERMINATES)) and (not ll->match(iJMP)) and (not ll->match(iJMPF)) and (not ll->match(iRET)) and (not ll->match(iRETF))) { - pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this); + //pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this); + pBB=BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this); + } /* Only process icodes that have valid instructions */ @@ -58,10 +61,11 @@ void Function::createCFG() case iJE: case iJNE: case iJS: case iJNS: case iJO: case iJNO: case iJP: case iJNP: case iJCXZ: - pBB = BB::Create(start, ip, TWO_BRANCH, 2, this); + pBB = BB::Create(iStart, pIcode, TWO_BRANCH, 2, this); CondJumps: - start = ip + 1; - pBB->edges[0].ip = (uint32_t)start; + //start = ip + 1; + iStart = ++iICODE(pIcode); + pBB->edges[0].ip = (uint32_t)iStart->loc_ip; /* This is for jumps off into nowhere */ if ( ll->testFlags(NO_LABEL) ) { @@ -72,25 +76,29 @@ CondJumps: break; case iLOOP: case iLOOPE: case iLOOPNE: - pBB = BB::Create(start, ip, LOOP_NODE, 2, this); + //pBB = BB::Create(start, ip, LOOP_NODE, 2, this); + pBB = BB::Create(iStart, pIcode, LOOP_NODE, 2, this); goto CondJumps; case iJMPF: case iJMP: if (ll->testFlags(SWITCH)) { - pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this); + //pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this); + pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl.numEntries, this); for (i = 0; i < ll->caseTbl.numEntries; i++) pBB->edges[i].ip = ll->caseTbl.entries[i]; hasCase = true; } else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT { - pBB = BB::Create(start, ip, ONE_BRANCH, 1, this); + //pBB = BB::Create(start, ip, ONE_BRANCH, 1, this); + pBB = BB::Create(iStart, pIcode, ONE_BRANCH, 1, this); + pBB->edges[0].ip = ll->src.op(); } else - BB::Create(start, ip, NOWHERE_NODE, 0, this); - start = ip + 1; + BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this); + iStart = ++iICODE(pIcode); break; case iCALLF: case iCALL: @@ -100,16 +108,17 @@ CondJumps: i = ((p->flg) & TERMINATES) ? 0 : 1; else i = 1; - pBB = BB::Create(start, ip, CALL_NODE, i, this); - start = ip + 1; + pBB = BB::Create(iStart, pIcode, CALL_NODE, i, this); + iStart = ++iICODE(pIcode);//start = ip + 1; if (i) - pBB->edges[0].ip = (uint32_t)start; + pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start; } break; case iRET: case iRETF: - BB::Create(start, ip, RETURN_NODE, 0, this); - start = ip + 1; + //BB::Create(start, ip, RETURN_NODE, 0, this); + BB::Create(iStart, pIcode, RETURN_NODE, 0, this); + iStart = ++iICODE(pIcode); break; default: @@ -117,18 +126,20 @@ CondJumps: iICODE next1=++iICODE(pIcode); if ( ll->testFlags(TERMINATES) ) { - pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this); - start = ip + 1; + pBB = BB::Create(iStart, pIcode, TERMINATE_NODE, 0, this); + //pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this); + iStart = ++iICODE(pIcode); // start = ip + 1; } /* Check for a fall through */ else if (next1 != Icode.end()) { - assert(next1->loc_ip==ip+1); if (next1->ll()->testFlags(TARGET | CASE)) { - pBB = BB::Create(start, ip, FALL_NODE, 1, this); - start = ip + 1; - pBB->edges[0].ip = (uint32_t)start; + //pBB = BB::Create(start, ip, FALL_NODE, 1, this); + pBB = BB::Create(iStart, pIcode, FALL_NODE, 1, this); + iStart = ++iICODE(pIcode); // start = ip + 1; + pBB->addOutEdge(iStart->loc_ip); + pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start; } } break; @@ -142,7 +153,7 @@ CondJumps: pBB = *iter; for (size_t edeg_idx = 0; edeg_idx < pBB->edges.size(); edeg_idx++) { - ip = pBB->edges[edeg_idx].ip; + uint32_t ip = pBB->edges[edeg_idx].ip; if (ip >= SYNTHESIZED_MIN) { fatalError (INVALID_SYNTHETIC_BB); @@ -273,13 +284,13 @@ void Function::compressCFG() ***************************************************************************/ BB *BB::rmJMP(int marker, BB * pBB) { - marker += DFS_JMP; + marker += (int)DFS_JMP; while (pBB->nodeType == ONE_BRANCH && pBB->size() == 1) { if (pBB->traversed != marker) { - pBB->traversed = marker; + pBB->traversed = (eDFS)marker; pBB->inEdges.pop_back(); if (not pBB->inEdges.empty()) { @@ -347,15 +358,14 @@ void BB::mergeFallThrough( CIcodeRec &Icode) back().ll()->setFlags(NO_CODE); back().invalidate(); nodeType = FALL_NODE; - range_end--; - + //instructions.advance_end(-1); //TODO: causes creation of empty BB } /* If there's no other edges into child can merge */ if (pChild->inEdges.size() != 1) break; nodeType = pChild->nodeType; - range_end = pChild->range_end; + instructions = boost::make_iterator_range(begin(),pChild->end()); pChild->front().ll()->clrFlags(TARGET); edges.swap(pChild->edges); diff --git a/src/icode.cpp b/src/icode.cpp index f687819..a84fe2f 100644 --- a/src/icode.cpp +++ b/src/icode.cpp @@ -36,6 +36,14 @@ void CIcodeRec::SetInBB(int start, int _end, BB *pnewBB) } } +void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB) +{ + for(ICODE &ic : rang) + { + ic.inBB = pnewBB; + } +} + /* labelSrchRepl - Searches the icodes for instruction with label = target, and replaces *pIndex with an icode index */ bool CIcodeRec::labelSrch(uint32_t target, uint32_t &pIndex) diff --git a/src/locident.cpp b/src/locident.cpp index 0399a72..1d26cc0 100644 --- a/src/locident.cpp +++ b/src/locident.cpp @@ -176,7 +176,12 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_) id_arr[idx].id.longId.l = regL; return (idx); } - +/* Returns an identifier conditional expression node of type TYPE_LONG or + * TYPE_WORD_SIGN */ +COND_EXPR * LOCAL_ID::createId(const ID *retVal, iICODE ix_) +{ + return COND_EXPR::idID(retVal,this,ix_); +} /* Checks if the entry exists in the locSym, if so, returns the idx to this * entry; otherwise creates a new global identifier node of type diff --git a/src/procs.cpp b/src/procs.cpp index 972cef5..f164167 100644 --- a/src/procs.cpp +++ b/src/procs.cpp @@ -92,11 +92,11 @@ void CALL_GRAPH::write() /* Updates the argument table by including the register(s) (ie. lhs of * picode) and the actual expression (ie. rhs of picode). * Note: register(s) are only included once in the table. */ -void Function::newRegArg(iICODE picode, iICODE ticode) +void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const { COND_EXPR *lhs; STKFRAME * call_args_stackframe, *target_stackframe; - ID *id; + const ID *id; int tidx; boolT regExist; condId type; @@ -114,7 +114,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode) type = lhs->expr.ident.idType; if (type == REGISTER) { - regL = localId.id_arr[lhs->expr.ident.idNode.regiIdx].id.regi; + regL = id_arr[lhs->expr.ident.idNode.regiIdx].id.regi; if (regL < rAL) tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL); else @@ -122,28 +122,28 @@ void Function::newRegArg(iICODE picode, iICODE ticode) } else if (type == LONG_VAR) { - regL = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l; - regH = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.h; + int longIdx = lhs->expr.ident.idNode.longIdx; + regL = id_arr[longIdx].id.longId.l; + regH = id_arr[longIdx].id.longId.h; tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/); - //tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, Icode.begin() /*0*/); } /* Check if register argument already on the formal argument list */ regExist = false; for(STKSYM &tgt_sym : *target_stackframe) { + if( tgt_sym.regs == NULL ) // both REGISTER and LONG_VAR require this precondition + continue; if (type == REGISTER) { - if ((tgt_sym.regs != NULL) && - (tgt_sym.regs->expr.ident.idNode.regiIdx == tidx)) + if ( tgt_sym.regs->expr.ident.idNode.regiIdx == tidx ) { regExist = true; } } else if (type == LONG_VAR) { - if ((tgt_sym.regs != NULL) && - (tgt_sym.regs->expr.ident.idNode.longIdx == tidx)) + if ( tgt_sym.regs->expr.ident.idNode.longIdx == tidx ) { regExist = true; } @@ -192,7 +192,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode) /* Mask off high and low register(s) in picode */ switch (type) { case REGISTER: - id = &localId.id_arr[lhs->expr.ident.idNode.regiIdx]; + id = &id_arr[lhs->expr.ident.idNode.regiIdx]; picode->du.def &= maskDuReg[id->id.regi]; if (id->id.regi < rAL) newsym.type = TYPE_WORD_SIGN; @@ -200,7 +200,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode) newsym.type = TYPE_BYTE_SIGN; break; case LONG_VAR: - id = &localId.id_arr[lhs->expr.ident.idNode.longIdx]; + id = &id_arr[lhs->expr.ident.idNode.longIdx]; picode->du.def &= maskDuReg[id->id.longId.h]; picode->du.def &= maskDuReg[id->id.longId.l]; newsym.type = TYPE_LONG_SIGN; @@ -252,6 +252,11 @@ void CallType::placeStkArg (COND_EXPR *exp, int pos) (*args)[pos].setArgName(pos); } +COND_EXPR *CallType::toId() +{ + return COND_EXPR::idFunc( proc, args); +} + /* Checks to determine whether the expression (actual argument) has the * same type as the given type (from the procedure's formal list). If not,