Ejemplo n.º 1
0
bool ARM64PromoteConstant::isDominated(Instruction *NewPt,
                                       Value::use_iterator &UseIt,
                                       InsertionPoints &InsertPts) {
  
  DominatorTree &DT =
    getAnalysis<DominatorTree>(*NewPt->getParent()->getParent());
  
  // Traverse all the existing insertion point and check if one is dominating
  // NewPt
  for (InsertionPoints::iterator IPI = InsertPts.begin(),
       EndIPI = InsertPts.end(); IPI != EndIPI; ++IPI) {
    if (NewPt == IPI->first || DT.dominates(IPI->first, NewPt) ||
        // When IPI->first is a terminator instruction, DT may think that
        // the result is defined on the edge.
        // Here we are testing the insertion point, not the definition.
        (IPI->first->getParent() != NewPt->getParent() &&
         DT.dominates(IPI->first->getParent(), NewPt->getParent()))) {
      // No need to insert this point
      // Record the dominated use
      DEBUG(dbgs() << "Insertion point dominated by:\n");
      DEBUG(IPI->first->print(dbgs()));
      DEBUG(dbgs() << '\n');
      IPI->second.push_back(UseIt);
      return true;
    }
  }
  return false;
}
Ejemplo n.º 2
0
bool AArch64PromoteConstant::tryAndMerge(Instruction *NewPt, Instruction *User,
                                         unsigned OpNo,
                                         InsertionPoints &InsertPts) {
  DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(
      *NewPt->getParent()->getParent()).getDomTree();
  BasicBlock *NewBB = NewPt->getParent();

  // Traverse all the existing insertion point and check if one is dominated by
  // NewPt and thus useless or can be combined with NewPt into a common
  // dominator.
  for (InsertionPoints::iterator IPI = InsertPts.begin(),
                                 EndIPI = InsertPts.end();
       IPI != EndIPI; ++IPI) {
    BasicBlock *CurBB = IPI->first->getParent();
    if (NewBB == CurBB) {
      // Instructions are in the same block.
      // By construction, NewPt is dominating the other.
      // Indeed, isDominated returned false with the exact same arguments.
      DEBUG(dbgs() << "Merge insertion point with:\n");
      DEBUG(IPI->first->print(dbgs()));
      DEBUG(dbgs() << "\nat considered insertion point.\n");
      appendAndTransferDominatedUses(NewPt, User, OpNo, IPI, InsertPts);
      return true;
    }

    // Look for a common dominator
    BasicBlock *CommonDominator = DT.findNearestCommonDominator(NewBB, CurBB);
    // If none exists, we cannot merge these two points.
    if (!CommonDominator)
      continue;

    if (CommonDominator != NewBB) {
      // By construction, the CommonDominator cannot be CurBB.
      assert(CommonDominator != CurBB &&
             "Instruction has not been rejected during isDominated check!");
      // Take the last instruction of the CommonDominator as insertion point
      NewPt = CommonDominator->getTerminator();
    }
    // else, CommonDominator is the block of NewBB, hence NewBB is the last
    // possible insertion point in that block.
    DEBUG(dbgs() << "Merge insertion point with:\n");
    DEBUG(IPI->first->print(dbgs()));
    DEBUG(dbgs() << '\n');
    DEBUG(NewPt->print(dbgs()));
    DEBUG(dbgs() << '\n');
    appendAndTransferDominatedUses(NewPt, User, OpNo, IPI, InsertPts);
    return true;
  }
  return false;
}
Ejemplo n.º 3
0
void AArch64PromoteConstant::insertDefinitions(Function &F,
                                               GlobalVariable &PromotedGV,
                                               InsertionPoints &InsertPts) {
#ifndef NDEBUG
  // Do more checking for debug purposes.
  DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
#endif
  assert(!InsertPts.empty() && "Empty uses does not need a definition");

  for (const auto &IPI : InsertPts) {
    // Create the load of the global variable.
    IRBuilder<> Builder(IPI.first);
    LoadInst *LoadedCst = Builder.CreateLoad(&PromotedGV);
    DEBUG(dbgs() << "**********\n");
    DEBUG(dbgs() << "New def: ");
    DEBUG(LoadedCst->print(dbgs()));
    DEBUG(dbgs() << '\n');

    // Update the dominated uses.
    for (auto Use : IPI.second) {
#ifndef NDEBUG
      assert(DT.dominates(LoadedCst,
                          findInsertionPoint(*Use.first, Use.second)) &&
             "Inserted definition does not dominate all its uses!");
#endif
      DEBUG({
            dbgs() << "Use to update " << Use.second << ":";
            Use.first->print(dbgs());
            dbgs() << '\n';
            });
      Use.first->setOperand(Use.second, LoadedCst);
      ++NumPromotedUses;
    }
  }