Browse Source

dataflow uses iterators now

Artur K 12 years ago
parent
commit
a007955543
6 changed files with 110 additions and 110 deletions
  1. 2 0
      include/BasicBlock.h
  2. 2 0
      include/icode.h
  3. 13 2
      src/BasicBlock.cpp
  4. 73 89
      src/dataflow.cpp
  5. 14 10
      src/graph.cpp
  6. 6 9
      src/proplong.cpp

+ 2 - 0
include/BasicBlock.h

@@ -45,6 +45,8 @@ public:
     Int	   end();
     Int    rbegin();
     Int    rend();
+    riICODE rbegin2();
+    riICODE rend2();
     ICODE &front();
     ICODE &back();
     size_t size();

+ 2 - 0
include/icode.h

@@ -327,6 +327,7 @@ struct DU1
     IC ic;/* intermediate code        */
     int loc_ip; // used by CICodeRec to number ICODEs
 
+    void  ClrLlFlag(dword flag) {ic.ll.flg &= ~flag;}
     void  SetLlFlag(dword flag) {ic.ll.flg |= flag;}
     dword GetLlFlag() {return ic.ll.flg;}
     bool isLlFlag(dword flg) {return (ic.ll.flg&flg)==flg;}
@@ -373,3 +374,4 @@ public:
     ICODE *	GetIcode(int ip);
 };
 typedef CIcodeRec::iterator iICODE;
+typedef CIcodeRec::reverse_iterator riICODE;

+ 13 - 2
src/BasicBlock.cpp

@@ -55,8 +55,7 @@ static const char *const s_loopType[] = {"noLoop", "while", "repeat", "loop", "f
 void BB::display()
 {
     printf("\nnode type = %s, ", s_nodeType[nodeType]);
-    printf("start = %ld, length = %ld, #out edges = %ld\n",
-           start, length, edges.size());
+    printf("start = %ld, length = %ld, #out edges = %ld\n", start, length, edges.size());
 
     for (int i = 0; i < edges.size(); i++)
         printf(" outEdge[%2d] = %ld\n",i, edges[i].BBptr->start);
@@ -386,3 +385,15 @@ ICODE &BB::front()
 {
     return Parent->Icode[start];
 }
+
+riICODE BB::rbegin2()
+{
+    riICODE res(Parent->Icode.begin()+start+length);
+    assert(res->loc_ip==back().loc_ip);
+    return res;
+}
+riICODE BB::rend2()
+{
+    riICODE res(Parent->Icode.begin()+start);
+    return res;
+}

+ 73 - 89
src/dataflow.cpp

@@ -55,67 +55,59 @@ static COND_EXPR *dstIdent (ICODE * pIcode, Function * pProc, Int i, ICODE * duI
 /* Eliminates all condition codes and generates new hlIcode instructions */
 void Function::elimCondCodes ()
 {
-    Int i,
-            useAt,            /* Index to instruction that used flag    */
-            defAt;            /* Index to instruction that defined flag */
-    byte use;             /* Used flags bit vector                  */
-    byte def;             /* Defined flags bit vector               */
-    boolT notSup;         /* Use/def combination not supported      */
-    COND_EXPR *rhs;       /* Source operand                         */
-    COND_EXPR *lhs;       /* Destination operand                    */
-    COND_EXPR *exp;       /* Boolean expression                     */
-    BB * pBB;              /* Pointer to BBs in dfs last ordering    */
-    ICODE *prev;          /* For extended basic blocks - previous icode inst */
+    Int i;
 
+    byte use;           /* Used flags bit vector                  */
+    byte def;           /* Defined flags bit vector               */
+    boolT notSup;       /* Use/def combination not supported      */
+    COND_EXPR *rhs;     /* Source operand                         */
+    COND_EXPR *lhs;     /* Destination operand                    */
+    COND_EXPR *exp;     /* Boolean expression                     */
+    BB * pBB;           /* Pointer to BBs in dfs last ordering    */
+    riICODE useAt;      /* Instruction that used flag    */
+    riICODE defAt;      /* Instruction that defined flag */
     for (i = 0; i < numBBs; i++)
     {
         pBB = dfsLast[i];
-        if (pBB->flg & INVALID_BB)	continue; /* Do not process invalid BBs */
+        if (pBB->flg & INVALID_BB)
+            continue; /* Do not process invalid BBs */
 
-        for (useAt = pBB->start + pBB->length; useAt != pBB->start; useAt--)
-            if ((Icode.GetIcode(useAt-1)->type == LOW_LEVEL) &&
-                (Icode.GetIcode(useAt-1)->invalid == FALSE) &&
-                (use = Icode.GetIcode(useAt-1)->ic.ll.flagDU.u))
+        for (useAt = pBB->rbegin2(); useAt != pBB->rend2(); useAt++)
+        {
+            if ((useAt->type == LOW_LEVEL) &&
+                    (useAt->invalid == FALSE) &&
+                    (use = useAt->ic.ll.flagDU.u))
             {
                 /* Find definition within the same basic block */
-                for (defAt = useAt-1; defAt != pBB->start; defAt--)
+                for (defAt = useAt+1; defAt != pBB->rend2(); defAt++)
                 {
-                    def = Icode.GetIcode(defAt-1)->ic.ll.flagDU.d;
+                    def = defAt->ic.ll.flagDU.d;
                     if ((use & def) == use)
                     {
                         notSup = FALSE;
-                        if ((Icode.GetLlOpcode(useAt-1) >= iJB) &&
-                            (Icode.GetLlOpcode(useAt-1) <= iJNS))
+                        if ((useAt->GetLlOpcode() >= iJB) && (useAt->GetLlOpcode() <= iJNS))
                         {
-                            switch (Icode.GetLlOpcode(defAt-1))
+                            switch (defAt->GetLlOpcode())
                             {
                                 case iCMP:
-                                    rhs = srcIdent (Icode.GetIcode(defAt-1),
-                                                    this, defAt-1,
-                                                    Icode.GetIcode(useAt-1), eUSE);
-                                    lhs = dstIdent (Icode.GetIcode(defAt-1),
-                                                    this, defAt-1,
-                                                    Icode.GetIcode(useAt-1), eUSE);
+                                    rhs = srcIdent (&(*defAt), this, defAt->loc_ip,&(*useAt), eUSE);
+                                    lhs = dstIdent (&(*defAt), this, defAt->loc_ip,&(*useAt), eUSE);
                                     break;
 
                                 case iOR:
-                                    lhs = Icode.GetIcode(defAt-1)->ic.hl.oper.asgn.lhs->clone();
-                                    Icode[useAt-1].copyDU(Icode[defAt-1], eUSE, eDEF);
-                                    if (Icode.GetLlFlag(defAt-1) & B)
+                                    lhs = defAt->ic.hl.oper.asgn.lhs->clone();
+                                    useAt->copyDU(*defAt, eUSE, eDEF);
+                                    if (defAt->isLlFlag(B))
                                         rhs = COND_EXPR::idKte (0, 1);
                                     else
                                         rhs = COND_EXPR::idKte (0, 2);
                                     break;
 
                                 case iTEST:
-                                    rhs = srcIdent (Icode.GetIcode(defAt-1),
-                                                    this, defAt-1,
-                                                    Icode.GetIcode(useAt-1), eUSE);
-                                    lhs = dstIdent (Icode.GetIcode(defAt-1),
-                                                    this, defAt-1,
-                                                    Icode.GetIcode(useAt-1), eUSE);
+                                    rhs = srcIdent (&(*defAt),this, defAt->loc_ip,&(*useAt), eUSE);
+                                    lhs = dstIdent (&(*defAt),this, defAt->loc_ip,&(*useAt), eUSE);
                                     lhs = COND_EXPR::boolOp (lhs, rhs, AND);
-                                    if (Icode.GetLlFlag(defAt-1) & B)
+                                    if (defAt->isLlFlag(B))
                                         rhs = COND_EXPR::idKte (0, 1);
                                     else
                                         rhs = COND_EXPR::idKte (0, 2);
@@ -123,31 +115,29 @@ void Function::elimCondCodes ()
 
                                 default:
                                     notSup = TRUE;
-                                    reportError (JX_NOT_DEF, Icode.GetLlOpcode(defAt-1));
+                                    reportError (JX_NOT_DEF, defAt->GetLlOpcode());
                                     flg |= PROC_ASM;		/* generate asm */
                             }
                             if (! notSup)
                             {
                                 exp = COND_EXPR::boolOp (lhs, rhs,
-                                                   condOpJCond[Icode.GetLlOpcode(useAt-1)-iJB]);
-                                Icode.GetIcode(useAt-1)->setJCond(exp);
+                                                         condOpJCond[useAt->GetLlOpcode()-iJB]);
+                                useAt->setJCond(exp);
                             }
                         }
 
-                        else if (Icode.GetLlOpcode(useAt-1) == iJCXZ)
+                        else if (useAt->GetLlOpcode() == iJCXZ)
                         {
                             lhs = COND_EXPR::idReg (rCX, 0, &localId);
-                            Icode.GetIcode(useAt-1)->setRegDU (rCX, eUSE);
+                            useAt->setRegDU (rCX, eUSE);
                             rhs = COND_EXPR::idKte (0, 2);
                             exp = COND_EXPR::boolOp (lhs, rhs, EQUAL);
-                            Icode.GetIcode(useAt-1)->setJCond(exp);
+                            useAt->setJCond(exp);
                         }
 
                         else
                         {
-                            reportError (NOT_DEF_USE,
-                                         Icode.GetLlOpcode(defAt-1),
-                                         Icode.GetLlOpcode(useAt-1));
+                            reportError (NOT_DEF_USE,defAt->GetLlOpcode(),useAt->GetLlOpcode());
                             flg |= PROC_ASM;		/* generate asm */
                         }
                         break;
@@ -155,26 +145,25 @@ void Function::elimCondCodes ()
                 }
 
                 /* Check for extended basic block */
-                if ((pBB->length == 1) &&
-                    (Icode.GetLlOpcode(useAt-1) >= iJB) &&
-                    (Icode.GetLlOpcode(useAt-1) <= iJNS))
+                if ((pBB->length == 1) &&(useAt->GetLlOpcode() >= iJB) && (useAt->GetLlOpcode() <= iJNS))
                 {
-                    ICODE & prev(pBB->back());
+                    ICODE & prev(pBB->back()); /* For extended basic blocks - previous icode inst */
                     if (prev.ic.hl.opcode == HLI_JCOND)
                     {
                         exp = prev.ic.hl.oper.exp->clone();
-                        exp->changeBoolOp (condOpJCond[Icode.GetLlOpcode(useAt-1)-iJB]);
-                        Icode[useAt-1].copyDU(prev, eUSE, eUSE);
-                        Icode[useAt-1].setJCond(exp);
+                        exp->changeBoolOp (condOpJCond[useAt->GetLlOpcode()-iJB]);
+                        useAt->copyDU(prev, eUSE, eUSE);
+                        useAt->setJCond(exp);
                     }
                 }
                 /* Error - definition not found for use of a cond code */
-                else if (defAt == pBB->start)
+                else if (defAt == pBB->rend2())
                 {
-                    reportError(DEF_NOT_FOUND,Icode.GetLlOpcode(useAt-1));
+                    reportError(DEF_NOT_FOUND,useAt->GetLlOpcode());
                     //fatalError (DEF_NOT_FOUND, Icode.GetLlOpcode(useAt-1));
                 }
             }
+        }
     }
 }
 
@@ -219,8 +208,8 @@ void Function::liveRegAnalysis (dword in_liveOut)
     Int i, j;
     BB * pbb=0;              /* pointer to current basic block   */
     Function * pcallee;        /* invoked subroutine               */
-    ICODE  *ticode,        /* icode that invokes a subroutine  */
-            *picode;		/* icode of function return			*/
+    ICODE  *ticode        /* icode that invokes a subroutine  */
+            ;
     dword prevLiveOut,	/* previous live out 				*/
             prevLiveIn;		/* previous live in					*/
     boolT change;			/* is there change in the live sets?*/
@@ -244,7 +233,7 @@ void Function::liveRegAnalysis (dword in_liveOut)
             prevLiveOut = pbb->liveOut;
 
             /* liveOut(b) = U LiveIn(s); where s is successor(b)
-         * liveOut(b) = {liveOut}; when b is a HLI_RET node     */
+             * liveOut(b) = {liveOut}; when b is a HLI_RET node     */
             if (pbb->edges.empty())      /* HLI_RET node         */
             {
                 pbb->liveOut = in_liveOut;
@@ -252,10 +241,9 @@ void Function::liveRegAnalysis (dword in_liveOut)
                 /* Get return expression of function */
                 if (flg & PROC_IS_FUNC)
                 {
-                    picode = Icode.GetIcode(pbb->start + pbb->length - 1);
+                    auto picode = pbb->rbegin2(); /* icode of function return */
                     if (picode->ic.hl.opcode == HLI_RET)
                     {
-                        assert(pbb->back().loc_ip == pbb->start+pbb->length-1);
                         picode->ic.hl.oper.exp = COND_EXPR::idID (&retVal, &localId, pbb->back().loc_ip);
                         picode->du.use = in_liveOut;
                     }
@@ -269,8 +257,8 @@ void Function::liveRegAnalysis (dword in_liveOut)
                 /* propagate to invoked procedure */
                 if (pbb->nodeType == CALL_NODE)
                 {
-                    ticode = Icode.GetIcode(pbb->start + pbb->length - 1);
-                    pcallee = ticode->ic.hl.oper.call.proc;
+                    ICODE &ticode(pbb->back());
+                    pcallee = ticode.ic.hl.oper.call.proc;
 
                     /* user/runtime routine */
                     if (! (pcallee->flg & PROC_ISLIB))
@@ -292,17 +280,17 @@ void Function::liveRegAnalysis (dword in_liveOut)
                     {
                         switch (pcallee->retVal.type) {
                             case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
-                                ticode->du1.numRegsDef = 2;
+                                ticode.du1.numRegsDef = 2;
                                 break;
                             case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
                             case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
-                                ticode->du1.numRegsDef = 1;
+                                ticode.du1.numRegsDef = 1;
                                 break;
                         } /*eos*/
 
                         /* Propagate def/use results to calling icode */
-                        ticode->du.use = pcallee->liveIn;
-                        ticode->du.def = pcallee->liveOut;
+                        ticode.du.use = pcallee->liveIn;
+                        ticode.du.def = pcallee->liveOut;
                     }
                 }
             }
@@ -338,8 +326,8 @@ void Function::liveRegAnalysis (dword in_liveOut)
 void Function::genDU1 ()
 {
     byte regi;            /* Register that was defined */
-    Int i, j, k, p, n, lastInst, defRegIdx, useIdx;
-    ICODE * picode, *ticode;/* Current and target bb    */
+    Int i,  k, defRegIdx, useIdx;
+    iICODE picode, ticode,lastInst;/* Current and target bb    */
     BB * pbb, *tbb;         /* Current and target basic block */
     boolT res;
     COND_EXPR *exp, *lhs;
@@ -353,10 +341,9 @@ void Function::genDU1 ()
         /* Process each register definition of a HIGH_LEVEL icode instruction.
          * Note that register variables should not be considered registers.
          */
-        lastInst = pbb->start + pbb->length;
-        for (j = pbb->start; j < lastInst; j++)
+        lastInst = pbb->end2();
+        for (picode = pbb->begin2(); picode != lastInst; picode++)
         {
-            picode = Icode.GetIcode(j);
             if (picode->type == HIGH_LEVEL)
             {
                 regi = 0;
@@ -369,34 +356,33 @@ void Function::genDU1 ()
                         picode->du1.regi[defRegIdx] = regi;
 
                         /* Check remaining instructions of the BB for all uses
-                     * of register regi, before any definitions of the
-                     * register */
+                         * of register regi, before any definitions of the
+                         * register */
                         if ((regi == rDI) && (flg & DI_REGVAR))
                             continue;
                         if ((regi == rSI) && (flg & SI_REGVAR))
                             continue;
-                        if ((j + 1) < lastInst)		/* several instructions */
+                        if ((picode + 1) != lastInst)		/* several instructions */
                         {
                             useIdx = 0;
-                            for (n = j+1; n < lastInst; n++)
+                            for (auto ricode = picode + 1; ricode != lastInst; ricode++)
                             {
+                                ticode=ricode;
                                 /* Only check uses of HIGH_LEVEL icodes */
-                                ticode = Icode.GetIcode(n);
-                                if (ticode->type == HIGH_LEVEL)
+                                if (ricode->type == HIGH_LEVEL)
                                 {
                                     /* if used, get icode index */
-                                    if (ticode->du.use & duReg[regi])
-                                        picode->du1.idx[defRegIdx][useIdx++] = n;
+                                    if (ricode->du.use & duReg[regi])
+                                        picode->du1.idx[defRegIdx][useIdx++] = ricode->loc_ip;
 
                                     /* if defined, stop finding uses for this reg */
-                                    if (ticode->du.def & duReg[regi])
+                                    if (ricode->du.def & duReg[regi])
                                         break;
                                 }
                             }
 
                             /* Check if last definition of this register */
-                            if ((! (ticode->du.def & duReg[regi])) &&
-                                (pbb->liveOut & duReg[regi]))
+                            if ((! (ticode->du.def & duReg[regi])) && (pbb->liveOut & duReg[regi]))
                                 picode->du.lastDefRegi |= duReg[regi];
                         }
                         else		/* only 1 instruction in this basic block */
@@ -415,14 +401,13 @@ void Function::genDU1 ()
                         {
                             tbb = pbb->edges[0].BBptr;
                             useIdx = 0;
-                            for (n = tbb->start; n < tbb->start + tbb->length; n++)
+                            for (ticode = tbb->begin2(); ticode != tbb->end2(); ticode++)
                             {
-                                ticode = Icode.GetIcode(n);
                                 if (ticode->type == HIGH_LEVEL)
                                 {
                                     /* if used, get icode index */
                                     if (ticode->du.use & duReg[regi])
-                                        picode->du1.idx[defRegIdx][useIdx++] = n;
+                                        picode->du1.idx[defRegIdx][useIdx++] = ticode->loc_ip;
 
                                     /* if defined, stop finding uses for this reg */
                                     if (ticode->du.def & duReg[regi])
@@ -458,12 +443,11 @@ void Function::genDU1 ()
                                 /* Backpatch any uses of this instruction, within
                                  * the same BB, if the instruction was invalidated */
                                 if (res == TRUE)
-                                    for (p = j; p > pbb->start; p--)
+                                    for (auto ticode = riICODE(picode); ticode != pbb->rend2(); ticode++)
                                     {
-                                        ticode = Icode.GetIcode(p-1);
-                                        for (n = 0; n < MAX_USES; n++)
+                                        for (int n = 0; n < MAX_USES; n++)
                                         {
-                                            if (ticode->du1.idx[0][n] == j)
+                                            if (ticode->du1.idx[0][n] == picode->loc_ip)
                                             {
                                                 if (n < MAX_USES - 1)
                                                 {

+ 14 - 10
src/graph.cpp

@@ -289,7 +289,7 @@ BB *BB::rmJMP(Int marker, BB * pBB)
         {
             /* We are going around in circles */
             pBB->nodeType = NOWHERE_NODE;
-            pBB->front().ic.ll.immed.op = (dword)pBB->start;
+            pBB->front().ic.ll.immed.op = pBB->front().loc_ip;
             do {
                 pBB = pBB->edges[0].BBptr;
                 pBB->inEdges.pop_back(); // was --numInedges
@@ -315,7 +315,7 @@ BB *BB::rmJMP(Int marker, BB * pBB)
 void BB::mergeFallThrough( CIcodeRec &Icode)
 {
     BB *	pChild;
-    Int	i, _ip;
+    Int	i;
 
     if (!this)
     {
@@ -327,12 +327,16 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
         /* Jump to next instruction can always be removed */
         if (nodeType == ONE_BRANCH)
         {
-            _ip = start + length;
-            for (i = _ip; i < pChild->start && (Icode.GetLlFlag(i) & NO_CODE); i++);
-                if (i != pChild->start)
-                    break;
-            Icode.SetLlFlag(_ip - 1, NO_CODE);
-            Icode.SetLlInvalid(_ip - 1, TRUE);
+            assert(Parent==pChild->Parent);
+            if(back().loc_ip>pChild->front().loc_ip) // back edege
+                break;
+            auto iter=std::find_if(this->end2(),pChild->begin2(),[](ICODE &c)
+                {return not c.isLlFlag(NO_CODE);});
+
+            if (iter != pChild->begin2())
+                break;
+            back().SetLlFlag(NO_CODE);
+            back().invalidate();
             nodeType = FALL_NODE;
             length--;
 
@@ -342,8 +346,8 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
             break;
 
         nodeType = pChild->nodeType;
-        length = pChild->start + pChild->length - start;
-        Icode.ClearLlFlag(pChild->start, TARGET);
+        length = (pChild->start - start) + pChild->length ;
+        pChild->front().ClrLlFlag(TARGET);
         edges.swap(pChild->edges);
 
         pChild->inEdges.clear();

+ 6 - 9
src/proplong.cpp

@@ -35,24 +35,21 @@ static boolT isLong23 (Int i, BB * pbb, Int *off, Int *arc)
     if ((t->length == 1) && (t->nodeType == TWO_BRANCH) && (t->inEdges.size() == 1))
     {
         obb2 = t->edges[THEN].BBptr;
-        if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) &&
-                (obb2->front().ic.ll.opcode == iCMP))
+        if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ic.ll.opcode == iCMP))
         {
-            *off = obb2->start - i;
+            *off = obb2->front().loc_ip - i;
             *arc = THEN;
             return true;
         }
     }
 
     /* Check along the ELSE path  */
-    else if ((e->length == 1) && (e->nodeType == TWO_BRANCH) &&
-             (e->inEdges.size() == 1))
+    else if ((e->length == 1) && (e->nodeType == TWO_BRANCH) && (e->inEdges.size() == 1))
     {
         obb2 = e->edges[THEN].BBptr;
-        if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) &&
-                (obb2->front().ic.ll.opcode == iCMP))
+        if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) &&  (obb2->front().ic.ll.opcode == iCMP))
         {
-            *off = obb2->start - i;
+            *off = obb2->front().loc_ip - i;
             *arc = ELSE;
             return true;
         }
@@ -178,7 +175,7 @@ static void longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode, Int *id
 
     /* Adjust outEdges[0] to the new target basic block */
     pbb = pIcode->inBB;
-    if ((pbb->start + pbb->length - 1) == (*idx + 1))
+    if (pbb->back().loc_ip == (*idx + 1))
     {
         /* Find intermediate and target basic blocks */
         obb1 = pbb->edges[THEN].BBptr;