Refactored BasicBlock::genDU1() into three utility methods.

Const'ized a few pointers in locident.cpp
This commit is contained in:
Artur K 2012-03-17 23:15:27 +01:00
parent 61392772e1
commit d3a22fc03c
3 changed files with 121 additions and 112 deletions

View File

@ -122,7 +122,10 @@ public:
{
edges[0].ip = ip;
}
void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
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;
Function *Parent;

View File

@ -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
* of register regi, before any definitions of the
* register */
bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
{
if ((regi == rDI) && (flg & DI_REGVAR))
continue;
return true;
if ((regi == rSI) && (flg & SI_REGVAR))
continue;
if (distance(picode,all_high_levels.end())>1) /* several instructions */
return true;
if (distance(start_at,end())>1) /* several instructions */
{
useIdx = 0;
for (auto ricode = ++iICODE(picode.base()); ricode != lastInst; ricode++)
iICODE ticode=end();
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 (ricode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
if (checked_icode->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 ((checked_icode->du.use & duReg[regi]).any())
start_at->du1.recordUse(defRegIdx,checked_icode.base());
/* 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;
}
}
if(ticode==end())
ticode=(++riICODE(rbegin())).base();
/* 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];
if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any())
start_at->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];
if ((liveOut & duReg[regi]).any())
start_at->du.lastDefRegi |= duReg[regi];
}
return false;
}
/* 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. */
void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode)
{
if ((picode->hl()->opcode == HLI_CALL) &&
(picode->hl()->call.proc->flg & PROC_IS_FUNC))
{
tbb = this->edges[0].BBptr;
for (ticode = tbb->begin(); ticode != tbb->end(); ticode++)
BB *tbb = this->edges[0].BBptr;
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 ((ticode->du.use & duReg[regi]).any())
picode->du1.recordUse(defRegIdx,ticode);
if ((iter->du.use & duReg[regi]).any())
picode->du1.recordUse(defRegIdx,iter.base());
/* if defined, stop finding uses for this reg */
if ((ticode->du.def & duReg[regi]).any())
if ((iter->du.def & duReg[regi]).any())
break;
}
@ -489,13 +468,15 @@ void BB::genDU1()
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). */
void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
{
if (picode->valid() and not picode->du1.used(defRegIdx) and
(not (picode->du.lastDefRegi & duReg[regi]).any()) &&
(not ((picode->hl()->opcode == HLI_CALL) &&
@ -503,23 +484,50 @@ void BB::genDU1()
{
if (! (this->liveOut & duReg[regi]).any()) /* not liveOut */
{
res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
if (res != true)
bool 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 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 */
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++;
/* Check if all defined registers have been processed */
@ -533,16 +541,13 @@ void Function::genDU1 ()
{
/* Traverse tree in dfsLast order */
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();
}
}
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
* of picode. */
void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const

View File

@ -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)
{
size_t idx;
LLOperand *pmH, *pmL;
const LLOperand *pmH, *pmL;
LLInst &p_ll(*pIcode->ll());
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. */
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;
pmLdst = &atOffset->ll()->dst;