IR: Introduce Module::global_objects().

This is a convenience iterator that allows clients to enumerate the
GlobalObjects within a Module.

Also start using it in a few places where it is obviously the right thing
to use.

Differential Revision: http://reviews.llvm.org/D21580

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273470 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Peter Collingbourne 2016-06-22 20:29:42 +00:00
parent e46cd3a4c3
commit 277258478e
7 changed files with 88 additions and 43 deletions

View File

@ -195,13 +195,8 @@ private:
for (const auto &M : Ms) {
Mangler Mang;
for (const auto &V : M->globals())
if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName,
ExportedSymbolsOnly))
return GV;
for (const auto &F : *M)
if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName,
for (const auto &GO : M->global_objects())
if (auto GV = addGlobalValue(*Symbols, GO, Mang, SearchName,
ExportedSymbolsOnly))
return GV;
}

View File

@ -604,9 +604,78 @@ public:
}
/// @}
/// @name Named Metadata Iteration
/// @name Convenience iterators
/// @{
template <bool IsConst> class global_object_iterator_t {
friend Module;
typename std::conditional<IsConst, const_iterator, iterator>::type
function_i,
function_e;
typename std::conditional<IsConst, const_global_iterator,
global_iterator>::type global_i;
typedef
typename std::conditional<IsConst, const Module, Module>::type ModuleTy;
global_object_iterator_t(ModuleTy &M)
: function_i(M.begin()), function_e(M.end()),
global_i(M.global_begin()) {}
global_object_iterator_t(ModuleTy &M, int)
: function_i(M.end()), function_e(M.end()), global_i(M.global_end()) {}
public:
global_object_iterator_t &operator++() {
if (function_i != function_e)
++function_i;
else
++global_i;
return *this;
}
typename std::conditional<IsConst, const GlobalObject, GlobalObject>::type &
operator*() const {
if (function_i != function_e)
return *function_i;
else
return *global_i;
}
bool operator!=(const global_object_iterator_t &other) const {
return function_i != other.function_i || global_i != other.global_i;
}
};
typedef global_object_iterator_t</*IsConst=*/false> global_object_iterator;
typedef global_object_iterator_t</*IsConst=*/true>
const_global_object_iterator;
global_object_iterator global_object_begin() {
return global_object_iterator(*this);
}
global_object_iterator global_object_end() {
return global_object_iterator(*this, 0);
}
const_global_object_iterator global_object_begin() const {
return const_global_object_iterator(*this);
}
const_global_object_iterator global_object_end() const {
return const_global_object_iterator(*this, 0);
}
iterator_range<global_object_iterator> global_objects() {
return make_range(global_object_begin(), global_object_end());
}
iterator_range<const_global_object_iterator> global_objects() const {
return make_range(global_object_begin(), global_object_end());
}
/// @}
/// @name Named Metadata Iteration
/// @{
named_metadata_iterator named_metadata_begin() { return NamedMDList.begin(); }
const_named_metadata_iterator named_metadata_begin() const {
return NamedMDList.begin();

View File

@ -1173,17 +1173,11 @@ bool AsmPrinter::doFinalization(Module &M) {
// to notice uses in operands (due to constant exprs etc). This should
// happen with the MC stuff eventually.
// Print out module-level global variables here.
for (const auto &G : M.globals()) {
if (!G.hasExternalWeakLinkage())
// Print out module-level global objects here.
for (const auto &GO : M.global_objects()) {
if (!GO.hasExternalWeakLinkage())
continue;
OutStreamer->EmitSymbolAttribute(getSymbol(&G), MCSA_WeakReference);
}
for (const auto &F : M) {
if (!F.hasExternalWeakLinkage())
continue;
OutStreamer->EmitSymbolAttribute(getSymbol(&F), MCSA_WeakReference);
OutStreamer->EmitSymbolAttribute(getSymbol(&GO), MCSA_WeakReference);
}
}

View File

@ -235,10 +235,8 @@ void ExecutionEngine::clearAllGlobalMappings() {
void ExecutionEngine::clearGlobalMappingsFromModule(Module *M) {
MutexGuard locked(lock);
for (Function &FI : *M)
EEState.RemoveMapping(getMangledName(&FI));
for (GlobalVariable &GI : M->globals())
EEState.RemoveMapping(getMangledName(&GI));
for (GlobalObject &GO : M->global_objects())
EEState.RemoveMapping(getMangledName(&GO));
}
uint64_t ExecutionEngine::updateGlobalMapping(const GlobalValue *GV,

View File

@ -2126,11 +2126,8 @@ AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
if (!TheModule)
return;
TypePrinter.incorporateTypes(*TheModule);
for (const Function &F : *TheModule)
if (const Comdat *C = F.getComdat())
Comdats.insert(C);
for (const GlobalVariable &GV : TheModule->globals())
if (const Comdat *C = GV.getComdat())
for (const GlobalObject &GO : TheModule->global_objects())
if (const Comdat *C = GO.getComdat())
Comdats.insert(C);
}

View File

@ -96,21 +96,14 @@ PreservedAnalyses GlobalDCEPass::run(Module &M, ModuleAnalysisManager &) {
ComdatMembers.insert(std::make_pair(C, &GA));
// Loop over the module, adding globals which are obviously necessary.
for (Function &F : M) {
Changed |= RemoveUnusedGlobalValue(F);
// Functions with external linkage are needed if they have a body
if (!F.isDeclaration() && !F.hasAvailableExternallyLinkage())
if (!F.isDiscardableIfUnused())
GlobalIsNeeded(&F);
}
for (GlobalVariable &GV : M.globals()) {
Changed |= RemoveUnusedGlobalValue(GV);
for (GlobalObject &GO : M.global_objects()) {
Changed |= RemoveUnusedGlobalValue(GO);
// Functions with external linkage are needed if they have a body.
// Externally visible & appending globals are needed, if they have an
// initializer.
if (!GV.isDeclaration() && !GV.hasAvailableExternallyLinkage())
if (!GV.isDiscardableIfUnused())
GlobalIsNeeded(&GV);
if (!GO.isDeclaration() && !GO.hasAvailableExternallyLinkage())
if (!GO.isDiscardableIfUnused())
GlobalIsNeeded(&GO);
}
for (GlobalAlias &GA : M.aliases()) {

View File

@ -42,9 +42,8 @@ define protected void @test_protected() {
; CHECK-NOT: .hidden test_hidden_declaration
; CHECK: .weak gr
@gr = extern_weak global i32
; CHECK: .weak fr
declare extern_weak void @fr(i32*, i32*)
; CHECK: .weak gr
@gr = extern_weak global i32