#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/System/DynamicLibrary.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/PluginLoader.h"
#include <iostream>
using namespace llvm;
static cl::list<const PassInfo*, bool, PassNameParser>
OptimizationList(cl::desc("Optimizations available:"));
static cl::opt<bool> DontVerify("disable-verify", cl::ReallyHidden);
static cl::opt<bool> DisableInline("disable-inlining",
cl::desc("Do not run the inliner pass"));
static cl::opt<bool>
DisableOptimizations("disable-opt",
cl::desc("Do not run any optimization passes"));
static cl::opt<bool> DisableInternalize("disable-internalize",
cl::desc("Do not mark all symbols as internal"));
static cl::opt<bool> VerifyEach("verify-each",
cl::desc("Verify intermediate results of all passes"));
static cl::alias ExportDynamic("export-dynamic",
cl::aliasopt(DisableInternalize),
cl::desc("Alias for -disable-internalize"));
static cl::opt<bool> Strip("strip-all",
cl::desc("Strip all symbol info from executable"));
static cl::alias A0("s", cl::desc("Alias for --strip-all"),
cl::aliasopt(Strip));
static cl::opt<bool> StripDebug("strip-debug",
cl::desc("Strip debugger symbol info from executable"));
static cl::alias A1("S", cl::desc("Alias for --strip-debug"),
cl::aliasopt(StripDebug));
static inline void addPass(PassManager &PM, Pass *P) {
PM.add(P);
if (VerifyEach)
PM.add(createVerifierPass());
}
namespace llvm {
void Optimize(Module* M) {
PassManager Passes;
if (VerifyEach)
Passes.add(createVerifierPass());
addPass(Passes, new TargetData(M));
if (!DisableOptimizations) {
if (!DisableInternalize)
addPass(Passes, createInternalizePass(true));
addPass(Passes, createIPSCCPPass());
addPass(Passes, createGlobalOptimizerPass());
addPass(Passes, createConstantMergePass());
addPass(Passes, createDeadArgEliminationPass());
addPass(Passes, createInstructionCombiningPass());
if (!DisableInline)
addPass(Passes, createFunctionInliningPass());
addPass(Passes, createPruneEHPass()); addPass(Passes, createGlobalOptimizerPass()); addPass(Passes, createGlobalDCEPass());
addPass(Passes, createArgumentPromotionPass());
addPass(Passes, createInstructionCombiningPass());
addPass(Passes, createJumpThreadingPass()); addPass(Passes, createScalarReplAggregatesPass());
addPass(Passes, createFunctionAttrsPass()); addPass(Passes, createGlobalsModRefPass());
addPass(Passes, createLICMPass()); addPass(Passes, createGVNPass()); addPass(Passes, createMemCpyOptPass()); addPass(Passes, createDeadStoreEliminationPass());
addPass(Passes, createInstructionCombiningPass());
addPass(Passes, createJumpThreadingPass()); addPass(Passes, createPromoteMemoryToRegisterPass());
addPass(Passes, createCFGSimplificationPass());
addPass(Passes, createGlobalDCEPass());
}
if (Strip || StripDebug)
addPass(Passes, createStripSymbolsPass(StripDebug && !Strip));
std::auto_ptr<TargetMachine> target;
for (unsigned i = 0; i < OptimizationList.size(); ++i) {
const PassInfo *Opt = OptimizationList[i];
if (Opt->getNormalCtor())
addPass(Passes, Opt->getNormalCtor()());
else
std::cerr << "llvm-ld: cannot create pass: " << Opt->getPassName()
<< "\n";
}
if (!DisableOptimizations) {
addPass(Passes, createInstructionCombiningPass());
addPass(Passes, createCFGSimplificationPass());
addPass(Passes, createAggressiveDCEPass());
addPass(Passes, createGlobalDCEPass());
}
if (!DontVerify)
Passes.add(createVerifierPass());
Passes.run(*M);
}
}