for (auto &Buf : Buffers) {
layoutBuffer(Buf, DL);
GlobalVariable *GV = replaceBuffer(Buf);
- M.getGlobalList().push_back(GV);
+ M.insertGlobalVariable(GV);
llvm::hlsl::ResourceClass RC = Buf.IsCBuffer
? llvm::hlsl::ResourceClass::CBuffer
: llvm::hlsl::ResourceClass::SRV;
GV->eraseFromParent();
}
GV = NewGV;
- CGM.getModule().getGlobalList().push_back(GV);
+ CGM.getModule().insertGlobalVariable(GV);
}
assert(GV->getLinkage() == L);
}
};
- for (llvm::GlobalVariable &global_var : m_module->getGlobalList()) {
+ for (llvm::GlobalVariable &global_var : m_module->globals()) {
RegisterOneValue(global_var);
}
* | ``Module::global_iterator`` - Typedef for global variable list iterator
| ``Module::const_global_iterator`` - Typedef for const_iterator.
+ | ``Module::insertGlobalVariable()`` - Inserts a global variable to the list.
+ | ``Module::removeGlobalVariable()`` - Removes a global variable frome the list.
+ | ``Module::eraseGlobalVariable()`` - Removes a global variable frome the list and deletes it.
| ``global_begin()``, ``global_end()``, ``global_size()``, ``global_empty()``
These are forwarding methods that make it easy to access the contents of a
``Module`` object's GlobalVariable_ list.
-* ``Module::GlobalListType &getGlobalList()``
-
- Returns the list of GlobalVariable_\ s. This is necessary to use when you
- need to update the list or perform a complex action that doesn't have a
- forwarding method.
-
----------------
* ``SymbolTable *getSymbolTable()``
llvm::Error materializeMetadata();
+ /// Detach global variable \p GV from the list but don't delete it.
+ void removeGlobalVariable(GlobalVariable *GV) { GlobalList.remove(GV); }
+ /// Remove global variable \p GV from the list and delete it.
+ void eraseGlobalVariable(GlobalVariable *GV) { GlobalList.erase(GV); }
+ /// Insert global variable \p GV at the end of the global variable list and
+ /// take ownership.
+ void insertGlobalVariable(GlobalVariable *GV) {
+ insertGlobalVariable(GlobalList.end(), GV);
+ }
+ /// Insert global variable \p GV into the global variable list before \p
+ /// Where and take ownership.
+ void insertGlobalVariable(GlobalListType::iterator Where, GlobalVariable *GV) {
+ GlobalList.insert(Where, GV);
+ }
+ // Use global_size() to get the total number of global variables.
+ // Use globals() to get the range of all global variables.
+
+private:
/// @}
/// @name Direct access to the globals list, functions list, and symbol table
/// @{
static GlobalListType Module::*getSublistAccess(GlobalVariable*) {
return &Module::GlobalList;
}
+ friend class llvm::SymbolTableListTraits<llvm::GlobalVariable>;
+public:
/// Get the Module's list of functions (constant).
const FunctionListType &getFunctionList() const { return FunctionList; }
/// Get the Module's list of functions.
UpgradedVariables.emplace_back(&GV, Upgraded);
for (auto &Pair : UpgradedVariables) {
Pair.first->eraseFromParent();
- TheModule->getGlobalList().push_back(Pair.second);
+ TheModule->insertGlobalVariable(Pair.second);
}
// Force deallocation of memory for these vectors to favor the client that
// Look for existing encoding of the location + flags, not needed but
// minimizes the difference to the existing solution while we transition.
- for (GlobalVariable &GV : M.getGlobalList())
+ for (GlobalVariable &GV : M.globals())
if (GV.getValueType() == OpenMPIRBuilder::Ident && GV.hasInitializer())
if (GV.getInitializer() == Initializer)
Ident = &GV;
// Look for existing encoding of the location, not needed but minimizes the
// difference to the existing solution while we transition.
- for (GlobalVariable &GV : M.getGlobalList())
+ for (GlobalVariable &GV : M.globals())
if (GV.isConstant() && GV.hasInitializer() &&
GV.getInitializer() == Initializer)
return SrcLocStr = ConstantExpr::getPointerCast(&GV, Int8Ptr);
}
if (Before)
- Before->getParent()->getGlobalList().insert(Before->getIterator(), this);
+ Before->getParent()->insertGlobalVariable(Before->getIterator(), this);
else
- M.getGlobalList().push_back(this);
+ M.insertGlobalVariable(this);
}
void GlobalVariable::removeFromParent() {
- getParent()->getGlobalList().remove(getIterator());
+ getParent()->removeGlobalVariable(this);
}
void GlobalVariable::eraseFromParent() {
- getParent()->getGlobalList().erase(getIterator());
+ getParent()->eraseGlobalVariable(this);
}
void GlobalVariable::setInitializer(Constant *InitVal) {
// Reorder the globals just added to the destination module to match their
// original order in the source module.
- Module::GlobalListType &Globals = DstM.getGlobalList();
for (GlobalVariable &GV : SrcM->globals()) {
if (GV.hasAppendingLinkage())
continue;
Value *NewValue = Mapper.mapValue(GV);
if (NewValue) {
auto *NewGV = dyn_cast<GlobalVariable>(NewValue->stripPointerCasts());
- if (NewGV)
- Globals.splice(Globals.end(), Globals, NewGV->getIterator());
+ if (NewGV) {
+ NewGV->removeFromParent();
+ DstM.insertGlobalVariable(NewGV);
+ }
}
}
for (const GlobalVariable &I : M.globals())
VisitGlobalVariableForEmission(&I, Globals, GVVisited, GVVisiting);
- assert(GVVisited.size() == M.getGlobalList().size() &&
- "Missed a global variable");
+ assert(GVVisited.size() == M.global_size() && "Missed a global variable");
assert(GVVisiting.size() == 0 && "Did not fully process a global variable");
const NVPTXTargetMachine &NTM = static_cast<const NVPTXTargetMachine &>(TM);
cast<StoreInst>(InitBool->user_back())->eraseFromParent();
delete InitBool;
} else
- GV->getParent()->getGlobalList().insert(GV->getIterator(), InitBool);
+ GV->getParent()->insertGlobalVariable(GV->getIterator(), InitBool);
// Now the GV is dead, nuke it and the allocation..
GV->eraseFromParent();
GV->getThreadLocalMode(),
GV->getType()->getAddressSpace());
NewGV->copyAttributesFrom(GV);
- GV->getParent()->getGlobalList().insert(GV->getIterator(), NewGV);
+ GV->getParent()->insertGlobalVariable(GV->getIterator(), NewGV);
Constant *InitVal = GV->getInitializer();
assert(InitVal->getType() != Type::getInt1Ty(GV->getContext()) &&
SI->eraseFromParent();
MadeChanges = true;
}
- M.getGlobalList().erase(GV);
+ M.eraseGlobalVariable(GV);
++NumGlobalConst;
}
PA.preserve<FunctionAnalysisManagerModuleProxy>();
return PA;
}
+
+namespace {
+
+//===--------------------------------------------------------------------===//
+//
+/// IPSCCP Class - This class implements interprocedural Sparse Conditional
+/// Constant Propagation.
+///
+class IPSCCPLegacyPass : public ModulePass {
+public:
+ static char ID;
+
+ IPSCCPLegacyPass() : ModulePass(ID) {
+ initializeIPSCCPLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnModule(Module &M) override {
+ if (skipModule(M))
+ return false;
+ const DataLayout &DL = M.getDataLayout();
+ auto GetTLI = [this](Function &F) -> const TargetLibraryInfo & {
+ return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
+ };
+ auto GetTTI = [this](Function &F) -> TargetTransformInfo & {
+ return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ };
+ auto GetAC = [this](Function &F) -> AssumptionCache & {
+ return this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+ };
+ auto getAnalysis = [this](Function &F) -> AnalysisResultsForFn {
+ DominatorTree &DT =
+ this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
+ return {
+ std::make_unique<PredicateInfo>(
+ F, DT,
+ this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
+ F)),
+ nullptr, // We cannot preserve the LI, DT or PDT with the legacy pass
+ nullptr, // manager, so set them to nullptr.
+ nullptr};
+ };
+
+ return runIPSCCP(M, DL, nullptr, GetTLI, GetTTI, GetAC, getAnalysis, false);
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<AssumptionCacheTracker>();
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
+ AU.addRequired<TargetTransformInfoWrapperPass>();
+ }
+};
+
+} // end anonymous namespace
+
+char IPSCCPLegacyPass::ID = 0;
+
+INITIALIZE_PASS_BEGIN(IPSCCPLegacyPass, "ipsccp",
+ "Interprocedural Sparse Conditional Constant Propagation",
+ false, false)
+INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
+INITIALIZE_PASS_END(IPSCCPLegacyPass, "ipsccp",
+ "Interprocedural Sparse Conditional Constant Propagation",
+ false, false)
+
+// createIPSCCPPass - This is the public interface to this file.
+ModulePass *llvm::createIPSCCPPass() { return new IPSCCPLegacyPass(); }
std::vector<VTableBits> &Bits,
DenseMap<Metadata *, std::set<TypeMemberInfo>> &TypeIdMap) {
DenseMap<GlobalVariable *, VTableBits *> GVToBits;
- Bits.reserve(M.getGlobalList().size());
+ Bits.reserve(M.global_size());
SmallVector<MDNode *, 2> Types;
for (GlobalVariable &GV : M.globals()) {
Types.clear();
GlobalVariable *NGV =
new GlobalVariable(CA->getType(), GCL->isConstant(), GCL->getLinkage(),
CA, "", GCL->getThreadLocalMode());
- GCL->getParent()->getGlobalList().insert(GCL->getIterator(), NGV);
+ GCL->getParent()->insertGlobalVariable(GCL->getIterator(), NGV);
NGV->takeName(GCL);
// Nuke the old list, replacing any uses with the new one.
// Sort the globals by name.
EXPECT_FALSE(std::is_sorted(M.global_begin(), M.global_end(), compare));
- M.getGlobalList().sort(compare);
- EXPECT_TRUE(std::is_sorted(M.global_begin(), M.global_end(), compare));
}
}
EXPECT_EQ(M->named_metadata_size(), 2u);
}
+TEST(ModuleTest, GlobalList) {
+ // This tests all Module's functions that interact with Module::GlobalList.
+ LLVMContext C;
+ SMDiagnostic Err;
+ LLVMContext Context;
+ std::unique_ptr<Module> M = parseAssemblyString(R"(
+@GV = external global i32
+)",
+ Err, Context);
+ auto *GV = cast<GlobalVariable>(M->getNamedValue("GV"));
+ EXPECT_EQ(M->global_size(), 1u);
+ GlobalVariable *NewGV = new GlobalVariable(
+ Type::getInt32Ty(C), /*isConstant=*/true, GlobalValue::InternalLinkage,
+ /*Initializer=*/nullptr, "NewGV");
+ EXPECT_EQ(M->global_size(), 1u);
+ // Insert before
+ M->insertGlobalVariable(M->globals().begin(), NewGV);
+ EXPECT_EQ(M->global_size(), 2u);
+ EXPECT_EQ(&*M->globals().begin(), NewGV);
+ // Insert at end()
+ M->removeGlobalVariable(NewGV);
+ EXPECT_EQ(M->global_size(), 1u);
+ M->insertGlobalVariable(NewGV);
+ EXPECT_EQ(M->global_size(), 2u);
+ EXPECT_EQ(&*std::prev(M->globals().end()), NewGV);
+ // Check globals()
+ auto Range = M->globals();
+ EXPECT_EQ(&*Range.begin(), GV);
+ EXPECT_EQ(&*std::next(Range.begin()), NewGV);
+ EXPECT_EQ(std::next(Range.begin(), 2), Range.end());
+ // Check remove
+ M->removeGlobalVariable(NewGV);
+ EXPECT_EQ(M->global_size(), 1u);
+ // Check erase
+ M->insertGlobalVariable(NewGV);
+ M->eraseGlobalVariable(NewGV);
+ EXPECT_EQ(M->global_size(), 1u);
+}
+
} // end namespace