//===----------------------------------------------------------------------===//
#include "llvm/LLVMContext.h"
+#include "llvm/DataLayout.h"
+#include "llvm/DebugInfo.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/CallGraphSCCPass.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/RegionPass.h"
#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/LinkAllVMCore.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include <memory>
#include <algorithm>
using namespace llvm;
static cl::opt<bool>
OptLevelO1("O1",
- cl::desc("Optimization level 1. Similar to llvm-gcc -O1"));
+ cl::desc("Optimization level 1. Similar to clang -O1"));
static cl::opt<bool>
OptLevelO2("O2",
- cl::desc("Optimization level 2. Similar to llvm-gcc -O2"));
+ cl::desc("Optimization level 2. Similar to clang -O2"));
+
+static cl::opt<bool>
+OptLevelOs("Os",
+ cl::desc("Like -O2 with extra optimizations for size. Similar to clang -Os"));
+
+static cl::opt<bool>
+OptLevelOz("Oz",
+ cl::desc("Like -Os but reduces code size further. Similar to clang -Oz"));
static cl::opt<bool>
OptLevelO3("O3",
- cl::desc("Optimization level 3. Similar to llvm-gcc -O3"));
+ cl::desc("Optimization level 3. Similar to clang -O3"));
+
+static cl::opt<std::string>
+TargetTriple("mtriple", cl::desc("Override target triple for module"));
static cl::opt<bool>
UnitAtATime("funit-at-a-time",
AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization"));
static cl::opt<bool>
-PrintBreakpoints("print-breakpoints-for-testing",
+PrintBreakpoints("print-breakpoints-for-testing",
cl::desc("Print select breakpoints location for testing"));
static cl::opt<std::string>
-DefaultDataLayout("default-data-layout",
+DefaultDataLayout("default-data-layout",
cl::desc("data layout string to use if not specified by module"),
cl::value_desc("layout-string"), cl::init(""));
virtual bool runOnRegion(Region *R, RGPassManager &RGM) {
if (!Quiet) {
Out << "Printing analysis '" << PassToPrint->getPassName() << "' for "
- << "region: '" << R->getNameStr() << "' in function '"
- << R->getEntry()->getParent()->getNameStr() << "':\n";
+ << "region: '" << R->getNameStr() << "' in function '"
+ << R->getEntry()->getParent()->getName() << "':\n";
}
// Get and print pass...
getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
<< "': Pass " << PassToPrint->getPassName() << ":\n";
// Get and print pass...
- getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
BB.getParent()->getParent());
return false;
}
char BasicBlockPassPrinter::ID = 0;
-struct BreakpointPrinter : public FunctionPass {
+struct BreakpointPrinter : public ModulePass {
raw_ostream &Out;
static char ID;
BreakpointPrinter(raw_ostream &out)
- : FunctionPass(ID), Out(out) {
+ : ModulePass(ID), Out(out) {
}
- virtual bool runOnFunction(Function &F) {
- BasicBlock &EntryBB = F.getEntryBlock();
- BasicBlock::const_iterator BI = EntryBB.end();
- --BI;
- do {
- const Instruction *In = BI;
- const DebugLoc DL = In->getDebugLoc();
- if (!DL.isUnknown()) {
- DIScope S(DL.getScope(getGlobalContext()));
- Out << S.getFilename() << " " << DL.getLine() << "\n";
- break;
+ void getContextName(DIDescriptor Context, std::string &N) {
+ if (Context.isNameSpace()) {
+ DINameSpace NS(Context);
+ if (!NS.getName().empty()) {
+ getContextName(NS.getContext(), N);
+ N = N + NS.getName().str() + "::";
+ }
+ } else if (Context.isType()) {
+ DIType TY(Context);
+ if (!TY.getName().empty()) {
+ getContextName(TY.getContext(), N);
+ N = N + TY.getName().str() + "::";
+ }
+ }
+ }
+
+ virtual bool runOnModule(Module &M) {
+ StringSet<> Processed;
+ if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp"))
+ for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
+ std::string Name;
+ DISubprogram SP(NMD->getOperand(i));
+ if (SP.Verify())
+ getContextName(SP.getContext(), Name);
+ Name = Name + SP.getDisplayName().str();
+ if (!Name.empty() && Processed.insert(Name)) {
+ Out << Name << "\n";
+ }
}
- --BI;
- } while (BI != EntryBB.begin());
return false;
}
AU.setPreservesAll();
}
};
+
+} // anonymous namespace
char BreakpointPrinter::ID = 0;
-inline void addPass(PassManagerBase &PM, Pass *P) {
+static inline void addPass(PassManagerBase &PM, Pass *P) {
// Add the pass to the pass manager...
PM.add(P);
/// duplicates llvm-gcc behaviour.
///
/// OptLevel - Optimization Level
-void AddOptimizationPasses(PassManagerBase &MPM, PassManagerBase &FPM,
- unsigned OptLevel) {
- createStandardFunctionPasses(&FPM, OptLevel);
+static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM,
+ unsigned OptLevel, unsigned SizeLevel) {
+ FPM.add(createVerifierPass()); // Verify that input is correct
+
+ PassManagerBuilder Builder;
+ Builder.OptLevel = OptLevel;
+ Builder.SizeLevel = SizeLevel;
- llvm::Pass *InliningPass = 0;
if (DisableInline) {
// No inlining pass
- } else if (OptLevel) {
+ } else if (OptLevel > 1) {
unsigned Threshold = 225;
+ if (SizeLevel == 1) // -Os
+ Threshold = 75;
+ else if (SizeLevel == 2) // -Oz
+ Threshold = 25;
if (OptLevel > 2)
Threshold = 275;
- InliningPass = createFunctionInliningPass(Threshold);
+ Builder.Inliner = createFunctionInliningPass(Threshold);
} else {
- InliningPass = createAlwaysInlinerPass();
+ Builder.Inliner = createAlwaysInlinerPass();
}
- createStandardModulePasses(&MPM, OptLevel,
- /*OptimizeSize=*/ false,
- UnitAtATime,
- /*UnrollLoops=*/ OptLevel > 1,
- !DisableSimplifyLibCalls,
- /*HaveExceptions=*/ true,
- InliningPass);
+ Builder.DisableUnitAtATime = !UnitAtATime;
+ Builder.DisableUnrollLoops = OptLevel == 0;
+ Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls;
+
+ Builder.populateFunctionPassManager(FPM);
+ Builder.populateModulePassManager(MPM);
}
-void AddStandardCompilePasses(PassManagerBase &PM) {
+static void AddStandardCompilePasses(PassManagerBase &PM) {
PM.add(createVerifierPass()); // Verify that input is correct
- addPass(PM, createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp
-
// If the -strip-debug command line option was specified, do it.
if (StripDebug)
addPass(PM, createStripSymbolsPass(true));
if (DisableOptimizations) return;
- llvm::Pass *InliningPass = !DisableInline ? createFunctionInliningPass() : 0;
-
// -std-compile-opts adds the same module passes as -O3.
- createStandardModulePasses(&PM, 3,
- /*OptimizeSize=*/ false,
- /*UnitAtATime=*/ true,
- /*UnrollLoops=*/ true,
- !DisableSimplifyLibCalls,
- /*HaveExceptions=*/ true,
- InliningPass);
+ PassManagerBuilder Builder;
+ if (!DisableInline)
+ Builder.Inliner = createFunctionInliningPass();
+ Builder.OptLevel = 3;
+ Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls;
+ Builder.populateModulePassManager(PM);
}
-void AddStandardLinkPasses(PassManagerBase &PM) {
+static void AddStandardLinkPasses(PassManagerBase &PM) {
PM.add(createVerifierPass()); // Verify that input is correct
// If the -strip-debug command line option was specified, do it.
if (DisableOptimizations) return;
- createStandardLTOPasses(&PM, /*Internalize=*/ !DisableInternalize,
- /*RunInliner=*/ !DisableInline,
- /*VerifyEach=*/ VerifyEach);
+ PassManagerBuilder Builder;
+ Builder.populateLTOPassManager(PM, /*Internalize=*/ !DisableInternalize,
+ /*RunInliner=*/ !DisableInline);
}
-} // anonymous namespace
-
//===----------------------------------------------------------------------===//
// main for opt
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
LLVMContext &Context = getGlobalContext();
-
+
// Initialize passes
PassRegistry &Registry = *PassRegistry::getPassRegistry();
initializeCore(Registry);
initializeScalarOpts(Registry);
+ initializeVectorization(Registry);
initializeIPO(Registry);
initializeAnalysis(Registry);
initializeIPA(Registry);
initializeInstCombine(Registry);
initializeInstrumentation(Registry);
initializeTarget(Registry);
-
+
cl::ParseCommandLineOptions(argc, argv,
"llvm .bc -> .bc modular optimizer and analysis printer\n");
return 1;
}
- // Allocate a full target machine description only if necessary.
- // FIXME: The choice of target should be controllable on the command line.
- std::auto_ptr<TargetMachine> target;
-
SMDiagnostic Err;
// Load the input module...
M.reset(ParseIRFile(InputFilename, Err, Context));
if (M.get() == 0) {
- Err.Print(argv[0], errs());
+ Err.print(argv[0], errs());
return 1;
}
+ // If we are supposed to override the target triple, do so now.
+ if (!TargetTriple.empty())
+ M->setTargetTriple(Triple::normalize(TargetTriple));
+
// Figure out what stream we are supposed to write to...
OwningPtr<tool_output_file> Out;
if (NoOutput) {
// Add an appropriate TargetLibraryInfo pass for the module's triple.
TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple()));
-
+
// The -disable-simplify-libcalls flag actually disables all builtin optzns.
if (DisableSimplifyLibCalls)
TLI->disableAllFunctions();
Passes.add(TLI);
-
- // Add an appropriate TargetData instance for this module.
- TargetData *TD = 0;
+
+ // Add an appropriate DataLayout instance for this module.
+ DataLayout *TD = 0;
const std::string &ModuleDataLayout = M.get()->getDataLayout();
if (!ModuleDataLayout.empty())
- TD = new TargetData(ModuleDataLayout);
+ TD = new DataLayout(ModuleDataLayout);
else if (!DefaultDataLayout.empty())
- TD = new TargetData(DefaultDataLayout);
+ TD = new DataLayout(DefaultDataLayout);
if (TD)
Passes.add(TD);
- OwningPtr<PassManager> FPasses;
- if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
- FPasses.reset(new PassManager());
+ OwningPtr<FunctionPassManager> FPasses;
+ if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
+ FPasses.reset(new FunctionPassManager(M.get()));
if (TD)
- FPasses->add(new TargetData(*TD));
+ FPasses->add(new DataLayout(*TD));
}
if (PrintBreakpoints) {
if (!Out) {
if (OutputFilename.empty())
OutputFilename = "-";
-
+
std::string ErrorInfo;
Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
raw_fd_ostream::F_Binary));
}
if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) {
- AddOptimizationPasses(Passes, *FPasses, 1);
+ AddOptimizationPasses(Passes, *FPasses, 1, 0);
OptLevelO1 = false;
}
if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) {
- AddOptimizationPasses(Passes, *FPasses, 2);
+ AddOptimizationPasses(Passes, *FPasses, 2, 0);
OptLevelO2 = false;
}
+ if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) {
+ AddOptimizationPasses(Passes, *FPasses, 2, 1);
+ OptLevelOs = false;
+ }
+
+ if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) {
+ AddOptimizationPasses(Passes, *FPasses, 2, 2);
+ OptLevelOz = false;
+ }
+
if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) {
- AddOptimizationPasses(Passes, *FPasses, 3);
+ AddOptimizationPasses(Passes, *FPasses, 3, 0);
OptLevelO3 = false;
}
}
if (OptLevelO1)
- AddOptimizationPasses(Passes, *FPasses, 1);
+ AddOptimizationPasses(Passes, *FPasses, 1, 0);
if (OptLevelO2)
- AddOptimizationPasses(Passes, *FPasses, 2);
+ AddOptimizationPasses(Passes, *FPasses, 2, 0);
+
+ if (OptLevelOs)
+ AddOptimizationPasses(Passes, *FPasses, 2, 1);
+
+ if (OptLevelOz)
+ AddOptimizationPasses(Passes, *FPasses, 2, 2);
if (OptLevelO3)
- AddOptimizationPasses(Passes, *FPasses, 3);
+ AddOptimizationPasses(Passes, *FPasses, 3, 0);
- if (OptLevelO1 || OptLevelO2 || OptLevelO3)
- FPasses->run(*M.get());
+ if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
+ FPasses->doInitialization();
+ for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F)
+ FPasses->run(*F);
+ FPasses->doFinalization();
+ }
// Check that the module is well formed on completion of optimization
if (!NoVerify && !VerifyEach)
Passes.add(createBitcodeWriterPass(Out->os()));
}
+ // Before executing passes, print the final values of the LLVM options.
+ cl::PrintOptionValues();
+
// Now that we have all of the passes ready, run them.
Passes.run(*M.get());