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 | |
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 | |
282 // main - Entry point for the llc compiler. | 216 // main - Entry point for the llc compiler. |
283 // | 217 // |
284 int llc_main(int argc, char **argv) { | 218 int llc_main(int argc, char **argv) { |
285 sys::PrintStackTraceOnErrorSignal(); | 219 sys::PrintStackTraceOnErrorSignal(); |
286 PrettyStackTraceProgram X(argc, argv); | 220 PrettyStackTraceProgram X(argc, argv); |
287 | 221 |
288 // Enable debug stream buffering. | 222 // Enable debug stream buffering. |
289 EnableDebugBuffering = true; | 223 EnableDebugBuffering = true; |
290 | 224 |
291 LLVMContext &Context = getGlobalContext(); | 225 LLVMContext &Context = getGlobalContext(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 } | 320 } |
387 | 321 |
388 // @LOCALMOD-BEGIN | 322 // @LOCALMOD-BEGIN |
389 if (PNaClABIVerify) { | 323 if (PNaClABIVerify) { |
390 // Verify the module (but not the functions yet) | 324 // Verify the module (but not the functions yet) |
391 ModulePass *VerifyPass = createPNaClABIVerifyModulePass(&ABIErrorReporter)
; | 325 ModulePass *VerifyPass = createPNaClABIVerifyModulePass(&ABIErrorReporter)
; |
392 VerifyPass->runOnModule(*mod); | 326 VerifyPass->runOnModule(*mod); |
393 CheckABIVerifyErrors(ABIErrorReporter, "Module"); | 327 CheckABIVerifyErrors(ABIErrorReporter, "Module"); |
394 } | 328 } |
395 #if defined(__native_client__) && defined(NACL_SRPC) | 329 #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 | 330 // 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, | 331 // least the metadata. Since we've already constructed the commandline, |
400 // we have to hack this in after commandline processing. | 332 // we have to hack this in after commandline processing. |
401 if (mod->getOutputFormat() == Module::SharedOutputFormat) { | 333 if (mod->getOutputFormat() == Module::SharedOutputFormat) { |
402 RelocModel = Reloc::PIC_; | 334 RelocModel = Reloc::PIC_; |
403 } | 335 } |
404 // Also set PIC_ for dynamic executables: | 336 // Also set PIC_ for dynamic executables: |
405 // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2351 | 337 // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2351 |
406 if (mod->lib_size() > 0) { | 338 if (mod->lib_size() > 0) { |
407 RelocModel = Reloc::PIC_; | 339 RelocModel = Reloc::PIC_; |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 P->doFinalization(); | 565 P->doFinalization(); |
634 } else { | 566 } else { |
635 static_cast<PassManager*>(PM.get())->run(*mod); | 567 static_cast<PassManager*>(PM.get())->run(*mod); |
636 } | 568 } |
637 } | 569 } |
638 | 570 |
639 // Declare success. | 571 // Declare success. |
640 Out->keep(); | 572 Out->keep(); |
641 #endif | 573 #endif |
642 | 574 |
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; | 575 return 0; |
661 } | 576 } |
662 | 577 |
663 #if !defined(NACL_SRPC) | 578 #if !defined(NACL_SRPC) |
664 int | 579 int |
665 main (int argc, char **argv) { | 580 main (int argc, char **argv) { |
666 return llc_main(argc, argv); | 581 return llc_main(argc, argv); |
667 } | 582 } |
668 #else | 583 #else |
669 // main() is in nacl_file.cpp. | 584 // main() is in nacl_file.cpp. |
670 #endif | 585 #endif |
OLD | NEW |