-static bool RemoveUnreachableGlobalVariables(Module &M) {
- bool Changed = false;
- // Eliminate all global variables that are unused, and that are internal, or
- // do not have an initializer.
- //
- for (Module::giterator I = M.gbegin(); I != M.gend(); )
- if (!I->use_empty() || (I->hasExternalLinkage() && I->hasInitializer()))
- ++I; // Cannot eliminate global variable
- else {
- I = M.getGlobalList().erase(I);
- ++NumVariables;
- Changed = true;
+ // The second pass drops the bodies of functions which are dead...
+ std::vector<Function*> DeadFunctions;
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (!AliveGlobals.count(I)) {
+ DeadFunctions.push_back(I); // Keep track of dead globals
+ if (!I->isDeclaration())
+ I->deleteBody();
+ }
+
+ // The third pass drops targets of aliases which are dead...
+ std::vector<GlobalAlias*> DeadAliases;
+ for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
+ ++I)
+ if (!AliveGlobals.count(I)) {
+ DeadAliases.push_back(I);
+ I->setAliasee(nullptr);
+ }
+
+ // Look for available externally constants that we can turn into normal
+ // externals by deleting their initalizers. This allows us to remove other
+ // globals that are referenced by the initializer.
+ if (!DiscardableGlobalInitializers.empty()) {
+ for (GlobalVariable *GV : DiscardableGlobalInitializers) {
+ if (!ContainsUsedGlobal(GV->getInitializer())) {
+ GV->setInitializer(nullptr);
+ GV->setLinkage(GlobalValue::ExternalLinkage);
+ Changed = true;
+ }
+ }
+ }
+
+ if (!DeadFunctions.empty()) {
+ // Now that all interferences have been dropped, delete the actual objects
+ // themselves.
+ for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) {
+ RemoveUnusedGlobalValue(*DeadFunctions[i]);
+ M.getFunctionList().erase(DeadFunctions[i]);
+ }
+ NumFunctions += DeadFunctions.size();
+ Changed = true;
+ }
+
+ if (!DeadGlobalVars.empty()) {
+ for (unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) {
+ RemoveUnusedGlobalValue(*DeadGlobalVars[i]);
+ M.getGlobalList().erase(DeadGlobalVars[i]);
+ }
+ NumVariables += DeadGlobalVars.size();
+ Changed = true;
+ }
+
+ // Now delete any dead aliases.
+ if (!DeadAliases.empty()) {
+ for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) {
+ RemoveUnusedGlobalValue(*DeadAliases[i]);
+ M.getAliasList().erase(DeadAliases[i]);