Esempio n. 1
0
bool AArch64PromoteConstant::insertDefinitions(
    Constant *Cst, InsertionPointsPerFunc &InsPtsPerFunc) {
  // We will create one global variable per Module.
  DenseMap<Module *, GlobalVariable *> ModuleToMergedGV;
  bool HasChanged = false;

  // Traverse all insertion points in all the function.
  for (InsertionPointsPerFunc::iterator FctToInstPtsIt = InsPtsPerFunc.begin(),
                                        EndIt = InsPtsPerFunc.end();
       FctToInstPtsIt != EndIt; ++FctToInstPtsIt) {
    InsertionPoints &InsertPts = FctToInstPtsIt->second;
// Do more checking for debug purposes.
#ifndef NDEBUG
    DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(
        *FctToInstPtsIt->first).getDomTree();
#endif
    GlobalVariable *PromotedGV;
    assert(!InsertPts.empty() && "Empty uses does not need a definition");

    Module *M = FctToInstPtsIt->first->getParent();
    DenseMap<Module *, GlobalVariable *>::iterator MapIt =
        ModuleToMergedGV.find(M);
    if (MapIt == ModuleToMergedGV.end()) {
      PromotedGV = new GlobalVariable(
          *M, Cst->getType(), true, GlobalValue::InternalLinkage, nullptr,
          "_PromotedConst", nullptr, GlobalVariable::NotThreadLocal);
      PromotedGV->setInitializer(Cst);
      ModuleToMergedGV[M] = PromotedGV;
      DEBUG(dbgs() << "Global replacement: ");
      DEBUG(PromotedGV->print(dbgs()));
      DEBUG(dbgs() << '\n');
      ++NumPromoted;
      HasChanged = true;
    } else {
      PromotedGV = MapIt->second;
    }

    for (InsertionPoints::iterator IPI = InsertPts.begin(),
                                   EndIPI = InsertPts.end();
         IPI != EndIPI; ++IPI) {
      // Create the load of the global variable.
      IRBuilder<> Builder(IPI->first->getParent(), 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.
      Users &DominatedUsers = IPI->second;
      for (Value::user_iterator Use : DominatedUsers) {
#ifndef NDEBUG
        assert((DT.dominates(LoadedCst, cast<Instruction>(*Use)) ||
                (isa<PHINode>(*Use) &&
                 DT.dominates(LoadedCst, findInsertionPoint(Use)))) &&
               "Inserted definition does not dominate all its uses!");
#endif
        DEBUG(dbgs() << "Use to update " << Use.getOperandNo() << ":");
        DEBUG(Use->print(dbgs()));
        DEBUG(dbgs() << '\n');
        Use->setOperand(Use.getOperandNo(), LoadedCst);
        ++NumPromotedUses;
      }
    }
  }
  return HasChanged;
}