Exemple #1
0
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;
}
Exemple #2
0
Value *RegionGenerator::copyPHIInstruction(ScopStmt &Stmt, const PHINode *PHI,
                                           ValueMapT &BBMap,
                                           ValueMapT &GlobalMap,
                                           LoopToScevMapT &LTS) {
  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;
    }