Internalize.cpp revision a92f696b74a99325026ebbdbffd2a44317e0c10b
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"
12a92f696b74a99325026ebbdbffd2a44317e0c10bChris Lattner#include "Support/Statistic.h"
133dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner
14f629309f74cf1a64aa7fd1cd5784fd7db9a8f59eChris Lattnernamespace {
15a92f696b74a99325026ebbdbffd2a44317e0c10bChris Lattner  Statistic<> NumFunctions("internalize", "Number of functions internalized");
16a92f696b74a99325026ebbdbffd2a44317e0c10bChris Lattner  Statistic<> NumGlobals  ("internalize", "Number of global vars internalized");
1755e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
1855e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner  class InternalizePass : public Pass {
1955e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner    virtual bool run(Module &M) {
2055e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      bool FoundMain = false;   // Look for a function named main...
2155e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
2255e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        if (I->getName() == "main" && !I->isExternal() &&
2355e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner            I->hasExternalLinkage()) {
2455e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          FoundMain = true;
2555e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          break;
2655e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        }
2755e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
2855e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      if (!FoundMain) return false;  // No main found, must be a library...
2955e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
3055e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      bool Changed = false;
3155e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
3255e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      // Found a main function, mark all functions not named main as internal.
3355e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
3455e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        if (I->getName() != "main" &&   // Leave the main function external
3555e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner            !I->isExternal() &&         // Function must be defined here
3655e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner            !I->hasInternalLinkage()) { // Can't already have internal linkage
3755e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          I->setInternalLinkage(true);
3855e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          Changed = true;
3955e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          ++NumFunctions;
4055e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          DEBUG(std::cerr << "Internalizing func " << I->getName() << "\n");
4155e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        }
4255e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
4355e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      // Mark all global variables with initializers as internal as well...
4455e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
4555e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        if (I->hasInitializer() && I->hasExternalLinkage()) {
4655e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          I->setInternalLinkage(true);
4755e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          Changed = true;
4855e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          ++NumGlobals;
4955e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner          DEBUG(std::cerr << "Internalizing gvar " << I->getName() << "\n");
5055e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner        }
5155e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner
5255e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner      return Changed;
5355e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner    }
5455e41ba3d293699e47fdeb8996cc743b2018bde8Chris Lattner  };
55dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner
561e43516dcf4aa152432447397334cd43744d63e1Chris Lattner  RegisterOpt<InternalizePass> X("internalize", "Internalize Functions");
57f629309f74cf1a64aa7fd1cd5784fd7db9a8f59eChris Lattner} // end anonymous namespace
58f629309f74cf1a64aa7fd1cd5784fd7db9a8f59eChris Lattner
59dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris LattnerPass *createInternalizePass() {
60dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner  return new InternalizePass();
61dbb1735673ed177a85f04698b9cd89f2dc1b4e91Chris Lattner}
62