Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===// | 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 // This is the llc code generator driver. It provides a convenient | 10 // pnacl-llc: the core of the PNaCl translator, compiling a pexe into a nexe. |
| 11 // command-line interface for generating native assembly-language code | |
| 12 // or C code, given LLVM bitcode. | |
| 13 // | 11 // |
| 14 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
| 15 | 13 |
| 16 #include "llvm/IR/LLVMContext.h" | |
| 17 #include "llvm/ADT/Triple.h" | 14 #include "llvm/ADT/Triple.h" |
| 18 #include "llvm/Analysis/NaCl.h" | 15 #include "llvm/Analysis/NaCl.h" |
| 19 #include "llvm/Assembly/PrintModulePass.h" | 16 #include "llvm/Assembly/PrintModulePass.h" |
| 20 #include "llvm/Support/DataStream.h" // @LOCALMOD | 17 #include "llvm/Support/DataStream.h" |
| 21 #include "llvm/CodeGen/CommandFlags.h" | 18 #include "llvm/CodeGen/CommandFlags.h" |
| 22 #include "llvm/CodeGen/IntrinsicLowering.h" // @LOCALMOD | |
| 23 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" | 19 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" |
| 24 #include "llvm/CodeGen/LinkAllCodegenComponents.h" | 20 #include "llvm/CodeGen/LinkAllCodegenComponents.h" |
| 25 #include "llvm/IR/DataLayout.h" | 21 #include "llvm/IR/DataLayout.h" |
| 22 #include "llvm/IR/LLVMContext.h" | |
| 26 #include "llvm/IR/Module.h" | 23 #include "llvm/IR/Module.h" |
| 27 #include "llvm/MC/SubtargetFeature.h" | 24 #include "llvm/MC/SubtargetFeature.h" |
| 28 #include "llvm/Pass.h" | 25 #include "llvm/Pass.h" |
| 29 #include "llvm/PassManager.h" | 26 #include "llvm/PassManager.h" |
| 30 #include "llvm/Support/CommandLine.h" | 27 #include "llvm/Support/CommandLine.h" |
| 31 #include "llvm/Support/Debug.h" | 28 #include "llvm/Support/Debug.h" |
| 32 #include "llvm/Support/FormattedStream.h" | 29 #include "llvm/Support/FormattedStream.h" |
| 33 #include "llvm/Support/Host.h" | 30 #include "llvm/Support/Host.h" |
| 34 #include "llvm/Support/IRReader.h" | 31 #include "llvm/Support/IRReader.h" |
| 35 #include "llvm/Support/ManagedStatic.h" | 32 #include "llvm/Support/ManagedStatic.h" |
| 36 #if !defined(__native_client__) | |
| 37 #include "llvm/Support/PluginLoader.h" | |
| 38 #endif | |
| 39 #include "llvm/Support/PrettyStackTrace.h" | 33 #include "llvm/Support/PrettyStackTrace.h" |
| 40 #include "llvm/Support/Signals.h" | 34 #include "llvm/Support/Signals.h" |
| 41 #include "llvm/Support/TargetRegistry.h" | 35 #include "llvm/Support/TargetRegistry.h" |
| 42 #include "llvm/Support/TargetSelect.h" | 36 #include "llvm/Support/TargetSelect.h" |
| 37 #include "llvm/Support/Timer.h" | |
| 43 #include "llvm/Support/ToolOutputFile.h" | 38 #include "llvm/Support/ToolOutputFile.h" |
| 44 #include "llvm/Target/TargetLibraryInfo.h" | 39 #include "llvm/Target/TargetLibraryInfo.h" |
| 45 #include "llvm/Target/TargetMachine.h" | 40 #include "llvm/Target/TargetMachine.h" |
| 46 #include <memory> | 41 #include <memory> |
| 47 | 42 |
| 48 // @LOCALMOD-BEGIN | |
| 49 #include "llvm/Support/Timer.h" | |
| 50 #include "StubMaker.h" | |
| 51 #include "TextStubWriter.h" | |
| 52 // @LOCALMOD-END | |
| 53 | 43 |
| 54 using namespace llvm; | 44 using namespace llvm; |
| 55 | 45 |
| 56 // @LOCALMOD-BEGIN | 46 // @LOCALMOD-BEGIN |
| 57 // NOTE: this tool can be build as a "sandboxed" translator. | 47 // NOTE: this tool can be build as a "sandboxed" translator. |
| 58 // There are two ways to build the translator | 48 // There are two ways to build the translator |
| 59 // SRPC-style: no file operations are allowed | 49 // SRPC-style: no file operations are allowed |
| 60 // see nacl_file.cc for support code | 50 // see nacl_file.cc for support code |
| 61 // non-SRPC-style: some basic file operations are allowed | 51 // non-SRPC-style: some basic file operations are allowed |
| 62 // This can be useful for debugging but will | 52 // This can be useful for debugging but will |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 87 static cl::opt<std::string> | 77 static cl::opt<std::string> |
| 88 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); | 78 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); |
| 89 | 79 |
| 90 static cl::opt<std::string> | 80 static cl::opt<std::string> |
| 91 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); | 81 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); |
| 92 | 82 |
| 93 static cl::opt<unsigned> | 83 static cl::opt<unsigned> |
| 94 TimeCompilations("time-compilations", cl::Hidden, cl::init(1u), | 84 TimeCompilations("time-compilations", cl::Hidden, cl::init(1u), |
| 95 cl::value_desc("N"), | 85 cl::value_desc("N"), |
| 96 cl::desc("Repeat compilation N times for timing")); | 86 cl::desc("Repeat compilation N times for timing")); |
| 97 // @LOCALMOD-BEGIN | |
| 98 static cl::opt<std::string> | |
| 99 MetadataTextFilename("metadata-text", cl::desc("Metadata as text, out filename") , | |
| 100 cl::value_desc("filename")); | |
| 101 | 87 |
| 102 // Using bitcode streaming has a couple of ramifications. Primarily it means | 88 // Using bitcode streaming has a couple of ramifications. Primarily it means |
| 103 // that the module in the file will be compiled one function at a time rather | 89 // that the module in the file will be compiled one function at a time rather |
| 104 // than the whole module. This allows earlier functions to be compiled before | 90 // than the whole module. This allows earlier functions to be compiled before |
| 105 // later functions are read from the bitcode but of course means no whole-module | 91 // later functions are read from the bitcode but of course means no whole-module |
| 106 // optimizations. For now, streaming is only supported for files and stdin. | 92 // optimizations. For now, streaming is only supported for files and stdin. |
| 107 static cl::opt<bool> | 93 static cl::opt<bool> |
| 108 LazyBitcode("streaming-bitcode", | 94 LazyBitcode("streaming-bitcode", |
| 109 cl::desc("Use lazy bitcode streaming for file inputs"), | 95 cl::desc("Use lazy bitcode streaming for file inputs"), |
| 110 cl::init(false)); | 96 cl::init(false)); |
| 111 | 97 |
| 112 // The option below overlaps very much with bitcode streaming. | 98 // The option below overlaps very much with bitcode streaming. |
| 113 // We keep it separate because it is still experimental and we want | 99 // We keep it separate because it is still experimental and we want |
| 114 // to use it without changing the outside behavior which is especially | 100 // to use it without changing the outside behavior which is especially |
| 115 // relevant for the sandboxed case. | 101 // relevant for the sandboxed case. |
| 116 static cl::opt<bool> | 102 static cl::opt<bool> |
| 117 ReduceMemoryFootprint("reduce-memory-footprint", | 103 ReduceMemoryFootprint("reduce-memory-footprint", |
| 118 cl::desc("Aggressively reduce memory used by llc"), | 104 cl::desc("Aggressively reduce memory used by llc"), |
| 119 cl::init(false)); | 105 cl::init(false)); |
| 120 | 106 |
| 121 static cl::opt<bool> | 107 static cl::opt<bool> |
| 122 PNaClABIVerify("pnaclabi-verify", | 108 PNaClABIVerify("pnaclabi-verify", |
| 123 cl::desc("Verify PNaCl bitcode ABI before translating"), | 109 cl::desc("Verify PNaCl bitcode ABI before translating"), |
| 124 cl::init(false)); | 110 cl::init(false)); |
| 125 static cl::opt<bool> | 111 static cl::opt<bool> |
| 126 PNaClABIVerifyFatalErrors("pnaclabi-verify-fatal-errors", | 112 PNaClABIVerifyFatalErrors("pnaclabi-verify-fatal-errors", |
| 127 cl::desc("PNaCl ABI verification errors are fatal"), | 113 cl::desc("PNaCl ABI verification errors are fatal"), |
| 128 cl::init(false)); | 114 cl::init(false)); |
| 129 // @LOCALMOD-END | |
| 130 | 115 |
| 131 // Determine optimization level. | 116 // Determine optimization level. |
| 132 static cl::opt<char> | 117 static cl::opt<char> |
| 133 OptLevel("O", | 118 OptLevel("O", |
| 134 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " | 119 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " |
| 135 "(default = '-O2')"), | 120 "(default = '-O2')"), |
| 136 cl::Prefix, | 121 cl::Prefix, |
| 137 cl::ZeroOrMore, | 122 cl::ZeroOrMore, |
| 138 cl::init(' ')); | 123 cl::init(' ')); |
| 139 | 124 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 OpenFlags); | 206 OpenFlags); |
| 222 if (!error.empty()) { | 207 if (!error.empty()) { |
| 223 errs() << error << '\n'; | 208 errs() << error << '\n'; |
| 224 delete FDOut; | 209 delete FDOut; |
| 225 return 0; | 210 return 0; |
| 226 } | 211 } |
| 227 | 212 |
| 228 return FDOut; | 213 return FDOut; |
| 229 } | 214 } |
| 230 | 215 |
| 231 // @LOCALMOD-BEGIN | 216 // @LOCALMOD-BEGIN |
|
jvoung (off chromium)
2013/05/15 18:10:21
dangling LOCALMOD-BEGIN?
eliben
2013/05/15 18:13:33
Done.
| |
| 232 #if defined(__native_client__) && defined(NACL_SRPC) | |
| 233 void RecordMetadataForSrpc(const Module &mod) { | |
| 234 bool is_shared = (mod.getOutputFormat() == Module::SharedOutputFormat); | |
| 235 std::string soname = mod.getSOName(); | |
| 236 NaClRecordObjectInformation(is_shared, soname); | |
| 237 for (Module::lib_iterator L = mod.lib_begin(), | |
| 238 E = mod.lib_end(); | |
| 239 L != E; ++L) { | |
| 240 NaClRecordSharedLibraryDependency(*L); | |
| 241 } | |
| 242 } | |
| 243 #endif // defined(__native_client__) && defined(NACL_SRPC) | |
| 244 // @LOCALMOD-END | |
| 245 | |
| 246 | |
| 247 // @LOCALMOD-BEGIN | |
| 248 | |
| 249 // Write the ELF Stubs to the metadata file, in text format | |
| 250 // Returns 0 on success, non-zero on error. | |
| 251 int WriteTextMetadataFile(const Module &M, const Triple &TheTriple) { | |
| 252 // Build the ELF stubs (in high level format) | |
| 253 SmallVector<ELFStub*, 8> StubList; | |
| 254 // NOTE: The triple is unnecessary for the text version. | |
| 255 MakeAllStubs(M, TheTriple, &StubList); | |
| 256 // For each stub, write the ELF object to the metadata file. | |
| 257 std::string s; | |
| 258 for (unsigned i = 0; i < StubList.size(); i++) { | |
| 259 WriteTextELFStub(StubList[i], &s); | |
| 260 } | |
| 261 FreeStubList(&StubList); | |
| 262 | |
| 263 #if defined(__native_client__) && defined(NACL_SRPC) | |
| 264 llvm_unreachable("Not yet implemented. Need a file handle to write to."); | |
| 265 #else | |
| 266 std::string error; | |
| 267 OwningPtr<tool_output_file> MOut( | |
| 268 new tool_output_file(MetadataTextFilename.c_str(), error, | |
| 269 raw_fd_ostream::F_Binary)); | |
| 270 if (!error.empty()) { | |
| 271 errs() << error << '\n'; | |
| 272 return 1; | |
| 273 } | |
| 274 MOut->os().write(s.data(), s.size()); | |
| 275 MOut->keep(); | |
| 276 #endif | |
| 277 return 0; | |
| 278 } | |
| 279 | |
| 280 // @LOCALMOD-END | |
| 281 | 217 |
| 282 // main - Entry point for the llc compiler. | 218 // main - Entry point for the llc compiler. |
| 283 // | 219 // |
| 284 int llc_main(int argc, char **argv) { | 220 int llc_main(int argc, char **argv) { |
| 285 sys::PrintStackTraceOnErrorSignal(); | 221 sys::PrintStackTraceOnErrorSignal(); |
| 286 PrettyStackTraceProgram X(argc, argv); | 222 PrettyStackTraceProgram X(argc, argv); |
| 287 | 223 |
| 288 // Enable debug stream buffering. | 224 // Enable debug stream buffering. |
| 289 EnableDebugBuffering = true; | 225 EnableDebugBuffering = true; |
| 290 | 226 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 } | 322 } |
| 387 | 323 |
| 388 // @LOCALMOD-BEGIN | 324 // @LOCALMOD-BEGIN |
| 389 if (PNaClABIVerify) { | 325 if (PNaClABIVerify) { |
| 390 // Verify the module (but not the functions yet) | 326 // Verify the module (but not the functions yet) |
| 391 ModulePass *VerifyPass = createPNaClABIVerifyModulePass(&ABIErrorReporter) ; | 327 ModulePass *VerifyPass = createPNaClABIVerifyModulePass(&ABIErrorReporter) ; |
| 392 VerifyPass->runOnModule(*mod); | 328 VerifyPass->runOnModule(*mod); |
| 393 CheckABIVerifyErrors(ABIErrorReporter, "Module"); | 329 CheckABIVerifyErrors(ABIErrorReporter, "Module"); |
| 394 } | 330 } |
| 395 #if defined(__native_client__) && defined(NACL_SRPC) | 331 #if defined(__native_client__) && defined(NACL_SRPC) |
| 396 RecordMetadataForSrpc(*mod); | |
| 397 | |
| 398 // To determine if we should compile PIC or not, we needed to load at | 332 // To determine if we should compile PIC or not, we needed to load at |
| 399 // least the metadata. Since we've already constructed the commandline, | 333 // least the metadata. Since we've already constructed the commandline, |
| 400 // we have to hack this in after commandline processing. | 334 // we have to hack this in after commandline processing. |
| 401 if (mod->getOutputFormat() == Module::SharedOutputFormat) { | 335 if (mod->getOutputFormat() == Module::SharedOutputFormat) { |
| 402 RelocModel = Reloc::PIC_; | 336 RelocModel = Reloc::PIC_; |
| 403 } | 337 } |
| 404 // Also set PIC_ for dynamic executables: | 338 // Also set PIC_ for dynamic executables: |
| 405 // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2351 | 339 // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2351 |
| 406 if (mod->lib_size() > 0) { | 340 if (mod->lib_size() > 0) { |
| 407 RelocModel = Reloc::PIC_; | 341 RelocModel = Reloc::PIC_; |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 633 P->doFinalization(); | 567 P->doFinalization(); |
| 634 } else { | 568 } else { |
| 635 static_cast<PassManager*>(PM.get())->run(*mod); | 569 static_cast<PassManager*>(PM.get())->run(*mod); |
| 636 } | 570 } |
| 637 } | 571 } |
| 638 | 572 |
| 639 // Declare success. | 573 // Declare success. |
| 640 Out->keep(); | 574 Out->keep(); |
| 641 #endif | 575 #endif |
| 642 | 576 |
| 643 // @LOCALMOD-BEGIN | |
| 644 // Write out the metadata. | |
| 645 // | |
| 646 // We need to ensure that intrinsic prototypes are available, in case | |
| 647 // we have a NeededRecord for one of them. | |
| 648 // They may have been eliminated by the StripDeadPrototypes pass, | |
| 649 // or some other pass that is unaware of NeededRecords / IntrinsicLowering. | |
| 650 if (!MetadataTextFilename.empty()) { | |
| 651 IntrinsicLowering IL(*target->getDataLayout()); | |
| 652 IL.AddPrototypes(*M); | |
| 653 | |
| 654 int err = WriteTextMetadataFile(*M.get(), TheTriple); | |
| 655 if (err != 0) | |
| 656 return err; | |
| 657 } | |
| 658 // @LOCALMOD-END | |
| 659 | |
| 660 return 0; | 577 return 0; |
| 661 } | 578 } |
| 662 | 579 |
| 663 #if !defined(NACL_SRPC) | 580 #if !defined(NACL_SRPC) |
| 664 int | 581 int |
| 665 main (int argc, char **argv) { | 582 main (int argc, char **argv) { |
| 666 return llc_main(argc, argv); | 583 return llc_main(argc, argv); |
| 667 } | 584 } |
| 668 #else | 585 #else |
| 669 // main() is in nacl_file.cpp. | 586 // main() is in nacl_file.cpp. |
| 670 #endif | 587 #endif |
| OLD | NEW |