Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 1 | //===- subzero/src/IceCompiler.cpp - Driver for bitcode translation -------===// |
| 2 | // |
| 3 | // The Subzero Code Generator |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 9 | /// |
| 10 | /// \file |
Jim Stichnoth | 92a6e5b | 2015-12-02 16:52:44 -0800 | [diff] [blame] | 11 | /// \brief Defines a driver for translating PNaCl bitcode into native code. |
| 12 | /// |
| 13 | /// The driver can either directly parse the binary bitcode file, or use LLVM |
| 14 | /// routines to parse a textual bitcode file into LLVM IR and then convert LLVM |
| 15 | /// IR into ICE. In either case, the high-level ICE is then compiled down to |
| 16 | /// native code, as either an ELF object file or a textual asm file. |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 17 | /// |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 18 | //===----------------------------------------------------------------------===// |
| 19 | |
John Porto | 67f8de9 | 2015-06-25 10:14:17 -0700 | [diff] [blame] | 20 | #include "IceCompiler.h" |
| 21 | |
Reed Kotler | 8dbb4a0 | 2015-12-11 09:51:47 -0800 | [diff] [blame] | 22 | #include "IceBuildDefs.h" |
John Porto | 67f8de9 | 2015-06-25 10:14:17 -0700 | [diff] [blame] | 23 | #include "IceCfg.h" |
| 24 | #include "IceClFlags.h" |
John Porto | 67f8de9 | 2015-06-25 10:14:17 -0700 | [diff] [blame] | 25 | #include "IceConverter.h" |
| 26 | #include "IceELFObjectWriter.h" |
| 27 | #include "PNaClTranslator.h" |
Eric Holk | 16f8061 | 2016-04-04 17:07:42 -0700 | [diff] [blame] | 28 | #include "WasmTranslator.h" |
Jim Stichnoth | 98da966 | 2015-06-27 06:38:08 -0700 | [diff] [blame] | 29 | |
Jim Stichnoth | b0051df | 2016-01-13 11:39:15 -0800 | [diff] [blame] | 30 | #ifdef __clang__ |
Jim Stichnoth | 98da966 | 2015-06-27 06:38:08 -0700 | [diff] [blame] | 31 | #pragma clang diagnostic push |
| 32 | #pragma clang diagnostic ignored "-Wunused-parameter" |
Jim Stichnoth | b0051df | 2016-01-13 11:39:15 -0800 | [diff] [blame] | 33 | #endif // __clang__ |
| 34 | |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 35 | #include "llvm/ADT/STLExtras.h" |
Karl Schimpf | 25529f7 | 2015-08-25 13:47:27 -0700 | [diff] [blame] | 36 | #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 37 | #include "llvm/IR/LLVMContext.h" |
| 38 | #include "llvm/IR/Module.h" |
| 39 | #include "llvm/IRReader/IRReader.h" |
| 40 | #include "llvm/Support/SourceMgr.h" |
| 41 | #include "llvm/Support/StreamingMemoryObject.h" |
Reed Kotler | 93d85ce | 2015-12-28 00:10:06 -0800 | [diff] [blame] | 42 | |
Jim Stichnoth | b0051df | 2016-01-13 11:39:15 -0800 | [diff] [blame] | 43 | #ifdef __clang__ |
Jim Stichnoth | 98da966 | 2015-06-27 06:38:08 -0700 | [diff] [blame] | 44 | #pragma clang diagnostic pop |
Jim Stichnoth | b0051df | 2016-01-13 11:39:15 -0800 | [diff] [blame] | 45 | #endif // __clang__ |
| 46 | |
| 47 | #include <regex> |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 48 | |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 49 | namespace Ice { |
| 50 | |
| 51 | namespace { |
| 52 | |
Jim Stichnoth | 467ffe5 | 2016-03-29 15:01:06 -0700 | [diff] [blame] | 53 | bool llvmIRInput(const std::string &Filename) { |
Reed Kotler | 93d85ce | 2015-12-28 00:10:06 -0800 | [diff] [blame] | 54 | return BuildDefs::llvmIrAsInput() && |
| 55 | std::regex_match(Filename, std::regex(".*\\.ll")); |
| 56 | } |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 57 | |
Eric Holk | 16f8061 | 2016-04-04 17:07:42 -0700 | [diff] [blame] | 58 | bool wasmInput(const std::string &Filename) { |
Eric Holk | 87def2c | 2016-04-29 14:42:17 -0700 | [diff] [blame] | 59 | return BuildDefs::wasm() && |
Eric Holk | 16f8061 | 2016-04-04 17:07:42 -0700 | [diff] [blame] | 60 | std::regex_match(Filename, std::regex(".*\\.wasm")); |
| 61 | } |
| 62 | |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 63 | } // end of anonymous namespace |
| 64 | |
John Porto | c5bc5cb | 2016-03-21 11:18:02 -0700 | [diff] [blame] | 65 | void Compiler::run(const Ice::ClFlags &Flags, GlobalContext &Ctx, |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 66 | std::unique_ptr<llvm::DataStreamer> &&InputStream) { |
Jim Stichnoth | 992f91d | 2015-08-10 11:18:38 -0700 | [diff] [blame] | 67 | // The Minimal build (specifically, when dump()/emit() are not implemented) |
Andrew Scull | 57e1268 | 2015-09-16 11:30:19 -0700 | [diff] [blame] | 68 | // allows only --filetype=obj. Check here to avoid cryptic error messages |
Jim Stichnoth | 992f91d | 2015-08-10 11:18:38 -0700 | [diff] [blame] | 69 | // downstream. |
Karl Schimpf | d469994 | 2016-04-02 09:55:31 -0700 | [diff] [blame] | 70 | if (!BuildDefs::dump() && getFlags().getOutFileType() != FT_Elf) { |
Jim Stichnoth | 992f91d | 2015-08-10 11:18:38 -0700 | [diff] [blame] | 71 | Ctx.getStrError() |
| 72 | << "Error: only --filetype=obj is supported in this build.\n"; |
Reed Kotler | 93d85ce | 2015-12-28 00:10:06 -0800 | [diff] [blame] | 73 | Ctx.getErrorStatus()->assign(EC_Args); |
| 74 | return; |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 75 | } |
| 76 | |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 77 | TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); |
| 78 | |
Jan Voung | fb79284 | 2015-06-11 15:27:50 -0700 | [diff] [blame] | 79 | Ctx.emitFileHeader(); |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 80 | Ctx.startWorkerThreads(); |
| 81 | |
| 82 | std::unique_ptr<Translator> Translator; |
Jim Stichnoth | 467ffe5 | 2016-03-29 15:01:06 -0700 | [diff] [blame] | 83 | const std::string IRFilename = Flags.getIRFilename(); |
Eric Holk | 16f8061 | 2016-04-04 17:07:42 -0700 | [diff] [blame] | 84 | const bool BuildOnRead = Flags.getBuildOnRead() && !llvmIRInput(IRFilename) && |
| 85 | !wasmInput(IRFilename); |
| 86 | const bool WasmBuildOnRead = Flags.getBuildOnRead() && wasmInput(IRFilename); |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 87 | if (BuildOnRead) { |
| 88 | std::unique_ptr<PNaClTranslator> PTranslator(new PNaClTranslator(&Ctx)); |
Jim Stichnoth | f5fdd23 | 2016-05-09 12:24:36 -0700 | [diff] [blame] | 89 | #ifdef PNACL_LLVM |
Jim Stichnoth | a5b16ab | 2016-05-10 11:20:41 -0700 | [diff] [blame] | 90 | std::unique_ptr<llvm::StreamingMemoryObject> MemObj( |
| 91 | new llvm::StreamingMemoryObjectImpl(InputStream.release())); |
| 92 | #else // !PNACL_LLVM |
| 93 | std::unique_ptr<llvm::StreamingMemoryObject> MemObj( |
| 94 | new llvm::StreamingMemoryObject(std::move(InputStream))); |
Jim Stichnoth | f5fdd23 | 2016-05-09 12:24:36 -0700 | [diff] [blame] | 95 | #endif // !PNACL_LLVM |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 96 | PTranslator->translate(IRFilename, std::move(MemObj)); |
| 97 | Translator.reset(PTranslator.release()); |
Eric Holk | 16f8061 | 2016-04-04 17:07:42 -0700 | [diff] [blame] | 98 | } else if (WasmBuildOnRead) { |
| 99 | if (BuildDefs::wasm()) { |
John Porto | 681f90f | 2016-04-05 06:20:50 -0700 | [diff] [blame] | 100 | #if !ALLOW_WASM |
| 101 | assert(false && "wasm not allowed"); |
| 102 | #else |
Eric Holk | 16f8061 | 2016-04-04 17:07:42 -0700 | [diff] [blame] | 103 | std::unique_ptr<WasmTranslator> WTranslator(new WasmTranslator(&Ctx)); |
| 104 | |
| 105 | WTranslator->translate(IRFilename, std::move(InputStream)); |
| 106 | |
| 107 | Translator.reset(WTranslator.release()); |
John Porto | 681f90f | 2016-04-05 06:20:50 -0700 | [diff] [blame] | 108 | #endif // !ALLOW_WASM |
Eric Holk | 16f8061 | 2016-04-04 17:07:42 -0700 | [diff] [blame] | 109 | } else { |
| 110 | Ctx.getStrError() << "WASM support not enabled\n"; |
| 111 | Ctx.getErrorStatus()->assign(EC_Args); |
| 112 | return; |
| 113 | } |
Jim Stichnoth | 20b71f5 | 2015-06-24 15:52:24 -0700 | [diff] [blame] | 114 | } else if (BuildDefs::llvmIr()) { |
Reed Kotler | 8dbb4a0 | 2015-12-11 09:51:47 -0800 | [diff] [blame] | 115 | if (BuildDefs::browser()) { |
Jim Stichnoth | 992f91d | 2015-08-10 11:18:38 -0700 | [diff] [blame] | 116 | Ctx.getStrError() |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 117 | << "non BuildOnRead is not supported w/ PNACL_BROWSER_TRANSLATOR\n"; |
Reed Kotler | 93d85ce | 2015-12-28 00:10:06 -0800 | [diff] [blame] | 118 | Ctx.getErrorStatus()->assign(EC_Args); |
Karl Schimpf | e8457a2 | 2016-03-31 10:20:23 -0700 | [diff] [blame] | 119 | Ctx.waitForWorkerThreads(); |
Reed Kotler | 93d85ce | 2015-12-28 00:10:06 -0800 | [diff] [blame] | 120 | return; |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 121 | } |
John Porto | a78e4ba | 2016-03-15 09:28:04 -0700 | [diff] [blame] | 122 | // Globals must be kept alive after lowering when converting from LLVM to |
| 123 | // Ice. |
| 124 | Ctx.setDisposeGlobalVariablesAfterLowering(false); |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 125 | // Parse the input LLVM IR file into a module. |
| 126 | llvm::SMDiagnostic Err; |
| 127 | TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); |
Jim Stichnoth | f5fdd23 | 2016-05-09 12:24:36 -0700 | [diff] [blame] | 128 | #ifdef PNACL_LLVM |
Karl Schimpf | 25529f7 | 2015-08-25 13:47:27 -0700 | [diff] [blame] | 129 | llvm::DiagnosticHandlerFunction DiagnosticHandler = |
John Porto | c5bc5cb | 2016-03-21 11:18:02 -0700 | [diff] [blame] | 130 | Flags.getLLVMVerboseErrors() |
Karl Schimpf | 25529f7 | 2015-08-25 13:47:27 -0700 | [diff] [blame] | 131 | ? redirectNaClDiagnosticToStream(llvm::errs()) |
| 132 | : nullptr; |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 133 | std::unique_ptr<llvm::Module> Mod = |
John Porto | c5bc5cb | 2016-03-21 11:18:02 -0700 | [diff] [blame] | 134 | NaClParseIRFile(IRFilename, Flags.getInputFileFormat(), Err, |
Karl Schimpf | 25529f7 | 2015-08-25 13:47:27 -0700 | [diff] [blame] | 135 | llvm::getGlobalContext(), DiagnosticHandler); |
Jim Stichnoth | a5b16ab | 2016-05-10 11:20:41 -0700 | [diff] [blame] | 136 | #else // !PNACL_LLVM |
Jim Stichnoth | f5fdd23 | 2016-05-09 12:24:36 -0700 | [diff] [blame] | 137 | llvm::DiagnosticHandlerFunction DiagnosticHandler = nullptr; |
| 138 | llvm::LLVMContext Context; |
Jim Stichnoth | a5b16ab | 2016-05-10 11:20:41 -0700 | [diff] [blame] | 139 | std::unique_ptr<llvm::Module> Mod = parseIRFile(IRFilename, Err, Context); |
Jim Stichnoth | f5fdd23 | 2016-05-09 12:24:36 -0700 | [diff] [blame] | 140 | #endif // !PNACL_LLVM |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 141 | if (!Mod) { |
John Porto | c5bc5cb | 2016-03-21 11:18:02 -0700 | [diff] [blame] | 142 | Err.print(Flags.getAppName().c_str(), llvm::errs()); |
Reed Kotler | 93d85ce | 2015-12-28 00:10:06 -0800 | [diff] [blame] | 143 | Ctx.getErrorStatus()->assign(EC_Bitcode); |
Karl Schimpf | e8457a2 | 2016-03-31 10:20:23 -0700 | [diff] [blame] | 144 | Ctx.waitForWorkerThreads(); |
Reed Kotler | 93d85ce | 2015-12-28 00:10:06 -0800 | [diff] [blame] | 145 | return; |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 146 | } |
| 147 | |
| 148 | std::unique_ptr<Converter> Converter(new class Converter(Mod.get(), &Ctx)); |
| 149 | Converter->convertToIce(); |
| 150 | Translator.reset(Converter.release()); |
| 151 | } else { |
Jim Stichnoth | 992f91d | 2015-08-10 11:18:38 -0700 | [diff] [blame] | 152 | Ctx.getStrError() << "Error: Build doesn't allow LLVM IR, " |
| 153 | << "--build-on-read=0 not allowed\n"; |
Reed Kotler | 93d85ce | 2015-12-28 00:10:06 -0800 | [diff] [blame] | 154 | Ctx.getErrorStatus()->assign(EC_Args); |
Karl Schimpf | e8457a2 | 2016-03-31 10:20:23 -0700 | [diff] [blame] | 155 | Ctx.waitForWorkerThreads(); |
Reed Kotler | 93d85ce | 2015-12-28 00:10:06 -0800 | [diff] [blame] | 156 | return; |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | Ctx.waitForWorkerThreads(); |
John Porto | 8b1a705 | 2015-06-17 13:20:08 -0700 | [diff] [blame] | 160 | if (Translator->getErrorStatus()) { |
| 161 | Ctx.getErrorStatus()->assign(Translator->getErrorStatus().value()); |
| 162 | } else { |
| 163 | Ctx.lowerGlobals("last"); |
| 164 | Ctx.lowerProfileData(); |
| 165 | Ctx.lowerConstants(); |
Andrew Scull | 86df4e9 | 2015-07-30 13:54:44 -0700 | [diff] [blame] | 166 | Ctx.lowerJumpTables(); |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 167 | |
Karl Schimpf | d469994 | 2016-04-02 09:55:31 -0700 | [diff] [blame] | 168 | if (getFlags().getOutFileType() == FT_Elf) { |
Karl Schimpf | b6e9b89 | 2016-03-08 12:27:12 -0800 | [diff] [blame] | 169 | TimerMarker T1(Ice::TimerStack::TT_emitAsm, &Ctx); |
John Porto | 8b1a705 | 2015-06-17 13:20:08 -0700 | [diff] [blame] | 170 | Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms()); |
Jaydeep Patil | 3da9f65 | 2016-11-03 22:54:06 -0700 | [diff] [blame] | 171 | Ctx.emitTargetRODataSections(); |
John Porto | 8b1a705 | 2015-06-17 13:20:08 -0700 | [diff] [blame] | 172 | Ctx.getObjectWriter()->writeNonUserSections(); |
| 173 | } |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 174 | } |
John Porto | 8b1a705 | 2015-06-17 13:20:08 -0700 | [diff] [blame] | 175 | |
Karl Schimpf | d469994 | 2016-04-02 09:55:31 -0700 | [diff] [blame] | 176 | if (getFlags().getSubzeroTimingEnabled()) |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 177 | Ctx.dumpTimers(); |
John Porto | 8b1a705 | 2015-06-17 13:20:08 -0700 | [diff] [blame] | 178 | |
Karl Schimpf | d469994 | 2016-04-02 09:55:31 -0700 | [diff] [blame] | 179 | if (getFlags().getTimeEachFunction()) { |
Jim Stichnoth | b88d8c8 | 2016-03-11 15:33:00 -0800 | [diff] [blame] | 180 | constexpr bool NoDumpCumulative = false; |
| 181 | Ctx.dumpTimers(GlobalContext::TSK_Funcs, NoDumpCumulative); |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 182 | } |
Jim Stichnoth | b5eee3d | 2016-03-31 11:05:39 -0700 | [diff] [blame] | 183 | Ctx.dumpStats(); |
Jan Voung | 44c3a80 | 2015-03-27 16:29:08 -0700 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | } // end of namespace Ice |