Chromium Code Reviews| Index: src/llvm2ice.cpp |
| diff --git a/src/llvm2ice.cpp b/src/llvm2ice.cpp |
| index bd86c57509c7d854ed5d432ce010dfa27e1165f2..4df78a1383a9626d7993e7eb695f5373ee6eebfe 100644 |
| --- a/src/llvm2ice.cpp |
| +++ b/src/llvm2ice.cpp |
| @@ -203,6 +203,18 @@ GenerateBuildAtts("build-atts", |
| "this executable."), |
| cl::init(false)); |
| +// Number of translation threads (in addition to the parser thread and |
| +// the emitter thread). The special case of 0 means purely |
| +// sequential, i.e. parser, translator, and emitter all within the |
| +// same single thread. (This may need a slight rework if we expand to |
| +// multiple parser or emitter threads.) |
| +static cl::opt<uint32_t> |
| +NumThreads("threads", |
| + cl::desc("Number of translation threads (0 for purely sequential)"), |
| + // TODO(stichnot): Settle on a good default. Consider |
| + // something related to std::thread::hardware_concurrency(). |
| + cl::init(0)); |
| + |
| static int GetReturnValue(int Val) { |
| if (AlwaysExitSuccess) |
| return 0; |
| @@ -288,14 +300,15 @@ int main(int argc, char **argv) { |
| Flags.DisableTranslation = DisableTranslation; |
| Flags.FunctionSections = FunctionSections; |
| Flags.DataSections = DataSections; |
| - Flags.UseIntegratedAssembler = UseIntegratedAssembler; |
| Flags.UseELFWriter = UseELFWriter; |
| + Flags.UseIntegratedAssembler = UseIntegratedAssembler; |
| Flags.UseSandboxing = UseSandboxing; |
| Flags.PhiEdgeSplit = EnablePhiEdgeSplit; |
| Flags.DecorateAsm = DecorateAsm; |
| Flags.DumpStats = DumpStats; |
| Flags.AllowUninitializedGlobals = AllowUninitializedGlobals; |
| Flags.TimeEachFunction = TimeEachFunction; |
| + Flags.NumTranslationThreads = NumThreads; |
| Flags.DefaultGlobalPrefix = DefaultGlobalPrefix; |
| Flags.DefaultFunctionPrefix = DefaultFunctionPrefix; |
| Flags.TimingFocusOn = TimingFocusOn; |
| @@ -351,11 +364,14 @@ int main(int argc, char **argv) { |
| Ctx.getObjectWriter()->writeInitialELFHeader(); |
| } |
| - int ErrorStatus = 0; |
| + Ctx.startWorkerThreads(); |
| + |
| + std::unique_ptr<Ice::Translator> Translator; |
| if (BuildOnRead) { |
| - Ice::PNaClTranslator Translator(&Ctx, Flags); |
| - Translator.translate(IRFilename); |
| - ErrorStatus = Translator.getErrorStatus(); |
| + std::unique_ptr<Ice::PNaClTranslator> PTranslator( |
| + new Ice::PNaClTranslator(&Ctx, Flags)); |
| + PTranslator->translate(IRFilename); |
| + Translator.reset(PTranslator.release()); |
| } else if (ALLOW_LLVM_IR) { |
| // Parse the input LLVM IR file into a module. |
| SMDiagnostic Err; |
| @@ -370,14 +386,24 @@ int main(int argc, char **argv) { |
| return GetReturnValue(1); |
| } |
| - Ice::Converter Converter(Mod, &Ctx, Flags); |
| - Converter.convertToIce(); |
| - ErrorStatus = Converter.getErrorStatus(); |
| + std::unique_ptr<Ice::Converter> Converter( |
| + new Ice::Converter(Mod, &Ctx, Flags)); |
| + Converter->convertToIce(); |
| + Translator.reset(Converter.release()); |
| } else { |
| *Ls << "Error: Build doesn't allow LLVM IR, " |
| << "--build-on-read=0 not allowed\n"; |
| return GetReturnValue(1); |
| } |
| + |
| + Ctx.waitForWorkerThreads(); |
| + Translator->emitConstants(); |
| + // Error status is the combination of the bitcode parser's error |
|
jvoung (off chromium)
2015/01/23 22:56:37
Seems like this could be a bit confusing but "tran
Jim Stichnoth
2015/01/25 07:29:39
Good point. Originally, each function tracked its
|
| + // status and the translation error status. |
| + std::error_code ErrorStatus = Translator->getErrorStatus(); |
| + if (!ErrorStatus) |
| + ErrorStatus = Ctx.getErrorStatus(); |
| + |
| if (UseELFWriter) { |
| Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); |
| Ctx.getObjectWriter()->writeNonUserSections(); |
| @@ -390,5 +416,5 @@ int main(int argc, char **argv) { |
| } |
| const bool FinalStats = true; |
| Ctx.dumpStats("_FINAL_", FinalStats); |
| - return GetReturnValue(ErrorStatus); |
| + return GetReturnValue(ErrorStatus.value()); |
| } |