bool CodePreparation::eliminatePHINodes(Function &F) { // The PHINodes that will be deleted. std::vector<PHINode*> PNtoDel; // The PHINodes that will be preserved. std::vector<PHINode*> PreservedPNs; // Scan the PHINodes in this function. for (Function::iterator ibb = F.begin(), ibe = F.end(); ibb != ibe; ++ibb) for (BasicBlock::iterator iib = ibb->begin(), iie = ibb->getFirstNonPHI(); iib != iie; ++iib) if (PHINode *PN = cast<PHINode>(iib)) { if (Loop *L = LI->getLoopFor(ibb)) { // Induction variable will be preserved. if (L->getCanonicalInductionVariable() == PN) { PreservedPNs.push_back(PN); continue; } } // As DemotePHIToStack does not support invoke edges, we preserve // PHINodes that have invoke edges. if (hasInvokeEdge(PN)) PreservedPNs.push_back(PN); else PNtoDel.push_back(PN); } if (PNtoDel.empty()) return false; // Eliminate the PHINodes that not an Induction variable. while (!PNtoDel.empty()) { PHINode *PN = PNtoDel.back(); PNtoDel.pop_back(); DemotePHIToStack(PN); } // Move all preserved PHINodes to the beginning of the BasicBlock. while (!PreservedPNs.empty()) { PHINode *PN = PreservedPNs.back(); PreservedPNs.pop_back(); BasicBlock *BB = PN->getParent(); if (PN == BB->begin()) continue; PN->moveBefore(BB->begin()); } return true; }
Value *RegionGenerator::copyPHIInstruction(ScopStmt &Stmt, const PHINode *PHI, ValueMapT &BBMap, ValueMapT &GlobalMap, LoopToScevMapT <S) { unsigned NumIncoming = PHI->getNumIncomingValues(); PHINode *PHICopy = Builder.CreatePHI(PHI->getType(), NumIncoming, "polly." + PHI->getName()); PHICopy->moveBefore(PHICopy->getParent()->getFirstNonPHI()); BBMap[PHI] = PHICopy; for (unsigned u = 0; u < NumIncoming; u++) addOperandToPHI(Stmt, PHI, PHICopy, PHI->getIncomingBlock(u), GlobalMap, LTS); return PHICopy; }
bool ModuloSchedulerDriverPass::runOnLoop(Loop *IncomingLoop, LPPassManager &LPM_Ref) { subscripts subs(IncomingLoop); if (!loop_is_ms_able(IncomingLoop) ) return false; // The header before the parallelized loop will be placed here BasicBlock* preheader = IncomingLoop->getLoopPreheader(); assert(preheader && "Unable to get a hold of the preheader"); // Balance all BasicBlocks in this loop for (Loop::block_iterator it=IncomingLoop->block_begin(); it!=IncomingLoop->block_end();++it) { duplicateValuesWithMultipleUses(*it,subs.getInductionVar()); } // For each BB in loop for (Loop::block_iterator it=IncomingLoop->block_begin(); it!=IncomingLoop->block_end();++it) { instructionPriority ip(*it); (*it)->setName("PipelinedLoop"); // ++++++++ Preheader part +++++++++ // Make a copy of the body for each instruction. Place a pointer to the // parallel cloned instruction in the map below. Later on we will replace it // with a PHINode. DenseMap<const Value *, Value *> InstToPreheader; // For each Instruction in body of the loop, clone, store, etc. for (BasicBlock::iterator ib = (*it)->begin(), eb = (*it)->end(); ib!=eb; ++ib) { // If this is NOT a phi node if (!dyn_cast<PHINode>(ib)) { // Get the priority of the instruction unsigned int p = ip.getPriority(ib); // This is the header version of each variable that goes into a PHI node. // The other edge needs to come from the 'prev' iteration // We subtract -1 because this is one iteration before // Store the result into the map of the cloned InstToPreheader[ib] = copyLoopBodyToHeader(ib, subs.getInductionVar(), preheader, p-1); } } // ++++++++ Loop body part +++++++++ // For each of the cloned increment the indexs if needed and place the PHINode. for (BasicBlock::iterator ib = (*it)->begin(), eb = (*it)->end(); ib!=eb; ++ib) { // If this is NOT a phi node if (!dyn_cast<PHINode>(ib)) { unsigned int p = ip.getPriority(ib); // If this variable is not dependent on i (not i:=i+1) // then we need to replace each i to i+5 ... // We also do not need to create a PHI node, etc. if (!subs.isUsedByInductionVariable(ib)) { incrementInductionVarIfUsed(ib,subs.getInductionVar(),p); // Create the new PHI Node to replace the node if (!dyn_cast<StoreInst>(ib) && !ib->isTerminator()) { std::string newname = "glue" + (*it)->getName(); //PHINode* np = PHINode::Create(ib->getType(), "glue", *it); PHINode* np = PHINode::Create(ib->getType(), newname, *it); ib->replaceAllUsesWith(np); np->reserveOperandSpace(2); np->addIncoming(InstToPreheader[ib], preheader); np->addIncoming(ib, *it); np->moveBefore((*it)->begin()); } }// end of if this is not an IV node (i:=i+1) } } } eliminateDuplicatedLoads(preheader); for (Loop::block_iterator it=IncomingLoop->block_begin(); it!=IncomingLoop->block_end();++it) { eliminateDuplicatedLoads(*it); for (BasicBlock::iterator in = (*it)->begin(); in != (*it)->end(); ++in) { foldAddInstructions(in); } } return true; }