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

This commit is contained in:
Artur K 2012-02-28 16:38:36 +01:00
parent 3cb26d99d2
commit fbf8cc3a7a
8 changed files with 239 additions and 200 deletions

View File

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

View File

@ -253,9 +253,8 @@ struct DU_ICODE
std::bitset<32> def; // For Registers: position in bitset is reg index 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 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> 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); return (dst.regi==dest);
} }
void set(llIcode op,uint32_t flags)
{
opcode = op;
flg =flags;
}
}; };
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */ /* Icode definition: LOW_LEVEL and HIGH_LEVEL */
@ -345,16 +349,60 @@ struct ICODE
{ {
struct DU1 struct DU1
{ {
Int numRegsDef; /* # registers defined by this inst */ struct DefUse
byte regi[MAX_REGS_DEF]; /* registers defined by this inst */ {
Int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */ 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 */ icodeType type; /* Icode type */
bool invalid; /* Has no HIGH_LEVEL equivalent */ bool invalid; /* Has no HIGH_LEVEL equivalent */
BB *inBB; /* BB to which this icode belongs */ BB *inBB; /* BB to which this icode belongs */
DU_ICODE du; /* Def/use regs/vars */ DU_ICODE du; /* Def/use regs/vars */
DU1 du1; /* du chain 1 */ DU1 du1; /* du chain 1 */
Int codeIdx; /* Index into cCode.code */ Int codeIdx; /* Index into cCode.code */
struct IC { /* Different types of icodes */ struct IC { /* Different types of icodes */
LLInst ll; LLInst ll;
HLTYPE hl; /* For HIGH_LEVEL icodes */ HLTYPE hl; /* For HIGH_LEVEL icodes */
@ -382,8 +430,9 @@ struct ICODE
void setJCond(COND_EXPR *cexp); void setJCond(COND_EXPR *cexp);
void emitGotoLabel(Int indLevel); void emitGotoLabel(Int indLevel);
void copyDU(const ICODE &duIcode, operDu _du, operDu duDu); void copyDU(const ICODE &duIcode, operDu _du, operDu duDu);
bool valid() {return not invalid;}
public: public:
boolT removeDefRegi(byte regi, Int thisDefIdx, LOCAL_ID *locId); bool removeDefRegi(byte regi, Int thisDefIdx, LOCAL_ID *locId);
void checkHlCall(); void checkHlCall();
}; };

View File

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

View File

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

View File

@ -273,14 +273,15 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
/* liveOut for this procedure */ /* liveOut for this procedure */
liveOut = in_liveOut; liveOut = in_liveOut;
change = TRUE; change = true;
while (change) while (change)
{ {
/* Process nodes in reverse postorder order */ /* Process nodes in reverse postorder order */
change = FALSE; change = false;
for (i = numBBs; i > 0; i--) //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 */ if (pbb->flg & INVALID_BB) /* Do not process invalid BBs */
continue; continue;
@ -361,7 +362,7 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
/* Check if live sets have been modified */ /* Check if live sets have been modified */
if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut)) if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
change = TRUE; change = true;
} }
} }
@ -382,7 +383,132 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
} }
} }
void BB::genDU1()
{
byte regi; /* Register that was defined */
Int k, defRegIdx, useIdx;
iICODE picode, ticode,lastInst;
BB *tbb; /* Target basic block */
bool res;
//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++)
{
if (picode->type != HIGH_LEVEL)
continue;
regi = 0;
defRegIdx = 0;
// foreach defined register
for (k = 0; k < INDEXBASE; k++)
{
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++)
{
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;
}
/* 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];
}
/* 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++)
{
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;
}
/* 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 */
{
res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
if (res != true)
{
defRegIdx++;
continue;
}
/* Backpatch any uses of this instruction, within
* the same BB, if the instruction was invalidated */
for (auto ticode = riICODE(picode); ticode != this->rend2(); ticode++)
{
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;
}
}
}
/* Generates the du chain of each instruction in a basic block */ /* Generates the du chain of each instruction in a basic block */
void Function::genDU1 () void Function::genDU1 ()
{ {
@ -395,145 +521,11 @@ void Function::genDU1 ()
/* Traverse tree in dfsLast order */ /* Traverse tree in dfsLast order */
assert(m_dfsLast.size()==numBBs); assert(m_dfsLast.size()==numBBs);
for (i = 0; i < numBBs; i++) for(BB *pbb : m_dfsLast)
{ {
pbb = m_dfsLast[i];
if (pbb->flg & INVALID_BB) if (pbb->flg & INVALID_BB)
continue; continue;
pbb->genDU1();
/* 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++)
{
if (picode->type != HIGH_LEVEL)
continue;
regi = 0;
defRegIdx = 0;
for (k = 0; k < INDEXBASE; k++)
{
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++)
{
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;
/* 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 (pbb->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 ((pbb->liveOut & duReg[regi]).any())
picode->du.lastDefRegi |= duReg[regi];
}
/* 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 = pbb->edges[0].BBptr;
useIdx = 0;
for (ticode = tbb->begin2(); ticode != tbb->end2(); ticode++)
{
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;
}
/* 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 */
{
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;
}
}
}
}
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;
}
}
} }
} }
@ -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 /* Returns whether the elements of the expression rhs are all x-clear from
* instruction f up to instruction t. */ * 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; iICODE i;
boolT res; 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) if (rhs->expr.ident.idType == REGISTER)
{ {
regi= pproc->localId.id_arr[rhs->expr.ident.idNode.regiIdx].id.regi; 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->type == HIGH_LEVEL) && ( not i->invalid ))
{ {
if ((i->du.def & duReg[regi]).any()) 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 /* Check for only one use of this register. If this is
* the last definition of the register in this BB, check * the last definition of the register in this BB, check
* that it is not liveOut from this basic block */ * that it is not liveOut from this basic block */
if ((picode->du1.idx[0][0] != 0) && if (picode->du1.numUses(0)==1)
(picode->du1.idx[0][1] == 0))
{ {
/* Check that this register is not liveOut, if it /* Check that this register is not liveOut, if it
* is the last definition of the register */ * is the last definition of the register */
@ -741,15 +732,14 @@ void Function::findExps()
case HLI_ASSIGN: case HLI_ASSIGN:
/* Replace rhs of current icode into target /* Replace rhs of current icode into target
* icode expression */ * icode expression */
ticode = Icode.begin(); ticode = picode->du1.idx[0].uses.front();
advance(ticode,picode->du1.idx[0][0]);
if ((picode->du.lastDefRegi & duReg[regi]).any() && if ((picode->du.lastDefRegi & duReg[regi]).any() &&
((ticode->ic.hl.opcode != HLI_CALL) && ((ticode->ic.hl.opcode != HLI_CALL) &&
(ticode->ic.hl.opcode != HLI_RET))) (ticode->ic.hl.opcode != HLI_RET)))
continue; continue;
if (xClear (picode->ic.hl.oper.asgn.rhs, picode, 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) { switch (ticode->ic.hl.opcode) {
case HLI_ASSIGN: case HLI_ASSIGN:
@ -782,8 +772,7 @@ void Function::findExps()
break; break;
case HLI_POP: case HLI_POP:
ticode = Icode.begin(); ticode = picode->du1.idx[0].uses.front();
advance(ticode,picode->du1.idx[0][0]);
if ((picode->du.lastDefRegi & duReg[regi]).any() && if ((picode->du.lastDefRegi & duReg[regi]).any() &&
((ticode->ic.hl.opcode != HLI_CALL) && ((ticode->ic.hl.opcode != HLI_CALL) &&
(ticode->ic.hl.opcode != HLI_RET))) (ticode->ic.hl.opcode != HLI_RET)))
@ -818,8 +807,7 @@ void Function::findExps()
break; break;
case HLI_CALL: case HLI_CALL:
ticode = Icode.begin(); ticode = picode->du1.idx[0].uses.front();
advance(ticode,picode->du1.idx[0][0]);
switch (ticode->ic.hl.opcode) { switch (ticode->ic.hl.opcode) {
case HLI_ASSIGN: case HLI_ASSIGN:
exp = COND_EXPR::idFunc ( exp = COND_EXPR::idFunc (
@ -877,19 +865,15 @@ void Function::findExps()
else if (picode->du1.numRegsDef == 2) /* long regs */ else if (picode->du1.numRegsDef == 2) /* long regs */
{ {
/* Check for only one use of these registers */ /* Check for only one use of these registers */
if ((picode->du1.idx[0][0] != 0) && if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
(picode->du1.idx[0][1] == 0) &&
(picode->du1.idx[1][0] != 0) &&
(picode->du1.idx[1][1] == 0))
{ {
switch (picode->ic.hl.opcode) { switch (picode->ic.hl.opcode) {
case HLI_ASSIGN: case HLI_ASSIGN:
/* Replace rhs of current icode into target /* Replace rhs of current icode into target
* icode expression */ * 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(); ticode = picode->du1.idx[0].uses.front();
advance(ticode,picode->du1.idx[0][0]);
if ((picode->du.lastDefRegi & duReg[regi]).any() && if ((picode->du.lastDefRegi & duReg[regi]).any() &&
((ticode->ic.hl.opcode != HLI_CALL) && ((ticode->ic.hl.opcode != HLI_CALL) &&
(ticode->ic.hl.opcode != HLI_RET))) (ticode->ic.hl.opcode != HLI_RET)))
@ -924,10 +908,9 @@ void Function::findExps()
break; break;
case HLI_POP: 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(); ticode = picode->du1.idx[0].uses.front();
advance(ticode,picode->du1.idx[0][0]);
if ((picode->du.lastDefRegi & duReg[regi]).any() && if ((picode->du.lastDefRegi & duReg[regi]).any() &&
((ticode->ic.hl.opcode != HLI_CALL) && ((ticode->ic.hl.opcode != HLI_CALL) &&
(ticode->ic.hl.opcode != HLI_RET))) (ticode->ic.hl.opcode != HLI_RET)))
@ -956,8 +939,7 @@ void Function::findExps()
break; break;
case HLI_CALL: /* check for function return */ case HLI_CALL: /* check for function return */
ticode = Icode.begin(); ticode = picode->du1.idx[0].uses.front();
advance(ticode,picode->du1.idx[0][0]);
switch (ticode->ic.hl.opcode) switch (ticode->ic.hl.opcode)
{ {
case HLI_ASSIGN: case HLI_ASSIGN:
@ -1066,16 +1048,14 @@ void Function::findExps()
} }
/* If we could not substitute the result of a function, /* 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) && if ((picode->ic.hl.opcode == HLI_CALL) &&
((picode->ic.hl.oper.call.proc->flg & PROC_ISLIB) != ((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)) (picode->du1.numRegsDef > 0))
{ {
exp = COND_EXPR::idFunc (picode->ic.hl.oper.call.proc, exp = COND_EXPR::idFunc (picode->ic.hl.oper.call.proc, picode->ic.hl.oper.call.args);
picode->ic.hl.oper.call.args); lhs = COND_EXPR::idID (&picode->ic.hl.oper.call.proc->retVal, &localId, picode);
lhs = COND_EXPR::idID (&picode->ic.hl.oper.call.proc->retVal,
&localId, picode/*picode->loc_ip*/);
picode->setAsgn(lhs, exp); picode->setAsgn(lhs, exp);
} }
} }

View File

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

View File

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

View File

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