OLD | NEW |
(Empty) | |
| 1 //===- subzero/src/IceCompiler.cpp - Driver for bitcode translation -------===// |
| 2 // |
| 3 // The Subzero Code Generator |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 // |
| 10 // This file defines a driver for translating PNaCl bitcode into native code. |
| 11 // It can either directly parse the binary bitcode file, or use LLVM routines to |
| 12 // parse a textual bitcode file into LLVM IR and then convert LLVM IR into ICE. |
| 13 // In either case, the high-level ICE is then compiled down to native code, as |
| 14 // either an ELF object file or a textual asm file. |
| 15 // |
| 16 //===----------------------------------------------------------------------===// |
| 17 |
| 18 #include "llvm/ADT/STLExtras.h" |
| 19 #include "llvm/IR/LLVMContext.h" |
| 20 #include "llvm/IR/Module.h" |
| 21 #include "llvm/IRReader/IRReader.h" |
| 22 #include "llvm/Support/SourceMgr.h" |
| 23 #include "llvm/Support/StreamingMemoryObject.h" |
| 24 |
| 25 #include "IceCfg.h" |
| 26 #include "IceClFlags.h" |
| 27 #include "IceClFlagsExtra.h" |
| 28 #include "IceCompiler.h" |
| 29 #include "IceConverter.h" |
| 30 #include "IceELFObjectWriter.h" |
| 31 #include "PNaClTranslator.h" |
| 32 namespace Ice { |
| 33 |
| 34 namespace { |
| 35 |
| 36 struct { |
| 37 const char *FlagName; |
| 38 int FlagValue; |
| 39 } ConditionalBuildAttributes[] = {{"dump", ALLOW_DUMP}, |
| 40 {"disable_ir_gen", ALLOW_DISABLE_IR_GEN}, |
| 41 {"llvm_cl", ALLOW_LLVM_CL}, |
| 42 {"llvm_ir", ALLOW_LLVM_IR}, |
| 43 {"llvm_ir_as_input", ALLOW_LLVM_IR_AS_INPUT}, |
| 44 {"minimal_build", ALLOW_MINIMAL_BUILD}, |
| 45 {"browser_mode", PNACL_BROWSER_TRANSLATOR}}; |
| 46 |
| 47 // Validates values of build attributes. Prints them to Stream if |
| 48 // Stream is non-null. |
| 49 void ValidateAndGenerateBuildAttributes(const ClFlags &Flags, Ostream *Stream) { |
| 50 if (Stream) |
| 51 *Stream << Flags.getTargetArch() << "\n"; |
| 52 |
| 53 for (size_t i = 0; i < llvm::array_lengthof(ConditionalBuildAttributes); |
| 54 ++i) { |
| 55 switch (ConditionalBuildAttributes[i].FlagValue) { |
| 56 case 0: |
| 57 if (Stream) |
| 58 *Stream << "no_" << ConditionalBuildAttributes[i].FlagName << "\n"; |
| 59 break; |
| 60 case 1: |
| 61 if (Stream) |
| 62 *Stream << "allow_" << ConditionalBuildAttributes[i].FlagName << "\n"; |
| 63 break; |
| 64 default: { |
| 65 std::string Buffer; |
| 66 llvm::raw_string_ostream StrBuf(Buffer); |
| 67 StrBuf << "Flag " << ConditionalBuildAttributes[i].FlagName |
| 68 << " must be defined as 0/1. Found: " |
| 69 << ConditionalBuildAttributes[i].FlagValue; |
| 70 llvm::report_fatal_error(StrBuf.str()); |
| 71 } |
| 72 } |
| 73 } |
| 74 } |
| 75 |
| 76 } // end of anonymous namespace |
| 77 |
| 78 void Compiler::run(const Ice::ClFlagsExtra &ExtraFlags, GlobalContext &Ctx, |
| 79 std::unique_ptr<llvm::DataStreamer> &&InputStream) { |
| 80 ValidateAndGenerateBuildAttributes( |
| 81 Ctx.getFlags(), |
| 82 ExtraFlags.getGenerateBuildAtts() ? &Ctx.getStrDump() : nullptr); |
| 83 if (ExtraFlags.getGenerateBuildAtts()) |
| 84 return Ctx.getErrorStatus()->assign(EC_None); |
| 85 |
| 86 if (!ALLOW_DISABLE_IR_GEN && Ctx.getFlags().getDisableIRGeneration()) { |
| 87 Ctx.getStrDump() << "Error: Build doesn't allow --no-ir-gen when not " |
| 88 << "ALLOW_DISABLE_IR_GEN!\n"; |
| 89 return Ctx.getErrorStatus()->assign(EC_Args); |
| 90 } |
| 91 |
| 92 // Force -build-on-read=0 for .ll files. |
| 93 const std::string LLSuffix = ".ll"; |
| 94 const IceString &IRFilename = ExtraFlags.getIRFilename(); |
| 95 bool BuildOnRead = ExtraFlags.getBuildOnRead(); |
| 96 if (ALLOW_LLVM_IR_AS_INPUT && IRFilename.length() >= LLSuffix.length() && |
| 97 IRFilename.compare(IRFilename.length() - LLSuffix.length(), |
| 98 LLSuffix.length(), LLSuffix) == 0) |
| 99 BuildOnRead = false; |
| 100 |
| 101 TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); |
| 102 |
| 103 if (Ctx.getFlags().getOutFileType() == FT_Elf) { |
| 104 TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); |
| 105 Ctx.getObjectWriter()->writeInitialELFHeader(); |
| 106 } |
| 107 |
| 108 Ctx.startWorkerThreads(); |
| 109 |
| 110 std::unique_ptr<Translator> Translator; |
| 111 if (BuildOnRead) { |
| 112 std::unique_ptr<PNaClTranslator> PTranslator(new PNaClTranslator(&Ctx)); |
| 113 std::unique_ptr<llvm::StreamingMemoryObject> MemObj( |
| 114 new llvm::StreamingMemoryObjectImpl(InputStream.release())); |
| 115 PTranslator->translate(IRFilename, std::move(MemObj)); |
| 116 Translator.reset(PTranslator.release()); |
| 117 } else if (ALLOW_LLVM_IR) { |
| 118 if (PNACL_BROWSER_TRANSLATOR) { |
| 119 Ctx.getStrDump() |
| 120 << "non BuildOnRead is not supported w/ PNACL_BROWSER_TRANSLATOR\n"; |
| 121 return Ctx.getErrorStatus()->assign(EC_Args); |
| 122 } |
| 123 // Parse the input LLVM IR file into a module. |
| 124 llvm::SMDiagnostic Err; |
| 125 TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); |
| 126 llvm::raw_ostream *Verbose = |
| 127 ExtraFlags.getLLVMVerboseErrors() ? &llvm::errs() : nullptr; |
| 128 std::unique_ptr<llvm::Module> Mod = |
| 129 NaClParseIRFile(IRFilename, ExtraFlags.getInputFileFormat(), Err, |
| 130 Verbose, llvm::getGlobalContext()); |
| 131 if (!Mod) { |
| 132 Err.print(ExtraFlags.getAppName().c_str(), llvm::errs()); |
| 133 return Ctx.getErrorStatus()->assign(EC_Bitcode); |
| 134 } |
| 135 |
| 136 std::unique_ptr<Converter> Converter(new class Converter(Mod.get(), &Ctx)); |
| 137 Converter->convertToIce(); |
| 138 Translator.reset(Converter.release()); |
| 139 } else { |
| 140 Ctx.getStrDump() << "Error: Build doesn't allow LLVM IR, " |
| 141 << "--build-on-read=0 not allowed\n"; |
| 142 return Ctx.getErrorStatus()->assign(EC_Args); |
| 143 } |
| 144 |
| 145 Ctx.waitForWorkerThreads(); |
| 146 Translator->transferErrorCode(); |
| 147 Translator->emitConstants(); |
| 148 |
| 149 if (Ctx.getFlags().getOutFileType() == FT_Elf) { |
| 150 TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); |
| 151 Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms()); |
| 152 Ctx.getObjectWriter()->writeNonUserSections(); |
| 153 } |
| 154 if (Ctx.getFlags().getSubzeroTimingEnabled()) |
| 155 Ctx.dumpTimers(); |
| 156 if (Ctx.getFlags().getTimeEachFunction()) { |
| 157 const bool DumpCumulative = false; |
| 158 Ctx.dumpTimers(GlobalContext::TSK_Funcs, DumpCumulative); |
| 159 } |
| 160 const bool FinalStats = true; |
| 161 Ctx.dumpStats("_FINAL_", FinalStats); |
| 162 } |
| 163 |
| 164 } // end of namespace Ice |
OLD | NEW |