| OLD | NEW |
| 1 //===- subzero/src/main.cpp - Driver for bitcode translation --------------===// | 1 //===- subzero/src/IceCompiler.cpp - Driver for bitcode translation -------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file defines a driver for translating PNaCl bitcode into native code. | 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 | 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. | 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 | 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. | 14 // either an ELF object file or a textual asm file. |
| 15 // | 15 // |
| 16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
| 17 | 17 |
| 18 #include "IceCompiler.h" |
| 19 |
| 18 #include <fstream> | 20 #include <fstream> |
| 19 #include <iostream> | 21 #include <iostream> |
| 20 | 22 |
| 21 #include "llvm/ADT/STLExtras.h" | 23 #include "llvm/ADT/STLExtras.h" |
| 22 #include "llvm/IR/LLVMContext.h" | 24 #include "llvm/IR/LLVMContext.h" |
| 23 #include "llvm/IR/Module.h" | 25 #include "llvm/IR/Module.h" |
| 24 #include "llvm/IRReader/IRReader.h" | 26 #include "llvm/IRReader/IRReader.h" |
| 25 #include "llvm/Support/CommandLine.h" | 27 #include "llvm/Support/CommandLine.h" |
| 26 #include "llvm/Support/FileSystem.h" | 28 #include "llvm/Support/FileSystem.h" |
| 27 #include "llvm/Support/raw_os_ostream.h" | 29 #include "llvm/Support/raw_os_ostream.h" |
| 28 #include "llvm/Support/SourceMgr.h" | 30 #include "llvm/Support/SourceMgr.h" |
| 29 #include "llvm/Support/StreamingMemoryObject.h" | 31 #include "llvm/Support/StreamingMemoryObject.h" |
| 30 | 32 |
| 31 #include "IceCfg.h" | 33 #include "IceCfg.h" |
| 32 #include "IceClFlags.h" | 34 #include "IceClFlags.h" |
| 35 #include "IceCompileServer.h" |
| 33 #include "IceConverter.h" | 36 #include "IceConverter.h" |
| 34 #include "IceELFObjectWriter.h" | 37 #include "IceELFObjectWriter.h" |
| 35 #include "IceELFStreamer.h" | 38 #include "IceELFStreamer.h" |
| 36 #include "PNaClTranslator.h" | 39 #include "PNaClTranslator.h" |
| 37 | 40 |
| 38 using namespace llvm; | 41 using namespace llvm; |
| 39 | 42 |
| 40 static cl::list<Ice::VerboseItem> VerboseList( | 43 static cl::list<Ice::VerboseItem> VerboseList( |
| 41 "verbose", cl::CommaSeparated, | 44 "verbose", cl::CommaSeparated, |
| 42 cl::desc("Verbose options (can be comma-separated):"), | 45 cl::desc("Verbose options (can be comma-separated):"), |
| 43 cl::values( | 46 cl::values( |
| 44 clEnumValN(Ice::IceV_Instructions, "inst", "Print basic instructions"), | 47 clEnumValN(Ice::IceV_Instructions, "inst", "Print basic instructions"), |
| 45 clEnumValN(Ice::IceV_Deleted, "del", "Include deleted instructions"), | 48 clEnumValN(Ice::IceV_Deleted, "del", "Include deleted instructions"), |
| 46 clEnumValN(Ice::IceV_InstNumbers, "instnum", | 49 clEnumValN(Ice::IceV_InstNumbers, "instnum", |
| 47 "Print instruction numbers"), | 50 "Print instruction numbers"), |
| 48 clEnumValN(Ice::IceV_Preds, "pred", "Show predecessors"), | 51 clEnumValN(Ice::IceV_Preds, "pred", "Show predecessors"), |
| 49 clEnumValN(Ice::IceV_Succs, "succ", "Show successors"), | 52 clEnumValN(Ice::IceV_Succs, "succ", "Show successors"), |
| 50 clEnumValN(Ice::IceV_Liveness, "live", "Liveness information"), | 53 clEnumValN(Ice::IceV_Liveness, "live", "Liveness information"), |
| 51 clEnumValN(Ice::IceV_RegOrigins, "orig", "Physical register origins"), | 54 clEnumValN(Ice::IceV_RegOrigins, "orig", "Physical register origins"), |
| 52 clEnumValN(Ice::IceV_LinearScan, "regalloc", "Linear scan details"), | 55 clEnumValN(Ice::IceV_LinearScan, "regalloc", "Linear scan details"), |
| 53 clEnumValN(Ice::IceV_Frame, "frame", "Stack frame layout details"), | 56 clEnumValN(Ice::IceV_Frame, "frame", "Stack frame layout details"), |
| 54 clEnumValN(Ice::IceV_AddrOpt, "addropt", "Address mode optimization"), | 57 clEnumValN(Ice::IceV_AddrOpt, "addropt", "Address mode optimization"), |
| 55 clEnumValN(Ice::IceV_Random, "random", "Randomization details"), | 58 clEnumValN(Ice::IceV_Random, "random", "Randomization details"), |
| 56 clEnumValN(Ice::IceV_All, "all", "Use all verbose options"), | 59 clEnumValN(Ice::IceV_All, "all", "Use all verbose options"), |
| 57 clEnumValN(Ice::IceV_Most, "most", | 60 clEnumValN(Ice::IceV_Most, "most", |
| 58 "Use all verbose options except 'regalloc' and 'time'"), | 61 "Use all verbose options except 'regalloc' and 'time'"), |
| 59 clEnumValN(Ice::IceV_None, "none", "No verbosity"), clEnumValEnd)); | 62 clEnumValN(Ice::IceV_None, "none", "No verbosity"), clEnumValEnd)); |
| 60 static cl::opt<Ice::TargetArch> TargetArch( | 63 static cl::opt<Ice::TargetArch> |
| 61 "target", cl::desc("Target architecture:"), cl::init(Ice::Target_X8632), | 64 TArch("target", cl::desc("Target architecture:"), |
| 62 cl::values( | 65 cl::init(Ice::Target_X8632), |
| 63 clEnumValN(Ice::Target_X8632, "x8632", "x86-32"), | 66 cl::values( |
| 64 clEnumValN(Ice::Target_X8632, "x86-32", "x86-32 (same as x8632)"), | 67 clEnumValN(Ice::Target_X8632, "x8632", "x86-32"), |
| 65 clEnumValN(Ice::Target_X8632, "x86_32", "x86-32 (same as x8632)"), | 68 clEnumValN(Ice::Target_X8632, "x86-32", "x86-32 (same as x8632)"), |
| 66 clEnumValN(Ice::Target_X8664, "x8664", "x86-64"), | 69 clEnumValN(Ice::Target_X8632, "x86_32", "x86-32 (same as x8632)"), |
| 67 clEnumValN(Ice::Target_X8664, "x86-64", "x86-64 (same as x8664)"), | 70 clEnumValN(Ice::Target_X8664, "x8664", "x86-64"), |
| 68 clEnumValN(Ice::Target_X8664, "x86_64", "x86-64 (same as x8664)"), | 71 clEnumValN(Ice::Target_X8664, "x86-64", "x86-64 (same as x8664)"), |
| 69 clEnumValN(Ice::Target_ARM32, "arm", "arm32"), | 72 clEnumValN(Ice::Target_X8664, "x86_64", "x86-64 (same as x8664)"), |
| 70 clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"), | 73 clEnumValN(Ice::Target_ARM32, "arm", "arm32"), |
| 71 clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd)); | 74 clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"), |
| 75 clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd)); |
| 72 static cl::opt<bool> UseSandboxing("sandbox", cl::desc("Use sandboxing")); | 76 static cl::opt<bool> UseSandboxing("sandbox", cl::desc("Use sandboxing")); |
| 73 static cl::opt<bool> | 77 static cl::opt<bool> |
| 74 FunctionSections("ffunction-sections", | 78 FunctionSections("ffunction-sections", |
| 75 cl::desc("Emit functions into separate sections")); | 79 cl::desc("Emit functions into separate sections")); |
| 76 static cl::opt<bool> | 80 static cl::opt<bool> |
| 77 DataSections("fdata-sections", | 81 DataSections("fdata-sections", |
| 78 cl::desc("Emit (global) data into separate sections")); | 82 cl::desc("Emit (global) data into separate sections")); |
| 79 static cl::opt<Ice::OptLevel> | 83 static cl::opt<Ice::OptLevel> |
| 80 OptLevel(cl::desc("Optimization level"), cl::init(Ice::Opt_m1), | 84 OLevel(cl::desc("Optimization level"), cl::init(Ice::Opt_m1), |
| 81 cl::value_desc("level"), | 85 cl::value_desc("level"), |
| 82 cl::values(clEnumValN(Ice::Opt_m1, "Om1", "-1"), | 86 cl::values(clEnumValN(Ice::Opt_m1, "Om1", "-1"), |
| 83 clEnumValN(Ice::Opt_m1, "O-1", "-1"), | 87 clEnumValN(Ice::Opt_m1, "O-1", "-1"), |
| 84 clEnumValN(Ice::Opt_0, "O0", "0"), | 88 clEnumValN(Ice::Opt_0, "O0", "0"), |
| 85 clEnumValN(Ice::Opt_1, "O1", "1"), | 89 clEnumValN(Ice::Opt_1, "O1", "1"), |
| 86 clEnumValN(Ice::Opt_2, "O2", "2"), clEnumValEnd)); | 90 clEnumValN(Ice::Opt_2, "O2", "2"), clEnumValEnd)); |
| 87 static cl::opt<std::string> IRFilename(cl::Positional, cl::desc("<IR file>"), | 91 static cl::opt<std::string> IRFilename(cl::Positional, cl::desc("<IR file>"), |
| 88 cl::init("-")); | 92 cl::init("-")); |
| 89 static cl::opt<std::string> OutputFilename("o", | 93 static cl::opt<std::string> OutputFilename("o", |
| 90 cl::desc("Override output filename"), | 94 cl::desc("Override output filename"), |
| 91 cl::init("-"), | 95 cl::init("-"), |
| 92 cl::value_desc("filename")); | 96 cl::value_desc("filename")); |
| 93 static cl::opt<std::string> LogFilename("log", cl::desc("Set log filename"), | 97 static cl::opt<std::string> LogFilename("log", cl::desc("Set log filename"), |
| 94 cl::init("-"), | 98 cl::init("-"), |
| 95 cl::value_desc("filename")); | 99 cl::value_desc("filename")); |
| 96 static cl::opt<std::string> | 100 static cl::opt<std::string> |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 {"llvm_cl", ALLOW_LLVM_CL}, | 235 {"llvm_cl", ALLOW_LLVM_CL}, |
| 232 {"llvm_ir", ALLOW_LLVM_IR}, | 236 {"llvm_ir", ALLOW_LLVM_IR}, |
| 233 {"llvm_ir_as_input", ALLOW_LLVM_IR_AS_INPUT}, | 237 {"llvm_ir_as_input", ALLOW_LLVM_IR_AS_INPUT}, |
| 234 {"minimal_build", ALLOW_MINIMAL_BUILD}}; | 238 {"minimal_build", ALLOW_MINIMAL_BUILD}}; |
| 235 | 239 |
| 236 // Validates values of build attributes. Prints them to Stream if | 240 // Validates values of build attributes. Prints them to Stream if |
| 237 // Stream is non-null. | 241 // Stream is non-null. |
| 238 static void ValidateAndGenerateBuildAttributes(Ice::Ostream *Stream) { | 242 static void ValidateAndGenerateBuildAttributes(Ice::Ostream *Stream) { |
| 239 | 243 |
| 240 if (Stream) | 244 if (Stream) |
| 241 *Stream << TargetArch << "\n"; | 245 *Stream << TArch << "\n"; |
| 242 | 246 |
| 243 for (size_t i = 0; i < array_lengthof(ConditionalBuildAttributes); ++i) { | 247 for (size_t i = 0; i < array_lengthof(ConditionalBuildAttributes); ++i) { |
| 244 switch (ConditionalBuildAttributes[i].FlagValue) { | 248 switch (ConditionalBuildAttributes[i].FlagValue) { |
| 245 case 0: | 249 case 0: |
| 246 if (Stream) | 250 if (Stream) |
| 247 *Stream << "no_" << ConditionalBuildAttributes[i].FlagName << "\n"; | 251 *Stream << "no_" << ConditionalBuildAttributes[i].FlagName << "\n"; |
| 248 break; | 252 break; |
| 249 case 1: | 253 case 1: |
| 250 if (Stream) | 254 if (Stream) |
| 251 *Stream << "allow_" << ConditionalBuildAttributes[i].FlagName << "\n"; | 255 *Stream << "allow_" << ConditionalBuildAttributes[i].FlagName << "\n"; |
| 252 break; | 256 break; |
| 253 default: { | 257 default: { |
| 254 std::string Buffer; | 258 std::string Buffer; |
| 255 raw_string_ostream StrBuf(Buffer); | 259 raw_string_ostream StrBuf(Buffer); |
| 256 StrBuf << "Flag " << ConditionalBuildAttributes[i].FlagName | 260 StrBuf << "Flag " << ConditionalBuildAttributes[i].FlagName |
| 257 << " must be defined as 0/1. Found: " | 261 << " must be defined as 0/1. Found: " |
| 258 << ConditionalBuildAttributes[i].FlagValue; | 262 << ConditionalBuildAttributes[i].FlagValue; |
| 259 report_fatal_error(StrBuf.str()); | 263 report_fatal_error(StrBuf.str()); |
| 260 } | 264 } |
| 261 } | 265 } |
| 262 } | 266 } |
| 263 } | 267 } |
| 264 | 268 |
| 265 int main(int argc, char **argv) { | 269 void Ice::Compiler::run(int argc, char **argv, Ice::CompileServer &Server) { |
| 266 | 270 |
| 267 cl::ParseCommandLineOptions(argc, argv); | 271 cl::ParseCommandLineOptions(argc, argv); |
| 268 | 272 |
| 269 if (DisableIRGeneration) | 273 if (DisableIRGeneration) |
| 270 DisableTranslation = true; | 274 DisableTranslation = true; |
| 271 | 275 |
| 272 Ice::VerboseMask VMask = Ice::IceV_None; | 276 Ice::VerboseMask VMask = Ice::IceV_None; |
| 273 // Don't generate verbose messages if routines | 277 // Don't generate verbose messages if routines |
| 274 // to dump messages are not available. | 278 // to dump messages are not available. |
| 275 if (ALLOW_DUMP) { | 279 if (ALLOW_DUMP) { |
| 276 for (unsigned i = 0; i != VerboseList.size(); ++i) | 280 for (unsigned i = 0; i != VerboseList.size(); ++i) |
| 277 VMask |= VerboseList[i]; | 281 VMask |= VerboseList[i]; |
| 278 } | 282 } |
| 279 | 283 |
| 280 std::ofstream Lfs; | 284 std::ofstream Lfs; |
| 281 std::unique_ptr<Ice::Ostream> Ls; | 285 std::unique_ptr<Ice::Ostream> Ls; |
| 282 if (LogFilename != "-") { | 286 if (LogFilename != "-") { |
| 283 Lfs.open(LogFilename.c_str(), std::ofstream::out); | 287 Lfs.open(LogFilename.c_str(), std::ofstream::out); |
| 284 Ls.reset(new raw_os_ostream(Lfs)); | 288 Ls.reset(new raw_os_ostream(Lfs)); |
| 285 } else { | 289 } else { |
| 286 Ls.reset(new raw_os_ostream(std::cout)); | 290 Ls.reset(new raw_os_ostream(std::cout)); |
| 287 } | 291 } |
| 288 Ls->SetUnbuffered(); | 292 Ls->SetUnbuffered(); |
| 289 | 293 |
| 290 ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Ls.get() : nullptr); | 294 ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Ls.get() : nullptr); |
| 291 if (GenerateBuildAtts) | 295 if (GenerateBuildAtts) |
| 292 return GetReturnValue(Ice::EC_None); | 296 return setReturnValue(GetReturnValue(Ice::EC_None)); |
| 293 | 297 |
| 294 if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) { | 298 if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) { |
| 295 *Ls << "Error: Build doesn't allow --no-ir-gen when not " | 299 *Ls << "Error: Build doesn't allow --no-ir-gen when not " |
| 296 << "ALLOW_DISABLE_IR_GEN!\n"; | 300 << "ALLOW_DISABLE_IR_GEN!\n"; |
| 297 return GetReturnValue(Ice::EC_Args); | 301 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
| 298 } | 302 } |
| 299 | 303 |
| 300 Ice::ClFlags Flags; | 304 Ice::ClFlags Flags; |
| 301 Flags.setAllowErrorRecovery(AllowErrorRecovery); | 305 Flags.setAllowErrorRecovery(AllowErrorRecovery); |
| 302 Flags.setAllowUninitializedGlobals(AllowUninitializedGlobals); | 306 Flags.setAllowUninitializedGlobals(AllowUninitializedGlobals); |
| 303 Flags.setDataSections(DataSections); | 307 Flags.setDataSections(DataSections); |
| 304 Flags.setDecorateAsm(DecorateAsm); | 308 Flags.setDecorateAsm(DecorateAsm); |
| 305 Flags.setDefaultFunctionPrefix(DefaultFunctionPrefix); | 309 Flags.setDefaultFunctionPrefix(DefaultFunctionPrefix); |
| 306 Flags.setDefaultGlobalPrefix(DefaultGlobalPrefix); | 310 Flags.setDefaultGlobalPrefix(DefaultGlobalPrefix); |
| 307 Flags.setDisableInternal(DisableInternal); | 311 Flags.setDisableInternal(DisableInternal); |
| 308 Flags.setDisableIRGeneration(DisableIRGeneration); | 312 Flags.setDisableIRGeneration(DisableIRGeneration); |
| 309 Flags.setDisableTranslation(DisableTranslation); | 313 Flags.setDisableTranslation(DisableTranslation); |
| 310 Flags.setDumpStats(DumpStats); | 314 Flags.setDumpStats(DumpStats); |
| 311 Flags.setFunctionSections(FunctionSections); | 315 Flags.setFunctionSections(FunctionSections); |
| 312 Flags.setNumTranslationThreads(NumThreads); | 316 Flags.setNumTranslationThreads(NumThreads); |
| 313 Flags.setPhiEdgeSplit(EnablePhiEdgeSplit); | 317 Flags.setPhiEdgeSplit(EnablePhiEdgeSplit); |
| 314 Flags.setStubConstantCalls(StubConstantCalls); | 318 Flags.setStubConstantCalls(StubConstantCalls); |
| 315 Flags.setSubzeroTimingEnabled(SubzeroTimingEnabled); | 319 Flags.setSubzeroTimingEnabled(SubzeroTimingEnabled); |
| 316 Flags.setTimeEachFunction(TimeEachFunction); | 320 Flags.setTimeEachFunction(TimeEachFunction); |
| 317 Flags.setTimingFocusOn(TimingFocusOn); | 321 Flags.setTimingFocusOn(TimingFocusOn); |
| 318 Flags.setTranslateOnly(TranslateOnly); | 322 Flags.setTranslateOnly(TranslateOnly); |
| 319 Flags.setUseSandboxing(UseSandboxing); | 323 Flags.setUseSandboxing(UseSandboxing); |
| 320 Flags.setVerboseFocusOn(VerboseFocusOn); | 324 Flags.setVerboseFocusOn(VerboseFocusOn); |
| 321 Flags.setOutFileType(OutFileType); | 325 Flags.setOutFileType(OutFileType); |
| 322 | 326 |
| 323 // Force -build-on-read=0 for .ll files. | 327 // Force -build-on-read=0 for .ll files. |
| 324 const std::string LLSuffix = ".ll"; | 328 const std::string LLSuffix = ".ll"; |
| 325 if (IRFilename.length() >= LLSuffix.length() && | 329 if (ALLOW_LLVM_IR_AS_INPUT && IRFilename.length() >= LLSuffix.length() && |
| 326 IRFilename.compare(IRFilename.length() - LLSuffix.length(), | 330 IRFilename.compare(IRFilename.length() - LLSuffix.length(), |
| 327 LLSuffix.length(), LLSuffix) == 0) | 331 LLSuffix.length(), LLSuffix) == 0) |
| 328 BuildOnRead = false; | 332 BuildOnRead = false; |
| 329 | 333 |
| 330 // With the ELF writer, use a raw_fd_ostream to allow seeking. | |
| 331 // Also don't buffer, otherwise it gets pretty slow. | |
| 332 std::unique_ptr<Ice::Ostream> Os; | 334 std::unique_ptr<Ice::Ostream> Os; |
| 333 std::unique_ptr<Ice::ELFStreamer> ELFStr; | 335 std::unique_ptr<Ice::ELFStreamer> ELFStr; |
| 334 std::ofstream Ofs; | |
| 335 switch (OutFileType) { | 336 switch (OutFileType) { |
| 336 case Ice::FT_Elf: { | 337 case Ice::FT_Elf: { |
| 337 if (OutputFilename == "-") { | 338 if (OutputFilename == "-") { |
| 338 *Ls << "Error: writing binary ELF to stdout is unsupported\n"; | 339 *Ls << "Error: writing binary ELF to stdout is unsupported\n"; |
| 339 return GetReturnValue(Ice::EC_Args); | 340 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
| 340 } | 341 } |
| 341 std::error_code EC; | 342 std::error_code EC; |
| 342 raw_fd_ostream *FdOs = | 343 std::unique_ptr<llvm::raw_fd_ostream> FdOs = |
| 343 new raw_fd_ostream(OutputFilename, EC, sys::fs::F_None); | 344 Server.getOutputStream(OutputFilename, EC); |
| 344 // NaCl sets st_blksize to 0, and LLVM uses that to pick the | |
| 345 // default preferred buffer size. Set to something non-zero. | |
| 346 FdOs->SetBufferSize(1 << 14); | |
| 347 Os.reset(FdOs); | |
| 348 if (EC) { | 345 if (EC) { |
| 349 *Ls << "Failed to open output file: " << OutputFilename << ":\n" | 346 *Ls << "Failed to open output file: " << OutputFilename << ":\n" |
| 350 << EC.message() << "\n"; | 347 << EC.message() << "\n"; |
| 351 return GetReturnValue(Ice::EC_Args); | 348 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
| 352 } | 349 } |
| 353 ELFStr.reset(new Ice::ELFStreamer(*FdOs)); | 350 ELFStr.reset(new Ice::ELFStreamer(*FdOs.get())); |
| 351 Os.reset(FdOs.release()); |
| 352 // NaCl sets st_blksize to 0, and LLVM uses that to pick the |
| 353 // default preferred buffer size. Set to something non-zero. |
| 354 Os->SetBufferSize(1 << 14); |
| 354 } break; | 355 } break; |
| 355 case Ice::FT_Asm: | 356 case Ice::FT_Asm: |
| 356 case Ice::FT_Iasm: { | 357 case Ice::FT_Iasm: { |
| 358 if (PNACL_BROWSER_TRANSLATOR) { |
| 359 *Ls << "Asm/Iasm is not supported under PNACL_BROWSER_TRANSLATOR\n"; |
| 360 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
| 361 } |
| 362 // Use raw_os_ostream instead of raw_fd_ostream. If both the |
| 363 // LogFilename and OutputFilename are stdout, then having |
| 364 // Os be a raw_fd_ostream while Ls is a raw_os_ostream backed by |
| 365 // a std::ofstream will confuse the buffering and have odd |
| 366 // interleavings (even with explicit flushes, for some reason). |
| 367 // So, make sure both are the same type of stream. In this case, |
| 368 // choose ofstream + raw_os_ostream for both. |
| 369 // This avoids asking the compiler server for the output file, |
| 370 // which won't work in the PNACL_BROWSER_TRANSLATOR case. |
| 371 // An alternative is to choose raw_fd_ostream for both, but then |
| 372 // you have to explicitly tell raw_fd_ostream not to own the |
| 373 // fd since it is shared by the two streams (you'll get a double-close). |
| 374 std::ofstream Ofs; |
| 357 if (OutputFilename != "-") { | 375 if (OutputFilename != "-") { |
| 358 Ofs.open(OutputFilename.c_str(), std::ofstream::out); | 376 Ofs.open(OutputFilename.c_str(), std::ofstream::out); |
| 359 Os.reset(new raw_os_ostream(Ofs)); | 377 Os.reset(new raw_os_ostream(Ofs)); |
| 360 } else { | 378 } else { |
| 361 Os.reset(new raw_os_ostream(std::cout)); | 379 Os.reset(new raw_os_ostream(std::cout)); |
| 362 } | 380 } |
| 363 Os->SetUnbuffered(); | 381 Os->SetUnbuffered(); |
| 364 } break; | 382 } break; |
| 365 } | 383 } |
| 366 | 384 |
| 367 Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TargetArch, | 385 Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TArch, OLevel, |
| 368 OptLevel, TestPrefix, Flags); | 386 TestPrefix, Flags); |
| 369 | 387 |
| 370 Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); | 388 Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); |
| 371 | 389 |
| 372 if (OutFileType == Ice::FT_Elf) { | 390 if (OutFileType == Ice::FT_Elf) { |
| 373 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); | 391 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); |
| 374 Ctx.getObjectWriter()->writeInitialELFHeader(); | 392 Ctx.getObjectWriter()->writeInitialELFHeader(); |
| 375 } | 393 } |
| 376 | 394 |
| 377 Ctx.startWorkerThreads(); | 395 Ctx.startWorkerThreads(); |
| 378 | 396 |
| 379 std::unique_ptr<Ice::Translator> Translator; | 397 std::unique_ptr<Ice::Translator> Translator; |
| 380 if (BuildOnRead) { | 398 if (BuildOnRead) { |
| 381 std::unique_ptr<Ice::PNaClTranslator> PTranslator( | 399 std::unique_ptr<Ice::PNaClTranslator> PTranslator( |
| 382 new Ice::PNaClTranslator(&Ctx)); | 400 new Ice::PNaClTranslator(&Ctx)); |
| 383 std::string StrError; | 401 std::string StrError; |
| 384 std::unique_ptr<DataStreamer> FileStreamer( | 402 std::unique_ptr<DataStreamer> FileStreamer = |
| 385 getDataFileStreamer(IRFilename, &StrError)); | 403 Server.getInputStream(IRFilename, StrError); |
| 386 if (!StrError.empty() || !FileStreamer) { | 404 if (!StrError.empty() || !FileStreamer) { |
| 387 SMDiagnostic Err(IRFilename, SourceMgr::DK_Error, StrError); | 405 SMDiagnostic Err(IRFilename, SourceMgr::DK_Error, StrError); |
| 388 Err.print(argv[0], errs()); | 406 Err.print(argv[0], errs()); |
| 389 return GetReturnValue(Ice::EC_Bitcode); | 407 return setReturnValue(GetReturnValue(Ice::EC_Bitcode)); |
| 390 } | 408 } |
| 391 std::unique_ptr<StreamingMemoryObject> MemObj( | 409 std::unique_ptr<StreamingMemoryObject> MemObj( |
| 392 new StreamingMemoryObjectImpl(FileStreamer.release())); | 410 new StreamingMemoryObjectImpl(FileStreamer.release())); |
| 393 PTranslator->translate(IRFilename, std::move(MemObj)); | 411 PTranslator->translate(IRFilename, std::move(MemObj)); |
| 394 Translator.reset(PTranslator.release()); | 412 Translator.reset(PTranslator.release()); |
| 395 } else if (ALLOW_LLVM_IR) { | 413 } else if (ALLOW_LLVM_IR) { |
| 414 if (PNACL_BROWSER_TRANSLATOR) { |
| 415 *Ls << "non BuildOnRead is not supported w/ PNACL_BROWSER_TRANSLATOR\n"; |
| 416 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
| 417 } |
| 396 // Parse the input LLVM IR file into a module. | 418 // Parse the input LLVM IR file into a module. |
| 397 SMDiagnostic Err; | 419 SMDiagnostic Err; |
| 398 Ice::TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); | 420 Ice::TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); |
| 399 raw_ostream *Verbose = LLVMVerboseErrors ? &errs() : nullptr; | 421 raw_ostream *Verbose = LLVMVerboseErrors ? &errs() : nullptr; |
| 400 std::unique_ptr<Module> Mod = NaClParseIRFile( | 422 std::unique_ptr<Module> Mod = NaClParseIRFile( |
| 401 IRFilename, InputFileFormat, Err, Verbose, getGlobalContext()); | 423 IRFilename, InputFileFormat, Err, Verbose, getGlobalContext()); |
| 402 if (!Mod) { | 424 if (!Mod) { |
| 403 Err.print(argv[0], errs()); | 425 Err.print(argv[0], errs()); |
| 404 return GetReturnValue(Ice::EC_Bitcode); | 426 return setReturnValue(GetReturnValue(Ice::EC_Bitcode)); |
| 405 } | 427 } |
| 406 | 428 |
| 407 std::unique_ptr<Ice::Converter> Converter( | 429 std::unique_ptr<Ice::Converter> Converter( |
| 408 new Ice::Converter(Mod.get(), &Ctx)); | 430 new Ice::Converter(Mod.get(), &Ctx)); |
| 409 Converter->convertToIce(); | 431 Converter->convertToIce(); |
| 410 Translator.reset(Converter.release()); | 432 Translator.reset(Converter.release()); |
| 411 } else { | 433 } else { |
| 412 *Ls << "Error: Build doesn't allow LLVM IR, " | 434 *Ls << "Error: Build doesn't allow LLVM IR, " |
| 413 << "--build-on-read=0 not allowed\n"; | 435 << "--build-on-read=0 not allowed\n"; |
| 414 return GetReturnValue(Ice::EC_Args); | 436 return setReturnValue(GetReturnValue(Ice::EC_Args)); |
| 415 } | 437 } |
| 416 | 438 |
| 417 Ctx.waitForWorkerThreads(); | 439 Ctx.waitForWorkerThreads(); |
| 418 Translator->transferErrorCode(); | 440 Translator->transferErrorCode(); |
| 419 Translator->emitConstants(); | 441 Translator->emitConstants(); |
| 420 | 442 |
| 421 if (OutFileType == Ice::FT_Elf) { | 443 if (OutFileType == Ice::FT_Elf) { |
| 422 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); | 444 Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx); |
| 423 Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms()); | 445 Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms()); |
| 424 Ctx.getObjectWriter()->writeNonUserSections(); | 446 Ctx.getObjectWriter()->writeNonUserSections(); |
| 425 } | 447 } |
| 426 if (SubzeroTimingEnabled) | 448 if (SubzeroTimingEnabled) |
| 427 Ctx.dumpTimers(); | 449 Ctx.dumpTimers(); |
| 428 if (TimeEachFunction) { | 450 if (TimeEachFunction) { |
| 429 const bool DumpCumulative = false; | 451 const bool DumpCumulative = false; |
| 430 Ctx.dumpTimers(Ice::GlobalContext::TSK_Funcs, DumpCumulative); | 452 Ctx.dumpTimers(Ice::GlobalContext::TSK_Funcs, DumpCumulative); |
| 431 } | 453 } |
| 432 const bool FinalStats = true; | 454 const bool FinalStats = true; |
| 433 Ctx.dumpStats("_FINAL_", FinalStats); | 455 Ctx.dumpStats("_FINAL_", FinalStats); |
| 434 return GetReturnValue(Ctx.getErrorStatus()->value()); | 456 return setReturnValue(GetReturnValue(Ctx.getErrorStatus()->value())); |
| 435 } | 457 } |
| OLD | NEW |