123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 |
- //===- opt.cpp - The LLVM Modular Optimizer -------------------------------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- //
- // Optimizations may be specified an arbitrary number of times on the command
- // line, They are run in the order specified.
- //
- //===----------------------------------------------------------------------===//
- #include "BreakpointPrinter.h"
- #include "NewPMDriver.h"
- #include "llvm/PassPrinters/PassPrinters.h"
- #include "llvm/ADT/Triple.h"
- #include "llvm/Analysis/CallGraph.h"
- #include "llvm/Analysis/CallGraphSCCPass.h"
- #include "llvm/Analysis/LoopPass.h"
- #include "llvm/Analysis/RegionPass.h"
- #include "llvm/Analysis/TargetLibraryInfo.h"
- #include "llvm/Analysis/TargetTransformInfo.h"
- #include "llvm/Bitcode/BitcodeWriterPass.h"
- #include "llvm/CodeGen/CommandFlags.h"
- #include "llvm/IR/DataLayout.h"
- #include "llvm/IR/DebugInfo.h"
- #include "llvm/IR/IRPrintingPasses.h"
- #include "llvm/IR/LLVMContext.h"
- #include "llvm/IR/LegacyPassNameParser.h"
- #include "llvm/IR/Module.h"
- #include "llvm/IR/Verifier.h"
- #include "llvm/IRReader/IRReader.h"
- #include "llvm/InitializePasses.h"
- #include "llvm/LinkAllIR.h"
- #include "llvm/LinkAllPasses.h"
- #include "llvm/MC/SubtargetFeature.h"
- #include "llvm/IR/LegacyPassManager.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/Support/FileSystem.h"
- #include "llvm/Support/Host.h"
- #include "llvm/Support/ManagedStatic.h"
- #include "llvm/Support/PluginLoader.h"
- #include "llvm/Support/PrettyStackTrace.h"
- #include "llvm/Support/Signals.h"
- #include "llvm/Support/SourceMgr.h"
- #include "llvm/Support/SystemUtils.h"
- #include "llvm/Support/TargetRegistry.h"
- #include "llvm/Support/TargetSelect.h"
- #include "llvm/Support/ToolOutputFile.h"
- #include "llvm/Target/TargetMachine.h"
- #include "llvm/Transforms/IPO/PassManagerBuilder.h"
- // HLSL Change Starts
- #include "dxc/Support/Global.h"
- #include "llvm/Analysis/ReducibilityAnalysis.h"
- #include "dxc/Support/WinIncludes.h"
- #include "llvm/Support/MSFileSystem.h"
- // HLSL Change Ends
- #include <algorithm>
- #include <memory>
- using namespace llvm;
- using namespace opt_tool;
- // The OptimizationList is automatically populated with registered Passes by the
- // PassNameParser.
- //
- static cl::list<const PassInfo*, bool, PassNameParser>
- PassList(cl::desc("Optimizations available:"));
- // This flag specifies a textual description of the optimization pass pipeline
- // to run over the module. This flag switches opt to use the new pass manager
- // infrastructure, completely disabling all of the flags specific to the old
- // pass management.
- static cl::opt<std::string> PassPipeline(
- "passes",
- cl::desc("A textual description of the pass pipeline for optimizing"),
- cl::Hidden);
- // Other command line options...
- //
- static cl::opt<std::string>
- InputFilename(cl::Positional, cl::desc("<input bitcode file>"),
- cl::init("-"), cl::value_desc("filename"));
- static cl::opt<std::string>
- OutputFilename("o", cl::desc("Override output filename"),
- cl::value_desc("filename"));
- static cl::opt<bool>
- Force("f", cl::desc("Enable binary output on terminals"));
- static cl::opt<bool>
- PrintEachXForm("p", cl::desc("Print module after each transformation"));
- static cl::opt<bool>
- NoOutput("disable-output",
- cl::desc("Do not write result bitcode file"), cl::Hidden);
- static cl::opt<bool>
- OutputAssembly("S", cl::desc("Write output as LLVM assembly"));
- static cl::opt<bool>
- NoVerify("disable-verify", cl::desc("Do not verify result module"), cl::Hidden);
- static cl::opt<bool>
- VerifyEach("verify-each", cl::desc("Verify after each transform"));
- static cl::opt<bool>
- StripDebug("strip-debug",
- cl::desc("Strip debugger symbol info from translation unit"));
- 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>
- StandardLinkOpts("std-link-opts",
- cl::desc("Include the standard link time optimizations"));
- static cl::opt<bool>
- OptLevelO1("O1",
- cl::desc("Optimization level 1. Similar to clang -O1"));
- static cl::opt<bool>
- OptLevelO2("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 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",
- cl::desc("Enable IPO. This corresponds to gcc's -funit-at-a-time"),
- cl::init(true));
- static cl::opt<bool>
- DisableLoopUnrolling("disable-loop-unrolling",
- cl::desc("Disable loop unrolling in all relevant passes"),
- cl::init(false));
- static cl::opt<bool>
- DisableLoopVectorization("disable-loop-vectorization",
- cl::desc("Disable the loop vectorization pass"),
- cl::init(false));
- static cl::opt<bool>
- DisableSLPVectorization("disable-slp-vectorization",
- cl::desc("Disable the slp vectorization pass"),
- cl::init(false));
- static cl::opt<bool>
- DisableSimplifyLibCalls("disable-simplify-libcalls",
- cl::desc("Disable simplify-libcalls"));
- static cl::opt<bool>
- Quiet("q", cl::desc("Obsolete option"), cl::Hidden);
- static cl::alias
- QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
- static cl::opt<bool>
- AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization"));
- static cl::opt<bool>
- PrintBreakpoints("print-breakpoints-for-testing",
- cl::desc("Print select breakpoints location for testing"));
- static cl::opt<std::string>
- DefaultDataLayout("default-data-layout",
- cl::desc("data layout string to use if not specified by module"),
- cl::value_desc("layout-string"), cl::init(""));
- static cl::opt<bool> PreserveBitcodeUseListOrder(
- "preserve-bc-uselistorder",
- cl::desc("Preserve use-list order when writing LLVM bitcode."),
- cl::init(true), cl::Hidden);
- static cl::opt<bool> PreserveAssemblyUseListOrder(
- "preserve-ll-uselistorder",
- cl::desc("Preserve use-list order when writing LLVM assembly."),
- cl::init(false), cl::Hidden);
- static inline void addPass(legacy::PassManagerBase &PM, Pass *P) {
- // Add the pass to the pass manager...
- PM.add(P);
- // If we are verifying all of the intermediate steps, add the verifier...
- if (VerifyEach)
- PM.add(createVerifierPass());
- }
- /// This routine adds optimization passes based on selected optimization level,
- /// OptLevel.
- ///
- /// OptLevel - Optimization Level
- static void AddOptimizationPasses(legacy::PassManagerBase &MPM,
- legacy::FunctionPassManager &FPM,
- unsigned OptLevel, unsigned SizeLevel) {
- FPM.add(createVerifierPass()); // Verify that input is correct
- PassManagerBuilder Builder;
- Builder.OptLevel = OptLevel;
- Builder.SizeLevel = SizeLevel;
- if (DisableInline) {
- // No inlining pass
- } else if (OptLevel > 1) {
- Builder.Inliner = createFunctionInliningPass(OptLevel, SizeLevel);
- } else {
- Builder.Inliner = createAlwaysInlinerPass();
- }
- Builder.DisableUnitAtATime = !UnitAtATime;
- Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ?
- DisableLoopUnrolling : OptLevel == 0;
- // This is final, unless there is a #pragma vectorize enable
- if (DisableLoopVectorization)
- Builder.LoopVectorize = false;
- // If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize)
- else if (!Builder.LoopVectorize)
- Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2;
- // When #pragma vectorize is on for SLP, do the same as above
- Builder.SLPVectorize =
- DisableSLPVectorization ? false : OptLevel > 1 && SizeLevel < 2;
- Builder.populateFunctionPassManager(FPM);
- Builder.populateModulePassManager(MPM);
- }
- static void AddStandardLinkPasses(legacy::PassManagerBase &PM) {
- PassManagerBuilder Builder;
- Builder.VerifyInput = true;
- if (DisableOptimizations)
- Builder.OptLevel = 0;
- if (!DisableInline)
- Builder.Inliner = createFunctionInliningPass();
- Builder.populateLTOPassManager(PM);
- }
- //===----------------------------------------------------------------------===//
- // CodeGen-related helper functions.
- //
- static CodeGenOpt::Level GetCodeGenOptLevel() {
- if (OptLevelO1)
- return CodeGenOpt::Less;
- if (OptLevelO2)
- return CodeGenOpt::Default;
- if (OptLevelO3)
- return CodeGenOpt::Aggressive;
- return CodeGenOpt::None;
- }
- // Returns the TargetMachine instance or zero if no triple is provided.
- static TargetMachine* GetTargetMachine(Triple TheTriple, StringRef CPUStr,
- StringRef FeaturesStr,
- const TargetOptions &Options) {
- std::string Error;
- const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
- Error);
- // Some modules don't specify a triple, and this is okay.
- if (!TheTarget) {
- return nullptr;
- }
- return TheTarget->createTargetMachine(TheTriple.getTriple(),
- CPUStr, FeaturesStr, Options,
- RelocModel, CMModel,
- GetCodeGenOptLevel());
- }
- #ifdef LINK_POLLY_INTO_TOOLS
- namespace polly {
- void initializePollyPasses(llvm::PassRegistry &Registry);
- }
- #endif
- // HLSL Change Start
- void __cdecl initializeDxilConvPasses(llvm::PassRegistry &);
- // HLSL Change End
- //===----------------------------------------------------------------------===//
- // main for opt
- //
- // HLSL Change: changed calling convention to __cdecl
- int __cdecl main(int argc, char **argv) {
- // HLSL Change Starts
- if (llvm::sys::fs::SetupPerThreadFileSystem())
- return 1;
- llvm::sys::fs::AutoCleanupPerThreadFileSystem auto_cleanup_fs;
- if (FAILED(DxcInitThreadMalloc())) return 1;
- DxcSetThreadMallocToDefault();
- llvm::sys::fs::MSFileSystem* msfPtr;
- if (FAILED(CreateMSFileSystemForDisk(&msfPtr))) return 1;
- std::unique_ptr<llvm::sys::fs::MSFileSystem> msf(msfPtr);
- llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
- //llvm::STDStreamCloser stdStreamCloser;
- // HLSL Change Ends
-
- //sys::PrintStackTraceOnErrorSignal(); // HLSL Change
- //llvm::PrettyStackTraceProgram X(argc, argv); // HLSL Change
- // Enable debug stream buffering.
- EnableDebugBuffering = true;
- llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
- LLVMContext &Context = getGlobalContext();
- InitializeAllTargets();
- // InitializeAllTargetMCs(); // HLSL Change: remove MC targets
- InitializeAllAsmPrinters();
- // Initialize passes
- PassRegistry &Registry = *PassRegistry::getPassRegistry();
- initializeCore(Registry);
- initializeScalarOpts(Registry);
- initializeReducibilityAnalysisPass(Registry); // HLSL Change: add ReducibilityAnalysis pass
- // initializeObjCARCOpts(Registry); // HLSL Change: remove ObjC ARC passes
- // initializeVectorization(Registry); // HLSL Change: remove vectorization passes
- initializeIPO(Registry);
- initializeAnalysis(Registry);
- initializeIPA(Registry);
- initializeTransformUtils(Registry);
- initializeInstCombine(Registry);
- // initializeInstrumentation(Registry); // HLSL Change: remove instrumentation
- initializeTarget(Registry);
- // For codegen passes, only passes that do IR to IR transformation are
- // supported.
- // initializeCodeGenPreparePass(Registry); // HLSL Change: remove EH passes
- //initializeAtomicExpandPass(Registry); // HLSL Change: remove EH passes
- initializeRewriteSymbolsPass(Registry);
- //initializeWinEHPreparePass(Registry); // HLSL Change: remove EH passes
- //initializeDwarfEHPreparePass(Registry); // HLSL Change: remove EH passes
- //initializeSjLjEHPreparePass(Registry); // HLSL Change: remove EH passes
- // HLSL Change Starts
- initializeReducibilityAnalysisPass(Registry);
- #ifdef _WIN32
- initializeDxilConvPasses(Registry);
- #endif
- // HLSL Change Ends
- #ifdef LINK_POLLY_INTO_TOOLS
- polly::initializePollyPasses(Registry);
- #endif
- cl::ParseCommandLineOptions(argc, argv,
- "llvm .bc -> .bc modular optimizer and analysis printer\n");
- if (AnalyzeOnly && NoOutput) {
- errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
- return 1;
- }
- SMDiagnostic Err;
- // Load the input module...
- std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);
- if (!M) {
- Err.print(argv[0], errs());
- return 1;
- }
- // Strip debug info before running the verifier.
- if (StripDebug)
- StripDebugInfo(*M);
- // Immediately run the verifier to catch any problems before starting up the
- // pass pipelines. Otherwise we can crash on broken code during
- // doInitialization().
- if (!NoVerify && verifyModule(*M, &errs())) {
- errs() << argv[0] << ": " << InputFilename
- << ": error: input module is broken!\n";
- 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...
- std::unique_ptr<tool_output_file> Out;
- if (NoOutput) {
- if (!OutputFilename.empty())
- errs() << "WARNING: The -o (output filename) option is ignored when\n"
- "the --disable-output option is used.\n";
- } else {
- // Default to standard output.
- if (OutputFilename.empty())
- OutputFilename = "-";
- std::error_code EC;
- Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None));
- if (EC) {
- errs() << EC.message() << '\n';
- return 1;
- }
- }
- Triple ModuleTriple(M->getTargetTriple());
- std::string CPUStr, FeaturesStr;
- TargetMachine *Machine = nullptr;
- const TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
- if (ModuleTriple.getArch()) {
- CPUStr = getCPUStr();
- FeaturesStr = getFeaturesStr();
- Machine = GetTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options);
- }
- std::unique_ptr<TargetMachine> TM(Machine);
- // Override function attributes based on CPUStr, FeaturesStr, and command line
- // flags.
- setFunctionAttributes(CPUStr, FeaturesStr, *M);
- // If the output is set to be emitted to standard out, and standard out is a
- // console, print out a warning message and refuse to do it. We don't
- // impress anyone by spewing tons of binary goo to a terminal.
- if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly)
- if (CheckBitcodeOutputToConsole(Out->os(), !Quiet))
- NoOutput = true;
- if (PassPipeline.getNumOccurrences() > 0) {
- OutputKind OK = OK_NoOutput;
- if (!NoOutput)
- OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode;
- VerifierKind VK = VK_VerifyInAndOut;
- if (NoVerify)
- VK = VK_NoVerifier;
- else if (VerifyEach)
- VK = VK_VerifyEachPass;
- // The user has asked to use the new pass manager and provided a pipeline
- // string. Hand off the rest of the functionality to the new code for that
- // layer.
- return runPassPipeline(argv[0], Context, *M, TM.get(), Out.get(),
- PassPipeline, OK, VK, PreserveAssemblyUseListOrder,
- PreserveBitcodeUseListOrder)
- ? 0
- : 1;
- }
- // Create a PassManager to hold and optimize the collection of passes we are
- // about to build.
- //
- legacy::PassManager Passes;
- // Add an appropriate TargetLibraryInfo pass for the module's triple.
- TargetLibraryInfoImpl TLII(ModuleTriple);
- // The -disable-simplify-libcalls flag actually disables all builtin optzns.
- if (DisableSimplifyLibCalls)
- TLII.disableAllFunctions();
- Passes.add(new TargetLibraryInfoWrapperPass(TLII));
- // Add an appropriate DataLayout instance for this module.
- const DataLayout &DL = M->getDataLayout();
- if (DL.isDefault() && !DefaultDataLayout.empty()) {
- M->setDataLayout(DefaultDataLayout);
- }
- // Add internal analysis passes from the target machine.
- Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()
- : TargetIRAnalysis()));
- std::unique_ptr<legacy::FunctionPassManager> FPasses;
- if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
- FPasses.reset(new legacy::FunctionPassManager(M.get()));
- FPasses->add(createTargetTransformInfoWrapperPass(
- TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis()));
- }
- if (PrintBreakpoints) {
- // Default to standard output.
- if (!Out) {
- if (OutputFilename.empty())
- OutputFilename = "-";
- std::error_code EC;
- Out = llvm::make_unique<tool_output_file>(OutputFilename, EC,
- sys::fs::F_None);
- if (EC) {
- errs() << EC.message() << '\n';
- return 1;
- }
- }
- Passes.add(createBreakpointPrinter(Out->os()));
- NoOutput = true;
- }
- // Create a new optimization pass for each one specified on the command line
- for (unsigned i = 0; i < PassList.size(); ++i) {
- if (StandardLinkOpts &&
- StandardLinkOpts.getPosition() < PassList.getPosition(i)) {
- AddStandardLinkPasses(Passes);
- StandardLinkOpts = false;
- }
- if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) {
- AddOptimizationPasses(Passes, *FPasses, 1, 0);
- OptLevelO1 = false;
- }
- if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) {
- 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, 0);
- OptLevelO3 = false;
- }
- const PassInfo *PassInf = PassList[i];
- Pass *P = nullptr;
- if (PassInf->getTargetMachineCtor())
- P = PassInf->getTargetMachineCtor()(TM.get());
- else if (PassInf->getNormalCtor())
- P = PassInf->getNormalCtor()();
- else
- errs() << argv[0] << ": cannot create pass: "
- << PassInf->getPassName() << "\n";
- if (P) {
- PassKind Kind = P->getPassKind();
- addPass(Passes, P);
- if (AnalyzeOnly) {
- switch (Kind) {
- case PT_BasicBlock:
- Passes.add(createBasicBlockPassPrinter(PassInf, Out->os(), Quiet));
- break;
- case PT_Region:
- Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet));
- break;
- case PT_Loop:
- Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet));
- break;
- case PT_Function:
- Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet));
- break;
- case PT_CallGraphSCC:
- Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet));
- break;
- default:
- Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet));
- break;
- }
- }
- }
- if (PrintEachXForm)
- Passes.add(
- createPrintModulePass(errs(), "", PreserveAssemblyUseListOrder));
- }
- if (StandardLinkOpts) {
- AddStandardLinkPasses(Passes);
- StandardLinkOpts = false;
- }
- if (OptLevelO1)
- AddOptimizationPasses(Passes, *FPasses, 1, 0);
- if (OptLevelO2)
- 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, 0);
- if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
- FPasses->doInitialization();
- for (Function &F : *M)
- FPasses->run(F);
- FPasses->doFinalization();
- }
- // Check that the module is well formed on completion of optimization
- if (!NoVerify && !VerifyEach)
- Passes.add(createVerifierPass());
- // Write bitcode or assembly to the output as the last step...
- if (!NoOutput && !AnalyzeOnly) {
- if (OutputAssembly)
- Passes.add(
- createPrintModulePass(Out->os(), "", PreserveAssemblyUseListOrder));
- else
- Passes.add(
- createBitcodeWriterPass(Out->os(), PreserveBitcodeUseListOrder));
- }
- // Before executing passes, print the final values of the LLVM options.
- cl::PrintOptionValues();
- // Now that we have all of the passes ready, run them.
- // HLSL Change Starts - wrap in try-catch
- try {
- Passes.run(*M);
- }
- catch(...) {
- exit(1);
- }
- // HLSL Change Ends
- // Declare success.
- if (!NoOutput || PrintBreakpoints)
- Out->keep();
- return 0;
- }
|