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:
parent
3cb26d99d2
commit
fbf8cc3a7a
@ -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;
|
||||
|
||||
|
||||
@ -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();
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
320
src/dataflow.cpp
320
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,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 */
|
||||
void Function::genDU1 ()
|
||||
{
|
||||
@ -395,145 +521,11 @@ void Function::genDU1 ()
|
||||
|
||||
/* Traverse tree in dfsLast order */
|
||||
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)
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user