Hi all,
I met an issue in Ia32WebMaker action recently.
In Ia32WebMaker action, function phase1() first generated array opndxs like
this:
void WebMaker::phase1()
{
opndxs.resize(opandcount);
for (unsigned i = 0; i != opandcount; ++i)
{
Opndx* opndxp = 0;
if (!irManager->getOpnd(i)->hasAssignedPhysicalLocation())
opndxp = new (mm) Opndx(mm);
opndxs[i] = opndxp;
}
......
So all the Opnd in IR are registed in array opndxp
And in function phase3(), there are codes to splitOpnd and replaceOpnd in the
same inst, like this:
....
if (opdefp->globid == -1)
{// local operand
if (isdef)
{
++opndxp->webscount;
if (opndxp->webscount > 1)
{
opndxp->newopndp = splitOpnd(opndp);
DBGOUT("**new local web found " << *opndp
<< " -> " << *opndxp->newopndp << endl;)
}
}
if (opndxp->webscount > 1 &&
opdefp->defp->getNode() == nodep)
{
instp->replaceOpnd(opndp, opndxp->newopndp,
isdef ? Inst::OpndRole_AllDefs : Inst::OpndRole_AllUses);
DBGOUT(" replace B#" <<
instp->getBasicBlock()->getId() << " " << *instp << endl;)
}
...
So the question is, if we meet an IR like
I6: CALL t14[t12]:ptr:uintptr (AU:s7:cls:Hello,s7:cls:Hello) [bcmap:unknown]
(from source code like hello.fun(hello) )
WebMaker decides to replace the s7 with new generated s19 at the second
Opnd(second iteration of I6) of I6, but the call of instp->replaceOpnd() will
also change the third Opnd of I6 to s19. In the next iteration(thrid iteration
of I6) of phase3(), the code
Opndx* opndxp = opndxs.at(opndp->getId());
will throw vector _range_out error because array opndxs has not been updated
with new generated Opnd s19.
So is this really a bug or I misunderstand some parts of the code?
Thanks a lot!
2009-10-15
johnnylj98