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;
|
||||
}
|
||||
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;
|
||||
|
||||
|
||||
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
|
||||
* 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
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user