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