예제 #1
0
/// create - Create an return a new JIT compiler if there is one available
/// for the current target.  Otherwise, return null.
///
ExecutionEngine *JIT::create(ModuleProvider *MP, IntrinsicLowering *IL) {
  if (MArch == 0) {
    std::string Error;
    MArch = TargetMachineRegistry::getClosestTargetForJIT(Error);
    if (MArch == 0) return 0;
  } else if (MArch->JITMatchQualityFn() == 0) {
    std::cerr << "WARNING: This target JIT is not designed for the host you are"
              << " running.  If bad things happen, please choose a different "
              << "-march switch.\n";
  }

  // Allocate a target...
  TargetMachine *Target = MArch->CtorFn(*MP->getModule(), IL);
  assert(Target && "Could not allocate target machine!");

  // If the target supports JIT code generation, return a new JIT now.
  if (TargetJITInfo *TJ = Target->getJITInfo())
    return new JIT(MP, *Target, *TJ);
  return 0;
}
예제 #2
0
// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
  PrintStackTraceOnErrorSignal();

  // Load the module to be compiled...
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
  if (M.get() == 0) {
    std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
    return 1;
  }
  Module &mod = *M.get();

  // Allocate target machine.  First, check whether the user has
  // explicitly specified an architecture to compile for.
  TargetMachine* (*TargetMachineAllocator)(const Module&,
                                           IntrinsicLowering *) = 0;
  if (MArch == 0) {
    std::string Err;
    MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
    if (MArch == 0) {
      std::cerr << argv[0] << ": error auto-selecting target for module '"
                << Err << "'.  Please use the -march option to explicitly "
                << "pick a target.\n";
      return 1;
    }
  }

  std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();
  const TargetData &TD = Target.getTargetData();

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;
  Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
                            TD.getPointerAlignment(), TD.getDoubleAlignment()));

  // Figure out where we are going to send the output...
  std::ostream *Out = 0;
  if (OutputFilename != "") {
    if (OutputFilename != "-") {
      // Specified an output filename?
      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists!\n"
                  << "Use -f command line argument to force output\n";
        return 1;
      }
      Out = new std::ofstream(OutputFilename.c_str());

      // Make sure that the Out file gets unlinked from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    } else {
      Out = &std::cout;
    }
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = &std::cout;
    } else {
      OutputFilename = GetFileNameRoot(InputFilename); 

      if (MArch->Name[0] != 'c' || MArch->Name[1] != 0)  // not CBE
        OutputFilename += ".s";
      else
        OutputFilename += ".cbe.c";
      
      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists!\n"
                  << "Use -f command line argument to force output\n";
        return 1;
      }
      
      Out = new std::ofstream(OutputFilename.c_str());
      if (!Out->good()) {
        std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
        delete Out;
        return 1;
      }
      
      // Make sure that the Out file gets unlinked from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    }
  }

  // Ask the target to add backend passes as necessary
  if (Target.addPassesToEmitAssembly(Passes, *Out)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' does not support static compilation!\n";
    if (Out != &std::cout) delete Out;
    // And the Out file is empty and useless, so remove it now.
    std::remove(OutputFilename.c_str());
    return 1;
  } else {
    // Run our queue of passes all at once now, efficiently.
    Passes.run(*M.get());
  }

  // Delete the ostream if it's not a stdout stream
  if (Out != &std::cout) delete Out;

  return 0;
}
예제 #3
0
파일: llc.cpp 프로젝트: marnen/rubinius
// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  llvm_shutdown_obj X;  // Call llvm_shutdown() on exit.
  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
  sys::PrintStackTraceOnErrorSignal();

  // Load the module to be compiled...
  std::string ErrorMessage;
  std::auto_ptr<Module> M;
  
  std::auto_ptr<MemoryBuffer> Buffer(
                   MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage));
  if (Buffer.get())
    M.reset(ParseBitcodeFile(Buffer.get(), &ErrorMessage));
  if (M.get() == 0) {
    std::cerr << argv[0] << ": bitcode didn't read correctly.\n";
    std::cerr << "Reason: " << ErrorMessage << "\n";
    return 1;
  }
  Module &mod = *M.get();
  
  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    mod.setTargetTriple(TargetTriple);
  
  // Allocate target machine.  First, check whether the user has
  // explicitly specified an architecture to compile for.
  if (MArch == 0) {
    std::string Err;
    MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
    if (MArch == 0) {
      std::cerr << argv[0] << ": error auto-selecting target for module '"
                << Err << "'.  Please use the -march option to explicitly "
                << "pick a target.\n";
      return 1;
    }
  }

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MCPU.size() || MAttrs.size()) {
    SubtargetFeatures Features;
    Features.setCPU(MCPU);
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }
  
  std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, FeaturesStr));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();

  // Figure out where we are going to send the output...
  std::ostream *Out = GetOutputStream(argv[0]);
  if (Out == 0) return 1;
  
  // If this target requires addPassesToEmitWholeFile, do it now.  This is
  // used by strange things like the C backend.
  if (Target.WantsWholeFile()) {
    PassManager PM;
    PM.add(new TargetData(*Target.getTargetData()));
    if (!NoVerify)
      PM.add(createVerifierPass());
    
    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, Fast)) {
      std::cerr << argv[0] << ": target does not support generation of this"
                << " file type!\n";
      if (Out != &std::cout) delete Out;
      // And the Out file is empty and useless, so remove it now.
      sys::Path(OutputFilename).eraseFromDisk();
      return 1;
    }
    PM.run(mod);
  } else {
    // Build up all of the passes that we want to do to the module.
    ExistingModuleProvider Provider(M.release());
    FunctionPassManager Passes(&Provider);
    Passes.add(new TargetData(*Target.getTargetData()));
    
#ifndef NDEBUG
    if (!NoVerify)
      Passes.add(createVerifierPass());
#endif
  
    // Ask the target to add backend passes as necessary.
    MachineCodeEmitter *MCE = 0;

    switch (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
    default:
      assert(0 && "Invalid file model!");
      return 1;
    case FileModel::Error:
      std::cerr << argv[0] << ": target does not support generation of this"
                << " file type!\n";
      if (Out != &std::cout) delete Out;
      // And the Out file is empty and useless, so remove it now.
      sys::Path(OutputFilename).eraseFromDisk();
      return 1;
    case FileModel::AsmFile:
      break;
    case FileModel::MachOFile:
      MCE = AddMachOWriter(Passes, *Out, Target);
      break;
    case FileModel::ElfFile:
      MCE = AddELFWriter(Passes, *Out, Target);
      break;
    }

    if (Target.addPassesToEmitFileFinish(Passes, MCE, Fast)) {
      std::cerr << argv[0] << ": target does not support generation of this"
                << " file type!\n";
      if (Out != &std::cout) delete Out;
      // And the Out file is empty and useless, so remove it now.
      sys::Path(OutputFilename).eraseFromDisk();
      return 1;
    }
  
    Passes.doInitialization();
  
    // Run our queue of passes all at once now, efficiently.
    // TODO: this could lazily stream functions out of the module.
    for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
      if (!I->isDeclaration())
        Passes.run(*I);
    
    Passes.doFinalization();
  }
    
  // Delete the ostream if it's not a stdout stream
  if (Out != &std::cout) delete Out;

  return 0;
}