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; }