[LLVMdev] Question about method CodeExtractor::severSplitPHINodes

Wei Dang jacdang at gmail.com
Sat Mar 2 15:22:15 PST 2013


Hi folks,

Hope this is not a silly question. But it bothers me when I am thinking
about it.

My question is:
1. In the implementation of serverSplitPHINodes(), why it only checks the
first PHI node for possible
    multiple inputs from outside the region to extract. There could be more
than one PHI nodes in the header
    block, and the code only checks the first one. I don't quite get it.
What if the first PHI node contains only
    incoming values from inside the region, while subsequent PHI nodes have
inputs from outside? Is that possible?

2. Oddly, later in the code, it creates a corresponding new PHI node in the
newBB for each PHI in the old header block. And
    then it adds the old PHI node as an incoming value to the newPHI node.
This is Okay for the first PHI node of original header
    as it's been proved to have multiple inputs from outside the region
earlier. But it does not make sense for subsequent PHI nodes since they
    may contain only incoming values from inside. Then what's the point of
adding it as an incoming value to the new PHI when it
    doesn't even have anything from outside. This looks redundant to me.

I could only guess it has something to do with the way PHI nodes get
inserted in LLVM. Any help is much appreciated!!!

/// severSplitPHINodes - If a PHI node has multiple inputs from
outside of the00185 /// region, we need to split the entry block of
the region so that the PHI node00186 /// is easier to deal with.00187
void CodeExtractor::severSplitPHINodes(BasicBlock
<http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html>
*&Header) {00188   unsigned NumPredsFromRegion = 0;00189   unsigned
NumPredsOutsideRegion = 0;00190 00191   if (Header !=
&Header->getParent
<http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html#aca229503e4f5c83a187a6a921c625fa8>()->getEntryBlock
<http://llvm.org/docs/doxygen/html/classllvm_1_1Function.html#a30f2c362631e3728d2f47a8203071ade>())
{00192     PHINode
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html> *PN =
dyn_cast <http://llvm.org/docs/doxygen/html/namespacellvm.html#ad6dbabbbb9495cf1501d64a5c71729ed><PHINode
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html>>(Header->begin
<http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html#a0ed5f3ab3c2e4196ee0cffffa080c062>());00193
    if (!PN) return;  // No PHI nodes.00194 00195     // If the header
node contains any PHI nodes, check to see if there is more00196     //
than one entry from outside the region.  If so, we need to sever
the00197     // header block into two.00198     for (unsigned i = 0, e
= PN->getNumIncomingValues
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#aa45f6c0433576e3858a6209a43750ad4>();
i != e; ++i)00199       if (Blocks.count
<http://llvm.org/docs/doxygen/html/classllvm_1_1SetVector.html#a0fd2953d62c1b1cabb87e420be5177c4>(PN->getIncomingBlock
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#a4c25b6c00c4867281779c81ab64d2081>(i)))00200
        ++NumPredsFromRegion;00201       else00202
++NumPredsOutsideRegion;00203 00204     // If there is one (or fewer)
predecessor from outside the region, we don't00205     // need to do
anything special.00206     if (NumPredsOutsideRegion <= 1)
return;00207   }00208 00209   // Otherwise, we need to split the
header block into two pieces: one00210   // containing PHI nodes
merging values from outside of the region, and a00211   // second that
contains all of the code for the block and merges back any00212   //
incoming values from inside of the region.00213   BasicBlock::iterator
<http://llvm.org/docs/doxygen/html/classllvm_1_1ilist__iterator.html>
AfterPHIs = Header->getFirstNonPHI
<http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html#a0e73f4e09745bb69fdd7b15232c45428>();00214
  BasicBlock <http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html>
*NewBB = Header->splitBasicBlock
<http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html#a19445f836d9e1ecb32cba27ec4338fff>(AfterPHIs,00215
                                              Header->getName
<http://llvm.org/docs/doxygen/html/classllvm_1_1Value.html#ad452febc1ac0b394876e640ec03ffa38>()+".ce");00216
00217   // We only want to code extract the second block now, and it
becomes the new00218   // header of the region.00219   BasicBlock
<http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html>
*OldPred = Header;00220   Blocks.remove
<http://llvm.org/docs/doxygen/html/classllvm_1_1SetVector.html#a6357ff5654c7cbe5fed8516dc8328eb4>(OldPred);00221
  Blocks.insert
<http://llvm.org/docs/doxygen/html/classllvm_1_1SetVector.html#a72d928b7fc2c5f2d56c6ac0265fd9c6e>(NewBB);00222
  Header = NewBB;00223 00224   // Okay, update dominator sets. The
blocks that dominate the new one are the00225   // blocks that
dominate TIBB plus the new block itself.00226   if (DT)00227
DT->splitBlock <http://llvm.org/docs/doxygen/html/classllvm_1_1DominatorTree.html#a3d5044cf4966abb56510f1883d275745>(NewBB);00228
00229   // Okay, now we need to adjust the PHI nodes and any branches
from within the00230   // region to go to the new header block instead
of the old header block.00231   if (NumPredsFromRegion) {00232
PHINode <http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html>
*PN = cast<PHINode>(OldPred->begin
<http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html#a0ed5f3ab3c2e4196ee0cffffa080c062>());00233
    // Loop over all of the predecessors of OldPred that are in the
region,00234     // changing them to branch to NewBB instead.00235
for (unsigned i = 0, e = PN->getNumIncomingValues
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#aa45f6c0433576e3858a6209a43750ad4>();
i != e; ++i)00236       if (Blocks.count
<http://llvm.org/docs/doxygen/html/classllvm_1_1SetVector.html#a0fd2953d62c1b1cabb87e420be5177c4>(PN->getIncomingBlock
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#a4c25b6c00c4867281779c81ab64d2081>(i)))
{00237         TerminatorInst
<http://llvm.org/docs/doxygen/html/classllvm_1_1TerminatorInst.html>
*TI = PN->getIncomingBlock
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#a4c25b6c00c4867281779c81ab64d2081>(i)->getTerminator
<http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html#a5cb76a65b6524dba1493dd2b9dc3abbe>();00238
        TI->replaceUsesOfWith
<http://llvm.org/docs/doxygen/html/classllvm_1_1User.html#a1f0b9358936e3e00c42a460abbfb2868>(OldPred,
NewBB);00239       }00240 00241     // Okay, everything within the
region is now branching to the right block, we00242     // just have
to update the PHI nodes now, inserting PHI nodes into NewBB.00243
for (AfterPHIs = OldPred->begin
<http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html#a0ed5f3ab3c2e4196ee0cffffa080c062>();
isa<PHINode>(AfterPHIs); ++AfterPHIs) {00244       PHINode
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html> *PN =
cast<PHINode>(AfterPHIs);00245       // Create a new PHI node in the
new region, which has an incoming value00246       // from OldPred of
PN.00247       PHINode
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html> *NewPN =
PHINode::Create
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#afb5e83bf5123ff7c51058eb0ebebcdc6>(PN->getType
<http://llvm.org/docs/doxygen/html/classllvm_1_1Value.html#a0cf3748dba54f931bb1241ae4adc76bc>(),
1 + NumPredsFromRegion,00248
PN->getName <http://llvm.org/docs/doxygen/html/classllvm_1_1Value.html#ad452febc1ac0b394876e640ec03ffa38>()+".ce",
NewBB->begin <http://llvm.org/docs/doxygen/html/classllvm_1_1BasicBlock.html#a0ed5f3ab3c2e4196ee0cffffa080c062>());00249
      NewPN->addIncoming
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#a089cccb6f231efee72abc76d0f9c695f>(PN,
OldPred);00250 00251       // Loop over all of the incoming value in
PN, moving them to NewPN if they00252       // are from the extracted
region.00253       for (unsigned i = 0; i != PN->getNumIncomingValues
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#aa45f6c0433576e3858a6209a43750ad4>();
++i) {00254         if (Blocks.count
<http://llvm.org/docs/doxygen/html/classllvm_1_1SetVector.html#a0fd2953d62c1b1cabb87e420be5177c4>(PN->getIncomingBlock
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#a4c25b6c00c4867281779c81ab64d2081>(i)))
{00255           NewPN->addIncoming(PN->getIncomingValue
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#aba6a4cc4ed6d6fef3664b8d65ef04820>(i),
PN->getIncomingBlock
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#a4c25b6c00c4867281779c81ab64d2081>(i));00256
          PN->removeIncomingValue
<http://llvm.org/docs/doxygen/html/classllvm_1_1PHINode.html#a6f01dbe965b38186b1a78378689d4105>(i);00257
          --i;00258         }00259       }00260     }00261   }00262 }


-- 
Wei
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130302/8ea10098/attachment.html>


More information about the llvm-dev mailing list