Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(549)

Side by Side Diff: tools/pnacl-llc/pnacl-llc.cpp

Issue 940243003: PNaCl localmod mods in LLVM to 223109 (local files only) (Closed)
Patch Set: xx Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/pnacl-llc/ThreadedStreamingCache.cpp ('k') | tools/pnacl-thaw/CMakeLists.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/Triple.h" 14 #include "llvm/ADT/Triple.h"
15 #include "llvm/Analysis/NaCl.h" 15 #include "llvm/Analysis/NaCl.h"
16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" 16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
17 #include "llvm/Bitcode/ReaderWriter.h" 17 #include "llvm/Bitcode/ReaderWriter.h"
18 #include "llvm/CodeGen/CommandFlags.h" 18 #include "llvm/CodeGen/CommandFlags.h"
19 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
20 #include "llvm/CodeGen/LinkAllCodegenComponents.h" 19 #include "llvm/CodeGen/LinkAllCodegenComponents.h"
21 #include "llvm/IR/DataLayout.h" 20 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/LLVMContext.h" 21 #include "llvm/IR/LLVMContext.h"
23 #include "llvm/IR/Module.h" 22 #include "llvm/IR/Module.h"
24 #include "llvm/IR/Verifier.h" 23 #include "llvm/IR/Verifier.h"
25 #include "llvm/IRReader/IRReader.h" 24 #include "llvm/IRReader/IRReader.h"
26 #include "llvm/MC/SubtargetFeature.h" 25 #include "llvm/MC/SubtargetFeature.h"
27 #include "llvm/Pass.h" 26 #include "llvm/Pass.h"
28 #include "llvm/PassManager.h" 27 #include "llvm/PassManager.h"
29 #include "llvm/Support/CommandLine.h" 28 #include "llvm/Support/CommandLine.h"
30 #include "llvm/Support/DataStream.h" 29 #include "llvm/Support/DataStream.h"
31 #include "llvm/Support/Debug.h" 30 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/FileSystem.h" 32 #include "llvm/Support/FileSystem.h"
34 #include "llvm/Support/FormattedStream.h" 33 #include "llvm/Support/FormattedStream.h"
35 #include "llvm/Support/Host.h" 34 #include "llvm/Support/Host.h"
36 #include "llvm/Support/ManagedStatic.h" 35 #include "llvm/Support/ManagedStatic.h"
37 #include "llvm/Support/Mutex.h"
38 #include "llvm/Support/PrettyStackTrace.h" 36 #include "llvm/Support/PrettyStackTrace.h"
39 #include "llvm/Support/Signals.h" 37 #include "llvm/Support/Signals.h"
40 #include "llvm/Support/SourceMgr.h" 38 #include "llvm/Support/SourceMgr.h"
41 #include "llvm/Support/StreamableMemoryObject.h" 39 #include "llvm/Support/StreamingMemoryObject.h"
42 #include "llvm/Support/TargetRegistry.h" 40 #include "llvm/Support/TargetRegistry.h"
43 #include "llvm/Support/TargetSelect.h" 41 #include "llvm/Support/TargetSelect.h"
44 #include "llvm/Support/ToolOutputFile.h" 42 #include "llvm/Support/ToolOutputFile.h"
45 #include "llvm/Target/TargetLibraryInfo.h" 43 #include "llvm/Target/TargetLibraryInfo.h"
46 #include "llvm/Target/TargetMachine.h" 44 #include "llvm/Target/TargetMachine.h"
45 #include "llvm/Target/TargetSubtargetInfo.h"
47 #include "llvm/Transforms/NaCl.h" 46 #include "llvm/Transforms/NaCl.h"
48 47
49 #include "ThreadedFunctionQueue.h" 48 #include "ThreadedFunctionQueue.h"
50 #include "ThreadedStreamingCache.h" 49 #include "ThreadedStreamingCache.h"
51 50
52 #include <pthread.h> 51 #include <pthread.h>
53 #include <memory> 52 #include <memory>
54 53
55 using namespace llvm; 54 using namespace llvm;
56 55
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 switch (FileType) { 218 switch (FileType) {
220 case TargetMachine::CGFT_AssemblyFile: 219 case TargetMachine::CGFT_AssemblyFile:
221 break; 220 break;
222 case TargetMachine::CGFT_ObjectFile: 221 case TargetMachine::CGFT_ObjectFile:
223 case TargetMachine::CGFT_Null: 222 case TargetMachine::CGFT_Null:
224 Binary = true; 223 Binary = true;
225 break; 224 break;
226 } 225 }
227 226
228 // Open the file. 227 // Open the file.
229 std::string error; 228 std::error_code EC;
230 sys::fs::OpenFlags OpenFlags = sys::fs::F_None; 229 sys::fs::OpenFlags OpenFlags = sys::fs::F_None;
231 if (!Binary) 230 if (!Binary)
232 OpenFlags |= sys::fs::F_Text; 231 OpenFlags |= sys::fs::F_Text;
233 tool_output_file *FDOut = 232 tool_output_file *FDOut = new tool_output_file(Filename, EC, OpenFlags);
234 new tool_output_file(Filename.c_str(), error, OpenFlags); 233 if (EC) {
235 if (!error.empty()) { 234 errs() << EC.message() << '\n';
236 errs() << error << '\n';
237 delete FDOut; 235 delete FDOut;
238 return nullptr; 236 return nullptr;
239 } 237 }
240 238
241 return FDOut; 239 return FDOut;
242 } 240 }
243 #endif // !defined(PNACL_BROWSER_TRANSLATOR) 241 #endif // !defined(PNACL_BROWSER_TRANSLATOR)
244 242
245 // main - Entry point for the llc compiler. 243 // main - Entry point for the llc compiler.
246 // 244 //
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 os << Name << " is not valid PNaCl bitcode:\n"; 310 os << Name << " is not valid PNaCl bitcode:\n";
313 Reporter.printErrors(os); 311 Reporter.printErrors(os);
314 if (PNaClABIVerifyFatalErrors) { 312 if (PNaClABIVerifyFatalErrors) {
315 report_fatal_error(os.str()); 313 report_fatal_error(os.str());
316 } 314 }
317 errs() << os.str(); 315 errs() << os.str();
318 } 316 }
319 Reporter.reset(); 317 Reporter.reset();
320 } 318 }
321 319
322 static Module* getModule(StringRef ProgramName, LLVMContext &Context, 320 static std::unique_ptr<Module> getModule(
323 StreamingMemoryObject *StreamingObject) { 321 StringRef ProgramName, LLVMContext &Context,
324 Module *M = nullptr; 322 StreamingMemoryObject *StreamingObject) {
323 std::unique_ptr<Module> M;
325 SMDiagnostic Err; 324 SMDiagnostic Err;
326 std::string VerboseBuffer; 325 std::string VerboseBuffer;
327 raw_string_ostream VerboseStrm(VerboseBuffer); 326 raw_string_ostream VerboseStrm(VerboseBuffer);
328 if (LazyBitcode) { 327 if (LazyBitcode) {
329 std::string StrError; 328 std::string StrError;
330 switch (InputFileFormat) { 329 switch (InputFileFormat) {
331 case PNaClFormat: 330 case PNaClFormat:
332 M = getNaClStreamedBitcodeModule( 331 M.reset(getNaClStreamedBitcodeModule(
333 InputFilename, 332 InputFilename,
334 new ThreadedStreamingCache(StreamingObject), Context, &VerboseStrm, 333 new ThreadedStreamingCache(StreamingObject), Context, &VerboseStrm,
335 &StrError); 334 &StrError));
336 break; 335 break;
337 case LLVMFormat: 336 case LLVMFormat:
338 M = getStreamedBitcodeModule( 337 M.reset(getStreamedBitcodeModule(
339 InputFilename, 338 InputFilename,
340 new ThreadedStreamingCache(StreamingObject), Context, &StrError); 339 new ThreadedStreamingCache(StreamingObject), Context, &StrError));
341 break; 340 break;
342 case AutodetectFileFormat: 341 case AutodetectFileFormat:
343 report_fatal_error("Command can't autodetect file format!"); 342 report_fatal_error("Command can't autodetect file format!");
344 } 343 }
345 if (!StrError.empty()) 344 if (!StrError.empty())
346 Err = SMDiagnostic(InputFilename, SourceMgr::DK_Error, StrError); 345 Err = SMDiagnostic(InputFilename, SourceMgr::DK_Error, StrError);
347 } else { 346 } else {
348 #if defined(PNACL_BROWSER_TRANSLATOR) 347 #if defined(PNACL_BROWSER_TRANSLATOR)
349 llvm_unreachable("native client SRPC only supports streaming"); 348 llvm_unreachable("native client SRPC only supports streaming");
350 #else 349 #else
351 // Parses binary bitcode as well as textual assembly 350 // Parses binary bitcode as well as textual assembly
352 // (so pulls in more code into pnacl-llc). 351 // (so pulls in more code into pnacl-llc).
353 M = NaClParseIRFile(InputFilename, InputFileFormat, Err, &VerboseStrm, 352 M = NaClParseIRFile(InputFilename, InputFileFormat, Err, &VerboseStrm,
354 Context); 353 Context);
355 #endif 354 #endif
356 } 355 }
357 if (!M) { 356 if (!M) {
358 #if defined(PNACL_BROWSER_TRANSLATOR) 357 #if defined(PNACL_BROWSER_TRANSLATOR)
359 report_fatal_error(VerboseStrm.str() + Err.getMessage()); 358 report_fatal_error(VerboseStrm.str() + Err.getMessage());
360 #else 359 #else
361 // Err.print is prettier, so use it for the non-sandboxed translator. 360 // Err.print is prettier, so use it for the non-sandboxed translator.
362 Err.print(ProgramName.data(), errs()); 361 Err.print(ProgramName.data(), errs());
363 errs() << VerboseStrm.str(); 362 errs() << VerboseStrm.str();
364 return nullptr; 363 return nullptr;
365 #endif 364 #endif
366 } 365 }
367 return M; 366 return std::move(M);
368 } 367 }
369 368
370 static cl::opt<bool> 369 static cl::opt<bool>
371 ExternalizeAll("externalize", 370 ExternalizeAll("externalize",
372 cl::desc("Externalize all symbols"), 371 cl::desc("Externalize all symbols"),
373 cl::init(false)); 372 cl::init(false));
374 373
375 static int runCompilePasses(Module *mod, 374 static int runCompilePasses(Module *ModuleRef,
jvoung (off chromium) 2015/02/24 18:38:48 Went ahead and capitalized the variable name for c
376 unsigned ModuleIndex, 375 unsigned ModuleIndex,
377 ThreadedFunctionQueue *FuncQueue, 376 ThreadedFunctionQueue *FuncQueue,
378 const Triple &TheTriple, 377 const Triple &TheTriple,
379 TargetMachine &Target, 378 TargetMachine &Target,
380 StringRef ProgramName, 379 StringRef ProgramName,
381 formatted_raw_ostream &FOS){ 380 formatted_raw_ostream &FOS){
382 PNaClABIErrorReporter ABIErrorReporter; 381 PNaClABIErrorReporter ABIErrorReporter;
383 382
384 if (SplitModuleCount > 1 || ExternalizeAll) { 383 if (SplitModuleCount > 1 || ExternalizeAll) {
385 // Add function and global names, and give them external linkage. 384 // Add function and global names, and give them external linkage.
386 // This relies on LLVM's consistent auto-generation of names, we could 385 // This relies on LLVM's consistent auto-generation of names, we could
387 // maybe do our own in case something changes there. 386 // maybe do our own in case something changes there.
388 for (Module::iterator I = mod->begin(), E = mod->end(); I != E; ++I) { 387 for (Function &F : *ModuleRef) {
389 if (!I->hasName()) 388 if (!F.hasName())
390 I->setName("Function"); 389 F.setName("Function");
391 if (I->hasInternalLinkage()) 390 if (F.hasInternalLinkage())
392 I->setLinkage(GlobalValue::ExternalLinkage); 391 F.setLinkage(GlobalValue::ExternalLinkage);
393 } 392 }
394 for (Module::global_iterator GI = mod->global_begin(), 393 for (Module::global_iterator GI = ModuleRef->global_begin(),
395 GE = mod->global_end(); 394 GE = ModuleRef->global_end();
396 GI != GE; ++GI) { 395 GI != GE; ++GI) {
397 if (!GI->hasName()) 396 if (!GI->hasName())
398 GI->setName("Global"); 397 GI->setName("Global");
399 if (GI->hasInternalLinkage()) 398 if (GI->hasInternalLinkage())
400 GI->setLinkage(GlobalValue::ExternalLinkage); 399 GI->setLinkage(GlobalValue::ExternalLinkage);
401 } 400 }
402 if (ModuleIndex > 0) { 401 if (ModuleIndex > 0) {
403 // Remove the initializers for all global variables, turning them into 402 // Remove the initializers for all global variables, turning them into
404 // declarations. 403 // declarations.
405 for (Module::global_iterator GI = mod->global_begin(), 404 for (Module::global_iterator GI = ModuleRef->global_begin(),
406 GE = mod->global_end(); 405 GE = ModuleRef->global_end();
407 GI != GE; ++GI) { 406 GI != GE; ++GI) {
408 assert(GI->hasInitializer() && "Global variable missing initializer"); 407 assert(GI->hasInitializer() && "Global variable missing initializer");
409 Constant *Init = GI->getInitializer(); 408 Constant *Init = GI->getInitializer();
410 GI->setInitializer(nullptr); 409 GI->setInitializer(nullptr);
411 if (Init->getNumUses() == 0) 410 if (Init->getNumUses() == 0)
412 Init->destroyConstant(); 411 Init->destroyConstant();
413 } 412 }
414 } 413 }
415 } 414 }
416 415
417 // Make all non-weak symbols hidden for better code. We cannot do 416 // Make all non-weak symbols hidden for better code. We cannot do
418 // this for weak symbols. The linker complains when some weak 417 // this for weak symbols. The linker complains when some weak
419 // symbols are not resolved. 418 // symbols are not resolved.
420 for (Module::iterator I = mod->begin(), E = mod->end(); I != E; ++I) { 419 for (Function &F : *ModuleRef) {
421 if (!I->isWeakForLinker() && !I->hasLocalLinkage()) 420 if (!F.isWeakForLinker() && !F.hasLocalLinkage())
422 I->setVisibility(GlobalValue::HiddenVisibility); 421 F.setVisibility(GlobalValue::HiddenVisibility);
423 } 422 }
424 for (Module::global_iterator GI = mod->global_begin(), 423 for (Module::global_iterator GI = ModuleRef->global_begin(),
425 GE = mod->global_end(); 424 GE = ModuleRef->global_end();
426 GI != GE; ++GI) { 425 GI != GE; ++GI) {
427 if (!GI->isWeakForLinker() && !GI->hasLocalLinkage()) 426 if (!GI->isWeakForLinker() && !GI->hasLocalLinkage())
428 GI->setVisibility(GlobalValue::HiddenVisibility); 427 GI->setVisibility(GlobalValue::HiddenVisibility);
429 } 428 }
430 429
431 // Build up all of the passes that we want to do to the module. 430 // Build up all of the passes that we want to do to the module.
432 std::unique_ptr<PassManagerBase> PM; 431 std::unique_ptr<PassManagerBase> PM;
433 if (LazyBitcode) 432 if (LazyBitcode)
434 PM.reset(new FunctionPassManager(mod)); 433 PM.reset(new FunctionPassManager(ModuleRef));
435 else 434 else
436 PM.reset(new PassManager()); 435 PM.reset(new PassManager());
437 436
438 // Add the target data from the target machine, if it exists, or the module. 437 // Add the target data from the target machine, if it exists, or the module.
439 if (const DataLayout *DL = Target.getDataLayout()) 438 if (const DataLayout *DL = Target.getSubtargetImpl()->getDataLayout())
440 mod->setDataLayout(DL); 439 ModuleRef->setDataLayout(DL);
441 PM->add(new DataLayoutPass(mod)); 440 PM->add(new DataLayoutPass());
442 441
443 // For conformance with llc, we let the user disable LLVM IR verification with 442 // For conformance with llc, we let the user disable LLVM IR verification with
444 // -disable-verify. Unlike llc, when LLVM IR verification is enabled we only 443 // -disable-verify. Unlike llc, when LLVM IR verification is enabled we only
445 // run it once, before PNaCl ABI verification. 444 // run it once, before PNaCl ABI verification.
446 if (!NoVerify) 445 if (!NoVerify)
447 PM->add(createVerifierPass()); 446 PM->add(createVerifierPass());
448 447
449 // Add the ABI verifier pass before the analysis and code emission passes. 448 // Add the ABI verifier pass before the analysis and code emission passes.
450 if (PNaClABIVerify) 449 if (PNaClABIVerify)
451 PM->add(createPNaClABIVerifyFunctionsPass(&ABIErrorReporter)); 450 PM->add(createPNaClABIVerifyFunctionsPass(&ABIErrorReporter));
(...skipping 23 matching lines...) Expand all
475 << ": target does not support generation of this file type!\n"; 474 << ": target does not support generation of this file type!\n";
476 return 1; 475 return 1;
477 } 476 }
478 477
479 if (LazyBitcode) { 478 if (LazyBitcode) {
480 auto FPM = static_cast<FunctionPassManager *>(PM.get()); 479 auto FPM = static_cast<FunctionPassManager *>(PM.get());
481 FPM->doInitialization(); 480 FPM->doInitialization();
482 unsigned FuncIndex = 0; 481 unsigned FuncIndex = 0;
483 switch (SplitModuleSched) { 482 switch (SplitModuleSched) {
484 case SplitModuleStatic: 483 case SplitModuleStatic:
485 for (Module::iterator I = mod->begin(), E = mod->end(); I != E; ++I) { 484 for (Function &F : *ModuleRef) {
486 if (FuncQueue->GrabFunctionStatic(FuncIndex, ModuleIndex)) { 485 if (FuncQueue->GrabFunctionStatic(FuncIndex, ModuleIndex)) {
487 FPM->run(*I); 486 FPM->run(F);
488 CheckABIVerifyErrors(ABIErrorReporter, "Function " + I->getName()); 487 CheckABIVerifyErrors(ABIErrorReporter, "Function " + F.getName());
489 I->Dematerialize(); 488 F.Dematerialize();
490 } 489 }
491 ++FuncIndex; 490 ++FuncIndex;
492 } 491 }
493 break; 492 break;
494 case SplitModuleDynamic: 493 case SplitModuleDynamic:
495 unsigned ChunkSize = 0; 494 unsigned ChunkSize = 0;
496 unsigned NumFunctions = FuncQueue->Size(); 495 unsigned NumFunctions = FuncQueue->Size();
497 Module::iterator I = mod->begin(); 496 Module::iterator I = ModuleRef->begin();
498 while (FuncIndex < NumFunctions) { 497 while (FuncIndex < NumFunctions) {
499 ChunkSize = FuncQueue->RecommendedChunkSize(); 498 ChunkSize = FuncQueue->RecommendedChunkSize();
500 unsigned NextIndex; 499 unsigned NextIndex;
501 bool grabbed = FuncQueue->GrabFunctionDynamic(FuncIndex, ChunkSize, 500 bool grabbed = FuncQueue->GrabFunctionDynamic(FuncIndex, ChunkSize,
502 NextIndex); 501 NextIndex);
503 if (grabbed) { 502 if (grabbed) {
504 while (FuncIndex < NextIndex) { 503 while (FuncIndex < NextIndex) {
505 if (!I->isMaterializable() && I->isDeclaration()) { 504 if (!I->isMaterializable() && I->isDeclaration()) {
506 ++I; 505 ++I;
507 continue; 506 continue;
(...skipping 12 matching lines...) Expand all
520 } 519 }
521 ++FuncIndex; 520 ++FuncIndex;
522 ++I; 521 ++I;
523 } 522 }
524 } 523 }
525 } 524 }
526 break; 525 break;
527 } 526 }
528 FPM->doFinalization(); 527 FPM->doFinalization();
529 } else 528 } else
530 static_cast<PassManager *>(PM.get())->run(*mod); 529 static_cast<PassManager *>(PM.get())->run(*ModuleRef);
531 530
532 return 0; 531 return 0;
533 } 532 }
534 533
535 static int compileSplitModule(const TargetOptions &Options, 534 static int compileSplitModule(const TargetOptions &Options,
536 const Triple &TheTriple, 535 const Triple &TheTriple,
537 const Target *TheTarget, 536 const Target *TheTarget,
538 const std::string &FeaturesStr, 537 const std::string &FeaturesStr,
539 CodeGenOpt::Level OLvl, 538 CodeGenOpt::Level OLvl,
540 const StringRef &ProgramName, 539 const StringRef &ProgramName,
541 Module *GlobalModule, 540 Module *GlobalModuleRef,
542 StreamingMemoryObject *StreamingObject, 541 StreamingMemoryObject *StreamingObject,
543 unsigned ModuleIndex, 542 unsigned ModuleIndex,
544 ThreadedFunctionQueue *FuncQueue) { 543 ThreadedFunctionQueue *FuncQueue) {
545 std::auto_ptr<TargetMachine> 544 std::auto_ptr<TargetMachine>
546 target(TheTarget->createTargetMachine(TheTriple.getTriple(), 545 target(TheTarget->createTargetMachine(TheTriple.getTriple(),
547 MCPU, FeaturesStr, Options, 546 MCPU, FeaturesStr, Options,
548 RelocModel, CMModel, OLvl)); 547 RelocModel, CMModel, OLvl));
549 assert(target.get() && "Could not allocate target machine!"); 548 assert(target.get() && "Could not allocate target machine!");
550 TargetMachine &Target = *target.get(); 549 TargetMachine &Target = *target.get();
551 // Override default to generate verbose assembly. 550 // Override default to generate verbose assembly.
552 Target.setAsmVerbosityDefault(true); 551 Target.setAsmVerbosityDefault(true);
553 if (RelaxAll.getNumOccurrences() > 0 && 552 if (RelaxAll.getNumOccurrences() > 0 &&
554 FileType != TargetMachine::CGFT_ObjectFile) 553 FileType != TargetMachine::CGFT_ObjectFile)
555 errs() << ProgramName 554 errs() << ProgramName
556 << ": warning: ignoring -mc-relax-all because filetype != obj"; 555 << ": warning: ignoring -mc-relax-all because filetype != obj";
557 // The OwningPtrs are only used if we are not the primary module. 556 // The OwningPtrs are only used if we are not the primary module.
558 std::unique_ptr<LLVMContext> C; 557 std::unique_ptr<LLVMContext> C;
559 std::unique_ptr<Module> M; 558 std::unique_ptr<Module> M;
560 Module *mod(nullptr); 559 Module *ModuleRef = nullptr;
561 560
562 if (ModuleIndex == 0) { 561 if (ModuleIndex == 0) {
563 mod = GlobalModule; 562 ModuleRef = GlobalModuleRef;
564 } else { 563 } else {
565 C.reset(new LLVMContext()); 564 C.reset(new LLVMContext());
566 mod = getModule(ProgramName, *C, StreamingObject); 565 M = getModule(ProgramName, *C, StreamingObject);
567 if (!mod) 566 if (!M)
568 return 1; 567 return 1;
569 M.reset(mod); 568 // M owns the temporary module, but use a reference through ModuleRef
569 // to also work in the case we are using GlobalModuleRef.
570 ModuleRef = M.get();
570 571
571 // Add declarations for external functions required by PNaCl. The 572 // Add declarations for external functions required by PNaCl. The
572 // ResolvePNaClIntrinsics function pass running during streaming 573 // ResolvePNaClIntrinsics function pass running during streaming
573 // depends on these declarations being in the module. 574 // depends on these declarations being in the module.
574 std::unique_ptr<ModulePass> AddPNaClExternalDeclsPass( 575 std::unique_ptr<ModulePass> AddPNaClExternalDeclsPass(
575 createAddPNaClExternalDeclsPass()); 576 createAddPNaClExternalDeclsPass());
576 AddPNaClExternalDeclsPass->runOnModule(*M); 577 AddPNaClExternalDeclsPass->runOnModule(*ModuleRef);
577 AddPNaClExternalDeclsPass.reset(); 578 AddPNaClExternalDeclsPass.reset();
578 } 579 }
579 580
580 mod->setTargetTriple(Triple::normalize(UserDefinedTriple)); 581 ModuleRef->setTargetTriple(Triple::normalize(UserDefinedTriple));
581 582
582 { 583 {
583 #if !defined(PNACL_BROWSER_TRANSLATOR) 584 #if !defined(PNACL_BROWSER_TRANSLATOR)
584 // Figure out where we are going to send the output. 585 // Figure out where we are going to send the output.
585 std::string N(OutputFilename); 586 std::string N(OutputFilename);
586 raw_string_ostream OutFileName(N); 587 raw_string_ostream OutFileName(N);
587 if (ModuleIndex > 0) 588 if (ModuleIndex > 0)
588 OutFileName << ".module" << ModuleIndex; 589 OutFileName << ".module" << ModuleIndex;
589 std::unique_ptr<tool_output_file> Out 590 std::unique_ptr<tool_output_file> Out
590 (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), 591 (GetOutputStream(TheTarget->getName(), TheTriple.getOS(),
591 OutFileName.str())); 592 OutFileName.str()));
592 if (!Out) return 1; 593 if (!Out) return 1;
593 formatted_raw_ostream FOS(Out->os()); 594 formatted_raw_ostream FOS(Out->os());
594 #else 595 #else
595 raw_fd_ostream ROS(getObjectFileFD(ModuleIndex), true, sys::fs::F_None); 596 raw_fd_ostream ROS(getObjectFileFD(ModuleIndex), /* ShouldClose */ true);
596 ROS.SetBufferSize(1 << 20); 597 ROS.SetBufferSize(1 << 20);
597 formatted_raw_ostream FOS(ROS); 598 formatted_raw_ostream FOS(ROS);
598 #endif 599 #endif
599 int ret = runCompilePasses(mod, ModuleIndex, FuncQueue, 600 int ret = runCompilePasses(ModuleRef, ModuleIndex, FuncQueue,
600 TheTriple, Target, ProgramName, 601 TheTriple, Target, ProgramName,
601 FOS); 602 FOS);
602 if (ret) 603 if (ret)
603 return ret; 604 return ret;
604 #if defined(PNACL_BROWSER_TRANSLATOR) 605 #if defined(PNACL_BROWSER_TRANSLATOR)
605 FOS.flush(); 606 FOS.flush();
606 ROS.flush(); 607 ROS.flush();
607 #else 608 #else
608 // Declare success. 609 // Declare success.
609 Out->keep(); 610 Out->keep();
610 #endif // PNACL_BROWSER_TRANSLATOR 611 #endif // PNACL_BROWSER_TRANSLATOR
611 } 612 }
612 return 0; 613 return 0;
613 } 614 }
614 615
615 struct ThreadData { 616 struct ThreadData {
616 const TargetOptions *Options; 617 const TargetOptions *Options;
617 const Triple *TheTriple; 618 const Triple *TheTriple;
618 const Target *TheTarget; 619 const Target *TheTarget;
619 std::string FeaturesStr; 620 std::string FeaturesStr;
620 CodeGenOpt::Level OLvl; 621 CodeGenOpt::Level OLvl;
621 std::string ProgramName; 622 std::string ProgramName;
622 Module *GlobalModule; 623 Module *GlobalModuleRef;
623 StreamingMemoryObject *StreamingObject; 624 StreamingMemoryObject *StreamingObject;
624 unsigned ModuleIndex; 625 unsigned ModuleIndex;
625 ThreadedFunctionQueue *FuncQueue; 626 ThreadedFunctionQueue *FuncQueue;
626 }; 627 };
627 628
628 629
629 static void *runCompileThread(void *arg) { 630 static void *runCompileThread(void *arg) {
630 struct ThreadData *Data = static_cast<ThreadData *>(arg); 631 struct ThreadData *Data = static_cast<ThreadData *>(arg);
631 int ret = compileSplitModule(*Data->Options, 632 int ret = compileSplitModule(*Data->Options,
632 *Data->TheTriple, 633 *Data->TheTriple,
633 Data->TheTarget, 634 Data->TheTarget,
634 Data->FeaturesStr, 635 Data->FeaturesStr,
635 Data->OLvl, 636 Data->OLvl,
636 Data->ProgramName, 637 Data->ProgramName,
637 Data->GlobalModule, 638 Data->GlobalModuleRef,
638 Data->StreamingObject, 639 Data->StreamingObject,
639 Data->ModuleIndex, 640 Data->ModuleIndex,
640 Data->FuncQueue); 641 Data->FuncQueue);
641 return reinterpret_cast<void *>(static_cast<intptr_t>(ret)); 642 return reinterpret_cast<void *>(static_cast<intptr_t>(ret));
642 } 643 }
643 644
644 static int compileModule(StringRef ProgramName) { 645 static int compileModule(StringRef ProgramName) {
645 // Use a new context instead of the global context for the main module. It mus t 646 // Use a new context instead of the global context for the main module. It mus t
646 // outlive the module object, declared below. We do this because 647 // outlive the module object, declared below. We do this because
647 // lib/CodeGen/PseudoSourceValue.cpp gets a type from the global context and 648 // lib/CodeGen/PseudoSourceValue.cpp gets a type from the global context and
648 // races with any other use of the context. Rather than doing an invasive 649 // races with any other use of the context. Rather than doing an invasive
649 // plumbing change to fix it, we work around it by using a new context here 650 // plumbing change to fix it, we work around it by using a new context here
650 // and leaving PseudoSourceValue as the only user of the global context. 651 // and leaving PseudoSourceValue as the only user of the global context.
651 std::unique_ptr<LLVMContext> MainContext(new LLVMContext()); 652 std::unique_ptr<LLVMContext> MainContext(new LLVMContext());
652 std::unique_ptr<Module> mod; 653 std::unique_ptr<Module> MainMod;
653 Triple TheTriple; 654 Triple TheTriple;
654 PNaClABIErrorReporter ABIErrorReporter; 655 PNaClABIErrorReporter ABIErrorReporter;
655 std::unique_ptr<StreamingMemoryObject> StreamingObject; 656 std::unique_ptr<StreamingMemoryObject> StreamingObject;
656 657
657 if (!MainContext) return 1; 658 if (!MainContext) return 1;
658 659
659 #if defined(PNACL_BROWSER_TRANSLATOR) 660 #if defined(PNACL_BROWSER_TRANSLATOR)
660 StreamingObject.reset( 661 StreamingObject.reset(
661 new StreamingMemoryObjectImpl(getNaClBitcodeStreamer())); 662 new StreamingMemoryObjectImpl(getNaClBitcodeStreamer()));
662 #else 663 #else
663 if (LazyBitcode) { 664 if (LazyBitcode) {
664 std::string StrError; 665 std::string StrError;
665 DataStreamer* FileStreamer(getDataFileStreamer(InputFilename, &StrError)); 666 DataStreamer* FileStreamer(getDataFileStreamer(InputFilename, &StrError));
666 if (!StrError.empty()) { 667 if (!StrError.empty()) {
667 SMDiagnostic Err(InputFilename, SourceMgr::DK_Error, StrError); 668 SMDiagnostic Err(InputFilename, SourceMgr::DK_Error, StrError);
668 Err.print(ProgramName.data(), errs()); 669 Err.print(ProgramName.data(), errs());
669 } 670 }
670 if (!FileStreamer) 671 if (!FileStreamer)
671 return 1; 672 return 1;
672 StreamingObject.reset(new StreamingMemoryObjectImpl(FileStreamer)); 673 StreamingObject.reset(new StreamingMemoryObjectImpl(FileStreamer));
673 } 674 }
674 #endif 675 #endif
675 mod.reset(getModule(ProgramName, *MainContext.get(), StreamingObject.get())); 676 MainMod = getModule(ProgramName, *MainContext.get(), StreamingObject.get());
676 677
677 if (!mod) return 1; 678 if (!MainMod) return 1;
678 679
679 if (PNaClABIVerify) { 680 if (PNaClABIVerify) {
680 // Verify the module (but not the functions yet) 681 // Verify the module (but not the functions yet)
681 std::unique_ptr<ModulePass> VerifyPass( 682 std::unique_ptr<ModulePass> VerifyPass(
682 createPNaClABIVerifyModulePass(&ABIErrorReporter, LazyBitcode)); 683 createPNaClABIVerifyModulePass(&ABIErrorReporter, LazyBitcode));
683 VerifyPass->runOnModule(*mod); 684 VerifyPass->runOnModule(*MainMod);
684 CheckABIVerifyErrors(ABIErrorReporter, "Module"); 685 CheckABIVerifyErrors(ABIErrorReporter, "Module");
685 VerifyPass.reset(); 686 VerifyPass.reset();
686 } 687 }
687 688
688 // Add declarations for external functions required by PNaCl. The 689 // Add declarations for external functions required by PNaCl. The
689 // ResolvePNaClIntrinsics function pass running during streaming 690 // ResolvePNaClIntrinsics function pass running during streaming
690 // depends on these declarations being in the module. 691 // depends on these declarations being in the module.
691 std::unique_ptr<ModulePass> AddPNaClExternalDeclsPass( 692 std::unique_ptr<ModulePass> AddPNaClExternalDeclsPass(
692 createAddPNaClExternalDeclsPass()); 693 createAddPNaClExternalDeclsPass());
693 AddPNaClExternalDeclsPass->runOnModule(*mod); 694 AddPNaClExternalDeclsPass->runOnModule(*MainMod);
694 AddPNaClExternalDeclsPass.reset(); 695 AddPNaClExternalDeclsPass.reset();
695 696
696 if (UserDefinedTriple.empty()) { 697 if (UserDefinedTriple.empty()) {
697 report_fatal_error("-mtriple must be set to a target triple for pnacl-llc"); 698 report_fatal_error("-mtriple must be set to a target triple for pnacl-llc");
698 } else { 699 } else {
699 mod->setTargetTriple(Triple::normalize(UserDefinedTriple)); 700 MainMod->setTargetTriple(Triple::normalize(UserDefinedTriple));
700 TheTriple = Triple(mod->getTargetTriple()); 701 TheTriple = Triple(MainMod->getTargetTriple());
701 } 702 }
702 703
703 // Get the target specific parser. 704 // Get the target specific parser.
704 std::string Error; 705 std::string Error;
705 const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, 706 const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
706 Error); 707 Error);
707 if (!TheTarget) { 708 if (!TheTarget) {
708 errs() << ProgramName << ": " << Error; 709 errs() << ProgramName << ": " << Error;
709 return 1; 710 return 1;
710 } 711 }
(...skipping 20 matching lines...) Expand all
731 return 1; 732 return 1;
732 case ' ': break; 733 case ' ': break;
733 case '0': OLvl = CodeGenOpt::None; break; 734 case '0': OLvl = CodeGenOpt::None; break;
734 case '1': OLvl = CodeGenOpt::Less; break; 735 case '1': OLvl = CodeGenOpt::Less; break;
735 case '2': OLvl = CodeGenOpt::Default; break; 736 case '2': OLvl = CodeGenOpt::Default; break;
736 case '3': OLvl = CodeGenOpt::Aggressive; break; 737 case '3': OLvl = CodeGenOpt::Aggressive; break;
737 } 738 }
738 739
739 SmallVector<pthread_t, 4> Pthreads(SplitModuleCount); 740 SmallVector<pthread_t, 4> Pthreads(SplitModuleCount);
740 SmallVector<ThreadData, 4> ThreadDatas(SplitModuleCount); 741 SmallVector<ThreadData, 4> ThreadDatas(SplitModuleCount);
741 ThreadedFunctionQueue FuncQueue(mod.get(), SplitModuleCount); 742 ThreadedFunctionQueue FuncQueue(MainMod.get(), SplitModuleCount);
742 743
743 if (SplitModuleCount == 1) { 744 if (SplitModuleCount == 1) {
744 // No need for dynamic scheduling with one thread. 745 // No need for dynamic scheduling with one thread.
745 SplitModuleSched = SplitModuleStatic; 746 SplitModuleSched = SplitModuleStatic;
746 return compileSplitModule(Options, TheTriple, TheTarget, FeaturesStr, 747 return compileSplitModule(Options, TheTriple, TheTarget, FeaturesStr,
747 OLvl, ProgramName, mod.get(), nullptr, 0, 748 OLvl, ProgramName, MainMod.get(), nullptr, 0,
748 &FuncQueue); 749 &FuncQueue);
749 } 750 }
750 751
751 for(unsigned ModuleIndex = 0; ModuleIndex < SplitModuleCount; ++ModuleIndex) { 752 for(unsigned ModuleIndex = 0; ModuleIndex < SplitModuleCount; ++ModuleIndex) {
752 ThreadDatas[ModuleIndex].Options = &Options; 753 ThreadDatas[ModuleIndex].Options = &Options;
753 ThreadDatas[ModuleIndex].TheTriple = &TheTriple; 754 ThreadDatas[ModuleIndex].TheTriple = &TheTriple;
754 ThreadDatas[ModuleIndex].TheTarget = TheTarget; 755 ThreadDatas[ModuleIndex].TheTarget = TheTarget;
755 ThreadDatas[ModuleIndex].FeaturesStr = FeaturesStr; 756 ThreadDatas[ModuleIndex].FeaturesStr = FeaturesStr;
756 ThreadDatas[ModuleIndex].OLvl = OLvl; 757 ThreadDatas[ModuleIndex].OLvl = OLvl;
757 ThreadDatas[ModuleIndex].ProgramName = ProgramName.str(); 758 ThreadDatas[ModuleIndex].ProgramName = ProgramName.str();
758 ThreadDatas[ModuleIndex].GlobalModule = mod.get(); 759 ThreadDatas[ModuleIndex].GlobalModuleRef = MainMod.get();
759 ThreadDatas[ModuleIndex].StreamingObject = StreamingObject.get(); 760 ThreadDatas[ModuleIndex].StreamingObject = StreamingObject.get();
760 ThreadDatas[ModuleIndex].ModuleIndex = ModuleIndex; 761 ThreadDatas[ModuleIndex].ModuleIndex = ModuleIndex;
761 ThreadDatas[ModuleIndex].FuncQueue = &FuncQueue; 762 ThreadDatas[ModuleIndex].FuncQueue = &FuncQueue;
762 if (pthread_create(&Pthreads[ModuleIndex], nullptr, runCompileThread, 763 if (pthread_create(&Pthreads[ModuleIndex], nullptr, runCompileThread,
763 &ThreadDatas[ModuleIndex])) { 764 &ThreadDatas[ModuleIndex])) {
764 report_fatal_error("Failed to create thread"); 765 report_fatal_error("Failed to create thread");
765 } 766 }
766 } 767 }
767 for(unsigned ModuleIndex = 0; ModuleIndex < SplitModuleCount; ++ModuleIndex) { 768 for(unsigned ModuleIndex = 0; ModuleIndex < SplitModuleCount; ++ModuleIndex) {
768 void *retval; 769 void *retval;
769 if (pthread_join(Pthreads[ModuleIndex], &retval)) 770 if (pthread_join(Pthreads[ModuleIndex], &retval))
770 report_fatal_error("Failed to join thread"); 771 report_fatal_error("Failed to join thread");
771 intptr_t ret = reinterpret_cast<intptr_t>(retval); 772 intptr_t ret = reinterpret_cast<intptr_t>(retval);
772 if (ret != 0) 773 if (ret != 0)
773 report_fatal_error("Thread returned nonzero"); 774 report_fatal_error("Thread returned nonzero");
774 } 775 }
775 return 0; 776 return 0;
776 } 777 }
777 778
778 int main(int argc, char **argv) { 779 int main(int argc, char **argv) {
779 #if defined(PNACL_BROWSER_TRANSLATOR) 780 #if defined(PNACL_BROWSER_TRANSLATOR)
780 return srpc_main(argc, argv); 781 return srpc_main(argc, argv);
781 #else 782 #else
782 return llc_main(argc, argv); 783 return llc_main(argc, argv);
783 #endif // PNACL_BROWSER_TRANSLATOR 784 #endif // PNACL_BROWSER_TRANSLATOR
784 } 785 }
OLDNEW
« no previous file with comments | « tools/pnacl-llc/ThreadedStreamingCache.cpp ('k') | tools/pnacl-thaw/CMakeLists.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698