OLD | NEW |
---|---|
1 //===-- pnacl-llc.cpp - PNaCl-specific llc: pexe ---> nexe ---------------===// | 1 //===-- pnacl-llc.cpp - PNaCl-specific llc: pexe ---> nexe ---------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
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 // pnacl-llc: the core of the PNaCl translator, compiling a pexe into a nexe. | 10 // pnacl-llc: the core of the PNaCl translator, compiling a pexe into a nexe. |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 #include "llvm/ADT/Triple.h" | 14 #include "llvm/ADT/Triple.h" |
15 #include "llvm/Analysis/NaCl.h" | 15 #include "llvm/Analysis/NaCl.h" |
16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" | 16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
17 #include "llvm/Bitcode/ReaderWriter.h" | 17 #include "llvm/Bitcode/ReaderWriter.h" |
18 #include "llvm/CodeGen/CommandFlags.h" | 18 #include "llvm/CodeGen/CommandFlags.h" |
19 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" | |
20 #include "llvm/CodeGen/LinkAllCodegenComponents.h" | 19 #include "llvm/CodeGen/LinkAllCodegenComponents.h" |
21 #include "llvm/IR/DataLayout.h" | 20 #include "llvm/IR/DataLayout.h" |
22 #include "llvm/IR/LLVMContext.h" | 21 #include "llvm/IR/LLVMContext.h" |
23 #include "llvm/IR/Module.h" | 22 #include "llvm/IR/Module.h" |
24 #include "llvm/IR/Verifier.h" | 23 #include "llvm/IR/Verifier.h" |
25 #include "llvm/IRReader/IRReader.h" | 24 #include "llvm/IRReader/IRReader.h" |
26 #include "llvm/MC/SubtargetFeature.h" | 25 #include "llvm/MC/SubtargetFeature.h" |
27 #include "llvm/Pass.h" | 26 #include "llvm/Pass.h" |
28 #include "llvm/PassManager.h" | 27 #include "llvm/PassManager.h" |
29 #include "llvm/Support/CommandLine.h" | 28 #include "llvm/Support/CommandLine.h" |
30 #include "llvm/Support/DataStream.h" | 29 #include "llvm/Support/DataStream.h" |
31 #include "llvm/Support/Debug.h" | 30 #include "llvm/Support/Debug.h" |
32 #include "llvm/Support/ErrorHandling.h" | 31 #include "llvm/Support/ErrorHandling.h" |
33 #include "llvm/Support/FileSystem.h" | 32 #include "llvm/Support/FileSystem.h" |
34 #include "llvm/Support/FormattedStream.h" | 33 #include "llvm/Support/FormattedStream.h" |
35 #include "llvm/Support/Host.h" | 34 #include "llvm/Support/Host.h" |
36 #include "llvm/Support/ManagedStatic.h" | 35 #include "llvm/Support/ManagedStatic.h" |
37 #include "llvm/Support/Mutex.h" | |
38 #include "llvm/Support/PrettyStackTrace.h" | 36 #include "llvm/Support/PrettyStackTrace.h" |
39 #include "llvm/Support/Signals.h" | 37 #include "llvm/Support/Signals.h" |
40 #include "llvm/Support/SourceMgr.h" | 38 #include "llvm/Support/SourceMgr.h" |
41 #include "llvm/Support/StreamableMemoryObject.h" | 39 #include "llvm/Support/StreamingMemoryObject.h" |
42 #include "llvm/Support/TargetRegistry.h" | 40 #include "llvm/Support/TargetRegistry.h" |
43 #include "llvm/Support/TargetSelect.h" | 41 #include "llvm/Support/TargetSelect.h" |
44 #include "llvm/Support/ToolOutputFile.h" | 42 #include "llvm/Support/ToolOutputFile.h" |
45 #include "llvm/Target/TargetLibraryInfo.h" | 43 #include "llvm/Target/TargetLibraryInfo.h" |
46 #include "llvm/Target/TargetMachine.h" | 44 #include "llvm/Target/TargetMachine.h" |
45 #include "llvm/Target/TargetSubtargetInfo.h" | |
47 #include "llvm/Transforms/NaCl.h" | 46 #include "llvm/Transforms/NaCl.h" |
48 | 47 |
49 #include "ThreadedFunctionQueue.h" | 48 #include "ThreadedFunctionQueue.h" |
50 #include "ThreadedStreamingCache.h" | 49 #include "ThreadedStreamingCache.h" |
51 | 50 |
52 #include <pthread.h> | 51 #include <pthread.h> |
53 #include <memory> | 52 #include <memory> |
54 | 53 |
55 using namespace llvm; | 54 using namespace llvm; |
56 | 55 |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 switch (FileType) { | 218 switch (FileType) { |
220 case TargetMachine::CGFT_AssemblyFile: | 219 case TargetMachine::CGFT_AssemblyFile: |
221 break; | 220 break; |
222 case TargetMachine::CGFT_ObjectFile: | 221 case TargetMachine::CGFT_ObjectFile: |
223 case TargetMachine::CGFT_Null: | 222 case TargetMachine::CGFT_Null: |
224 Binary = true; | 223 Binary = true; |
225 break; | 224 break; |
226 } | 225 } |
227 | 226 |
228 // Open the file. | 227 // Open the file. |
229 std::string error; | 228 std::error_code EC; |
230 sys::fs::OpenFlags OpenFlags = sys::fs::F_None; | 229 sys::fs::OpenFlags OpenFlags = sys::fs::F_None; |
231 if (!Binary) | 230 if (!Binary) |
232 OpenFlags |= sys::fs::F_Text; | 231 OpenFlags |= sys::fs::F_Text; |
233 tool_output_file *FDOut = | 232 tool_output_file *FDOut = new tool_output_file(Filename, EC, OpenFlags); |
234 new tool_output_file(Filename.c_str(), error, OpenFlags); | 233 if (EC) { |
235 if (!error.empty()) { | 234 errs() << EC.message() << '\n'; |
236 errs() << error << '\n'; | |
237 delete FDOut; | 235 delete FDOut; |
238 return nullptr; | 236 return nullptr; |
239 } | 237 } |
240 | 238 |
241 return FDOut; | 239 return FDOut; |
242 } | 240 } |
243 #endif // !defined(PNACL_BROWSER_TRANSLATOR) | 241 #endif // !defined(PNACL_BROWSER_TRANSLATOR) |
244 | 242 |
245 // main - Entry point for the llc compiler. | 243 // main - Entry point for the llc compiler. |
246 // | 244 // |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 os << Name << " is not valid PNaCl bitcode:\n"; | 310 os << Name << " is not valid PNaCl bitcode:\n"; |
313 Reporter.printErrors(os); | 311 Reporter.printErrors(os); |
314 if (PNaClABIVerifyFatalErrors) { | 312 if (PNaClABIVerifyFatalErrors) { |
315 report_fatal_error(os.str()); | 313 report_fatal_error(os.str()); |
316 } | 314 } |
317 errs() << os.str(); | 315 errs() << os.str(); |
318 } | 316 } |
319 Reporter.reset(); | 317 Reporter.reset(); |
320 } | 318 } |
321 | 319 |
322 static Module* getModule(StringRef ProgramName, LLVMContext &Context, | 320 static Module* getModule(StringRef ProgramName, LLVMContext &Context, |
JF
2015/02/24 05:35:37
This could now be a unique_ptr. One of the two use
jvoung (off chromium)
2015/02/24 18:38:48
Converted the function to return a unique_ptr.
Th
JF
2015/02/24 19:32:55
sgtm
| |
323 StreamingMemoryObject *StreamingObject) { | 321 StreamingMemoryObject *StreamingObject) { |
324 Module *M = nullptr; | 322 std::unique_ptr<Module> M; |
325 SMDiagnostic Err; | 323 SMDiagnostic Err; |
326 std::string VerboseBuffer; | 324 std::string VerboseBuffer; |
327 raw_string_ostream VerboseStrm(VerboseBuffer); | 325 raw_string_ostream VerboseStrm(VerboseBuffer); |
328 if (LazyBitcode) { | 326 if (LazyBitcode) { |
329 std::string StrError; | 327 std::string StrError; |
330 switch (InputFileFormat) { | 328 switch (InputFileFormat) { |
331 case PNaClFormat: | 329 case PNaClFormat: |
332 M = getNaClStreamedBitcodeModule( | 330 M.reset(getNaClStreamedBitcodeModule( |
333 InputFilename, | 331 InputFilename, |
334 new ThreadedStreamingCache(StreamingObject), Context, &VerboseStrm, | 332 new ThreadedStreamingCache(StreamingObject), Context, &VerboseStrm, |
335 &StrError); | 333 &StrError)); |
336 break; | 334 break; |
337 case LLVMFormat: | 335 case LLVMFormat: |
338 M = getStreamedBitcodeModule( | 336 M.reset(getStreamedBitcodeModule( |
339 InputFilename, | 337 InputFilename, |
340 new ThreadedStreamingCache(StreamingObject), Context, &StrError); | 338 new ThreadedStreamingCache(StreamingObject), Context, &StrError)); |
341 break; | 339 break; |
342 case AutodetectFileFormat: | 340 case AutodetectFileFormat: |
343 report_fatal_error("Command can't autodetect file format!"); | 341 report_fatal_error("Command can't autodetect file format!"); |
344 } | 342 } |
345 if (!StrError.empty()) | 343 if (!StrError.empty()) |
346 Err = SMDiagnostic(InputFilename, SourceMgr::DK_Error, StrError); | 344 Err = SMDiagnostic(InputFilename, SourceMgr::DK_Error, StrError); |
347 } else { | 345 } else { |
348 #if defined(PNACL_BROWSER_TRANSLATOR) | 346 #if defined(PNACL_BROWSER_TRANSLATOR) |
349 llvm_unreachable("native client SRPC only supports streaming"); | 347 llvm_unreachable("native client SRPC only supports streaming"); |
350 #else | 348 #else |
351 // Parses binary bitcode as well as textual assembly | 349 // Parses binary bitcode as well as textual assembly |
352 // (so pulls in more code into pnacl-llc). | 350 // (so pulls in more code into pnacl-llc). |
353 M = NaClParseIRFile(InputFilename, InputFileFormat, Err, &VerboseStrm, | 351 M = NaClParseIRFile(InputFilename, InputFileFormat, Err, &VerboseStrm, |
354 Context); | 352 Context); |
355 #endif | 353 #endif |
356 } | 354 } |
357 if (!M) { | 355 if (!M) { |
358 #if defined(PNACL_BROWSER_TRANSLATOR) | 356 #if defined(PNACL_BROWSER_TRANSLATOR) |
359 report_fatal_error(VerboseStrm.str() + Err.getMessage()); | 357 report_fatal_error(VerboseStrm.str() + Err.getMessage()); |
360 #else | 358 #else |
361 // Err.print is prettier, so use it for the non-sandboxed translator. | 359 // Err.print is prettier, so use it for the non-sandboxed translator. |
362 Err.print(ProgramName.data(), errs()); | 360 Err.print(ProgramName.data(), errs()); |
363 errs() << VerboseStrm.str(); | 361 errs() << VerboseStrm.str(); |
364 return nullptr; | 362 return nullptr; |
365 #endif | 363 #endif |
366 } | 364 } |
367 return M; | 365 return M.release(); |
368 } | 366 } |
369 | 367 |
370 static cl::opt<bool> | 368 static cl::opt<bool> |
371 ExternalizeAll("externalize", | 369 ExternalizeAll("externalize", |
372 cl::desc("Externalize all symbols"), | 370 cl::desc("Externalize all symbols"), |
373 cl::init(false)); | 371 cl::init(false)); |
374 | 372 |
375 static int runCompilePasses(Module *mod, | 373 static int runCompilePasses(Module *mod, |
376 unsigned ModuleIndex, | 374 unsigned ModuleIndex, |
377 ThreadedFunctionQueue *FuncQueue, | 375 ThreadedFunctionQueue *FuncQueue, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 } | 427 } |
430 | 428 |
431 // Build up all of the passes that we want to do to the module. | 429 // Build up all of the passes that we want to do to the module. |
432 std::unique_ptr<PassManagerBase> PM; | 430 std::unique_ptr<PassManagerBase> PM; |
433 if (LazyBitcode) | 431 if (LazyBitcode) |
434 PM.reset(new FunctionPassManager(mod)); | 432 PM.reset(new FunctionPassManager(mod)); |
435 else | 433 else |
436 PM.reset(new PassManager()); | 434 PM.reset(new PassManager()); |
437 | 435 |
438 // Add the target data from the target machine, if it exists, or the module. | 436 // Add the target data from the target machine, if it exists, or the module. |
439 if (const DataLayout *DL = Target.getDataLayout()) | 437 if (const DataLayout *DL = Target.getSubtargetImpl()->getDataLayout()) |
440 mod->setDataLayout(DL); | 438 mod->setDataLayout(DL); |
441 PM->add(new DataLayoutPass(mod)); | 439 PM->add(new DataLayoutPass()); |
442 | 440 |
443 // For conformance with llc, we let the user disable LLVM IR verification with | 441 // For conformance with llc, we let the user disable LLVM IR verification with |
444 // -disable-verify. Unlike llc, when LLVM IR verification is enabled we only | 442 // -disable-verify. Unlike llc, when LLVM IR verification is enabled we only |
445 // run it once, before PNaCl ABI verification. | 443 // run it once, before PNaCl ABI verification. |
446 if (!NoVerify) | 444 if (!NoVerify) |
447 PM->add(createVerifierPass()); | 445 PM->add(createVerifierPass()); |
448 | 446 |
449 // Add the ABI verifier pass before the analysis and code emission passes. | 447 // Add the ABI verifier pass before the analysis and code emission passes. |
450 if (PNaClABIVerify) | 448 if (PNaClABIVerify) |
451 PM->add(createPNaClABIVerifyFunctionsPass(&ABIErrorReporter)); | 449 PM->add(createPNaClABIVerifyFunctionsPass(&ABIErrorReporter)); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
585 std::string N(OutputFilename); | 583 std::string N(OutputFilename); |
586 raw_string_ostream OutFileName(N); | 584 raw_string_ostream OutFileName(N); |
587 if (ModuleIndex > 0) | 585 if (ModuleIndex > 0) |
588 OutFileName << ".module" << ModuleIndex; | 586 OutFileName << ".module" << ModuleIndex; |
589 std::unique_ptr<tool_output_file> Out | 587 std::unique_ptr<tool_output_file> Out |
590 (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), | 588 (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), |
591 OutFileName.str())); | 589 OutFileName.str())); |
592 if (!Out) return 1; | 590 if (!Out) return 1; |
593 formatted_raw_ostream FOS(Out->os()); | 591 formatted_raw_ostream FOS(Out->os()); |
594 #else | 592 #else |
595 raw_fd_ostream ROS(getObjectFileFD(ModuleIndex), true, sys::fs::F_None); | 593 raw_fd_ostream ROS(getObjectFileFD(ModuleIndex), /* ShouldClose */ true); |
596 ROS.SetBufferSize(1 << 20); | 594 ROS.SetBufferSize(1 << 20); |
597 formatted_raw_ostream FOS(ROS); | 595 formatted_raw_ostream FOS(ROS); |
598 #endif | 596 #endif |
599 int ret = runCompilePasses(mod, ModuleIndex, FuncQueue, | 597 int ret = runCompilePasses(mod, ModuleIndex, FuncQueue, |
600 TheTriple, Target, ProgramName, | 598 TheTriple, Target, ProgramName, |
601 FOS); | 599 FOS); |
602 if (ret) | 600 if (ret) |
603 return ret; | 601 return ret; |
604 #if defined(PNACL_BROWSER_TRANSLATOR) | 602 #if defined(PNACL_BROWSER_TRANSLATOR) |
605 FOS.flush(); | 603 FOS.flush(); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
775 return 0; | 773 return 0; |
776 } | 774 } |
777 | 775 |
778 int main(int argc, char **argv) { | 776 int main(int argc, char **argv) { |
779 #if defined(PNACL_BROWSER_TRANSLATOR) | 777 #if defined(PNACL_BROWSER_TRANSLATOR) |
780 return srpc_main(argc, argv); | 778 return srpc_main(argc, argv); |
781 #else | 779 #else |
782 return llc_main(argc, argv); | 780 return llc_main(argc, argv); |
783 #endif // PNACL_BROWSER_TRANSLATOR | 781 #endif // PNACL_BROWSER_TRANSLATOR |
784 } | 782 } |
OLD | NEW |