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 | 19 #include "llvm/CodeGen/IntrinsicLowering.h" |
|
jvoung (off chromium)
2013/05/15 16:56:06
Can remove this localmod #include (not just remove
eliben
2013/05/15 18:01:18
Done.
| |
| 23 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" | 20 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" |
| 24 #include "llvm/CodeGen/LinkAllCodegenComponents.h" | 21 #include "llvm/CodeGen/LinkAllCodegenComponents.h" |
| 25 #include "llvm/IR/DataLayout.h" | 22 #include "llvm/IR/DataLayout.h" |
| 23 #include "llvm/IR/LLVMContext.h" | |
| 26 #include "llvm/IR/Module.h" | 24 #include "llvm/IR/Module.h" |
| 27 #include "llvm/MC/SubtargetFeature.h" | 25 #include "llvm/MC/SubtargetFeature.h" |
| 28 #include "llvm/Pass.h" | 26 #include "llvm/Pass.h" |
| 29 #include "llvm/PassManager.h" | 27 #include "llvm/PassManager.h" |
| 30 #include "llvm/Support/CommandLine.h" | 28 #include "llvm/Support/CommandLine.h" |
| 31 #include "llvm/Support/Debug.h" | 29 #include "llvm/Support/Debug.h" |
| 32 #include "llvm/Support/FormattedStream.h" | 30 #include "llvm/Support/FormattedStream.h" |
| 33 #include "llvm/Support/Host.h" | 31 #include "llvm/Support/Host.h" |
| 34 #include "llvm/Support/IRReader.h" | 32 #include "llvm/Support/IRReader.h" |
| 35 #include "llvm/Support/ManagedStatic.h" | 33 #include "llvm/Support/ManagedStatic.h" |
| 36 #if !defined(__native_client__) | |
| 37 #include "llvm/Support/PluginLoader.h" | |
| 38 #endif | |
| 39 #include "llvm/Support/PrettyStackTrace.h" | 34 #include "llvm/Support/PrettyStackTrace.h" |
| 40 #include "llvm/Support/Signals.h" | 35 #include "llvm/Support/Signals.h" |
| 41 #include "llvm/Support/TargetRegistry.h" | 36 #include "llvm/Support/TargetRegistry.h" |
| 42 #include "llvm/Support/TargetSelect.h" | 37 #include "llvm/Support/TargetSelect.h" |
| 38 #include "llvm/Support/Timer.h" | |
| 43 #include "llvm/Support/ToolOutputFile.h" | 39 #include "llvm/Support/ToolOutputFile.h" |
| 44 #include "llvm/Target/TargetLibraryInfo.h" | 40 #include "llvm/Target/TargetLibraryInfo.h" |
| 45 #include "llvm/Target/TargetMachine.h" | 41 #include "llvm/Target/TargetMachine.h" |
| 46 #include <memory> | 42 #include <memory> |
| 47 | 43 |
| 48 // @LOCALMOD-BEGIN | |
| 49 #include "llvm/Support/Timer.h" | |
| 50 #include "StubMaker.h" | |
| 51 #include "TextStubWriter.h" | |
| 52 // @LOCALMOD-END | |
| 53 | 44 |
| 54 using namespace llvm; | 45 using namespace llvm; |
| 55 | 46 |
| 56 // @LOCALMOD-BEGIN | 47 // @LOCALMOD-BEGIN |
| 57 // NOTE: this tool can be build as a "sandboxed" translator. | 48 // NOTE: this tool can be build as a "sandboxed" translator. |
| 58 // There are two ways to build the translator | 49 // There are two ways to build the translator |
| 59 // SRPC-style: no file operations are allowed | 50 // SRPC-style: no file operations are allowed |
| 60 // see nacl_file.cc for support code | 51 // see nacl_file.cc for support code |
| 61 // non-SRPC-style: some basic file operations are allowed | 52 // non-SRPC-style: some basic file operations are allowed |
| 62 // This can be useful for debugging but will | 53 // This can be useful for debugging but will |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 87 static cl::opt<std::string> | 78 static cl::opt<std::string> |
| 88 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); | 79 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); |
| 89 | 80 |
| 90 static cl::opt<std::string> | 81 static cl::opt<std::string> |
| 91 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); | 82 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); |
| 92 | 83 |
| 93 static cl::opt<unsigned> | 84 static cl::opt<unsigned> |
| 94 TimeCompilations("time-compilations", cl::Hidden, cl::init(1u), | 85 TimeCompilations("time-compilations", cl::Hidden, cl::init(1u), |
| 95 cl::value_desc("N"), | 86 cl::value_desc("N"), |
| 96 cl::desc("Repeat compilation N times for timing")); | 87 cl::desc("Repeat compilation N times for timing")); |
| 97 // @LOCALMOD-BEGIN | 88 // @LOCALMOD-BEGIN |
|
Mark Seaborn
2013/05/15 16:20:08
Should these @LOCALMOD comments be removed too?
eliben
2013/05/15 18:01:18
Yes, I'm removing them. I wanted this CL not to be
| |
| 98 static cl::opt<std::string> | |
| 99 MetadataTextFilename("metadata-text", cl::desc("Metadata as text, out filename") , | |
| 100 cl::value_desc("filename")); | |
| 101 | |
| 102 // Using bitcode streaming has a couple of ramifications. Primarily it means | 89 // 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 | 90 // 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 | 91 // 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 | 92 // 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. | 93 // optimizations. For now, streaming is only supported for files and stdin. |
| 107 static cl::opt<bool> | 94 static cl::opt<bool> |
| 108 LazyBitcode("streaming-bitcode", | 95 LazyBitcode("streaming-bitcode", |
| 109 cl::desc("Use lazy bitcode streaming for file inputs"), | 96 cl::desc("Use lazy bitcode streaming for file inputs"), |
| 110 cl::init(false)); | 97 cl::init(false)); |
| 111 | 98 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 if (!error.empty()) { | 209 if (!error.empty()) { |
| 223 errs() << error << '\n'; | 210 errs() << error << '\n'; |
| 224 delete FDOut; | 211 delete FDOut; |
| 225 return 0; | 212 return 0; |
| 226 } | 213 } |
| 227 | 214 |
| 228 return FDOut; | 215 return FDOut; |
| 229 } | 216 } |
| 230 | 217 |
| 231 // @LOCALMOD-BEGIN | 218 // @LOCALMOD-BEGIN |
| 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 | 219 |
| 282 // main - Entry point for the llc compiler. | 220 // main - Entry point for the llc compiler. |
| 283 // | 221 // |
| 284 int llc_main(int argc, char **argv) { | 222 int llc_main(int argc, char **argv) { |
| 285 sys::PrintStackTraceOnErrorSignal(); | 223 sys::PrintStackTraceOnErrorSignal(); |
| 286 PrettyStackTraceProgram X(argc, argv); | 224 PrettyStackTraceProgram X(argc, argv); |
| 287 | 225 |
| 288 // Enable debug stream buffering. | 226 // Enable debug stream buffering. |
| 289 EnableDebugBuffering = true; | 227 EnableDebugBuffering = true; |
| 290 | 228 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 } | 324 } |
| 387 | 325 |
| 388 // @LOCALMOD-BEGIN | 326 // @LOCALMOD-BEGIN |
| 389 if (PNaClABIVerify) { | 327 if (PNaClABIVerify) { |
| 390 // Verify the module (but not the functions yet) | 328 // Verify the module (but not the functions yet) |
| 391 ModulePass *VerifyPass = createPNaClABIVerifyModulePass(&ABIErrorReporter) ; | 329 ModulePass *VerifyPass = createPNaClABIVerifyModulePass(&ABIErrorReporter) ; |
| 392 VerifyPass->runOnModule(*mod); | 330 VerifyPass->runOnModule(*mod); |
| 393 CheckABIVerifyErrors(ABIErrorReporter, "Module"); | 331 CheckABIVerifyErrors(ABIErrorReporter, "Module"); |
| 394 } | 332 } |
| 395 #if defined(__native_client__) && defined(NACL_SRPC) | 333 #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 | 334 // 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, | 335 // least the metadata. Since we've already constructed the commandline, |
| 400 // we have to hack this in after commandline processing. | 336 // we have to hack this in after commandline processing. |
| 401 if (mod->getOutputFormat() == Module::SharedOutputFormat) { | 337 if (mod->getOutputFormat() == Module::SharedOutputFormat) { |
| 402 RelocModel = Reloc::PIC_; | 338 RelocModel = Reloc::PIC_; |
| 403 } | 339 } |
| 404 // Also set PIC_ for dynamic executables: | 340 // Also set PIC_ for dynamic executables: |
| 405 // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2351 | 341 // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2351 |
| 406 if (mod->lib_size() > 0) { | 342 if (mod->lib_size() > 0) { |
| 407 RelocModel = Reloc::PIC_; | 343 RelocModel = Reloc::PIC_; |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 633 P->doFinalization(); | 569 P->doFinalization(); |
| 634 } else { | 570 } else { |
| 635 static_cast<PassManager*>(PM.get())->run(*mod); | 571 static_cast<PassManager*>(PM.get())->run(*mod); |
| 636 } | 572 } |
| 637 } | 573 } |
| 638 | 574 |
| 639 // Declare success. | 575 // Declare success. |
| 640 Out->keep(); | 576 Out->keep(); |
| 641 #endif | 577 #endif |
| 642 | 578 |
| 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; | 579 return 0; |
| 661 } | 580 } |
| 662 | 581 |
| 663 #if !defined(NACL_SRPC) | 582 #if !defined(NACL_SRPC) |
| 664 int | 583 int |
| 665 main (int argc, char **argv) { | 584 main (int argc, char **argv) { |
| 666 return llc_main(argc, argv); | 585 return llc_main(argc, argv); |
| 667 } | 586 } |
| 668 #else | 587 #else |
| 669 // main() is in nacl_file.cpp. | 588 // main() is in nacl_file.cpp. |
| 670 #endif | 589 #endif |
| OLD | NEW |