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...) 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...) 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...) 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...) 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 |