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/STLExtras.h" |
14 #include "llvm/ADT/Triple.h" | 15 #include "llvm/ADT/Triple.h" |
15 #include "llvm/Analysis/NaCl.h" | 16 #include "llvm/Analysis/NaCl.h" |
16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" | 17 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
17 #include "llvm/Bitcode/ReaderWriter.h" | 18 #include "llvm/Bitcode/ReaderWriter.h" |
18 #include "llvm/CodeGen/CommandFlags.h" | 19 #include "llvm/CodeGen/CommandFlags.h" |
19 #include "llvm/CodeGen/LinkAllCodegenComponents.h" | 20 #include "llvm/CodeGen/LinkAllCodegenComponents.h" |
20 #include "llvm/IR/DataLayout.h" | 21 #include "llvm/IR/DataLayout.h" |
21 #include "llvm/IR/LLVMContext.h" | 22 #include "llvm/IR/LLVMContext.h" |
22 #include "llvm/IR/Module.h" | 23 #include "llvm/IR/Module.h" |
23 #include "llvm/IR/Verifier.h" | 24 #include "llvm/IR/Verifier.h" |
24 #include "llvm/IRReader/IRReader.h" | 25 #include "llvm/IRReader/IRReader.h" |
25 #include "llvm/MC/SubtargetFeature.h" | 26 #include "llvm/MC/SubtargetFeature.h" |
26 #include "llvm/Pass.h" | 27 #include "llvm/Pass.h" |
27 #include "llvm/PassManager.h" | 28 #include "llvm/IR/LegacyPassManager.h" |
28 #include "llvm/Support/CommandLine.h" | 29 #include "llvm/Support/CommandLine.h" |
29 #include "llvm/Support/DataStream.h" | 30 #include "llvm/Support/DataStream.h" |
30 #include "llvm/Support/Debug.h" | 31 #include "llvm/Support/Debug.h" |
31 #include "llvm/Support/ErrorHandling.h" | 32 #include "llvm/Support/ErrorHandling.h" |
32 #include "llvm/Support/FileSystem.h" | 33 #include "llvm/Support/FileSystem.h" |
33 #include "llvm/Support/FormattedStream.h" | 34 #include "llvm/Support/FormattedStream.h" |
34 #include "llvm/Support/Host.h" | 35 #include "llvm/Support/Host.h" |
35 #include "llvm/Support/ManagedStatic.h" | 36 #include "llvm/Support/ManagedStatic.h" |
36 #include "llvm/Support/PrettyStackTrace.h" | 37 #include "llvm/Support/PrettyStackTrace.h" |
37 #include "llvm/Support/Signals.h" | 38 #include "llvm/Support/Signals.h" |
38 #include "llvm/Support/SourceMgr.h" | 39 #include "llvm/Support/SourceMgr.h" |
39 #include "llvm/Support/StreamingMemoryObject.h" | 40 #include "llvm/Support/StreamingMemoryObject.h" |
40 #include "llvm/Support/TargetRegistry.h" | 41 #include "llvm/Support/TargetRegistry.h" |
41 #include "llvm/Support/TargetSelect.h" | 42 #include "llvm/Support/TargetSelect.h" |
42 #include "llvm/Support/ToolOutputFile.h" | 43 #include "llvm/Support/ToolOutputFile.h" |
43 #include "llvm/Target/TargetLibraryInfo.h" | 44 #include "llvm/Analysis/TargetLibraryInfo.h" |
44 #include "llvm/Target/TargetMachine.h" | 45 #include "llvm/Target/TargetMachine.h" |
45 #include "llvm/Target/TargetSubtargetInfo.h" | 46 #include "llvm/Target/TargetSubtargetInfo.h" |
46 #include "llvm/Transforms/NaCl.h" | 47 #include "llvm/Transforms/NaCl.h" |
47 | 48 |
48 #include "ThreadedFunctionQueue.h" | 49 #include "ThreadedFunctionQueue.h" |
49 #include "ThreadedStreamingCache.h" | 50 #include "ThreadedStreamingCache.h" |
50 | 51 |
51 #include <pthread.h> | 52 #include <pthread.h> |
52 #include <memory> | 53 #include <memory> |
53 | 54 |
(...skipping 25 matching lines...) Expand all Loading... |
79 #endif | 80 #endif |
80 ); | 81 ); |
81 | 82 |
82 // General options for llc. Other pass-specific options are specified | 83 // General options for llc. Other pass-specific options are specified |
83 // within the corresponding llc passes, and target-specific options | 84 // within the corresponding llc passes, and target-specific options |
84 // and back-end code generation options are specified with the target machine. | 85 // and back-end code generation options are specified with the target machine. |
85 // | 86 // |
86 static cl::opt<std::string> | 87 static cl::opt<std::string> |
87 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); | 88 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); |
88 | 89 |
| 90 // Primary output filename. If module splitting is used, the other output files |
| 91 // will have names derived from this one. |
89 static cl::opt<std::string> | 92 static cl::opt<std::string> |
90 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); | 93 MainOutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"))
; |
91 | 94 |
92 // Using bitcode streaming allows compilation of one function at a time. This | 95 // Using bitcode streaming allows compilation of one function at a time. This |
93 // allows earlier functions to be compiled before later functions are read from | 96 // allows earlier functions to be compiled before later functions are read from |
94 // the bitcode but of course means no whole-module optimizations. This means | 97 // the bitcode but of course means no whole-module optimizations. This means |
95 // that Module passes that run should only touch globals/function declarations | 98 // that Module passes that run should only touch globals/function declarations |
96 // and not function bodies, otherwise the streaming and non-streaming code | 99 // and not function bodies, otherwise the streaming and non-streaming code |
97 // pathes wouldn't emit the same code for each function. For now, streaming is | 100 // pathes wouldn't emit the same code for each function. For now, streaming is |
98 // only supported for files and stdin. | 101 // only supported for files and stdin. |
99 static cl::opt<bool> | 102 static cl::opt<bool> |
100 LazyBitcode("streaming-bitcode", | 103 LazyBitcode("streaming-bitcode", |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 "Static thread scheduling"), | 157 "Static thread scheduling"), |
155 clEnumValEnd), | 158 clEnumValEnd), |
156 cl::init(SplitModuleDynamic)); | 159 cl::init(SplitModuleDynamic)); |
157 | 160 |
158 /// Compile the module provided to pnacl-llc. The file name for reading the | 161 /// Compile the module provided to pnacl-llc. The file name for reading the |
159 /// module and other options are taken from globals populated by command-line | 162 /// module and other options are taken from globals populated by command-line |
160 /// option parsing. | 163 /// option parsing. |
161 static int compileModule(StringRef ProgramName); | 164 static int compileModule(StringRef ProgramName); |
162 | 165 |
163 #if !defined(PNACL_BROWSER_TRANSLATOR) | 166 #if !defined(PNACL_BROWSER_TRANSLATOR) |
164 // GetFileNameRoot - Helper function to get the basename of a filename. | 167 static std::unique_ptr<tool_output_file> |
165 static std::string | 168 GetOutputStream(const char *TargetName, |
166 GetFileNameRoot(StringRef InputFilename) { | 169 Triple::OSType OS, |
167 std::string IFN = InputFilename; | 170 std::string OutputFilename) { |
168 std::string outputFilename; | |
169 int Len = IFN.length(); | |
170 if ((Len > 2) && | |
171 IFN[Len-3] == '.' && | |
172 ((IFN[Len-2] == 'b' && IFN[Len-1] == 'c') || | |
173 (IFN[Len-2] == 'l' && IFN[Len-1] == 'l'))) { | |
174 outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ | |
175 } else { | |
176 outputFilename = IFN; | |
177 } | |
178 return outputFilename; | |
179 } | |
180 | |
181 static tool_output_file *GetOutputStream(const char *TargetName, | |
182 Triple::OSType OS, | |
183 std::string Filename) { | |
184 // If we don't yet have an output filename, make one. | 171 // If we don't yet have an output filename, make one. |
185 if (Filename.empty()) { | 172 if (OutputFilename.empty()) { |
186 if (InputFilename == "-") | 173 if (InputFilename == "-") |
187 Filename = "-"; | 174 OutputFilename = "-"; |
188 else { | 175 else { |
189 Filename = GetFileNameRoot(InputFilename); | 176 // If InputFilename ends in .bc or .ll, remove it. |
| 177 StringRef IFN = InputFilename; |
| 178 if (IFN.endswith(".bc") || IFN.endswith(".ll")) |
| 179 OutputFilename = IFN.drop_back(3); |
| 180 else |
| 181 OutputFilename = IFN; |
190 | 182 |
191 switch (FileType) { | 183 switch (FileType) { |
192 case TargetMachine::CGFT_AssemblyFile: | 184 case TargetMachine::CGFT_AssemblyFile: |
193 if (TargetName[0] == 'c') { | 185 if (TargetName[0] == 'c') { |
194 if (TargetName[1] == 0) | 186 if (TargetName[1] == 0) |
195 Filename += ".cbe.c"; | 187 OutputFilename += ".cbe.c"; |
196 else if (TargetName[1] == 'p' && TargetName[2] == 'p') | 188 else if (TargetName[1] == 'p' && TargetName[2] == 'p') |
197 Filename += ".cpp"; | 189 OutputFilename += ".cpp"; |
198 else | 190 else |
199 Filename += ".s"; | 191 OutputFilename += ".s"; |
200 } else | 192 } else |
201 Filename += ".s"; | 193 OutputFilename += ".s"; |
202 break; | 194 break; |
203 case TargetMachine::CGFT_ObjectFile: | 195 case TargetMachine::CGFT_ObjectFile: |
204 if (OS == Triple::Win32) | 196 if (OS == Triple::Win32) |
205 Filename += ".obj"; | 197 OutputFilename += ".obj"; |
206 else | 198 else |
207 Filename += ".o"; | 199 OutputFilename += ".o"; |
208 break; | 200 break; |
209 case TargetMachine::CGFT_Null: | 201 case TargetMachine::CGFT_Null: |
210 Filename += ".null"; | 202 OutputFilename += ".null"; |
211 break; | 203 break; |
212 } | 204 } |
213 } | 205 } |
214 } | 206 } |
215 | 207 |
216 // Decide if we need "binary" output. | 208 // Decide if we need "binary" output. |
217 bool Binary = false; | 209 bool Binary = false; |
218 switch (FileType) { | 210 switch (FileType) { |
219 case TargetMachine::CGFT_AssemblyFile: | 211 case TargetMachine::CGFT_AssemblyFile: |
220 break; | 212 break; |
221 case TargetMachine::CGFT_ObjectFile: | 213 case TargetMachine::CGFT_ObjectFile: |
222 case TargetMachine::CGFT_Null: | 214 case TargetMachine::CGFT_Null: |
223 Binary = true; | 215 Binary = true; |
224 break; | 216 break; |
225 } | 217 } |
226 | 218 |
227 // Open the file. | 219 // Open the file. |
228 std::error_code EC; | 220 std::error_code EC; |
229 sys::fs::OpenFlags OpenFlags = sys::fs::F_None; | 221 sys::fs::OpenFlags OpenFlags = sys::fs::F_None; |
230 if (!Binary) | 222 if (!Binary) |
231 OpenFlags |= sys::fs::F_Text; | 223 OpenFlags |= sys::fs::F_Text; |
232 tool_output_file *FDOut = new tool_output_file(Filename, EC, OpenFlags); | 224 auto FDOut = llvm::make_unique<tool_output_file>(OutputFilename, EC, |
| 225 OpenFlags); |
233 if (EC) { | 226 if (EC) { |
234 errs() << EC.message() << '\n'; | 227 errs() << EC.message() << '\n'; |
235 delete FDOut; | |
236 return nullptr; | 228 return nullptr; |
237 } | 229 } |
238 | 230 |
239 return FDOut; | 231 return FDOut; |
240 } | 232 } |
241 #endif // !defined(PNACL_BROWSER_TRANSLATOR) | 233 #endif // !defined(PNACL_BROWSER_TRANSLATOR) |
242 | 234 |
243 // main - Entry point for the llc compiler. | 235 // main - Entry point for the llc compiler. |
244 // | 236 // |
245 int llc_main(int argc, char **argv) { | 237 int llc_main(int argc, char **argv) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 static std::unique_ptr<Module> getModule( | 312 static std::unique_ptr<Module> getModule( |
321 StringRef ProgramName, LLVMContext &Context, | 313 StringRef ProgramName, LLVMContext &Context, |
322 StreamingMemoryObject *StreamingObject) { | 314 StreamingMemoryObject *StreamingObject) { |
323 std::unique_ptr<Module> M; | 315 std::unique_ptr<Module> M; |
324 SMDiagnostic Err; | 316 SMDiagnostic Err; |
325 std::string VerboseBuffer; | 317 std::string VerboseBuffer; |
326 raw_string_ostream VerboseStrm(VerboseBuffer); | 318 raw_string_ostream VerboseStrm(VerboseBuffer); |
327 if (LazyBitcode) { | 319 if (LazyBitcode) { |
328 std::string StrError; | 320 std::string StrError; |
329 switch (InputFileFormat) { | 321 switch (InputFileFormat) { |
330 case PNaClFormat: | 322 case PNaClFormat: { |
| 323 std::unique_ptr<StreamingMemoryObject> Cache( |
| 324 new ThreadedStreamingCache(StreamingObject)); |
331 M.reset(getNaClStreamedBitcodeModule( | 325 M.reset(getNaClStreamedBitcodeModule( |
332 InputFilename, | 326 InputFilename, Cache.release(), Context, &VerboseStrm, &StrError)); |
333 new ThreadedStreamingCache(StreamingObject), Context, &VerboseStrm, | |
334 &StrError)); | |
335 break; | 327 break; |
336 case LLVMFormat: | 328 } |
337 M.reset(getStreamedBitcodeModule( | 329 case LLVMFormat: { |
338 InputFilename, | 330 std::unique_ptr<StreamingMemoryObject> Cache( |
339 new ThreadedStreamingCache(StreamingObject), Context, &StrError)); | 331 new ThreadedStreamingCache(StreamingObject)); |
| 332 ErrorOr<std::unique_ptr<Module>> MOrErr = |
| 333 getStreamedBitcodeModule( |
| 334 InputFilename, Cache.release(), Context); |
| 335 M = std::move(*MOrErr); |
340 break; | 336 break; |
| 337 } |
341 case AutodetectFileFormat: | 338 case AutodetectFileFormat: |
342 report_fatal_error("Command can't autodetect file format!"); | 339 report_fatal_error("Command can't autodetect file format!"); |
343 } | 340 } |
344 if (!StrError.empty()) | 341 if (!StrError.empty()) |
345 Err = SMDiagnostic(InputFilename, SourceMgr::DK_Error, StrError); | 342 Err = SMDiagnostic(InputFilename, SourceMgr::DK_Error, StrError); |
346 } else { | 343 } else { |
347 #if defined(PNACL_BROWSER_TRANSLATOR) | 344 #if defined(PNACL_BROWSER_TRANSLATOR) |
348 llvm_unreachable("native client SRPC only supports streaming"); | 345 llvm_unreachable("native client SRPC only supports streaming"); |
349 #else | 346 #else |
350 // Parses binary bitcode as well as textual assembly | 347 // Parses binary bitcode as well as textual assembly |
(...skipping 19 matching lines...) Expand all Loading... |
370 ExternalizeAll("externalize", | 367 ExternalizeAll("externalize", |
371 cl::desc("Externalize all symbols"), | 368 cl::desc("Externalize all symbols"), |
372 cl::init(false)); | 369 cl::init(false)); |
373 | 370 |
374 static int runCompilePasses(Module *ModuleRef, | 371 static int runCompilePasses(Module *ModuleRef, |
375 unsigned ModuleIndex, | 372 unsigned ModuleIndex, |
376 ThreadedFunctionQueue *FuncQueue, | 373 ThreadedFunctionQueue *FuncQueue, |
377 const Triple &TheTriple, | 374 const Triple &TheTriple, |
378 TargetMachine &Target, | 375 TargetMachine &Target, |
379 StringRef ProgramName, | 376 StringRef ProgramName, |
380 formatted_raw_ostream &FOS){ | 377 raw_pwrite_stream &OS){ |
381 PNaClABIErrorReporter ABIErrorReporter; | 378 PNaClABIErrorReporter ABIErrorReporter; |
382 | 379 |
383 if (SplitModuleCount > 1 || ExternalizeAll) { | 380 if (SplitModuleCount > 1 || ExternalizeAll) { |
384 // Add function and global names, and give them external linkage. | 381 // Add function and global names, and give them external linkage. |
385 // This relies on LLVM's consistent auto-generation of names, we could | 382 // This relies on LLVM's consistent auto-generation of names, we could |
386 // maybe do our own in case something changes there. | 383 // maybe do our own in case something changes there. |
387 for (Function &F : *ModuleRef) { | 384 for (Function &F : *ModuleRef) { |
388 if (!F.hasName()) | 385 if (!F.hasName()) |
389 F.setName("Function"); | 386 F.setName("Function"); |
390 if (F.hasInternalLinkage()) | 387 if (F.hasInternalLinkage()) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 for (Module::global_iterator GI = ModuleRef->global_begin(), | 420 for (Module::global_iterator GI = ModuleRef->global_begin(), |
424 GE = ModuleRef->global_end(); | 421 GE = ModuleRef->global_end(); |
425 GI != GE; ++GI) { | 422 GI != GE; ++GI) { |
426 if (!GI->isWeakForLinker() && !GI->hasLocalLinkage()) | 423 if (!GI->isWeakForLinker() && !GI->hasLocalLinkage()) |
427 GI->setVisibility(GlobalValue::HiddenVisibility); | 424 GI->setVisibility(GlobalValue::HiddenVisibility); |
428 } | 425 } |
429 | 426 |
430 // Build up all of the passes that we want to do to the module. | 427 // Build up all of the passes that we want to do to the module. |
431 // We always use a FunctionPassManager to divide up the functions | 428 // We always use a FunctionPassManager to divide up the functions |
432 // among threads (instead of a whole-module PassManager). | 429 // among threads (instead of a whole-module PassManager). |
433 std::unique_ptr<FunctionPassManager> PM(new FunctionPassManager(ModuleRef)); | 430 std::unique_ptr<legacy::FunctionPassManager> PM( |
| 431 new legacy::FunctionPassManager(ModuleRef)); |
434 | 432 |
435 // Add the target data from the target machine, if it exists, or the module. | 433 // Add the target data from the target machine, if it exists, or the module. |
436 if (const DataLayout *DL = Target.getSubtargetImpl()->getDataLayout()) | 434 if (const DataLayout *DL = Target.getDataLayout()) |
437 ModuleRef->setDataLayout(DL); | 435 ModuleRef->setDataLayout(*DL); |
438 PM->add(new DataLayoutPass()); | |
439 | 436 |
440 // For conformance with llc, we let the user disable LLVM IR verification with | 437 // For conformance with llc, we let the user disable LLVM IR verification with |
441 // -disable-verify. Unlike llc, when LLVM IR verification is enabled we only | 438 // -disable-verify. Unlike llc, when LLVM IR verification is enabled we only |
442 // run it once, before PNaCl ABI verification. | 439 // run it once, before PNaCl ABI verification. |
443 if (!NoVerify) | 440 if (!NoVerify) |
444 PM->add(createVerifierPass()); | 441 PM->add(createVerifierPass()); |
445 | 442 |
446 // Add the ABI verifier pass before the analysis and code emission passes. | 443 // Add the ABI verifier pass before the analysis and code emission passes. |
447 if (PNaClABIVerify) | 444 if (PNaClABIVerify) |
448 PM->add(createPNaClABIVerifyFunctionsPass(&ABIErrorReporter)); | 445 PM->add(createPNaClABIVerifyFunctionsPass(&ABIErrorReporter)); |
449 | 446 |
450 // Add the intrinsic resolution pass. It assumes ABI-conformant code. | 447 // Add the intrinsic resolution pass. It assumes ABI-conformant code. |
451 PM->add(createResolvePNaClIntrinsicsPass()); | 448 PM->add(createResolvePNaClIntrinsicsPass()); |
452 | 449 |
453 // Add an appropriate TargetLibraryInfo pass for the module's triple. | 450 // Add an appropriate TargetLibraryInfo pass for the module's triple. |
454 TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple); | 451 TargetLibraryInfoImpl TLII(TheTriple); |
| 452 |
| 453 // The -disable-simplify-libcalls flag actually disables all builtin optzns. |
455 if (DisableSimplifyLibCalls) | 454 if (DisableSimplifyLibCalls) |
456 TLI->disableAllFunctions(); | 455 TLII.disableAllFunctions(); |
457 PM->add(TLI); | 456 PM->add(new TargetLibraryInfoWrapperPass(TLII)); |
458 | 457 |
459 // Allow subsequent passes and the backend to better optimize instructions | 458 // Allow subsequent passes and the backend to better optimize instructions |
460 // that were simplified for PNaCl's ABI. This pass uses the TargetLibraryInfo | 459 // that were simplified for PNaCl's ABI. This pass uses the TargetLibraryInfo |
461 // above. | 460 // above. |
462 PM->add(createBackendCanonicalizePass()); | 461 PM->add(createBackendCanonicalizePass()); |
463 | 462 |
464 // Add internal analysis passes from the target machine. | |
465 Target.addAnalysisPasses(*PM); | |
466 | |
467 // Ask the target to add backend passes as necessary. We explicitly ask it | 463 // Ask the target to add backend passes as necessary. We explicitly ask it |
468 // not to add the verifier pass because we added it earlier. | 464 // not to add the verifier pass because we added it earlier. |
469 if (Target.addPassesToEmitFile(*PM, FOS, FileType, | 465 if (Target.addPassesToEmitFile(*PM, OS, FileType, |
470 /* DisableVerify */ true)) { | 466 /* DisableVerify */ true)) { |
471 errs() << ProgramName | 467 errs() << ProgramName |
472 << ": target does not support generation of this file type!\n"; | 468 << ": target does not support generation of this file type!\n"; |
473 return 1; | 469 return 1; |
474 } | 470 } |
475 | 471 |
476 PM->doInitialization(); | 472 PM->doInitialization(); |
477 unsigned FuncIndex = 0; | 473 unsigned FuncIndex = 0; |
478 switch (SplitModuleSched) { | 474 switch (SplitModuleSched) { |
479 case SplitModuleStatic: | 475 case SplitModuleStatic: |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 Module *GlobalModuleRef, | 529 Module *GlobalModuleRef, |
534 StreamingMemoryObject *StreamingObject, | 530 StreamingMemoryObject *StreamingObject, |
535 unsigned ModuleIndex, | 531 unsigned ModuleIndex, |
536 ThreadedFunctionQueue *FuncQueue) { | 532 ThreadedFunctionQueue *FuncQueue) { |
537 std::auto_ptr<TargetMachine> | 533 std::auto_ptr<TargetMachine> |
538 target(TheTarget->createTargetMachine(TheTriple.getTriple(), | 534 target(TheTarget->createTargetMachine(TheTriple.getTriple(), |
539 MCPU, FeaturesStr, Options, | 535 MCPU, FeaturesStr, Options, |
540 RelocModel, CMModel, OLvl)); | 536 RelocModel, CMModel, OLvl)); |
541 assert(target.get() && "Could not allocate target machine!"); | 537 assert(target.get() && "Could not allocate target machine!"); |
542 TargetMachine &Target = *target.get(); | 538 TargetMachine &Target = *target.get(); |
543 // Override default to generate verbose assembly. | |
544 Target.setAsmVerbosityDefault(true); | |
545 if (RelaxAll.getNumOccurrences() > 0 && | 539 if (RelaxAll.getNumOccurrences() > 0 && |
546 FileType != TargetMachine::CGFT_ObjectFile) | 540 FileType != TargetMachine::CGFT_ObjectFile) |
547 errs() << ProgramName | 541 errs() << ProgramName |
548 << ": warning: ignoring -mc-relax-all because filetype != obj"; | 542 << ": warning: ignoring -mc-relax-all because filetype != obj"; |
549 // The OwningPtrs are only used if we are not the primary module. | 543 // The OwningPtrs are only used if we are not the primary module. |
550 std::unique_ptr<LLVMContext> C; | 544 std::unique_ptr<LLVMContext> C; |
551 std::unique_ptr<Module> M; | 545 std::unique_ptr<Module> M; |
552 Module *ModuleRef = nullptr; | 546 Module *ModuleRef = nullptr; |
553 | 547 |
554 if (ModuleIndex == 0) { | 548 if (ModuleIndex == 0) { |
(...skipping 14 matching lines...) Expand all Loading... |
569 createAddPNaClExternalDeclsPass()); | 563 createAddPNaClExternalDeclsPass()); |
570 AddPNaClExternalDeclsPass->runOnModule(*ModuleRef); | 564 AddPNaClExternalDeclsPass->runOnModule(*ModuleRef); |
571 AddPNaClExternalDeclsPass.reset(); | 565 AddPNaClExternalDeclsPass.reset(); |
572 } | 566 } |
573 | 567 |
574 ModuleRef->setTargetTriple(Triple::normalize(UserDefinedTriple)); | 568 ModuleRef->setTargetTriple(Triple::normalize(UserDefinedTriple)); |
575 | 569 |
576 { | 570 { |
577 #if !defined(PNACL_BROWSER_TRANSLATOR) | 571 #if !defined(PNACL_BROWSER_TRANSLATOR) |
578 // Figure out where we are going to send the output. | 572 // Figure out where we are going to send the output. |
579 std::string N(OutputFilename); | 573 std::string N(MainOutputFilename); |
580 raw_string_ostream OutFileName(N); | 574 raw_string_ostream OutFileName(N); |
581 if (ModuleIndex > 0) | 575 if (ModuleIndex > 0) |
582 OutFileName << ".module" << ModuleIndex; | 576 OutFileName << ".module" << ModuleIndex; |
583 std::unique_ptr<tool_output_file> Out | 577 std::unique_ptr<tool_output_file> Out = |
584 (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), | 578 GetOutputStream(TheTarget->getName(), TheTriple.getOS(), |
585 OutFileName.str())); | 579 OutFileName.str()); |
586 if (!Out) return 1; | 580 if (!Out) return 1; |
587 formatted_raw_ostream FOS(Out->os()); | 581 raw_pwrite_stream *OS = &Out->os(); |
| 582 std::unique_ptr<buffer_ostream> BOS; |
| 583 if (FileType != TargetMachine::CGFT_AssemblyFile && |
| 584 !Out->os().supportsSeeking()) { |
| 585 BOS = make_unique<buffer_ostream>(*OS); |
| 586 OS = BOS.get(); |
| 587 } |
588 #else | 588 #else |
589 raw_fd_ostream ROS(getObjectFileFD(ModuleIndex), /* ShouldClose */ true); | 589 auto OS = llvm::make_unique<raw_fd_ostream>( |
590 ROS.SetBufferSize(1 << 20); | 590 getObjectFileFD(ModuleIndex), /* ShouldClose */ true); |
591 formatted_raw_ostream FOS(ROS); | 591 OS->SetBufferSize(1 << 20); |
592 #endif | 592 #endif |
593 int ret = runCompilePasses(ModuleRef, ModuleIndex, FuncQueue, | 593 int ret = runCompilePasses(ModuleRef, ModuleIndex, FuncQueue, |
594 TheTriple, Target, ProgramName, | 594 TheTriple, Target, ProgramName, |
595 FOS); | 595 *OS); |
596 if (ret) | 596 if (ret) |
597 return ret; | 597 return ret; |
598 #if defined(PNACL_BROWSER_TRANSLATOR) | 598 #if defined(PNACL_BROWSER_TRANSLATOR) |
599 FOS.flush(); | 599 OS->flush(); |
600 ROS.flush(); | |
601 #else | 600 #else |
602 // Declare success. | 601 // Declare success. |
603 Out->keep(); | 602 Out->keep(); |
604 #endif // PNACL_BROWSER_TRANSLATOR | 603 #endif // PNACL_BROWSER_TRANSLATOR |
605 } | 604 } |
606 return 0; | 605 return 0; |
607 } | 606 } |
608 | 607 |
609 struct ThreadData { | 608 struct ThreadData { |
610 const TargetOptions *Options; | 609 const TargetOptions *Options; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 std::string Error; | 697 std::string Error; |
699 const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, | 698 const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, |
700 Error); | 699 Error); |
701 if (!TheTarget) { | 700 if (!TheTarget) { |
702 errs() << ProgramName << ": " << Error; | 701 errs() << ProgramName << ": " << Error; |
703 return 1; | 702 return 1; |
704 } | 703 } |
705 | 704 |
706 TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); | 705 TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); |
707 Options.DisableIntegratedAS = NoIntegratedAssembler; | 706 Options.DisableIntegratedAS = NoIntegratedAssembler; |
| 707 Options.MCOptions.AsmVerbose = true; |
708 | 708 |
709 if (GenerateSoftFloatCalls) | 709 if (GenerateSoftFloatCalls) |
710 FloatABIForCalls = FloatABI::Soft; | 710 FloatABIForCalls = FloatABI::Soft; |
711 | 711 |
712 // Package up features to be passed to target/subtarget | 712 // Package up features to be passed to target/subtarget |
713 std::string FeaturesStr; | 713 std::string FeaturesStr; |
714 if (MAttrs.size()) { | 714 if (MAttrs.size()) { |
715 SubtargetFeatures Features; | 715 SubtargetFeatures Features; |
716 for (unsigned i = 0; i != MAttrs.size(); ++i) | 716 for (unsigned i = 0; i != MAttrs.size(); ++i) |
717 Features.AddFeature(MAttrs[i]); | 717 Features.AddFeature(MAttrs[i]); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 return 0; | 769 return 0; |
770 } | 770 } |
771 | 771 |
772 int main(int argc, char **argv) { | 772 int main(int argc, char **argv) { |
773 #if defined(PNACL_BROWSER_TRANSLATOR) | 773 #if defined(PNACL_BROWSER_TRANSLATOR) |
774 return srpc_main(argc, argv); | 774 return srpc_main(argc, argv); |
775 #else | 775 #else |
776 return llc_main(argc, argv); | 776 return llc_main(argc, argv); |
777 #endif // PNACL_BROWSER_TRANSLATOR | 777 #endif // PNACL_BROWSER_TRANSLATOR |
778 } | 778 } |
OLD | NEW |