Refactored BasicBlock::genDU1() into three utility methods.
Const'ized a few pointers in locident.cpp
This commit is contained in:
parent
61392772e1
commit
d3a22fc03c
@ -122,7 +122,10 @@ public:
|
|||||||
{
|
{
|
||||||
edges[0].ip = ip;
|
edges[0].ip = ip;
|
||||||
}
|
}
|
||||||
|
void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
|
||||||
private:
|
private:
|
||||||
|
bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);
|
||||||
|
void ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode);
|
||||||
bool isEndOfPath(int latch_node_idx) const;
|
bool isEndOfPath(int latch_node_idx) const;
|
||||||
Function *Parent;
|
Function *Parent;
|
||||||
|
|
||||||
|
|||||||
139
src/dataflow.cpp
139
src/dataflow.cpp
@ -397,89 +397,68 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BB::genDU1()
|
|
||||||
{
|
|
||||||
eReg 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->end();
|
|
||||||
ICODE::TypeFilter<HIGH_LEVEL> zq;
|
|
||||||
auto all_high_levels = instructions | filtered(zq);
|
|
||||||
printf("\n");
|
|
||||||
for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode)
|
|
||||||
{
|
|
||||||
// if (picode->type != HIGH_LEVEL)
|
|
||||||
// continue;
|
|
||||||
regi = rUNDEF;
|
|
||||||
defRegIdx = 0;
|
|
||||||
// foreach defined register
|
|
||||||
bitset<32> processed=0;
|
|
||||||
for (k = 0; k < INDEX_BX_SI; k++)
|
|
||||||
{
|
|
||||||
if (not picode->du.def.test(k))
|
|
||||||
continue;
|
|
||||||
//printf("Processing reg")
|
|
||||||
processed |= duReg[k];
|
|
||||||
regi = (eReg)(k + 1); /* defined register */
|
|
||||||
picode->du1.regi[defRegIdx] = regi;
|
|
||||||
|
|
||||||
/* Check remaining instructions of the BB for all uses
|
/* Check remaining instructions of the BB for all uses
|
||||||
* of register regi, before any definitions of the
|
* of register regi, before any definitions of the
|
||||||
* register */
|
* register */
|
||||||
|
bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
|
||||||
|
{
|
||||||
if ((regi == rDI) && (flg & DI_REGVAR))
|
if ((regi == rDI) && (flg & DI_REGVAR))
|
||||||
continue;
|
return true;
|
||||||
if ((regi == rSI) && (flg & SI_REGVAR))
|
if ((regi == rSI) && (flg & SI_REGVAR))
|
||||||
continue;
|
return true;
|
||||||
if (distance(picode,all_high_levels.end())>1) /* several instructions */
|
if (distance(start_at,end())>1) /* several instructions */
|
||||||
{
|
{
|
||||||
useIdx = 0;
|
iICODE ticode=end();
|
||||||
for (auto ricode = ++iICODE(picode.base()); ricode != lastInst; ricode++)
|
auto hl_range=make_iterator_range(start_at,end()) | filtered(ICODE::select_high_level);
|
||||||
|
auto checked_icode=hl_range.begin();
|
||||||
|
++checked_icode;
|
||||||
|
for (; checked_icode != hl_range.end(); checked_icode++)
|
||||||
{
|
{
|
||||||
ticode=ricode;
|
if (checked_icode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
|
||||||
if (ricode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
|
|
||||||
continue;
|
continue;
|
||||||
/* if used, get icode index */
|
/* if used, get icode index */
|
||||||
if ((ricode->du.use & duReg[regi]).any())
|
if ((checked_icode->du.use & duReg[regi]).any())
|
||||||
picode->du1.recordUse(defRegIdx,ricode);
|
start_at->du1.recordUse(defRegIdx,checked_icode.base());
|
||||||
/* if defined, stop finding uses for this reg */
|
/* if defined, stop finding uses for this reg */
|
||||||
if ((ricode->du.def & duReg[regi]).any())
|
if ((checked_icode->du.def & duReg[regi]).any())
|
||||||
|
{
|
||||||
|
ticode=checked_icode.base();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(ticode==end())
|
||||||
|
ticode=(++riICODE(rbegin())).base();
|
||||||
|
|
||||||
/* Check if last definition of this register */
|
/* Check if last definition of this register */
|
||||||
if ((not (ticode->du.def & duReg[regi]).any()) and (this->liveOut & duReg[regi]).any())
|
if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any())
|
||||||
picode->du.lastDefRegi |= duReg[regi];
|
start_at->du.lastDefRegi |= duReg[regi];
|
||||||
}
|
}
|
||||||
else /* only 1 instruction in this basic block */
|
else /* only 1 instruction in this basic block */
|
||||||
{
|
{
|
||||||
/* Check if last definition of this register */
|
/* Check if last definition of this register */
|
||||||
if ((this->liveOut & duReg[regi]).any())
|
if ((liveOut & duReg[regi]).any())
|
||||||
picode->du.lastDefRegi |= duReg[regi];
|
start_at->du.lastDefRegi |= duReg[regi];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find target icode for HLI_CALL icodes to procedures
|
/* Find target icode for HLI_CALL icodes to procedures
|
||||||
* that are functions. The target icode is in the
|
* that are functions. The target icode is in the
|
||||||
* next basic block (unoptimized code) or somewhere else
|
* next basic block (unoptimized code) or somewhere else
|
||||||
* on optimized code. */
|
* on optimized code. */
|
||||||
|
void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode)
|
||||||
|
{
|
||||||
if ((picode->hl()->opcode == HLI_CALL) &&
|
if ((picode->hl()->opcode == HLI_CALL) &&
|
||||||
(picode->hl()->call.proc->flg & PROC_IS_FUNC))
|
(picode->hl()->call.proc->flg & PROC_IS_FUNC))
|
||||||
{
|
{
|
||||||
tbb = this->edges[0].BBptr;
|
BB *tbb = this->edges[0].BBptr;
|
||||||
for (ticode = tbb->begin(); ticode != tbb->end(); ticode++)
|
auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level);
|
||||||
|
for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (ticode->type != HIGH_LEVEL)
|
|
||||||
continue;
|
|
||||||
/* if used, get icode index */
|
/* if used, get icode index */
|
||||||
if ((ticode->du.use & duReg[regi]).any())
|
if ((iter->du.use & duReg[regi]).any())
|
||||||
picode->du1.recordUse(defRegIdx,ticode);
|
picode->du1.recordUse(defRegIdx,iter.base());
|
||||||
/* if defined, stop finding uses for this reg */
|
/* if defined, stop finding uses for this reg */
|
||||||
if ((ticode->du.def & duReg[regi]).any())
|
if ((iter->du.def & duReg[regi]).any())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,13 +468,15 @@ void BB::genDU1()
|
|||||||
if ( picode->du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
|
if ( picode->du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
|
||||||
picode->du.lastDefRegi |= duReg[regi];
|
picode->du.lastDefRegi |= duReg[regi];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* If not used within this bb or in successors of this
|
/* If not used within this bb or in successors of this
|
||||||
* bb (ie. not in liveOut), then register is useless,
|
* bb (ie. not in liveOut), then register is useless,
|
||||||
* thus remove it. Also check that this is not a return
|
* thus remove it. Also check that this is not a return
|
||||||
* from a library function (routines such as printf
|
* from a library function (routines such as printf
|
||||||
* return an integer, which is normally not taken into
|
* return an integer, which is normally not taken into
|
||||||
* account by the programmer). */
|
* account by the programmer). */
|
||||||
|
void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
|
||||||
|
{
|
||||||
if (picode->valid() and not picode->du1.used(defRegIdx) and
|
if (picode->valid() and not picode->du1.used(defRegIdx) and
|
||||||
(not (picode->du.lastDefRegi & duReg[regi]).any()) &&
|
(not (picode->du.lastDefRegi & duReg[regi]).any()) &&
|
||||||
(not ((picode->hl()->opcode == HLI_CALL) &&
|
(not ((picode->hl()->opcode == HLI_CALL) &&
|
||||||
@ -503,23 +484,50 @@ void BB::genDU1()
|
|||||||
{
|
{
|
||||||
if (! (this->liveOut & duReg[regi]).any()) /* not liveOut */
|
if (! (this->liveOut & duReg[regi]).any()) /* not liveOut */
|
||||||
{
|
{
|
||||||
res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
|
bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
|
||||||
if (res != true)
|
if (res == true)
|
||||||
{
|
{
|
||||||
defRegIdx++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Backpatch any uses of this instruction, within
|
/* Backpatch any uses of this instruction, within
|
||||||
* the same BB, if the instruction was invalidated */
|
* the same BB, if the instruction was invalidated */
|
||||||
for (auto back_patch_at = riICODE(picode.base()); back_patch_at != rend(); back_patch_at++)
|
rICODE the_rest(begin(),picode);
|
||||||
|
for ( ICODE &back_patch_at : the_rest|reversed)
|
||||||
{
|
{
|
||||||
back_patch_at->du1.remove(0,picode.base());
|
back_patch_at.du1.remove(0,picode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* liveOut */
|
else /* liveOut */
|
||||||
picode->du.lastDefRegi |= duReg[regi];
|
picode->du.lastDefRegi |= duReg[regi];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BB::genDU1()
|
||||||
|
{
|
||||||
|
/* Process each register definition of a HIGH_LEVEL icode instruction.
|
||||||
|
* Note that register variables should not be considered registers.
|
||||||
|
*/
|
||||||
|
assert(0!=Parent);
|
||||||
|
ICODE::TypeFilter<HIGH_LEVEL> select_high_level;
|
||||||
|
auto all_high_levels = instructions | filtered(select_high_level);
|
||||||
|
printf("\n");
|
||||||
|
for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode)
|
||||||
|
{
|
||||||
|
int defRegIdx = 0;
|
||||||
|
// foreach defined register
|
||||||
|
for (int k = 0; k < INDEX_BX_SI; k++)
|
||||||
|
{
|
||||||
|
if (not picode->du.def.test(k))
|
||||||
|
continue;
|
||||||
|
eReg regi = (eReg)(k + 1); /* Register that was defined */
|
||||||
|
picode->du1.regi[defRegIdx] = regi;
|
||||||
|
|
||||||
|
if(FindUseBeforeDef(regi,defRegIdx, picode.base()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ProcessUseDefForFunc(regi, defRegIdx,picode.base());
|
||||||
|
RemoveUnusedDefs(regi, defRegIdx, picode.base());
|
||||||
|
|
||||||
defRegIdx++;
|
defRegIdx++;
|
||||||
|
|
||||||
/* Check if all defined registers have been processed */
|
/* Check if all defined registers have been processed */
|
||||||
@ -533,16 +541,13 @@ void Function::genDU1 ()
|
|||||||
{
|
{
|
||||||
/* Traverse tree in dfsLast order */
|
/* Traverse tree in dfsLast order */
|
||||||
assert(m_dfsLast.size()==numBBs);
|
assert(m_dfsLast.size()==numBBs);
|
||||||
for(BB *pbb : m_dfsLast)
|
for(BB *pbb : m_dfsLast | filtered(BB::ValidFunctor()))
|
||||||
{
|
{
|
||||||
if (pbb->flg & INVALID_BB)
|
|
||||||
continue;
|
|
||||||
pbb->genDU1();
|
pbb->genDU1();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
|
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
|
||||||
* of picode. */
|
* of picode. */
|
||||||
void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
|
void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
|
||||||
|
|||||||
@ -278,7 +278,7 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
|||||||
int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, iICODE atOffset)
|
int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, iICODE atOffset)
|
||||||
{
|
{
|
||||||
size_t idx;
|
size_t idx;
|
||||||
LLOperand *pmH, *pmL;
|
const LLOperand *pmH, *pmL;
|
||||||
LLInst &p_ll(*pIcode->ll());
|
LLInst &p_ll(*pIcode->ll());
|
||||||
if (f == LOW_FIRST)
|
if (f == LOW_FIRST)
|
||||||
{
|
{
|
||||||
@ -334,7 +334,8 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, i
|
|||||||
* rhs, lhs : return expressions if successful. */
|
* rhs, lhs : return expressions if successful. */
|
||||||
boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, iICODE atOffset)
|
boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, iICODE atOffset)
|
||||||
{
|
{
|
||||||
LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; /* pointers to LOW_LEVEL icodes */
|
/* pointers to LOW_LEVEL icodes */
|
||||||
|
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
||||||
|
|
||||||
pmHdst = &pIcode->ll()->dst;
|
pmHdst = &pIcode->ll()->dst;
|
||||||
pmLdst = &atOffset->ll()->dst;
|
pmLdst = &atOffset->ll()->dst;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user