Internalize.cpp revision 55e41ba3d293699e47fdeb8996cc743b2018bde8
1dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner//===-- Internalize.cpp - Mark functions internal -------------------------===//
2dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner//
3dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner// This pass loops over all of the functions in the input module, looking for a
455e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner// main function.  If a main function is found, all other functions and all
555e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner// global variables with initializers are marked as internal.
6dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner//
7dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner//===----------------------------------------------------------------------===//
8dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner
9568ddabc8f9015baf2d42cc425618412972f1b92Chris Lattner#include "llvm/Transforms/IPO.h"
10dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner#include "llvm/Pass.h"
11dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner#include "llvm/Module.h"
123dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner#include "Support/StatisticReporter.h"
133dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner
14f629309f74cf1a64aa7fd1cd5784fd7db9a8f59eChris Lattnernamespace {
1555e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner  Statistic<> NumFunctions("internalize\t- Number of functions internalized");
1655e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner  Statistic<> NumGlobals  ("internalize\t- Number of global vars internalized");
1755e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
1855e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
1955e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner  class InternalizePass : public Pass {
2055e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner    virtual bool run(Module &M) {
2155e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      bool FoundMain = false;   // Look for a function named main...
2255e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
2355e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        if (I->getName() == "main" && !I->isExternal() &&
2455e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner            I->hasExternalLinkage()) {
2555e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          FoundMain = true;
2655e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          break;
2755e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        }
2855e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
2955e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      if (!FoundMain) return false;  // No main found, must be a library...
3055e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
3155e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      bool Changed = false;
3255e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
3355e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      // Found a main function, mark all functions not named main as internal.
3455e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
3555e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        if (I->getName() != "main" &&   // Leave the main function external
3655e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner            !I->isExternal() &&         // Function must be defined here
3755e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner            !I->hasInternalLinkage()) { // Can't already have internal linkage
3855e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          I->setInternalLinkage(true);
3955e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          Changed = true;
4055e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          ++NumFunctions;
4155e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          DEBUG(std::cerr << "Internalizing func " << I->getName() << "\n");
4255e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        }
4355e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
4455e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      // Mark all global variables with initializers as internal as well...
4555e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
4655e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        if (I->hasInitializer() && I->hasExternalLinkage()) {
4755e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          I->setInternalLinkage(true);
4855e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          Changed = true;
4955e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          ++NumGlobals;
5055e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          DEBUG(std::cerr << "Internalizing gvar " << I->getName() << "\n");
5155e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        }
5255e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
5355e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      return Changed;
5455e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner    }
5555e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner  };
56dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner
571e43516dcf4aa152432447397334cd43744d63e1Chris Lattner  RegisterOpt<InternalizePass> X("internalize", "Internalize Functions");
58f629309f74cf1a64aa7fd1cd5784fd7db9a8f59eChris Lattner} // end anonymous namespace
59f629309f74cf1a64aa7fd1cd5784fd7db9a8f59eChris Lattner
60dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris LattnerPass *createInternalizePass() {
61dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner  return new InternalizePass();
62dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner}
63