ElimAvailExtern.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //===-- ElimAvailExtern.cpp - DCE unreachable internal functions ----------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This transform is designed to eliminate available external global
  11. // definitions from the program, turning them into declarations.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/Transforms/IPO.h"
  15. #include "llvm/ADT/Statistic.h"
  16. #include "llvm/IR/Constants.h"
  17. #include "llvm/IR/Instructions.h"
  18. #include "llvm/IR/Module.h"
  19. #include "llvm/Transforms/Utils/CtorUtils.h"
  20. #include "llvm/Transforms/Utils/GlobalStatus.h"
  21. #include "llvm/Pass.h"
  22. using namespace llvm;
  23. #define DEBUG_TYPE "elim-avail-extern"
  24. STATISTIC(NumFunctions, "Number of functions removed");
  25. STATISTIC(NumVariables, "Number of global variables removed");
  26. namespace {
  27. struct EliminateAvailableExternally : public ModulePass {
  28. static char ID; // Pass identification, replacement for typeid
  29. EliminateAvailableExternally() : ModulePass(ID) {
  30. initializeEliminateAvailableExternallyPass(
  31. *PassRegistry::getPassRegistry());
  32. }
  33. // run - Do the EliminateAvailableExternally pass on the specified module,
  34. // optionally updating the specified callgraph to reflect the changes.
  35. //
  36. bool runOnModule(Module &M) override;
  37. };
  38. }
  39. char EliminateAvailableExternally::ID = 0;
  40. INITIALIZE_PASS(EliminateAvailableExternally, "elim-avail-extern",
  41. "Eliminate Available Externally Globals", false, false)
  42. ModulePass *llvm::createEliminateAvailableExternallyPass() {
  43. return new EliminateAvailableExternally();
  44. }
  45. bool EliminateAvailableExternally::runOnModule(Module &M) {
  46. bool Changed = false;
  47. // Drop initializers of available externally global variables.
  48. for (Module::global_iterator I = M.global_begin(), E = M.global_end();
  49. I != E; ++I) {
  50. if (!I->hasAvailableExternallyLinkage())
  51. continue;
  52. if (I->hasInitializer()) {
  53. Constant *Init = I->getInitializer();
  54. I->setInitializer(nullptr);
  55. if (isSafeToDestroyConstant(Init))
  56. Init->destroyConstant();
  57. }
  58. I->removeDeadConstantUsers();
  59. I->setLinkage(GlobalValue::ExternalLinkage);
  60. NumVariables++;
  61. }
  62. // Drop the bodies of available externally functions.
  63. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
  64. if (!I->hasAvailableExternallyLinkage())
  65. continue;
  66. if (!I->isDeclaration())
  67. // This will set the linkage to external
  68. I->deleteBody();
  69. I->removeDeadConstantUsers();
  70. NumFunctions++;
  71. }
  72. return Changed;
  73. }