blob: 30b9d1f00797737bcbe9284fb74bc1cfd8bba15d [file] [log] [blame]
Jan Voung44c3a802015-03-27 16:29:08 -07001//===- 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 Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \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 Scull9612d322015-07-06 14:53:25 -070017///
Jan Voung44c3a802015-03-27 16:29:08 -070018//===----------------------------------------------------------------------===//
19
John Porto67f8de92015-06-25 10:14:17 -070020#include "IceCompiler.h"
21
Reed Kotler8dbb4a02015-12-11 09:51:47 -080022#include "IceBuildDefs.h"
John Porto67f8de92015-06-25 10:14:17 -070023#include "IceCfg.h"
24#include "IceClFlags.h"
John Porto67f8de92015-06-25 10:14:17 -070025#include "IceConverter.h"
26#include "IceELFObjectWriter.h"
27#include "PNaClTranslator.h"
Eric Holk16f80612016-04-04 17:07:42 -070028#include "WasmTranslator.h"
Jim Stichnoth98da9662015-06-27 06:38:08 -070029
Jim Stichnothb0051df2016-01-13 11:39:15 -080030#ifdef __clang__
Jim Stichnoth98da9662015-06-27 06:38:08 -070031#pragma clang diagnostic push
32#pragma clang diagnostic ignored "-Wunused-parameter"
Jim Stichnothb0051df2016-01-13 11:39:15 -080033#endif // __clang__
34
Jan Voung44c3a802015-03-27 16:29:08 -070035#include "llvm/ADT/STLExtras.h"
Karl Schimpf25529f72015-08-25 13:47:27 -070036#include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
Jan Voung44c3a802015-03-27 16:29:08 -070037#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 Kotler93d85ce2015-12-28 00:10:06 -080042
Jim Stichnothb0051df2016-01-13 11:39:15 -080043#ifdef __clang__
Jim Stichnoth98da9662015-06-27 06:38:08 -070044#pragma clang diagnostic pop
Jim Stichnothb0051df2016-01-13 11:39:15 -080045#endif // __clang__
46
47#include <regex>
Jan Voung44c3a802015-03-27 16:29:08 -070048
Jan Voung44c3a802015-03-27 16:29:08 -070049namespace Ice {
50
51namespace {
52
Jim Stichnoth467ffe52016-03-29 15:01:06 -070053bool llvmIRInput(const std::string &Filename) {
Reed Kotler93d85ce2015-12-28 00:10:06 -080054 return BuildDefs::llvmIrAsInput() &&
55 std::regex_match(Filename, std::regex(".*\\.ll"));
56}
Jan Voung44c3a802015-03-27 16:29:08 -070057
Eric Holk16f80612016-04-04 17:07:42 -070058bool wasmInput(const std::string &Filename) {
Eric Holk87def2c2016-04-29 14:42:17 -070059 return BuildDefs::wasm() &&
Eric Holk16f80612016-04-04 17:07:42 -070060 std::regex_match(Filename, std::regex(".*\\.wasm"));
61}
62
Jan Voung44c3a802015-03-27 16:29:08 -070063} // end of anonymous namespace
64
John Portoc5bc5cb2016-03-21 11:18:02 -070065void Compiler::run(const Ice::ClFlags &Flags, GlobalContext &Ctx,
Jan Voung44c3a802015-03-27 16:29:08 -070066 std::unique_ptr<llvm::DataStreamer> &&InputStream) {
Jim Stichnoth992f91d2015-08-10 11:18:38 -070067 // The Minimal build (specifically, when dump()/emit() are not implemented)
Andrew Scull57e12682015-09-16 11:30:19 -070068 // allows only --filetype=obj. Check here to avoid cryptic error messages
Jim Stichnoth992f91d2015-08-10 11:18:38 -070069 // downstream.
Karl Schimpfd4699942016-04-02 09:55:31 -070070 if (!BuildDefs::dump() && getFlags().getOutFileType() != FT_Elf) {
Jim Stichnoth992f91d2015-08-10 11:18:38 -070071 Ctx.getStrError()
72 << "Error: only --filetype=obj is supported in this build.\n";
Reed Kotler93d85ce2015-12-28 00:10:06 -080073 Ctx.getErrorStatus()->assign(EC_Args);
74 return;
Jan Voung44c3a802015-03-27 16:29:08 -070075 }
76
Jan Voung44c3a802015-03-27 16:29:08 -070077 TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx);
78
Jan Voungfb792842015-06-11 15:27:50 -070079 Ctx.emitFileHeader();
Jan Voung44c3a802015-03-27 16:29:08 -070080 Ctx.startWorkerThreads();
81
82 std::unique_ptr<Translator> Translator;
Jim Stichnoth467ffe52016-03-29 15:01:06 -070083 const std::string IRFilename = Flags.getIRFilename();
Eric Holk16f80612016-04-04 17:07:42 -070084 const bool BuildOnRead = Flags.getBuildOnRead() && !llvmIRInput(IRFilename) &&
85 !wasmInput(IRFilename);
86 const bool WasmBuildOnRead = Flags.getBuildOnRead() && wasmInput(IRFilename);
Jan Voung44c3a802015-03-27 16:29:08 -070087 if (BuildOnRead) {
88 std::unique_ptr<PNaClTranslator> PTranslator(new PNaClTranslator(&Ctx));
Jim Stichnothf5fdd232016-05-09 12:24:36 -070089#ifdef PNACL_LLVM
Jim Stichnotha5b16ab2016-05-10 11:20:41 -070090 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 Stichnothf5fdd232016-05-09 12:24:36 -070095#endif // !PNACL_LLVM
Jan Voung44c3a802015-03-27 16:29:08 -070096 PTranslator->translate(IRFilename, std::move(MemObj));
97 Translator.reset(PTranslator.release());
Eric Holk16f80612016-04-04 17:07:42 -070098 } else if (WasmBuildOnRead) {
99 if (BuildDefs::wasm()) {
John Porto681f90f2016-04-05 06:20:50 -0700100#if !ALLOW_WASM
101 assert(false && "wasm not allowed");
102#else
Eric Holk16f80612016-04-04 17:07:42 -0700103 std::unique_ptr<WasmTranslator> WTranslator(new WasmTranslator(&Ctx));
104
105 WTranslator->translate(IRFilename, std::move(InputStream));
106
107 Translator.reset(WTranslator.release());
John Porto681f90f2016-04-05 06:20:50 -0700108#endif // !ALLOW_WASM
Eric Holk16f80612016-04-04 17:07:42 -0700109 } else {
110 Ctx.getStrError() << "WASM support not enabled\n";
111 Ctx.getErrorStatus()->assign(EC_Args);
112 return;
113 }
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700114 } else if (BuildDefs::llvmIr()) {
Reed Kotler8dbb4a02015-12-11 09:51:47 -0800115 if (BuildDefs::browser()) {
Jim Stichnoth992f91d2015-08-10 11:18:38 -0700116 Ctx.getStrError()
Jan Voung44c3a802015-03-27 16:29:08 -0700117 << "non BuildOnRead is not supported w/ PNACL_BROWSER_TRANSLATOR\n";
Reed Kotler93d85ce2015-12-28 00:10:06 -0800118 Ctx.getErrorStatus()->assign(EC_Args);
Karl Schimpfe8457a22016-03-31 10:20:23 -0700119 Ctx.waitForWorkerThreads();
Reed Kotler93d85ce2015-12-28 00:10:06 -0800120 return;
Jan Voung44c3a802015-03-27 16:29:08 -0700121 }
John Portoa78e4ba2016-03-15 09:28:04 -0700122 // Globals must be kept alive after lowering when converting from LLVM to
123 // Ice.
124 Ctx.setDisposeGlobalVariablesAfterLowering(false);
Jan Voung44c3a802015-03-27 16:29:08 -0700125 // Parse the input LLVM IR file into a module.
126 llvm::SMDiagnostic Err;
127 TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx);
Jim Stichnothf5fdd232016-05-09 12:24:36 -0700128#ifdef PNACL_LLVM
Karl Schimpf25529f72015-08-25 13:47:27 -0700129 llvm::DiagnosticHandlerFunction DiagnosticHandler =
John Portoc5bc5cb2016-03-21 11:18:02 -0700130 Flags.getLLVMVerboseErrors()
Karl Schimpf25529f72015-08-25 13:47:27 -0700131 ? redirectNaClDiagnosticToStream(llvm::errs())
132 : nullptr;
Jan Voung44c3a802015-03-27 16:29:08 -0700133 std::unique_ptr<llvm::Module> Mod =
John Portoc5bc5cb2016-03-21 11:18:02 -0700134 NaClParseIRFile(IRFilename, Flags.getInputFileFormat(), Err,
Karl Schimpf25529f72015-08-25 13:47:27 -0700135 llvm::getGlobalContext(), DiagnosticHandler);
Jim Stichnotha5b16ab2016-05-10 11:20:41 -0700136#else // !PNACL_LLVM
Jim Stichnothf5fdd232016-05-09 12:24:36 -0700137 llvm::DiagnosticHandlerFunction DiagnosticHandler = nullptr;
138 llvm::LLVMContext Context;
Jim Stichnotha5b16ab2016-05-10 11:20:41 -0700139 std::unique_ptr<llvm::Module> Mod = parseIRFile(IRFilename, Err, Context);
Jim Stichnothf5fdd232016-05-09 12:24:36 -0700140#endif // !PNACL_LLVM
Jan Voung44c3a802015-03-27 16:29:08 -0700141 if (!Mod) {
John Portoc5bc5cb2016-03-21 11:18:02 -0700142 Err.print(Flags.getAppName().c_str(), llvm::errs());
Reed Kotler93d85ce2015-12-28 00:10:06 -0800143 Ctx.getErrorStatus()->assign(EC_Bitcode);
Karl Schimpfe8457a22016-03-31 10:20:23 -0700144 Ctx.waitForWorkerThreads();
Reed Kotler93d85ce2015-12-28 00:10:06 -0800145 return;
Jan Voung44c3a802015-03-27 16:29:08 -0700146 }
147
148 std::unique_ptr<Converter> Converter(new class Converter(Mod.get(), &Ctx));
149 Converter->convertToIce();
150 Translator.reset(Converter.release());
151 } else {
Jim Stichnoth992f91d2015-08-10 11:18:38 -0700152 Ctx.getStrError() << "Error: Build doesn't allow LLVM IR, "
153 << "--build-on-read=0 not allowed\n";
Reed Kotler93d85ce2015-12-28 00:10:06 -0800154 Ctx.getErrorStatus()->assign(EC_Args);
Karl Schimpfe8457a22016-03-31 10:20:23 -0700155 Ctx.waitForWorkerThreads();
Reed Kotler93d85ce2015-12-28 00:10:06 -0800156 return;
Jan Voung44c3a802015-03-27 16:29:08 -0700157 }
158
159 Ctx.waitForWorkerThreads();
John Porto8b1a7052015-06-17 13:20:08 -0700160 if (Translator->getErrorStatus()) {
161 Ctx.getErrorStatus()->assign(Translator->getErrorStatus().value());
162 } else {
163 Ctx.lowerGlobals("last");
164 Ctx.lowerProfileData();
165 Ctx.lowerConstants();
Andrew Scull86df4e92015-07-30 13:54:44 -0700166 Ctx.lowerJumpTables();
Jan Voung44c3a802015-03-27 16:29:08 -0700167
Karl Schimpfd4699942016-04-02 09:55:31 -0700168 if (getFlags().getOutFileType() == FT_Elf) {
Karl Schimpfb6e9b892016-03-08 12:27:12 -0800169 TimerMarker T1(Ice::TimerStack::TT_emitAsm, &Ctx);
John Porto8b1a7052015-06-17 13:20:08 -0700170 Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms());
Jaydeep Patil3da9f652016-11-03 22:54:06 -0700171 Ctx.emitTargetRODataSections();
John Porto8b1a7052015-06-17 13:20:08 -0700172 Ctx.getObjectWriter()->writeNonUserSections();
173 }
Jan Voung44c3a802015-03-27 16:29:08 -0700174 }
John Porto8b1a7052015-06-17 13:20:08 -0700175
Karl Schimpfd4699942016-04-02 09:55:31 -0700176 if (getFlags().getSubzeroTimingEnabled())
Jan Voung44c3a802015-03-27 16:29:08 -0700177 Ctx.dumpTimers();
John Porto8b1a7052015-06-17 13:20:08 -0700178
Karl Schimpfd4699942016-04-02 09:55:31 -0700179 if (getFlags().getTimeEachFunction()) {
Jim Stichnothb88d8c82016-03-11 15:33:00 -0800180 constexpr bool NoDumpCumulative = false;
181 Ctx.dumpTimers(GlobalContext::TSK_Funcs, NoDumpCumulative);
Jan Voung44c3a802015-03-27 16:29:08 -0700182 }
Jim Stichnothb5eee3d2016-03-31 11:05:39 -0700183 Ctx.dumpStats();
Jan Voung44c3a802015-03-27 16:29:08 -0700184}
185
186} // end of namespace Ice