| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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, |
| 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 |