OLD | NEW |
1 //===- subzero/src/main.cpp - Driver for bitcode translation --------------===// | 1 //===- subzero/src/IceCompiler.cpp - Driver for bitcode translation -------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines a driver for translating PNaCl bitcode into native code. | 10 // This file defines a driver for translating PNaCl bitcode into native code. |
11 // It can either directly parse the binary bitcode file, or use LLVM routines to | 11 // It can either directly parse the binary bitcode file, or use LLVM routines to |
12 // parse a textual bitcode file into LLVM IR and then convert LLVM IR into ICE. | 12 // parse a textual bitcode file into LLVM IR and then convert LLVM IR into ICE. |
13 // In either case, the high-level ICE is then compiled down to native code, as | 13 // In either case, the high-level ICE is then compiled down to native code, as |
14 // either an ELF object file or a textual asm file. | 14 // either an ELF object file or a textual asm file. |
15 // | 15 // |
16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
17 | 17 |
| 18 #include "IceCompiler.h" |
| 19 |
18 #include <fstream> | 20 #include <fstream> |
19 #include <iostream> | 21 #include <iostream> |
20 | 22 |
21 #include "llvm/ADT/STLExtras.h" | 23 #include "llvm/ADT/STLExtras.h" |
22 #include "llvm/IR/LLVMContext.h" | 24 #include "llvm/IR/LLVMContext.h" |
23 #include "llvm/IR/Module.h" | 25 #include "llvm/IR/Module.h" |
24 #include "llvm/IRReader/IRReader.h" | 26 #include "llvm/IRReader/IRReader.h" |
25 #include "llvm/Support/CommandLine.h" | 27 #include "llvm/Support/CommandLine.h" |
26 #include "llvm/Support/FileSystem.h" | 28 #include "llvm/Support/FileSystem.h" |
27 #include "llvm/Support/raw_os_ostream.h" | 29 #include "llvm/Support/raw_os_ostream.h" |
28 #include "llvm/Support/SourceMgr.h" | 30 #include "llvm/Support/SourceMgr.h" |
29 #include "llvm/Support/StreamingMemoryObject.h" | 31 #include "llvm/Support/StreamingMemoryObject.h" |
30 | 32 |
31 #include "IceCfg.h" | 33 #include "IceCfg.h" |
32 #include "IceClFlags.h" | 34 #include "IceClFlags.h" |
| 35 #include "IceCompileServer.h" |
33 #include "IceConverter.h" | 36 #include "IceConverter.h" |
34 #include "IceELFObjectWriter.h" | 37 #include "IceELFObjectWriter.h" |
35 #include "IceELFStreamer.h" | 38 #include "IceELFStreamer.h" |
36 #include "PNaClTranslator.h" | 39 #include "PNaClTranslator.h" |
37 | 40 |
38 using namespace llvm; | 41 using namespace llvm; |
39 | 42 |
40 static cl::list<Ice::VerboseItem> VerboseList( | 43 static cl::list<Ice::VerboseItem> VerboseList( |
41 "verbose", cl::CommaSeparated, | 44 "verbose", cl::CommaSeparated, |
42 cl::desc("Verbose options (can be comma-separated):"), | 45 cl::desc("Verbose options (can be comma-separated):"), |
43 cl::values( | 46 cl::values( |
44 clEnumValN(Ice::IceV_Instructions, "inst", "Print basic instructions"), | 47 clEnumValN(Ice::IceV_Instructions, "inst", "Print basic instructions"), |
45 clEnumValN(Ice::IceV_Deleted, "del", "Include deleted instructions"), | 48 clEnumValN(Ice::IceV_Deleted, "del", "Include deleted instructions"), |
46 clEnumValN(Ice::IceV_InstNumbers, "instnum", | 49 clEnumValN(Ice::IceV_InstNumbers, "instnum", |
47 "Print instruction numbers"), | 50 "Print instruction numbers"), |
48 clEnumValN(Ice::IceV_Preds, "pred", "Show predecessors"), | 51 clEnumValN(Ice::IceV_Preds, "pred", "Show predecessors"), |
49 clEnumValN(Ice::IceV_Succs, "succ", "Show successors"), | 52 clEnumValN(Ice::IceV_Succs, "succ", "Show successors"), |
50 clEnumValN(Ice::IceV_Liveness, "live", "Liveness information"), | 53 clEnumValN(Ice::IceV_Liveness, "live", "Liveness information"), |
51 clEnumValN(Ice::IceV_RegOrigins, "orig", "Physical register origins"), | 54 clEnumValN(Ice::IceV_RegOrigins, "orig", "Physical register origins"), |
52 clEnumValN(Ice::IceV_LinearScan, "regalloc", "Linear scan details"), | 55 clEnumValN(Ice::IceV_LinearScan, "regalloc", "Linear scan details"), |
53 clEnumValN(Ice::IceV_Frame, "frame", "Stack frame layout details"), | 56 clEnumValN(Ice::IceV_Frame, "frame", "Stack frame layout details"), |
54 clEnumValN(Ice::IceV_AddrOpt, "addropt", "Address mode optimization"), | 57 clEnumValN(Ice::IceV_AddrOpt, "addropt", "Address mode optimization"), |
55 clEnumValN(Ice::IceV_Random, "random", "Randomization details"), | 58 clEnumValN(Ice::IceV_Random, "random", "Randomization details"), |
56 clEnumValN(Ice::IceV_All, "all", "Use all verbose options"), | 59 clEnumValN(Ice::IceV_All, "all", "Use all verbose options"), |
57 clEnumValN(Ice::IceV_Most, "most", | 60 clEnumValN(Ice::IceV_Most, "most", |
58 "Use all verbose options except 'regalloc' and 'time'"), | 61 "Use all verbose options except 'regalloc' and 'time'"), |
59 clEnumValN(Ice::IceV_None, "none", "No verbosity"), clEnumValEnd)); | 62 clEnumValN(Ice::IceV_None, "none", "No verbosity"), clEnumValEnd)); |
60 static cl::opt<Ice::TargetArch> TargetArch( | 63 static cl::opt<Ice::TargetArch> |
61 "target", cl::desc("Target architecture:"), cl::init(Ice::Target_X8632), | 64 TArch("target", cl::desc("Target architecture:"), |
62 cl::values( | 65 cl::init(Ice::Target_X8632), |
63 clEnumValN(Ice::Target_X8632, "x8632", "x86-32"), | 66 cl::values( |
64 clEnumValN(Ice::Target_X8632, "x86-32", "x86-32 (same as x8632)"), | 67 clEnumValN(Ice::Target_X8632, "x8632", "x86-32"), |
65 clEnumValN(Ice::Target_X8632, "x86_32", "x86-32 (same as x8632)"), | 68 clEnumValN(Ice::Target_X8632, "x86-32", "x86-32 (same as x8632)"), |
66 clEnumValN(Ice::Target_X8664, "x8664", "x86-64"), | 69 clEnumValN(Ice::Target_X8632, "x86_32", "x86-32 (same as x8632)"), |
67 clEnumValN(Ice::Target_X8664, "x86-64", "x86-64 (same as x8664)"), | 70 clEnumValN(Ice::Target_X8664, "x8664", "x86-64"), |
68 clEnumValN(Ice::Target_X8664, "x86_64", "x86-64 (same as x8664)"), | 71 clEnumValN(Ice::Target_X8664, "x86-64", "x86-64 (same as x8664)"), |
69 clEnumValN(Ice::Target_ARM32, "arm", "arm32"), | 72 clEnumValN(Ice::Target_X8664, "x86_64", "x86-64 (same as x8664)"), |
70 clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"), | 73 clEnumValN(Ice::Target_ARM32, "arm", "arm32"), |
71 clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd)); | 74 clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"), |
| 75 clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd)); |
72 static cl::opt<bool> UseSandboxing("sandbox", cl::desc("Use sandboxing")); | 76 static cl::opt<bool> UseSandboxing("sandbox", cl::desc("Use sandboxing")); |
73 static cl::opt<bool> | 77 static cl::opt<bool> |
74 FunctionSections("ffunction-sections", | 78 FunctionSections("ffunction-sections", |
75 cl::desc("Emit functions into separate sections")); | 79 cl::desc("Emit functions into separate sections")); |
76 static cl::opt<bool> | 80 static cl::opt<bool> |
77 DataSections("fdata-sections", | 81 DataSections("fdata-sections", |
78 cl::desc("Emit (global) data into separate sections")); | 82 cl::desc("Emit (global) data into separate sections")); |
79 static cl::opt<Ice::OptLevel> | 83 static cl::opt<Ice::OptLevel> |
80 OptLevel(cl::desc("Optimization level"), cl::init(Ice::Opt_m1), | 84 OLevel(cl::desc("Optimization level"), cl::init(Ice::Opt_m1), |
81 cl::value_desc("level"), | 85 cl::value_desc("level"), |
82 cl::values(clEnumValN(Ice::Opt_m1, "Om1", "-1"), | 86 cl::values(clEnumValN(Ice::Opt_m1, "Om1", "-1"), |
83 clEnumValN(Ice::Opt_m1, "O-1", "-1"), | 87 clEnumValN(Ice::Opt_m1, "O-1", "-1"), |
84 clEnumValN(Ice::Opt_0, "O0", "0"), | 88 clEnumValN(Ice::Opt_0, "O0", "0"), |
85 clEnumValN(Ice::Opt_1, "O1", "1"), | 89 clEnumValN(Ice::Opt_1, "O1", "1"), |
86 clEnumValN(Ice::Opt_2, "O2", "2"), clEnumValEnd)); | 90 clEnumValN(Ice::Opt_2, "O2", "2"), clEnumValEnd)); |
87 static cl::opt<std::string> IRFilename(cl::Positional, cl::desc("<IR file>"), | 91 static cl::opt<std::string> IRFilename(cl::Positional, cl::desc("<IR file>"), |
88 cl::init("-")); | 92 cl::init("-")); |
89 static cl::opt<std::string> OutputFilename("o", | 93 static cl::opt<std::string> OutputFilename("o", |
90 cl::desc("Override output filename"), | 94 cl::desc("Override output filename"), |
91 cl::init("-"), | 95 cl::init("-"), |
92 cl::value_desc("filename")); | 96 cl::value_desc("filename")); |
93 static cl::opt<std::string> LogFilename("log", cl::desc("Set log filename"), | 97 static cl::opt<std::string> LogFilename("log", cl::desc("Set log filename"), |
94 cl::init("-"), | 98 cl::init("-"), |
95 cl::value_desc("filename")); | 99 cl::value_desc("filename")); |
96 static cl::opt<std::string> | 100 static cl::opt<std::string> |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 {"llvm_cl", ALLOW_LLVM_CL}, | 235 {"llvm_cl", ALLOW_LLVM_CL}, |
232 {"llvm_ir", ALLOW_LLVM_IR}, | 236 {"llvm_ir", ALLOW_LLVM_IR}, |
233 {"llvm_ir_as_input", ALLOW_LLVM_IR_AS_INPUT}, | 237 {"llvm_ir_as_input", ALLOW_LLVM_IR_AS_INPUT}, |
234 {"minimal_build", ALLOW_MINIMAL_BUILD}}; | 238 {"minimal_build", ALLOW_MINIMAL_BUILD}}; |
235 | 239 |
236 // Validates values of build attributes. Prints them to Stream if | 240 // Validates values of build attributes. Prints them to Stream if |
237 // Stream is non-null. | 241 // Stream is non-null. |
238 static void ValidateAndGenerateBuildAttributes(Ice::Ostream *Stream) { | 242 static void ValidateAndGenerateBuildAttributes(Ice::Ostream *Stream) { |
239 | 243 |
240 if (Stream) | 244 if (Stream) |
241 *Stream << TargetArch << "\n"; | 245 *Stream << TArch << "\n"; |
242 | 246 |
243 for (size_t i = 0; i < array_lengthof(ConditionalBuildAttributes); ++i) { | 247 for (size_t i = 0; i < array_lengthof(ConditionalBuildAttributes); ++i) { |
244 switch (ConditionalBuildAttributes[i].FlagValue) { | 248 switch (ConditionalBuildAttributes[i].FlagValue) { |
245 case 0: | 249 case 0: |
246 if (Stream) | 250 if (Stream) |
247 *Stream << "no_" << ConditionalBuildAttributes[i].FlagName << "\n"; | 251 *Stream << "no_" << ConditionalBuildAttributes[i].FlagName << "\n"; |
248 break; | 252 break; |
249 case 1: | 253 case 1: |
250 if (Stream) | 254 if (Stream) |
251 *Stream << "allow_" << ConditionalBuildAttributes[i].FlagName << "\n"; | 255 *Stream << "allow_" << ConditionalBuildAttributes[i].FlagName << "\n"; |
252 break; | 256 break; |
253 default: { | 257 default: { |
254 std::string Buffer; | 258 std::string Buffer; |
255 raw_string_ostream StrBuf(Buffer); | 259 raw_string_ostream StrBuf(Buffer); |
256 StrBuf << "Flag " << ConditionalBuildAttributes[i].FlagName | 260 StrBuf << "Flag " << ConditionalBuildAttributes[i].FlagName |
257 << " must be defined as 0/1. Found: " | 261 << " must be defined as 0/1. Found: " |
258 << ConditionalBuildAttributes[i].FlagValue; | 262 << ConditionalBuildAttributes[i].FlagValue; |
259 report_fatal_error(StrBuf.str()); | 263 report_fatal_error(StrBuf.str()); |
260 } | 264 } |
261 } | 265 } |
262 } | 266 } |
263 } | 267 } |
264 | 268 |
265 int main(int argc, char **argv) { | 269 void Ice::Compiler::run(int argc, char **argv, Ice::CompileServer &Server) { |
266 | 270 |
267 cl::ParseCommandLineOptions(argc, argv); | 271 cl::ParseCommandLineOptions(argc, argv); |
268 | 272 |
269 if (DisableIRGeneration) | 273 if (DisableIRGeneration) |
270 DisableTranslation = true; | 274 DisableTranslation = true; |
271 | 275 |
272 Ice::VerboseMask VMask = Ice::IceV_None; | 276 Ice::VerboseMask VMask = Ice::IceV_None; |
273 // Don't generate verbose messages if routines | 277 // Don't generate verbose messages if routines |
274 // to dump messages are not available. | 278 // to dump messages are not available. |
275 if (ALLOW_DUMP) { | 279 if (ALLOW_DUMP) { |
276 for (unsigned i = 0; i != VerboseList.size(); ++i) | 280 for (unsigned i = 0; i != VerboseList.size(); ++i) |
277 VMask |= VerboseList[i]; | 281 VMask |= VerboseList[i]; |
278 } | 282 } |
279 | 283 |
280 std::ofstream Lfs; | 284 std::ofstream Lfs; |
281 std::unique_ptr<Ice::Ostream> Ls; | 285 std::unique_ptr<Ice::Ostream> Ls; |
282 if (LogFilename != "-") { | 286 if (LogFilename != "-") { |
283 Lfs.open(LogFilename.c_str(), std::ofstream::out); | 287 Lfs.open(LogFilename.c_str(), std::ofstream::out); |
284 Ls.reset(new raw_os_ostream(Lfs)); | 288 Ls.reset(new raw_os_ostream(Lfs)); |
285 } else { | 289 } else { |
286 Ls.reset(new raw_os_ostream(std::cout)); | 290 Ls.reset(new raw_os_ostream(std::cout)); |
287 } | 291 } |
288 Ls->SetUnbuffered(); | 292 Ls->SetUnbuffered(); |
289 | 293 |
290 ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Ls.get() : nullptr); | 294 ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Ls.get() : nullptr); |
291 if (GenerateBuildAtts) | 295 if (GenerateBuildAtts) |
292 return GetReturnValue(Ice::EC_None); | 296 return setReturnValue(GetReturnValue(Ice::EC_None)); |
293 | 297 |
294 if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) { | 298 if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) { |
295 *Ls << "Error: Build doesn't allow --no-ir-gen when not " | 299 *Ls << "Error: Build doesn't allow --no-ir-gen when not " |
296 << "ALLOW_DISABLE_IR_GEN!\n"; | 300 << "ALLOW_DISABLE_IR_GEN!\n"; |
297 return GetReturnValue(Ice::EC_Args); | 301 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
298 } | 302 } |
299 | 303 |
300 Ice::ClFlags Flags; | 304 Ice::ClFlags Flags; |
301 Flags.setAllowErrorRecovery(AllowErrorRecovery); | 305 Flags.setAllowErrorRecovery(AllowErrorRecovery); |
302 Flags.setAllowUninitializedGlobals(AllowUninitializedGlobals); | 306 Flags.setAllowUninitializedGlobals(AllowUninitializedGlobals); |
303 Flags.setDataSections(DataSections); | 307 Flags.setDataSections(DataSections); |
304 Flags.setDecorateAsm(DecorateAsm); | 308 Flags.setDecorateAsm(DecorateAsm); |
305 Flags.setDefaultFunctionPrefix(DefaultFunctionPrefix); | 309 Flags.setDefaultFunctionPrefix(DefaultFunctionPrefix); |
306 Flags.setDefaultGlobalPrefix(DefaultGlobalPrefix); | 310 Flags.setDefaultGlobalPrefix(DefaultGlobalPrefix); |
307 Flags.setDisableInternal(DisableInternal); | 311 Flags.setDisableInternal(DisableInternal); |
308 Flags.setDisableIRGeneration(DisableIRGeneration); | 312 Flags.setDisableIRGeneration(DisableIRGeneration); |
309 Flags.setDisableTranslation(DisableTranslation); | 313 Flags.setDisableTranslation(DisableTranslation); |
310 Flags.setDumpStats(DumpStats); | 314 Flags.setDumpStats(DumpStats); |
311 Flags.setFunctionSections(FunctionSections); | 315 Flags.setFunctionSections(FunctionSections); |
312 Flags.setNumTranslationThreads(NumThreads); | 316 Flags.setNumTranslationThreads(NumThreads); |
313 Flags.setPhiEdgeSplit(EnablePhiEdgeSplit); | 317 Flags.setPhiEdgeSplit(EnablePhiEdgeSplit); |
314 Flags.setStubConstantCalls(StubConstantCalls); | 318 Flags.setStubConstantCalls(StubConstantCalls); |
315 Flags.setSubzeroTimingEnabled(SubzeroTimingEnabled); | 319 Flags.setSubzeroTimingEnabled(SubzeroTimingEnabled); |
316 Flags.setTimeEachFunction(TimeEachFunction); | 320 Flags.setTimeEachFunction(TimeEachFunction); |
317 Flags.setTimingFocusOn(TimingFocusOn); | 321 Flags.setTimingFocusOn(TimingFocusOn); |
318 Flags.setTranslateOnly(TranslateOnly); | 322 Flags.setTranslateOnly(TranslateOnly); |
319 Flags.setUseSandboxing(UseSandboxing); | 323 Flags.setUseSandboxing(UseSandboxing); |
320 Flags.setVerboseFocusOn(VerboseFocusOn); | 324 Flags.setVerboseFocusOn(VerboseFocusOn); |
321 Flags.setOutFileType(OutFileType); | 325 Flags.setOutFileType(OutFileType); |
322 | 326 |
323 // Force -build-on-read=0 for .ll files. | 327 // Force -build-on-read=0 for .ll files. |
324 const std::string LLSuffix = ".ll"; | 328 const std::string LLSuffix = ".ll"; |
325 if (IRFilename.length() >= LLSuffix.length() && | 329 if (ALLOW_LLVM_IR_AS_INPUT && IRFilename.length() >= LLSuffix.length() && |
326 IRFilename.compare(IRFilename.length() - LLSuffix.length(), | 330 IRFilename.compare(IRFilename.length() - LLSuffix.length(), |
327 LLSuffix.length(), LLSuffix) == 0) | 331 LLSuffix.length(), LLSuffix) == 0) |
328 BuildOnRead = false; | 332 BuildOnRead = false; |
329 | 333 |
330 // With the ELF writer, use a raw_fd_ostream to allow seeking. | |
331 // Also don't buffer, otherwise it gets pretty slow. | |
332 std::unique_ptr<Ice::Ostream> Os; | 334 std::unique_ptr<Ice::Ostream> Os; |
333 std::unique_ptr<Ice::ELFStreamer> ELFStr; | 335 std::unique_ptr<Ice::ELFStreamer> ELFStr; |
334 std::ofstream Ofs; | |
335 switch (OutFileType) { | 336 switch (OutFileType) { |
336 case Ice::FT_Elf: { | 337 case Ice::FT_Elf: { |
337 if (OutputFilename == "-") { | 338 if (OutputFilename == "-") { |
338 *Ls << "Error: writing binary ELF to stdout is unsupported\n"; | 339 *Ls << "Error: writing binary ELF to stdout is unsupported\n"; |
339 return GetReturnValue(Ice::EC_Args); | 340 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
340 } | 341 } |
341 std::error_code EC; | 342 std::error_code EC; |
342 raw_fd_ostream *FdOs = | 343 std::unique_ptr<llvm::raw_fd_ostream> FdOs = |
343 new raw_fd_ostream(OutputFilename, EC, sys::fs::F_None); | 344 Server.getOutputStream(OutputFilename, EC); |
344 // NaCl sets st_blksize to 0, and LLVM uses that to pick the | |
345 // default preferred buffer size. Set to something non-zero. | |
346 FdOs->SetBufferSize(1 << 14); | |
347 Os.reset(FdOs); | |
348 if (EC) { | 345 if (EC) { |
349 *Ls << "Failed to open output file: " << OutputFilename << ":\n" | 346 *Ls << "Failed to open output file: " << OutputFilename << ":\n" |
350 << EC.message() << "\n"; | 347 << EC.message() << "\n"; |
351 return GetReturnValue(Ice::EC_Args); | 348 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
352 } | 349 } |
353 ELFStr.reset(new Ice::ELFStreamer(*FdOs)); | 350 ELFStr.reset(new Ice::ELFStreamer(*FdOs.get())); |
| 351 Os.reset(FdOs.release()); |
| 352 // NaCl sets st_blksize to 0, and LLVM uses that to pick the |
| 353 // default preferred buffer size. Set to something non-zero. |
| 354 Os->SetBufferSize(1 << 14); |
354 } break; | 355 } break; |
355 case Ice::FT_Asm: | 356 case Ice::FT_Asm: |
356 case Ice::FT_Iasm: { | 357 case Ice::FT_Iasm: { |
| 358 if (PNACL_BROWSER_TRANSLATOR) { |
| 359 *Ls << "Asm/Iasm is not supported under PNACL_BROWSER_TRANSLATOR\n"; |
| 360 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
| 361 } |
| 362 // Use raw_os_ostream instead of raw_fd_ostream. If both the |
| 363 // LogFilename and OutputFilename are stdout, then having |
| 364 // Os be a raw_fd_ostream while Ls is a raw_os_ostream backed by |
| 365 // a std::ofstream will confuse the buffering and have odd |
| 366 // interleavings (even with explicit flushes, for some reason). |
| 367 // So, make sure both are the same type of stream. In this case, |
| 368 // choose ofstream + raw_os_ostream for both. |
| 369 // This avoids asking the compiler server for the output file, |
| 370 // which won't work in the PNACL_BROWSER_TRANSLATOR case. |
| 371 // An alternative is to choose raw_fd_ostream for both, but then |
| 372 // you have to explicitly tell raw_fd_ostream not to own the |
| 373 // fd since it is shared by the two streams (you'll get a double-close). |
| 374 std::ofstream Ofs; |
357 if (OutputFilename != "-") { | 375 if (OutputFilename != "-") { |
358 Ofs.open(OutputFilename.c_str(), std::ofstream::out); | 376 Ofs.open(OutputFilename.c_str(), std::ofstream::out); |
359 Os.reset(new raw_os_ostream(Ofs)); | 377 Os.reset(new raw_os_ostream(Ofs)); |
360 } else { | 378 } else { |
361 Os.reset(new raw_os_ostream(std::cout)); | 379 Os.reset(new raw_os_ostream(std::cout)); |
362 } | 380 } |
363 Os->SetUnbuffered(); | 381 Os->SetUnbuffered(); |
364 } break; | 382 } break; |
365 } | 383 } |
366 | 384 |
367 Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TargetArch, | 385 Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TArch, OLevel, |
368 OptLevel, TestPrefix, Flags); | 386 TestPrefix, Flags); |
369 | 387 |
370 Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); | 388 Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); |
371 | 389 |
372 if (OutFileType == Ice::FT_Elf) { | 390 if (OutFileType == Ice::FT_Elf) { |
373 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); | 391 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); |
374 Ctx.getObjectWriter()->writeInitialELFHeader(); | 392 Ctx.getObjectWriter()->writeInitialELFHeader(); |
375 } | 393 } |
376 | 394 |
377 Ctx.startWorkerThreads(); | 395 Ctx.startWorkerThreads(); |
378 | 396 |
379 std::unique_ptr<Ice::Translator> Translator; | 397 std::unique_ptr<Ice::Translator> Translator; |
380 if (BuildOnRead) { | 398 if (BuildOnRead) { |
381 std::unique_ptr<Ice::PNaClTranslator> PTranslator( | 399 std::unique_ptr<Ice::PNaClTranslator> PTranslator( |
382 new Ice::PNaClTranslator(&Ctx)); | 400 new Ice::PNaClTranslator(&Ctx)); |
383 std::string StrError; | 401 std::string StrError; |
384 std::unique_ptr<DataStreamer> FileStreamer( | 402 std::unique_ptr<DataStreamer> FileStreamer = |
385 getDataFileStreamer(IRFilename, &StrError)); | 403 Server.getInputStream(IRFilename, StrError); |
386 if (!StrError.empty() || !FileStreamer) { | 404 if (!StrError.empty() || !FileStreamer) { |
387 SMDiagnostic Err(IRFilename, SourceMgr::DK_Error, StrError); | 405 SMDiagnostic Err(IRFilename, SourceMgr::DK_Error, StrError); |
388 Err.print(argv[0], errs()); | 406 Err.print(argv[0], errs()); |
389 return GetReturnValue(Ice::EC_Bitcode); | 407 return setReturnValue(GetReturnValue(Ice::EC_Bitcode)); |
390 } | 408 } |
391 std::unique_ptr<StreamingMemoryObject> MemObj( | 409 std::unique_ptr<StreamingMemoryObject> MemObj( |
392 new StreamingMemoryObjectImpl(FileStreamer.release())); | 410 new StreamingMemoryObjectImpl(FileStreamer.release())); |
393 PTranslator->translate(IRFilename, std::move(MemObj)); | 411 PTranslator->translate(IRFilename, std::move(MemObj)); |
394 Translator.reset(PTranslator.release()); | 412 Translator.reset(PTranslator.release()); |
395 } else if (ALLOW_LLVM_IR) { | 413 } else if (ALLOW_LLVM_IR) { |
| 414 if (PNACL_BROWSER_TRANSLATOR) { |
| 415 *Ls << "non BuildOnRead is not supported w/ PNACL_BROWSER_TRANSLATOR\n"; |
| 416 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
| 417 } |
396 // Parse the input LLVM IR file into a module. | 418 // Parse the input LLVM IR file into a module. |
397 SMDiagnostic Err; | 419 SMDiagnostic Err; |
398 Ice::TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); | 420 Ice::TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); |
399 raw_ostream *Verbose = LLVMVerboseErrors ? &errs() : nullptr; | 421 raw_ostream *Verbose = LLVMVerboseErrors ? &errs() : nullptr; |
400 std::unique_ptr<Module> Mod = NaClParseIRFile( | 422 std::unique_ptr<Module> Mod = NaClParseIRFile( |
401 IRFilename, InputFileFormat, Err, Verbose, getGlobalContext()); | 423 IRFilename, InputFileFormat, Err, Verbose, getGlobalContext()); |
402 if (!Mod) { | 424 if (!Mod) { |
403 Err.print(argv[0], errs()); | 425 Err.print(argv[0], errs()); |
404 return GetReturnValue(Ice::EC_Bitcode); | 426 return setReturnValue(GetReturnValue(Ice::EC_Bitcode)); |
405 } | 427 } |
406 | 428 |
407 std::unique_ptr<Ice::Converter> Converter( | 429 std::unique_ptr<Ice::Converter> Converter( |
408 new Ice::Converter(Mod.get(), &Ctx)); | 430 new Ice::Converter(Mod.get(), &Ctx)); |
409 Converter->convertToIce(); | 431 Converter->convertToIce(); |
410 Translator.reset(Converter.release()); | 432 Translator.reset(Converter.release()); |
411 } else { | 433 } else { |
412 *Ls << "Error: Build doesn't allow LLVM IR, " | 434 *Ls << "Error: Build doesn't allow LLVM IR, " |
413 << "--build-on-read=0 not allowed\n"; | 435 << "--build-on-read=0 not allowed\n"; |
414 return GetReturnValue(Ice::EC_Args); | 436 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
415 } | 437 } |
416 | 438 |
417 Ctx.waitForWorkerThreads(); | 439 Ctx.waitForWorkerThreads(); |
418 Translator->transferErrorCode(); | 440 Translator->transferErrorCode(); |
419 Translator->emitConstants(); | 441 Translator->emitConstants(); |
420 | 442 |
421 if (OutFileType == Ice::FT_Elf) { | 443 if (OutFileType == Ice::FT_Elf) { |
422 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); | 444 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); |
423 Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms()); | 445 Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms()); |
424 Ctx.getObjectWriter()->writeNonUserSections(); | 446 Ctx.getObjectWriter()->writeNonUserSections(); |
425 } | 447 } |
426 if (SubzeroTimingEnabled) | 448 if (SubzeroTimingEnabled) |
427 Ctx.dumpTimers(); | 449 Ctx.dumpTimers(); |
428 if (TimeEachFunction) { | 450 if (TimeEachFunction) { |
429 const bool DumpCumulative = false; | 451 const bool DumpCumulative = false; |
430 Ctx.dumpTimers(Ice::GlobalContext::TSK_Funcs, DumpCumulative); | 452 Ctx.dumpTimers(Ice::GlobalContext::TSK_Funcs, DumpCumulative); |
431 } | 453 } |
432 const bool FinalStats = true; | 454 const bool FinalStats = true; |
433 Ctx.dumpStats("_FINAL_", FinalStats); | 455 Ctx.dumpStats("_FINAL_", FinalStats); |
434 return GetReturnValue(Ctx.getErrorStatus()->value()); | 456 return setReturnValue(GetReturnValue(Ctx.getErrorStatus()->value())); |
435 } | 457 } |
OLD | NEW |