OLD | NEW |
1 //===- subzero/src/llvm2ice.cpp - Driver for testing ----------------------===// | 1 //===- subzero/src/llvm2ice.cpp - Driver for testing ----------------------===// |
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 that uses LLVM capabilities to parse a | 10 // This file defines a driver that uses LLVM capabilities to parse a |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 static cl::opt<bool> AlwaysExitSuccess( | 196 static cl::opt<bool> AlwaysExitSuccess( |
197 "exit-success", cl::desc("Exit with success status, even if errors found"), | 197 "exit-success", cl::desc("Exit with success status, even if errors found"), |
198 cl::init(false)); | 198 cl::init(false)); |
199 | 199 |
200 static cl::opt<bool> | 200 static cl::opt<bool> |
201 GenerateBuildAtts("build-atts", | 201 GenerateBuildAtts("build-atts", |
202 cl::desc("Generate list of build attributes associated with " | 202 cl::desc("Generate list of build attributes associated with " |
203 "this executable."), | 203 "this executable."), |
204 cl::init(false)); | 204 cl::init(false)); |
205 | 205 |
| 206 // Number of translation threads (in addition to the parser thread and |
| 207 // the emitter thread). The special case of 0 means purely |
| 208 // sequential, i.e. parser, translator, and emitter all within the |
| 209 // same single thread. (This may need a slight rework if we expand to |
| 210 // multiple parser or emitter threads.) |
| 211 static cl::opt<uint32_t> |
| 212 NumThreads("threads", |
| 213 cl::desc("Number of translation threads (0 for purely sequential)"), |
| 214 // TODO(stichnot): Settle on a good default. Consider |
| 215 // something related to std::thread::hardware_concurrency(). |
| 216 cl::init(0)); |
| 217 |
206 static int GetReturnValue(int Val) { | 218 static int GetReturnValue(int Val) { |
207 if (AlwaysExitSuccess) | 219 if (AlwaysExitSuccess) |
208 return 0; | 220 return 0; |
209 return Val; | 221 return Val; |
210 } | 222 } |
211 | 223 |
212 static struct { | 224 static struct { |
213 const char *FlagName; | 225 const char *FlagName; |
214 int FlagValue; | 226 int FlagValue; |
215 } ConditionalBuildAttributes[] = {{"dump", ALLOW_DUMP}, | 227 } ConditionalBuildAttributes[] = {{"dump", ALLOW_DUMP}, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 if (LogFilename != "-") { | 279 if (LogFilename != "-") { |
268 Lfs.open(LogFilename.c_str(), std::ofstream::out); | 280 Lfs.open(LogFilename.c_str(), std::ofstream::out); |
269 Ls.reset(new raw_os_ostream(Lfs)); | 281 Ls.reset(new raw_os_ostream(Lfs)); |
270 } else { | 282 } else { |
271 Ls.reset(new raw_os_ostream(std::cout)); | 283 Ls.reset(new raw_os_ostream(std::cout)); |
272 } | 284 } |
273 Ls->SetUnbuffered(); | 285 Ls->SetUnbuffered(); |
274 | 286 |
275 ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Ls.get() : nullptr); | 287 ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Ls.get() : nullptr); |
276 if (GenerateBuildAtts) | 288 if (GenerateBuildAtts) |
277 return GetReturnValue(0); | 289 return GetReturnValue(Ice::EC_None); |
278 | 290 |
279 if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) { | 291 if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) { |
280 *Ls << "Error: Build doesn't allow --no-ir-gen when not " | 292 *Ls << "Error: Build doesn't allow --no-ir-gen when not " |
281 << "ALLOW_DISABLE_IR_GEN!\n"; | 293 << "ALLOW_DISABLE_IR_GEN!\n"; |
282 return GetReturnValue(1); | 294 return GetReturnValue(Ice::EC_Args); |
283 } | 295 } |
284 | 296 |
285 Ice::ClFlags Flags; | 297 Ice::ClFlags Flags; |
286 Flags.DisableInternal = DisableInternal; | 298 Flags.DisableInternal = DisableInternal; |
287 Flags.SubzeroTimingEnabled = SubzeroTimingEnabled; | 299 Flags.SubzeroTimingEnabled = SubzeroTimingEnabled; |
288 Flags.DisableTranslation = DisableTranslation; | 300 Flags.DisableTranslation = DisableTranslation; |
289 Flags.FunctionSections = FunctionSections; | 301 Flags.FunctionSections = FunctionSections; |
290 Flags.DataSections = DataSections; | 302 Flags.DataSections = DataSections; |
| 303 Flags.UseELFWriter = UseELFWriter; |
291 Flags.UseIntegratedAssembler = UseIntegratedAssembler; | 304 Flags.UseIntegratedAssembler = UseIntegratedAssembler; |
292 Flags.UseELFWriter = UseELFWriter; | |
293 Flags.UseSandboxing = UseSandboxing; | 305 Flags.UseSandboxing = UseSandboxing; |
294 Flags.PhiEdgeSplit = EnablePhiEdgeSplit; | 306 Flags.PhiEdgeSplit = EnablePhiEdgeSplit; |
295 Flags.DecorateAsm = DecorateAsm; | 307 Flags.DecorateAsm = DecorateAsm; |
296 Flags.DumpStats = DumpStats; | 308 Flags.DumpStats = DumpStats; |
297 Flags.AllowUninitializedGlobals = AllowUninitializedGlobals; | 309 Flags.AllowUninitializedGlobals = AllowUninitializedGlobals; |
298 Flags.TimeEachFunction = TimeEachFunction; | 310 Flags.TimeEachFunction = TimeEachFunction; |
| 311 Flags.NumTranslationThreads = NumThreads; |
299 Flags.DefaultGlobalPrefix = DefaultGlobalPrefix; | 312 Flags.DefaultGlobalPrefix = DefaultGlobalPrefix; |
300 Flags.DefaultFunctionPrefix = DefaultFunctionPrefix; | 313 Flags.DefaultFunctionPrefix = DefaultFunctionPrefix; |
301 Flags.TimingFocusOn = TimingFocusOn; | 314 Flags.TimingFocusOn = TimingFocusOn; |
302 Flags.VerboseFocusOn = VerboseFocusOn; | 315 Flags.VerboseFocusOn = VerboseFocusOn; |
303 Flags.TranslateOnly = TranslateOnly; | 316 Flags.TranslateOnly = TranslateOnly; |
304 Flags.DisableIRGeneration = DisableIRGeneration; | 317 Flags.DisableIRGeneration = DisableIRGeneration; |
305 Flags.AllowErrorRecovery = AllowErrorRecovery; | 318 Flags.AllowErrorRecovery = AllowErrorRecovery; |
306 | 319 |
307 // Force -build-on-read=0 for .ll files. | 320 // Force -build-on-read=0 for .ll files. |
308 const std::string LLSuffix = ".ll"; | 321 const std::string LLSuffix = ".ll"; |
309 if (IRFilename.length() >= LLSuffix.length() && | 322 if (IRFilename.length() >= LLSuffix.length() && |
310 IRFilename.compare(IRFilename.length() - LLSuffix.length(), | 323 IRFilename.compare(IRFilename.length() - LLSuffix.length(), |
311 LLSuffix.length(), LLSuffix) == 0) | 324 LLSuffix.length(), LLSuffix) == 0) |
312 BuildOnRead = false; | 325 BuildOnRead = false; |
313 | 326 |
314 // With the ELF writer, use a raw_fd_ostream to allow seeking. | 327 // With the ELF writer, use a raw_fd_ostream to allow seeking. |
315 // Also don't buffer, otherwise it gets pretty slow. | 328 // Also don't buffer, otherwise it gets pretty slow. |
316 std::unique_ptr<Ice::Ostream> Os; | 329 std::unique_ptr<Ice::Ostream> Os; |
317 std::unique_ptr<Ice::ELFStreamer> ELFStr; | 330 std::unique_ptr<Ice::ELFStreamer> ELFStr; |
318 std::ofstream Ofs; | 331 std::ofstream Ofs; |
319 if (UseELFWriter) { | 332 if (UseELFWriter) { |
320 if (OutputFilename == "-") { | 333 if (OutputFilename == "-") { |
321 *Ls << "Error: writing binary ELF to stdout is unsupported\n"; | 334 *Ls << "Error: writing binary ELF to stdout is unsupported\n"; |
322 return GetReturnValue(1); | 335 return GetReturnValue(Ice::EC_Args); |
323 } | 336 } |
324 std::string ErrorInfo; | 337 std::string ErrorInfo; |
325 raw_fd_ostream *FdOs = | 338 raw_fd_ostream *FdOs = |
326 new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, sys::fs::F_None); | 339 new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, sys::fs::F_None); |
327 Os.reset(FdOs); | 340 Os.reset(FdOs); |
328 if (!ErrorInfo.empty()) { | 341 if (!ErrorInfo.empty()) { |
329 *Ls << "Failed to open output file: " << OutputFilename << ":\n" | 342 *Ls << "Failed to open output file: " << OutputFilename << ":\n" |
330 << ErrorInfo << "\n"; | 343 << ErrorInfo << "\n"; |
331 return GetReturnValue(1); | 344 return GetReturnValue(Ice::EC_Args); |
332 } | 345 } |
333 ELFStr.reset(new Ice::ELFStreamer(*FdOs)); | 346 ELFStr.reset(new Ice::ELFStreamer(*FdOs)); |
334 } else { | 347 } else { |
335 if (OutputFilename != "-") { | 348 if (OutputFilename != "-") { |
336 Ofs.open(OutputFilename.c_str(), std::ofstream::out); | 349 Ofs.open(OutputFilename.c_str(), std::ofstream::out); |
337 Os.reset(new raw_os_ostream(Ofs)); | 350 Os.reset(new raw_os_ostream(Ofs)); |
338 } else { | 351 } else { |
339 Os.reset(new raw_os_ostream(std::cout)); | 352 Os.reset(new raw_os_ostream(std::cout)); |
340 } | 353 } |
341 Os->SetUnbuffered(); | 354 Os->SetUnbuffered(); |
342 } | 355 } |
343 | 356 |
344 Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TargetArch, | 357 Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TargetArch, |
345 OptLevel, TestPrefix, Flags); | 358 OptLevel, TestPrefix, Flags); |
346 | 359 |
347 Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); | 360 Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); |
348 | 361 |
349 if (UseELFWriter) { | 362 if (UseELFWriter) { |
350 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); | 363 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); |
351 Ctx.getObjectWriter()->writeInitialELFHeader(); | 364 Ctx.getObjectWriter()->writeInitialELFHeader(); |
352 } | 365 } |
353 | 366 |
354 int ErrorStatus = 0; | 367 Ctx.startWorkerThreads(); |
| 368 |
| 369 std::unique_ptr<Ice::Translator> Translator; |
355 if (BuildOnRead) { | 370 if (BuildOnRead) { |
356 Ice::PNaClTranslator Translator(&Ctx, Flags); | 371 std::unique_ptr<Ice::PNaClTranslator> PTranslator( |
357 Translator.translate(IRFilename); | 372 new Ice::PNaClTranslator(&Ctx, Flags)); |
358 ErrorStatus = Translator.getErrorStatus(); | 373 PTranslator->translate(IRFilename); |
| 374 Translator.reset(PTranslator.release()); |
359 } else if (ALLOW_LLVM_IR) { | 375 } else if (ALLOW_LLVM_IR) { |
360 // Parse the input LLVM IR file into a module. | 376 // Parse the input LLVM IR file into a module. |
361 SMDiagnostic Err; | 377 SMDiagnostic Err; |
362 Ice::TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); | 378 Ice::TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); |
363 raw_ostream *Verbose = LLVMVerboseErrors ? &errs() : nullptr; | 379 raw_ostream *Verbose = LLVMVerboseErrors ? &errs() : nullptr; |
364 Module *Mod = | 380 Module *Mod = |
365 NaClParseIRFile(IRFilename, InputFileFormat, Err, Verbose, | 381 NaClParseIRFile(IRFilename, InputFileFormat, Err, Verbose, |
366 getGlobalContext()); | 382 getGlobalContext()); |
367 | 383 |
368 if (!Mod) { | 384 if (!Mod) { |
369 Err.print(argv[0], errs()); | 385 Err.print(argv[0], errs()); |
370 return GetReturnValue(1); | 386 return GetReturnValue(Ice::EC_Bitcode); |
371 } | 387 } |
372 | 388 |
373 Ice::Converter Converter(Mod, &Ctx, Flags); | 389 std::unique_ptr<Ice::Converter> Converter( |
374 Converter.convertToIce(); | 390 new Ice::Converter(Mod, &Ctx, Flags)); |
375 ErrorStatus = Converter.getErrorStatus(); | 391 Converter->convertToIce(); |
| 392 Translator.reset(Converter.release()); |
376 } else { | 393 } else { |
377 *Ls << "Error: Build doesn't allow LLVM IR, " | 394 *Ls << "Error: Build doesn't allow LLVM IR, " |
378 << "--build-on-read=0 not allowed\n"; | 395 << "--build-on-read=0 not allowed\n"; |
379 return GetReturnValue(1); | 396 return GetReturnValue(Ice::EC_Args); |
380 } | 397 } |
| 398 |
| 399 Ctx.waitForWorkerThreads(); |
| 400 Translator->transferErrorCode(); |
| 401 Translator->emitConstants(); |
| 402 |
381 if (UseELFWriter) { | 403 if (UseELFWriter) { |
382 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); | 404 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); |
383 Ctx.getObjectWriter()->writeNonUserSections(); | 405 Ctx.getObjectWriter()->writeNonUserSections(); |
384 } | 406 } |
385 if (SubzeroTimingEnabled) | 407 if (SubzeroTimingEnabled) |
386 Ctx.dumpTimers(); | 408 Ctx.dumpTimers(); |
387 if (TimeEachFunction) { | 409 if (TimeEachFunction) { |
388 const bool DumpCumulative = false; | 410 const bool DumpCumulative = false; |
389 Ctx.dumpTimers(Ice::GlobalContext::TSK_Funcs, DumpCumulative); | 411 Ctx.dumpTimers(Ice::GlobalContext::TSK_Funcs, DumpCumulative); |
390 } | 412 } |
391 const bool FinalStats = true; | 413 const bool FinalStats = true; |
392 Ctx.dumpStats("_FINAL_", FinalStats); | 414 Ctx.dumpStats("_FINAL_", FinalStats); |
393 return GetReturnValue(ErrorStatus); | 415 return GetReturnValue(Ctx.getErrorStatus()->value()); |
394 } | 416 } |
OLD | NEW |