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;
    }
  }
示例#2
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 (const auto &FctToInstPtsIt : InsPtsPerFunc) {
    const InsertionPoints &InsertPts = FctToInstPtsIt.second;
// Do more checking for debug purposes.
#ifndef NDEBUG
    DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(
                            *FctToInstPtsIt.first).getDomTree();
#endif
    assert(!InsertPts.empty() && "Empty uses does not need a definition");

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

    for (const auto &IPI : InsertPts) {
      // 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.
      for (Use *Use : IPI.second) {
#ifndef NDEBUG
        assert(DT.dominates(LoadedCst, findInsertionPoint(*Use)) &&
               "Inserted definition does not dominate all its uses!");
#endif
        DEBUG(dbgs() << "Use to update " << Use->getOperandNo() << ":");
        DEBUG(Use->getUser()->print(dbgs()));
        DEBUG(dbgs() << '\n');
        Use->set(LoadedCst);
        ++NumPromotedUses;
      }
    }
  }
  return HasChanged;
}
示例#3
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;
}