Browse Source

ICODE::DU1 idx[][] is now an array of structures containing vectors<iICODE>, seems that while changing that some dataflow issues were fixed

Artur K 12 years ago
parent
commit
fbf8cc3a7a
8 changed files with 232 additions and 193 deletions
  1. 1 0
      include/BasicBlock.h
  2. 61 12
      include/icode.h
  3. 4 0
      include/locident.h
  4. 1 5
      src/ast.cpp
  5. 143 163
      src/dataflow.cpp
  6. 19 10
      src/hlicode.cpp
  7. 1 1
      src/icode.cpp
  8. 2 2
      src/parser.cpp

+ 1 - 0
include/BasicBlock.h

@@ -110,6 +110,7 @@ static BB * Create(Int start, Int ip, byte nodeType, Int numOutEdges, Function *
     Function *getParent()       { return Parent; }
     void writeBB(Int lev, Function *pProc, Int *numLoc);
     BB *rmJMP(Int marker, BB *pBB);
+    void genDU1();
 private:
     Function *Parent;
 

+ 61 - 12
include/icode.h

@@ -253,9 +253,8 @@ struct DU_ICODE
     std::bitset<32> def;        // For Registers: position in bitset is reg index
     //dword	def;		// For Registers: position in dword is reg index
     //dword	def;		// For Registers: position in dword is reg index
-    //dword	lastDefRegi;    // Bit set if last def of this register in BB
     std::bitset<32>	use;	// For Registers: position in dword is reg index
-    std::bitset<32> lastDefRegi;
+    std::bitset<32> lastDefRegi;// Bit set if last def of this register in BB
 };
 
 
@@ -338,6 +337,11 @@ struct LLInst : public llvm::MCInst
     {
         return (dst.regi==dest);
     }
+    void set(llIcode op,uint32_t flags)
+    {
+        opcode = op;
+        flg =flags;
+    }
 };
 
 /* Icode definition: LOW_LEVEL and HIGH_LEVEL */
@@ -345,16 +349,60 @@ struct ICODE
 {
     struct DU1
     {
-        Int     numRegsDef;			/* # registers defined by this inst		*/
-        byte	regi[MAX_REGS_DEF];	/* registers defined by this inst		*/
-        Int     idx[MAX_REGS_DEF][MAX_USES];	/* inst that uses this def  */
+        struct DefUse
+        {
+            int Reg; // used register
+            int DefLoc;
+            std::vector<std::list<ICODE>::iterator > useLoc; // use locations [MAX_USES]
+
+        };
+        struct Use
+        {
+            int Reg; // used register
+            std::vector<std::list<ICODE>::iterator> uses; // use locations [MAX_USES]
+            void removeUser(std::list<ICODE>::iterator us)
+            {
+                // ic is no no longer an user
+                auto iter=std::find(uses.begin(),uses.end(),us);
+                if(iter==uses.end())
+                    return;
+                uses.erase(iter);
+                assert("Same user more then once!" && uses.end()==std::find(uses.begin(),uses.end(),us));
+            }
+
+        };
+        Int     numRegsDef;             /* # registers defined by this inst */
+        byte	regi[MAX_REGS_DEF];	/* registers defined by this inst   */
+        Use     idx[MAX_REGS_DEF];
+        //Int     idx[MAX_REGS_DEF][MAX_USES];	/* inst that uses this def  */
+        bool    used(int regIdx)
+                {
+                    return not idx[regIdx].uses.empty();
+                }
+        int     numUses(int regIdx)
+                {
+                    return idx[regIdx].uses.size();
+                }
+        void recordUse(int regIdx,std::list<ICODE>::iterator location)
+                {
+                    idx[regIdx].uses.push_back(location);
+                }
+        void remove(int regIdx,int use_idx)
+                {
+                    idx[regIdx].uses.erase(idx[regIdx].uses.begin()+use_idx);
+                }
+        void remove(int regIdx,std::list<ICODE>::iterator ic)
+                {
+                    Use &u(idx[regIdx]);
+                    u.removeUser(ic);
+                }
     };
-    icodeType           type;           /* Icode type                   */
-    bool                invalid;        /* Has no HIGH_LEVEL equivalent */
-    BB			*inBB;      	/* BB to which this icode belongs */
-    DU_ICODE		du;             /* Def/use regs/vars			*/
-    DU1			du1;        	/* du chain 1					*/
-    Int			codeIdx;    	/* Index into cCode.code		*/
+    icodeType           type;           /* Icode type                       */
+    bool                invalid;        /* Has no HIGH_LEVEL equivalent     */
+    BB			*inBB;      	/* BB to which this icode belongs   */
+    DU_ICODE		du;             /* Def/use regs/vars                */
+    DU1			du1;        	/* du chain 1                       */
+    Int			codeIdx;    	/* Index into cCode.code            */
     struct IC {         /* Different types of icodes    */
         LLInst ll;
         HLTYPE hl;  	/* For HIGH_LEVEL icodes    */
@@ -382,8 +430,9 @@ struct ICODE
     void setJCond(COND_EXPR *cexp);
     void emitGotoLabel(Int indLevel);
     void copyDU(const ICODE &duIcode, operDu _du, operDu duDu);
+    bool valid() {return not invalid;}
 public:
-    boolT removeDefRegi(byte regi, Int thisDefIdx, LOCAL_ID *locId);
+    bool removeDefRegi(byte regi, Int thisDefIdx, LOCAL_ID *locId);
     void checkHlCall();
 };
 

+ 4 - 0
include/locident.h

@@ -101,10 +101,14 @@ struct ID
     } id;
     ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
     {
+        name[0]=0;
+        macro[0]=0;
         memset(&id,0,sizeof(id));
     }
     ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
     {
+        name[0]=0;
+        macro[0]=0;
         memset(&id,0,sizeof(id));
         loc=f;
     }

+ 1 - 5
src/ast.cpp

@@ -48,18 +48,14 @@ void ICODE::setRegDU (byte regi, operDu du_in)
     case eDEF:
         du.def |= duReg[regi];
         du1.numRegsDef++;
-//        printf("%s du.def |= %x\n",__FUNCTION__,duReg[regi]);
         break;
     case eUSE:
         du.use |= duReg[regi];
-//        printf("%s du.use |= %x\n",__FUNCTION__,duReg[regi]);
         break;
     case USE_DEF:
         du.def |= duReg[regi];
-        du1.numRegsDef++;
-//        printf("%s du.def |= %x\n",__FUNCTION__,duReg[regi]);
-//        printf("%s du.use |= %x\n",__FUNCTION__,duReg[regi]);
         du.use |= duReg[regi];
+        du1.numRegsDef++;
         break;
     case NONE:    /* do nothing */
         break;

+ 143 - 163
src/dataflow.cpp

@@ -273,14 +273,15 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
     /* liveOut for this procedure */
     liveOut = in_liveOut;
 
-    change = TRUE;
+    change = true;
     while (change)
     {
         /* Process nodes in reverse postorder order */
-        change = FALSE;
-        for (i = numBBs; i > 0; i--)
+        change = false;
+        //for (i = numBBs; i > 0; i--)
+        for(auto iBB=m_dfsLast.rbegin(); iBB!=m_dfsLast.rend(); ++iBB)
         {
-            pbb = m_dfsLast[i-1];
+            pbb = *iBB;//m_dfsLast[i-1];
             if (pbb->flg & INVALID_BB)		/* Do not process invalid BBs */
                 continue;
 
@@ -361,7 +362,7 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
 
             /* Check if live sets have been modified */
             if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
-                change = TRUE;
+                change = true;
         }
     }
 
@@ -382,159 +383,150 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
     }
 }
 
-
-/* Generates the du chain of each instruction in a basic block */
-void Function::genDU1 ()
+void BB::genDU1()
 {
     byte regi;            /* Register that was defined */
-    Int i,  k, defRegIdx, useIdx;
-    iICODE picode, ticode,lastInst;/* Current and target bb    */
-    BB * pbb, *tbb;         /* Current and target basic block */
+    Int k, defRegIdx, useIdx;
+    iICODE picode, ticode,lastInst;
+    BB *tbb;         /* Target basic block */
     bool res;
-    //COND_EXPR *exp, *lhs;
-
-    /* Traverse tree in dfsLast order */
-    assert(m_dfsLast.size()==numBBs);
-    for (i = 0; i < numBBs; i++)
+    //COND_EXPR *e
+    /* Process each register definition of a HIGH_LEVEL icode instruction.
+     * Note that register variables should not be considered registers.
+     */
+    assert(0!=Parent);
+    lastInst = this->end2();
+    for (picode = this->begin2(); picode != lastInst; picode++)
     {
-        pbb = m_dfsLast[i];
-        if (pbb->flg & INVALID_BB)
+        if (picode->type != HIGH_LEVEL)
             continue;
-
-        /* Process each register definition of a HIGH_LEVEL icode instruction.
-         * Note that register variables should not be considered registers.
-         */
-        lastInst = pbb->end2();
-        for (picode = pbb->begin2(); picode != lastInst; picode++)
+        regi = 0;
+        defRegIdx = 0;
+        // foreach defined register
+        for (k = 0; k < INDEXBASE; k++)
         {
-            if (picode->type != HIGH_LEVEL)
+            if (not picode->du.def.test(k))
+                continue;
+            regi = (byte)(k + 1);       /* defined register */
+            picode->du1.regi[defRegIdx] = regi;
+
+            /* Check remaining instructions of the BB for all uses
+             * of register regi, before any definitions of the
+             * register */
+            if ((regi == rDI) && (flg & DI_REGVAR))
                 continue;
-            regi = 0;
-            defRegIdx = 0;
-            for (k = 0; k < INDEXBASE; k++)
+            if ((regi == rSI) && (flg & SI_REGVAR))
+                continue;
+            if (distance(picode,lastInst)>1) /* several instructions */
             {
-                if (not picode->du.def.test(k))
-                    continue;
-                regi = (byte)(k + 1);       /* defined register */
-                picode->du1.regi[defRegIdx] = regi;
-
-                /* Check remaining instructions of the BB for all uses
-                 * of register regi, before any definitions of the
-                 * register */
-                if ((regi == rDI) && (flg & DI_REGVAR))
-                    continue;
-                if ((regi == rSI) && (flg & SI_REGVAR))
-                    continue;
-                if (distance(picode,lastInst)>1) /* several instructions */
+                useIdx = 0;
+                for (auto ricode = ++iICODE(picode); ricode != lastInst; ricode++)
                 {
-                    useIdx = 0;
-                    for (auto ricode = ++iICODE(picode); ricode != lastInst; ricode++)
-                    {
-                        ticode=ricode;
-                        /* Only check uses of HIGH_LEVEL icodes */
-                        if (ricode->type == HIGH_LEVEL)
-                        {
-                            /* if used, get icode index */
-                            if ((ricode->du.use & duReg[regi]).any())
-                                picode->du1.idx[defRegIdx][useIdx++] = ricode->loc_ip;
+                    ticode=ricode;
+                    if (ricode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
+                        continue;
+                    /* if used, get icode index */
+                    if ((ricode->du.use & duReg[regi]).any())
+                        picode->du1.recordUse(defRegIdx,ricode);
+                    /* if defined, stop finding uses for this reg */
+                    if ((ricode->du.def & duReg[regi]).any())
+                        break;
+                }
 
-                            /* if defined, stop finding uses for this reg */
-                            if ((ricode->du.def & duReg[regi]).any())
-                                break;
-                        }
-                    }
+                /* Check if last definition of this register */
+                if ((not (ticode->du.def & duReg[regi]).any()) and (this->liveOut & duReg[regi]).any())
+                    picode->du.lastDefRegi |= duReg[regi];
+            }
+            else		/* only 1 instruction in this basic block */
+            {
+                /* Check if last definition of this register */
+                if ((this->liveOut & duReg[regi]).any())
+                    picode->du.lastDefRegi |= duReg[regi];
+            }
 
-                    /* Check if last definition of this register */
-                    if ((not (ticode->du.def & duReg[regi]).any()) and (pbb->liveOut & duReg[regi]).any())
-                        picode->du.lastDefRegi |= duReg[regi];
-                }
-                else		/* only 1 instruction in this basic block */
+            /* Find target icode for HLI_CALL icodes to procedures
+             * that are functions.  The target icode is in the
+             * next basic block (unoptimized code) or somewhere else
+             * on optimized code. */
+            if ((picode->ic.hl.opcode == HLI_CALL) &&
+                    (picode->ic.hl.oper.call.proc->flg & PROC_IS_FUNC))
+            {
+                tbb = this->edges[0].BBptr;
+                for (ticode = tbb->begin2(); ticode != tbb->end2(); ticode++)
                 {
-                    /* Check if last definition of this register */
-                    if ((pbb->liveOut & duReg[regi]).any())
-                        picode->du.lastDefRegi |= duReg[regi];
+                    if (ticode->type != HIGH_LEVEL)
+                        continue;
+                    /* if used, get icode index */
+                    if ((ticode->du.use & duReg[regi]).any())
+                        picode->du1.recordUse(defRegIdx,ticode);
+                    /* if defined, stop finding uses for this reg */
+                    if ((ticode->du.def & duReg[regi]).any())
+                        break;
                 }
 
-                /* Find target icode for HLI_CALL icodes to procedures
-                                 * that are functions.  The target icode is in the
-                                 * next basic block (unoptimized code) or somewhere else
-                                 * on optimized code. */
-                if ((picode->ic.hl.opcode == HLI_CALL) &&
-                        (picode->ic.hl.oper.call.proc->flg & PROC_IS_FUNC))
+                /* if not used in this basic block, check if the
+                 * register is live out, if so, make it the last
+                 * definition of this register */
+                if ( picode->du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
+                    picode->du.lastDefRegi |= duReg[regi];
+            }
+
+            /* If not used within this bb or in successors of this
+             * bb (ie. not in liveOut), then register is useless,
+             * thus remove it.  Also check that this is not a return
+             * from a library function (routines such as printf
+             * return an integer, which is normally not taken into
+             * account by the programmer). 	*/
+            if (picode->valid() and not picode->du1.used(defRegIdx) and
+                (not (picode->du.lastDefRegi & duReg[regi]).any()) &&
+                (not ((picode->ic.hl.opcode == HLI_CALL) &&
+                (picode->ic.hl.oper.call.proc->flg & PROC_ISLIB))))
+            {
+                if (! (this->liveOut & duReg[regi]).any())	/* not liveOut */
                 {
-                    tbb = pbb->edges[0].BBptr;
-                    useIdx = 0;
-                    for (ticode = tbb->begin2(); ticode != tbb->end2(); ticode++)
+                    res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
+                    if (res != true)
                     {
-                        if (ticode->type != HIGH_LEVEL)
-                            continue;
-                        /* if used, get icode index */
-                        if ((ticode->du.use & duReg[regi]).any())
-                            picode->du1.idx[defRegIdx][useIdx++] = ticode->loc_ip;
-
-                        /* if defined, stop finding uses for this reg */
-                        if ((ticode->du.def & duReg[regi]).any())
-                            break;
+                        defRegIdx++;
+                        continue;
                     }
 
-                    /* if not used in this basic block, check if the
-                     * register is live out, if so, make it the last
-                     * definition of this register */
-                    if ((picode->du1.idx[defRegIdx][useIdx] == 0) &&
-                            (tbb->liveOut & duReg[regi]).any())
-                        picode->du.lastDefRegi |= duReg[regi];
-                }
-
-                /* If not used within this bb or in successors of this
-                 * bb (ie. not in liveOut), then register is useless,
-                 * thus remove it.  Also check that this is not a return
-                 * from a library function (routines such as printf
-                 * return an integer, which is normally not taken into
-                 * account by the programmer). 	*/
-                if ((picode->invalid == FALSE) &&
-                    (picode->du1.idx[defRegIdx][0] == 0) &&
-                    (not (picode->du.lastDefRegi & duReg[regi]).any()) &&
-                        //(! ((picode->ic.hl.opcode != HLI_CALL) &&
-                    (not ((picode->ic.hl.opcode == HLI_CALL) &&
-                    (picode->ic.hl.oper.call.proc->flg & PROC_ISLIB))))
-                {
-                    if (! (pbb->liveOut & duReg[regi]).any())	/* not liveOut */
+                    /* Backpatch any uses of this instruction, within
+                     * the same BB, if the instruction was invalidated */
+                    for (auto ticode = riICODE(picode); ticode != this->rend2(); ticode++)
                     {
-                        res = picode->removeDefRegi (regi, defRegIdx+1,&localId);
-
-                        /* Backpatch any uses of this instruction, within
-                         * the same BB, if the instruction was invalidated */
-                        if (res == TRUE)
-                            for (auto ticode = riICODE(picode); ticode != pbb->rend2(); ticode++)
-                            {
-                                for (int n = 0; n < MAX_USES; n++)
-                                {
-                                    if (ticode->du1.idx[0][n] == picode->loc_ip)
-                                    {
-                                        if (n < MAX_USES - 1)
-                                        {
-                                            memmove (&ticode->du1.idx[0][n],
-                                                     &ticode->du1.idx[0][n+1],
-                                                     (size_t)((MAX_USES - n - 1) * sizeof(Int)));
-                                            n--;
-                                        }
-                                        ticode->du1.idx[0][MAX_USES - 1] = 0;
-                                    }
-                                }
-                            }
+                        ticode->du1.remove(0,picode);
                     }
-                    else		/* liveOut */
-                        picode->du.lastDefRegi |= duReg[regi];
                 }
-                defRegIdx++;
-
-                /* Check if all defined registers have been processed */
-                if ((defRegIdx >= picode->du1.numRegsDef) ||
-                        (defRegIdx == MAX_REGS_DEF))
-                    break;
+                else		/* liveOut */
+                    picode->du.lastDefRegi |= duReg[regi];
             }
+            defRegIdx++;
+
+            /* Check if all defined registers have been processed */
+            if ((defRegIdx >= picode->du1.numRegsDef) || (defRegIdx == MAX_REGS_DEF))
+                break;
         }
     }
+}
+/* Generates the du chain of each instruction in a basic block */
+void Function::genDU1 ()
+{
+    byte regi;            /* Register that was defined */
+    Int i,  k, defRegIdx, useIdx;
+    iICODE picode, ticode,lastInst;/* Current and target bb    */
+    BB * pbb, *tbb;         /* Current and target basic block */
+    bool res;
+    //COND_EXPR *exp, *lhs;
+
+    /* Traverse tree in dfsLast order */
+    assert(m_dfsLast.size()==numBBs);
+    for(BB *pbb : m_dfsLast)
+    {
+        if (pbb->flg & INVALID_BB)
+            continue;
+        pbb->genDU1();
+    }
 
 }
 
@@ -605,7 +597,7 @@ static void forwardSubsLong (Int longIdx, COND_EXPR *exp, ICODE * picode,
 
 /* Returns whether the elements of the expression rhs are all x-clear from
  * instruction f up to instruction t.	*/
-static boolT xClear (COND_EXPR *rhs, iICODE f, Int t, iICODE lastBBinst, Function * pproc)
+static boolT xClear (COND_EXPR *rhs, iICODE f, iICODE t, iICODE lastBBinst, Function * pproc)
 {
     iICODE i;
     boolT res;
@@ -620,7 +612,7 @@ static boolT xClear (COND_EXPR *rhs, iICODE f, Int t, iICODE lastBBinst, Functio
         if (rhs->expr.ident.idType == REGISTER)
         {
             regi= pproc->localId.id_arr[rhs->expr.ident.idNode.regiIdx].id.regi;
-            for (i = ++iICODE(f); (i != lastBBinst) && (i->loc_ip < t); i++)
+            for (i = ++iICODE(f); (i != lastBBinst) && (i!=t); i++)
                 if ((i->type == HIGH_LEVEL) && ( not i->invalid ))
                 {
                     if ((i->du.def & duReg[regi]).any())
@@ -728,8 +720,7 @@ void Function::findExps()
                     /* 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.idx[0][0] != 0) &&
-                            (picode->du1.idx[0][1] == 0))
+                    if (picode->du1.numUses(0)==1)
                     {
                         /* Check that this register is not liveOut, if it
                          * is the last definition of the register */
@@ -741,15 +732,14 @@ void Function::findExps()
                         case HLI_ASSIGN:
                             /* Replace rhs of current icode into target
                              * icode expression */
-                            ticode = Icode.begin();
-                            advance(ticode,picode->du1.idx[0][0]);
+                            ticode = picode->du1.idx[0].uses.front();
                             if ((picode->du.lastDefRegi & duReg[regi]).any() &&
                                     ((ticode->ic.hl.opcode != HLI_CALL) &&
                                      (ticode->ic.hl.opcode != HLI_RET)))
                                 continue;
 
                             if (xClear (picode->ic.hl.oper.asgn.rhs, picode,
-                                        picode->du1.idx[0][0],  lastInst, this))
+                                        picode->du1.idx[0].uses[0],  lastInst, this))
                             {
                                 switch (ticode->ic.hl.opcode) {
                                 case HLI_ASSIGN:
@@ -782,8 +772,7 @@ void Function::findExps()
                             break;
 
                         case HLI_POP:
-                            ticode = Icode.begin();
-                            advance(ticode,picode->du1.idx[0][0]);
+                            ticode = picode->du1.idx[0].uses.front();
                             if ((picode->du.lastDefRegi & duReg[regi]).any() &&
                                     ((ticode->ic.hl.opcode != HLI_CALL) &&
                                      (ticode->ic.hl.opcode != HLI_RET)))
@@ -818,8 +807,7 @@ void Function::findExps()
                             break;
 
                         case HLI_CALL:
-                            ticode = Icode.begin();
-                            advance(ticode,picode->du1.idx[0][0]);
+                            ticode = picode->du1.idx[0].uses.front();
                             switch (ticode->ic.hl.opcode) {
                             case HLI_ASSIGN:
                                 exp = COND_EXPR::idFunc (
@@ -877,19 +865,15 @@ void Function::findExps()
                 else if (picode->du1.numRegsDef == 2)   /* long regs */
                 {
                     /* Check for only one use of these registers */
-                    if ((picode->du1.idx[0][0] != 0) &&
-                            (picode->du1.idx[0][1] == 0) &&
-                            (picode->du1.idx[1][0] != 0) &&
-                            (picode->du1.idx[1][1] == 0))
+                    if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
                     {
                         switch (picode->ic.hl.opcode) {
                         case HLI_ASSIGN:
                             /* Replace rhs of current icode into target
                              * icode expression */
-                            if (picode->du1.idx[0][0] == picode->du1.idx[1][0])
+                            if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
                             {
-                                ticode = Icode.begin();
-                                advance(ticode,picode->du1.idx[0][0]);
+                                ticode = picode->du1.idx[0].uses.front();
                                 if ((picode->du.lastDefRegi & duReg[regi]).any() &&
                                         ((ticode->ic.hl.opcode != HLI_CALL) &&
                                          (ticode->ic.hl.opcode != HLI_RET)))
@@ -924,10 +908,9 @@ void Function::findExps()
                             break;
 
                         case HLI_POP:
-                            if (picode->du1.idx[0][0] == picode->du1.idx[1][0])
+                            if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
                             {
-                                ticode = Icode.begin();
-                                advance(ticode,picode->du1.idx[0][0]);
+                                ticode = picode->du1.idx[0].uses.front();
                                 if ((picode->du.lastDefRegi & duReg[regi]).any() &&
                                         ((ticode->ic.hl.opcode != HLI_CALL) &&
                                          (ticode->ic.hl.opcode != HLI_RET)))
@@ -956,8 +939,7 @@ void Function::findExps()
                             break;
 
                         case HLI_CALL:    /* check for function return */
-                            ticode = Icode.begin();
-                            advance(ticode,picode->du1.idx[0][0]);
+                            ticode = picode->du1.idx[0].uses.front();
                             switch (ticode->ic.hl.opcode)
                             {
                             case HLI_ASSIGN:
@@ -1066,16 +1048,14 @@ void Function::findExps()
                 }
 
                 /* If we could not substitute the result of a function,
-                                 * assign it to the corresponding registers */
+                 * assign it to the corresponding registers */
                 if ((picode->ic.hl.opcode == HLI_CALL) &&
                         ((picode->ic.hl.oper.call.proc->flg & PROC_ISLIB) !=
-                         PROC_ISLIB) && (picode->du1.idx[0][0] == 0) &&
+                         PROC_ISLIB) && (not picode->du1.used(0)) &&
                         (picode->du1.numRegsDef > 0))
                 {
-                    exp = COND_EXPR::idFunc (picode->ic.hl.oper.call.proc,
-                                             picode->ic.hl.oper.call.args);
-                    lhs = COND_EXPR::idID (&picode->ic.hl.oper.call.proc->retVal,
-                                           &localId, picode/*picode->loc_ip*/);
+                    exp = COND_EXPR::idFunc (picode->ic.hl.oper.call.proc, picode->ic.hl.oper.call.args);
+                    lhs = COND_EXPR::idID (&picode->ic.hl.oper.call.proc->retVal, &localId, picode);
                     picode->setAsgn(lhs, exp);
                 }
             }

+ 19 - 10
src/hlicode.cpp

@@ -90,19 +90,30 @@ void ICODE ::invalidate()
 }
 
 
-/* Removes the defined register regi from the lhs subtree.  If all registers
- * of this instruction are unused, the instruction is invalidated (ie.
- * removed) */
-boolT ICODE::removeDefRegi (byte regi, Int thisDefIdx, LOCAL_ID *locId)
+/* Removes the defined register regi from the lhs subtree.
+ * If all registers
+ * of this instruction are unused, the instruction is invalidated (ie. removed)
+ */
+bool ICODE::removeDefRegi (byte regi, Int thisDefIdx, LOCAL_ID *locId)
 {
     Int numDefs;
 
     numDefs = du1.numRegsDef;
+//    if (numDefs == thisDefIdx)
+//    {
+//        for ( ; numDefs > 0; numDefs--)
+//        {
+//            if ((du1.idx[numDefs-1][0] != 0)||(du.lastDefRegi.any()))
+//                break;
+//        }
+//    }
+
     if (numDefs == thisDefIdx)
     {
         for ( ; numDefs > 0; numDefs--)
         {
-            if ((du1.idx[numDefs-1][0] != 0)||(du.lastDefRegi.any()))
+
+            if (du1.used(numDefs-1)||(du.lastDefRegi[regi]))
                 break;
         }
     }
@@ -478,14 +489,12 @@ void ICODE::writeDU(Int idx)
     printf ("# regs defined = %d\n", du1.numRegsDef);
     for (i = 0; i < MAX_REGS_DEF; i++)
     {
-        if (du1.idx[i][0] != 0)
+        if (du1.used(i))
         {
             printf ("%d: du1[%d][] = ", idx, i);
-            for (j = 0; j < MAX_USES; j++)
+            for(std::list<ICODE>::iterator j : du1.idx[i].uses)
             {
-                if (du1.idx[i][j] == 0)
-                    break;
-                printf ("%d ", du1.idx[i][j]);
+                printf ("%d ", j->loc_ip);
             }
             printf ("\n");
         }

+ 1 - 1
src/icode.cpp

@@ -43,7 +43,7 @@ bool CIcodeRec::labelSrch(dword target, dword &pIndex)
     Int  i;
     iICODE location=labelSrch(target);
     if(end()==location)
-	    return false;
+            return false;
     pIndex=location->loc_ip;
     return true;
 }

+ 2 - 2
src/parser.cpp

@@ -154,8 +154,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
         if (Icode.end()!=labLoc)
         {   /* Synthetic jump */
             _Icode.type = LOW_LEVEL;
-            _Icode.ic.ll.opcode = iJMP;
-            _Icode.ic.ll.flg = I | SYNTHETIC | NO_OPS;
+            _Icode.ic.ll.set(iJMP,I | SYNTHETIC | NO_OPS);
             _Icode.ic.ll.src.SetImmediateOp(labLoc->GetLlLabel());
             _Icode.ic.ll.label = SynthLab++;
         }
@@ -882,6 +881,7 @@ static void setBits(int16 type, dword start, dword len)
 
 /* DU bit definitions for each reg value - including index registers */
 std::bitset<32> duReg[] = { 0x00,
+                  //AH AL . . AX, BH
                   0x11001, 0x22002, 0x44004, 0x88008, /* word regs    */
                   0x10, 0x20, 0x40, 0x80,
                   0x100, 0x200, 0x400, 0x800,         /* seg regs     */