bool EntryPointAnalysis::runOnModule(llvm::Module& M) {
  if (epaFile.size()) {
    haveNames = true;
    readNames(names);
  }
  return false;
}
Пример #2
0
static int DisassembleInput() {
    BrigContainer c;
    int format = BifFileFormat ? FILE_FORMAT_BIF : FILE_FORMAT_AUTO;
    if (BrigIO::load(c, format, BrigIO::fileReadingAdapter(InputFilename.c_str()))) {
      return 1;
    }

    DEBUG(HSAIL_ASM::dump(c, std::cout));

    int res = ValidateContainer(c, NULL);
    if (res) return res;

    Disassembler disasm(c);
    disasm.setOutputOptions(static_cast<unsigned>(FloatDisassemblyMode)
      | (DisasmInstOffset ? static_cast<unsigned>(Disassembler::PrintInstOffset) : 0u));
    disasm.log(std::cerr);

    if ( DebugInfoFilename.size() > 0 )
        DumpDebugInfoToFile( c );
    std::string ofn = getOutputFileName();
    if (ofn == "-") {
        return disasm.run(std::cout);
    } else {
        return disasm.run(ofn.c_str());
    }
}
Пример #3
0
static int AssembleInput() {

    using namespace std;
    using namespace HSAIL_ASM;

    std::ifstream ifs((const char*)(InputFilename.c_str()), ifstream::in | ifstream::binary);
    if ((!ifs.is_open()) || ifs.bad()) {
        std::cout << "Could not open file "<<InputFilename.c_str()<<". Exiting...\n";
        return 1;
    }

    BrigContainer c;

    try {
        Scanner s(ifs,!EnableComments);
        Parser p(s, c);
        p.parseSource();
    }
    catch (const SyntaxError& e) {
        e.print(cerr,ifs);
        return 1;
    }

    int res = ValidateContainer(c, &ifs);
    if (res) return res;

    if ( EnableDebugInfo ) {
#ifdef WITH_LIBBRIGDWARF
        std::stringstream ssVersion;
        ssVersion << "HSAIL Assembler (C) AMD 2013, all rights reserved, ";
        ssVersion << "Version " << BRIG_ASM_VERSION;
        ssVersion << ", HSAIL version ";
        ssVersion << Brig::BRIG_VERSION_HSAIL_MAJOR << ':' << Brig::BRIG_VERSION_HSAIL_MINOR;

        std::unique_ptr<BrigDebug::BrigDwarfGenerator> pBdig(
            BrigDebug::BrigDwarfGenerator::Create( ssVersion.str(),
                                                   GetCurrentWorkingDirectory(),
                                                   InputFilename ) );
        pBdig->generate( c );
        pBdig->storeInBrig( c );
#else
        assert(!"libBrigDwarf not enabled");
#endif
    }

    if ( DebugInfoFilename.size() > 0 )
        DumpDebugInfoToFile( c );

    DEBUG(HSAIL_ASM::dump(c, std::cout));

    /*if (!DisableOperandOptimizer) {
        c.optimizeOperands();
    }*/
    int format = (BifFileFormat ? FILE_FORMAT_BIF : FILE_FORMAT_BRIG)
               | (Elf64FileFormat ? FILE_FORMAT_ELF64 : FILE_FORMAT_ELF32);
    return BrigIO::save(c, format, BrigIO::fileWritingAdapter(getOutputFileName().c_str()));
}
Пример #4
0
static string getOutputFileName() {
    if (OutputFilename.size() > 0) {
        return OutputFilename;
    } else { // not defined, generate using InputFileName
        string fileName = InputFilename;
        string::size_type pos = fileName.find_last_of('.');
        string new_ext = (Action == AC_Assemble)? ".brig" : ".hsail";
        if (pos != string::npos && pos > 0 && fileName.substr(pos) != new_ext) {
            fileName = fileName.substr(0, pos);
        }
        return fileName + new_ext;
    }
}
Пример #5
0
GCOVOptions GCOVOptions::getDefault() {
  GCOVOptions Options;
  Options.EmitNotes = true;
  Options.EmitData = true;
  Options.UseCfgChecksum = false;
  Options.NoRedZone = false;
  Options.FunctionNamesInData = true;

  if (DefaultGCOVVersion.size() != 4) {
    llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") +
                             DefaultGCOVVersion);
  }
  memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4);
  return Options;
}
/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
static int AnalyzeBitcode() {
  // Read the input file.
  MemoryBuffer *Buffer;
  if (InputFilename == "-")
    Buffer = MemoryBuffer::getSTDIN();
  else
    Buffer = MemoryBuffer::getFile(&InputFilename[0], InputFilename.size());

  if (Buffer == 0)
    return Error("Error reading '" + InputFilename + "'.");
  
  if (Buffer->getBufferSize() & 3)
    return Error("Bitcode stream should be a multiple of 4 bytes in length");
  
  unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
  BitstreamReader Stream(BufPtr, BufPtr+Buffer->getBufferSize());

  
  // Read the stream signature.
  char Signature[6];
  Signature[0] = Stream.Read(8);
  Signature[1] = Stream.Read(8);
  Signature[2] = Stream.Read(4);
  Signature[3] = Stream.Read(4);
  Signature[4] = Stream.Read(4);
  Signature[5] = Stream.Read(4);
  
  // Autodetect the file contents, if it is one we know.
  CurStreamType = UnknownBitstream;
  if (Signature[0] == 'B' && Signature[1] == 'C' &&
      Signature[2] == 0x0 && Signature[3] == 0xC &&
      Signature[4] == 0xE && Signature[5] == 0xD)
    CurStreamType = LLVMIRBitstream;

  unsigned NumTopBlocks = 0;
  
  // Parse the top-level structure.  We only allow blocks at the top-level.
  while (!Stream.AtEndOfStream()) {
    unsigned Code = Stream.ReadCode();
    if (Code != bitc::ENTER_SUBBLOCK)
      return Error("Invalid record at top-level");
    
    if (ParseBlock(Stream, 0))
      return true;
    ++NumTopBlocks;
  }
  
  if (Dump) std::cerr << "\n\n";
  
  uint64_t BufferSizeBits = Buffer->getBufferSize()*8;
  // Print a summary of the read file.
  std::cerr << "Summary of " << InputFilename << ":\n";
  std::cerr << "         Total size: ";
  PrintSize(BufferSizeBits);
  std::cerr << "\n";
  std::cerr << "        Stream type: ";
  switch (CurStreamType) {
  default: assert(0 && "Unknown bitstream type");
  case UnknownBitstream: std::cerr << "unknown\n"; break;
  case LLVMIRBitstream:  std::cerr << "LLVM IR\n"; break;
  }
  std::cerr << "  # Toplevel Blocks: " << NumTopBlocks << "\n";
  std::cerr << "\n";

  // Emit per-block stats.
  std::cerr << "Per-block Summary:\n";
  for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
       E = BlockIDStats.end(); I != E; ++I) {
    std::cerr << "  Block ID #" << I->first;
    if (const char *BlockName = GetBlockName(I->first))
      std::cerr << " (" << BlockName << ")";
    std::cerr << ":\n";
    
    const PerBlockIDStats &Stats = I->second;
    std::cerr << "      Num Instances: " << Stats.NumInstances << "\n";
    std::cerr << "         Total Size: ";
    PrintSize(Stats.NumBits);
    std::cerr << "\n";
    std::cerr << "          % of file: "
              << Stats.NumBits/(double)BufferSizeBits*100 << "\n";
    if (Stats.NumInstances > 1) {
      std::cerr << "       Average Size: ";
      PrintSize(Stats.NumBits/(double)Stats.NumInstances);
      std::cerr << "\n";
      std::cerr << "  Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
                << Stats.NumSubBlocks/(double)Stats.NumInstances << "\n";
      std::cerr << "    Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
                << Stats.NumAbbrevs/(double)Stats.NumInstances << "\n";
      std::cerr << "    Tot/Avg Records: " << Stats.NumRecords << "/"
                << Stats.NumRecords/(double)Stats.NumInstances << "\n";
    } else {
      std::cerr << "      Num SubBlocks: " << Stats.NumSubBlocks << "\n";
      std::cerr << "        Num Abbrevs: " << Stats.NumAbbrevs << "\n";
      std::cerr << "        Num Records: " << Stats.NumRecords << "\n";
    }
    if (Stats.NumRecords)
      std::cerr << "      % Abbrev Recs: " << (Stats.NumAbbreviatedRecords/
                   (double)Stats.NumRecords)*100 << "\n";
    std::cerr << "\n";
    
    // Print a histogram of the codes we see.
    if (!NoHistogram && !Stats.CodeFreq.empty()) {
      std::vector<std::pair<unsigned, unsigned> > FreqPairs;  // <freq,code>
      for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i)
        if (unsigned Freq = Stats.CodeFreq[i])
          FreqPairs.push_back(std::make_pair(Freq, i));
      std::stable_sort(FreqPairs.begin(), FreqPairs.end());
      std::reverse(FreqPairs.begin(), FreqPairs.end());
      
      std::cerr << "\tCode Histogram:\n";
      for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) {
        std::cerr << "\t\t" << FreqPairs[i].first << "\t";
        if (const char *CodeName = GetCodeName(FreqPairs[i].second, I->first))
          std::cerr << CodeName << "\n";
        else
          std::cerr << "UnknownCode" << FreqPairs[i].second << "\n";
      }
      std::cerr << "\n";
      
    }
  }
  return 0;
}
Пример #7
0
// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  // Enable debug stream buffering.
  EnableDebugBuffering = true;

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets first, so that --version shows registered targets.
  InitializeAllTargets();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();

  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");

  // Load the module to be compiled...
  SMDiagnostic Err;
  std::auto_ptr<Module> M;

  M.reset(ParseIRFile(InputFilename, Err, Context));
  if (M.get() == 0) {
    Err.Print(argv[0], errs());
    return 1;
  }
  Module &mod = *M.get();

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    mod.setTargetTriple(Triple::normalize(TargetTriple));

  Triple TheTriple(mod.getTargetTriple());
  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getHostTriple());

  // Allocate target machine.  First, check whether the user has explicitly
  // specified an architecture to compile for. If so we have to look it up by
  // name, because it might be a backend that has no mapping to a target triple.
  const Target *TheTarget = 0;
  if (!MArch.empty()) {
    for (TargetRegistry::iterator it = TargetRegistry::begin(),
           ie = TargetRegistry::end(); it != ie; ++it) {
      if (MArch == it->getName()) {
        TheTarget = &*it;
        break;
      }
    }

    if (!TheTarget) {
      errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
      return 1;
    }

    // Adjust the triple to match (if known), otherwise stick with the
    // module/host triple.
    Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
    if (Type != Triple::UnknownArch)
      TheTriple.setArch(Type);
  } else {
    std::string Err;
    TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
    if (TheTarget == 0) {
      errs() << 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(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();

  if (DisableDotLoc)
    Target.setMCUseLoc(false);
  if (TheTriple.getOS() == Triple::Darwin) {
    switch (TheTriple.getDarwinMajorNumber()) {
    case 7:
    case 8:
    case 9:
      // disable .loc support for older darwin OS.
      Target.setMCUseLoc(false);
      break;
    default:
      break;
    }
  }

  // Figure out where we are going to send the output...
  OwningPtr<tool_output_file> Out
    (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]));
  if (!Out) return 1;

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (OptLevel) {
  default:
    errs() << argv[0] << ": invalid optimization level.\n";
    return 1;
  case ' ': break;
  case '0': OLvl = CodeGenOpt::None; break;
  case '1': OLvl = CodeGenOpt::Less; break;
  case '2': OLvl = CodeGenOpt::Default; break;
  case '3': OLvl = CodeGenOpt::Aggressive; break;
  }

  // Build up all of the passes that we want to do to the module.
  PassManager PM;

  // Add the target data from the target machine, if it exists, or the module.
  if (const TargetData *TD = Target.getTargetData())
    PM.add(new TargetData(*TD));
  else
    PM.add(new TargetData(&mod));

  // Override default to generate verbose assembly.
  Target.setAsmVerbosityDefault(true);

  if (RelaxAll) {
    if (FileType != TargetMachine::CGFT_ObjectFile)
      errs() << argv[0]
             << ": warning: ignoring -mc-relax-all because filetype != obj";
    else
      Target.setMCRelaxAll(true);
  }

  {
    formatted_raw_ostream FOS(Out->os());

    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitFile(PM, FOS, FileType, OLvl, NoVerify)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      return 1;
    }

    // Before executing passes, print the final values of the LLVM options.
    cl::PrintOptionValues();

    PM.run(mod);
  }

  // Declare success.
  Out->keep();

  return 0;
}
Пример #8
0
/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings.  The strings are added to the CheckStrings vector.
/// Returns true in case of an error, false otherwise.
static bool ReadCheckFile(SourceMgr &SM,
                          std::vector<CheckString> &CheckStrings) {
  OwningPtr<MemoryBuffer> File;
  if (error_code ec =
        MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), File)) {
    errs() << "Could not open check file '" << CheckFilename << "': "
           << ec.message() << '\n';
    return true;
  }

  // If we want to canonicalize whitespace, strip excess whitespace from the
  // buffer containing the CHECK lines. Remove DOS style line endings.
  MemoryBuffer *F =
    CanonicalizeInputFile(File.take(), NoCanonicalizeWhiteSpace);

  SM.AddNewSourceBuffer(F, SMLoc());

  // Find all instances of CheckPrefix followed by : in the file.
  StringRef Buffer = F->getBuffer();
  std::vector<std::pair<SMLoc, Pattern> > NotMatches;

  // LineNumber keeps track of the line on which CheckPrefix instances are
  // found.
  unsigned LineNumber = 1;

  while (1) {
    // See if Prefix occurs in the memory buffer.
    size_t PrefixLoc = Buffer.find(CheckPrefix);
    // If we didn't find a match, we're done.
    if (PrefixLoc == StringRef::npos)
      break;

    LineNumber += Buffer.substr(0, PrefixLoc).count('\n');

    Buffer = Buffer.substr(PrefixLoc);

    const char *CheckPrefixStart = Buffer.data();

    // When we find a check prefix, keep track of whether we find CHECK: or
    // CHECK-NEXT:
    bool IsCheckNext = false, IsCheckNot = false;

    // Verify that the : is present after the prefix.
    if (Buffer[CheckPrefix.size()] == ':') {
      Buffer = Buffer.substr(CheckPrefix.size()+1);
    } else if (Buffer.size() > CheckPrefix.size()+6 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+6);
      IsCheckNext = true;
    } else if (Buffer.size() > CheckPrefix.size()+5 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+5);
      IsCheckNot = true;
    } else {
      Buffer = Buffer.substr(1);
      continue;
    }

    // Okay, we found the prefix, yay.  Remember the rest of the line, but
    // ignore leading and trailing whitespace.
    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));

    // Scan ahead to the end of line.
    size_t EOL = Buffer.find_first_of("\n\r");

    // Remember the location of the start of the pattern, for diagnostics.
    SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());

    // Parse the pattern.
    Pattern P;
    if (P.ParsePattern(Buffer.substr(0, EOL), SM, LineNumber))
      return true;

    Buffer = Buffer.substr(EOL);

    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
    if (IsCheckNext && CheckStrings.empty()) {
      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
                      SourceMgr::DK_Error,
                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
                      CheckPrefix+ ": line");
      return true;
    }

    // Handle CHECK-NOT.
    if (IsCheckNot) {
      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
                                          P));
      continue;
    }

    // Okay, add the string we captured to the output vector and move on.
    CheckStrings.push_back(CheckString(P,
                                       PatternLoc,
                                       IsCheckNext));
    std::swap(NotMatches, CheckStrings.back().NotStrings);
  }

  // Add an EOF pattern for any trailing CHECK-NOTs.
  if (!NotMatches.empty()) {
    CheckStrings.push_back(CheckString(Pattern(true),
                                       SMLoc::getFromPointer(Buffer.data()),
                                       false));
    std::swap(NotMatches, CheckStrings.back().NotStrings);
  }

  if (CheckStrings.empty()) {
    errs() << "error: no check strings found with prefix '" << CheckPrefix
           << ":'\n";
    return true;
  }

  return false;
}
Пример #9
0
// parseCommandLine - Parse the command line options as presented and return the
// operation specified. Process all modifiers and check to make sure that
// constraints on modifier/operation pairs have not been violated.
ArchiveOperation parseCommandLine() {

    // Keep track of number of operations. We can only specify one
    // per execution.
    unsigned NumOperations = 0;

    // Keep track of the number of positional modifiers (a,b,i). Only
    // one can be specified.
    unsigned NumPositional = 0;

    // Keep track of which operation was requested
    ArchiveOperation Operation = NoOperation;

    for(unsigned i=0; i<Options.size(); ++i) {
        switch(Options[i]) {
        case 'd':
            ++NumOperations;
            Operation = Delete;
            break;
        case 'm':
            ++NumOperations;
            Operation = Move ;
            break;
        case 'p':
            ++NumOperations;
            Operation = Print;
            break;
        case 'q':
            ++NumOperations;
            Operation = QuickAppend;
            break;
        case 'r':
            ++NumOperations;
            Operation = ReplaceOrInsert;
            break;
        case 't':
            ++NumOperations;
            Operation = DisplayTable;
            break;
        case 'x':
            ++NumOperations;
            Operation = Extract;
            break;
        case 'c':
            Create = true;
            break;
        case 'f':
            TruncateNames = true;
            break;
        case 'k':
            DontSkipBitcode = true;
            break;
        case 'l': /* accepted but unused */
            break;
        case 'o':
            OriginalDates = true;
            break;
        case 'P':
            FullPath = true;
            break;
        case 'R':
            RecurseDirectories = true;
            break;
        case 's':
            SymTable = true;
            break;
        case 'S':
            SymTable = false;
            break;
        case 'u':
            OnlyUpdate = true;
            break;
        case 'v':
            Verbose = true;
            break;
        case 'V':
            Verbose = ReallyVerbose = true;
            break;
        case 'z':
            Compression = true;
            break;
        case 'a':
            getRelPos();
            AddAfter = true;
            NumPositional++;
            break;
        case 'b':
            getRelPos();
            AddBefore = true;
            NumPositional++;
            break;
        case 'i':
            getRelPos();
            InsertBefore = true;
            NumPositional++;
            break;
        case 'N':
            getCount();
            UseCount = true;
            break;
        default:
            cl::PrintHelpMessage();
        }
    }

    // At this point, the next thing on the command line must be
    // the archive name.
    getArchive();

    // Everything on the command line at this point is a member.
    getMembers();

    // Perform various checks on the operation/modifier specification
    // to make sure we are dealing with a legal request.
    if (NumOperations == 0)
        throw "You must specify at least one of the operations";
    if (NumOperations > 1)
        throw "Only one operation may be specified";
    if (NumPositional > 1)
        throw "You may only specify one of a, b, and i modifiers";
    if (AddAfter || AddBefore || InsertBefore)
        if (Operation != Move && Operation != ReplaceOrInsert)
            throw "The 'a', 'b' and 'i' modifiers can only be specified with "
            "the 'm' or 'r' operations";
    if (RecurseDirectories && Operation != ReplaceOrInsert)
        throw "The 'R' modifiers is only applicabe to the 'r' operation";
    if (OriginalDates && Operation != Extract)
        throw "The 'o' modifier is only applicable to the 'x' operation";
    if (TruncateNames && Operation!=QuickAppend && Operation!=ReplaceOrInsert)
        throw "The 'f' modifier is only applicable to the 'q' and 'r' operations";
    if (OnlyUpdate && Operation != ReplaceOrInsert)
        throw "The 'u' modifier is only applicable to the 'r' operation";
    if (Compression && Operation!=ReplaceOrInsert && Operation!=Extract)
        throw "The 'z' modifier is only applicable to the 'r' and 'x' operations";
    if (Count > 1 && Members.size() > 1)
        throw "Only one member name may be specified with the 'N' modifier";

    // Return the parsed operation to the caller
    return Operation;
}
Пример #10
0
// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  // Enable debug stream buffering.
  EnableDebugBuffering = true;

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets first, so that --version shows registered targets.
  InitializeAllTargets();
  InitializeAllAsmPrinters();

  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
  
  // Load the module to be compiled...
  SMDiagnostic Err;
  std::auto_ptr<Module> M;

  M.reset(ParseIRFile(InputFilename, Err, Context));
  if (M.get() == 0) {
    Err.Print(argv[0], errs());
    return 1;
  }
  Module &mod = *M.get();

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    mod.setTargetTriple(TargetTriple);

  Triple TheTriple(mod.getTargetTriple());
  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getHostTriple());

  // Allocate target machine.  First, check whether the user has explicitly
  // specified an architecture to compile for. If so we have to look it up by
  // name, because it might be a backend that has no mapping to a target triple.
  const Target *TheTarget = 0;
  if (!MArch.empty()) {
    for (TargetRegistry::iterator it = TargetRegistry::begin(),
           ie = TargetRegistry::end(); it != ie; ++it) {
      if (MArch == it->getName()) {
        TheTarget = &*it;
        break;
      }
    }

    if (!TheTarget) {
      errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
      return 1;
    }

    // Adjust the triple to match (if known), otherwise stick with the
    // module/host triple.
    Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
    if (Type != Triple::UnknownArch)
      TheTriple.setArch(Type);
  } else {
    std::string Err;
    TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
    if (TheTarget == 0) {
      errs() << 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(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();

  // Figure out where we are going to send the output...
  formatted_raw_ostream *Out = GetOutputStream(TheTarget->getName(), argv[0]);
  if (Out == 0) return 1;

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (OptLevel) {
  default:
    errs() << argv[0] << ": invalid optimization level.\n";
    return 1;
  case ' ': break;
  case '0': OLvl = CodeGenOpt::None; break;
  case '1': OLvl = CodeGenOpt::Less; break;
  case '2': OLvl = CodeGenOpt::Default; break;
  case '3': OLvl = CodeGenOpt::Aggressive; break;
  }

  // Request that addPassesToEmitFile run the Verifier after running
  // passes which modify the IR.
#ifndef NDEBUG
  bool DisableVerify = false;
#else
  bool DisableVerify = true;
#endif

  // If this target requires addPassesToEmitWholeFile, do it now.  This is
  // used by strange things like the C backend.
  if (Target.WantsWholeFile()) {
    PassManager PM;

    // Add the target data from the target machine, if it exists, or the module.
    if (const TargetData *TD = Target.getTargetData())
      PM.add(new TargetData(*TD));
    else
      PM.add(new TargetData(&mod));

    if (!NoVerify)
      PM.add(createVerifierPass());

    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl,
                                        DisableVerify)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      if (Out != &fouts()) 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.
    FunctionPassManager Passes(M.get());

    // Add the target data from the target machine, if it exists, or the module.
    if (const TargetData *TD = Target.getTargetData())
      Passes.add(new TargetData(*TD));
    else
      Passes.add(new TargetData(&mod));

#ifndef NDEBUG
    if (!NoVerify)
      Passes.add(createVerifierPass());
#endif

    // Override default to generate verbose assembly.
    Target.setAsmVerbosityDefault(true);

    if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl,
                                   DisableVerify)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      if (Out != &fouts()) 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()) {
        if (DisableRedZone)
          I->addFnAttr(Attribute::NoRedZone);
        if (NoImplicitFloats)
          I->addFnAttr(Attribute::NoImplicitFloat);
        Passes.run(*I);
      }

    Passes.doFinalization();
  }

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

  return 0;
}
Пример #11
0
int main(int argc, char *argv[])
{
	cl::ParseCommandLineOptions(argc, argv);

	bool getres = Output.size() > 0 || Print;

	switch (Command)
	{
	case Create:
		case CreateFromTrees:
		case CreateFromMira:
		{
		//read in all the molecules and calculate the max bounding box
		KSamplePartitioner topdown(KCenters, KSampleMult,
				KSamplePartitioner::AveCenter, SwitchToPack);

		PackerPtr packer;
		switch (PackerChoice)
		{
		case FullMerge:
			packer = PackerPtr(
					new FullMergePacker(Pack, ClusterDist, Knn, Sentinals));
			break;
		case MatchPack:
			packer = PackerPtr(
					new MatcherPacker(Pack, Knn, Sentinals, ClusterDist));
			break;
		case GreedyMerge:
			packer = PackerPtr(
					new GreedyPacker(Pack, ClusterDist, Knn, Sentinals));
			break;
		case Spectral:
			packer = PackerPtr(
					new SpectralPacker(Pack, SpectralAlg, !UseUnnorm));
			break;
		}

		setDistance(ShapeDist);

		GSSLevelCreator leveler(&topdown, packer.get(), SwitchToPack,
				SwitchToPack);

		GSSTreeCreator creator(&leveler, SuperNodeDepth);

		filesystem::path dbpath(Database.c_str());

		if (Command == Create)
		{
			Molecule::iterator molitr(Input, MaxDimension, Resolution,
					KeepHydrogens, ProbeRadius);
			if (!creator.create<Molecule, Molecule::iterator>(dbpath, molitr,
					MaxDimension, Resolution))
			{
				cerr << "Error creating database\n";
				exit(1);
			}
		}
		else if (Command == CreateFromMira)
		{
			MiraObject::iterator miraitr(Input);
			if (!creator.create<MiraObject, MiraObject::iterator>(dbpath,
					miraitr, MaxDimension, Resolution))
			{
				cerr << "Error creating database\n";
				exit(1);
			}
		}
		else if (Command == CreateFromTrees) //trees already created
		{
			filesystem::path treedir(Input.c_str());
			if (!creator.create(dbpath, treedir, MaxDimension, Resolution))
			{
				cerr << "Error creating database\n";
				exit(1);
			}
		}

		if (Verbose)
			creator.printStats(cout);

	}
		break;
	case CreateTrees:
		{
		//read in all the molecules and calculate the max bounding box
		KSamplePartitioner topdown(KCenters, KSampleMult,
				KSamplePartitioner::AveCenter, SwitchToPack);

		PackerPtr packer = PackerPtr(
				new MatcherPacker(Pack, Knn, Sentinals, ClusterDist));

		setDistance(ShapeDist);

		GSSLevelCreator leveler(&topdown, packer.get(), SwitchToPack,
				SwitchToPack);

		GSSTreeCreator creator(&leveler, SuperNodeDepth);

		filesystem::path dbpath(Database.c_str());
		Molecule::iterator molitr(Input, MaxDimension, Resolution,
				KeepHydrogens, ProbeRadius);
		if (!creator.createTreesOnly<Molecule, Molecule::iterator>(dbpath,
				molitr, MaxDimension, Resolution))
		{
			cerr << "Error creating database\n";
			exit(1);
		}

	}
		break;
	case MiraSearch:
		{
		//read in database
		filesystem::path dbfile(Database.c_str());
		GSSTreeSearcher gss(Verbose);
		if (!gss.load(dbfile))
		{
			cerr << "Could not read database " << Database << "\n";
			exit(-1);
		}

		setDistance(ShapeDist);
		ifstream mirain(Input.c_str());
		MiraObject obj;
		obj.read(mirain);

		StringResults res;
		ObjectTree objTree = gss.createTreeFromObject(obj);

		if (K < 1) //scan
		{
			gss.nn_scan(objTree, true, res);
		}
		else
		{
			gss.nn_search(objTree, K, HUGE_VAL, true, res);
		}

		for (unsigned i = 0, n = res.size(); i < n; i++)
		{
			cout << i << "\t" << res.getString(i) << "\t" << res.getScore(i)
					<< "\n";
		}
	}
		break;
	case DCMiraSearch:
		{
		//read in database
		filesystem::path dbfile(Database.c_str());
		GSSTreeSearcher gss(Verbose);

		if (!gss.load(dbfile))
		{
			cerr << "Could not read database " << Database << "\n";
			exit(-1);
		}
		setDistance(ShapeDist);

		double resolution = gss.getResolution();

		setDistance(ShapeDist);

		StringResults res;
		ObjectTree objTree;
		ObjectTree smallTree, bigTree;

		if(Input.size() > 0)
		{
			ifstream mirain(Input.c_str());
			MiraObject obj;
			obj.read(mirain);
			objTree = gss.createTreeFromObject(obj);
		}

		//search with passed shapes, does not invert exclude
		if (MSVShape.size() > 0 && MIVShape.size() > 0)
		{
			MiraObject miv, msv;
			ifstream mivin(MIVShape.c_str());
			ifstream msvin(MSVShape.c_str());
			miv.read(mivin);
			msv.read(msvin);

			smallTree = gss.createTreeFromObject(miv);
			bigTree = gss.createTreeFromObject(msv);
		}
		else if(MSVShape.size() > 0 || MIVShape.size() > 0)
		{
			cerr << "Error, need to specify both MIV and MSV\n";
			exit(-1);
		}
		else //base off of query shape
		{
			MGrid smallgrid, biggrid;
			objTree->makeGrid(smallgrid, resolution);
			biggrid = smallgrid;
			smallgrid.shrink(LessDist);
			biggrid.grow(MoreDist);

			smallTree = ObjectTree(
					MappableOctTree::createFromGrid(smallgrid));
			bigTree = ObjectTree(
					MappableOctTree::createFromGrid(biggrid));
		}

		if (!ScanOnly)
			gss.dc_search(smallTree, bigTree, objTree, Output.size() > 1, res);

		if (ScanCheck || ScanOnly)
		{
			StringResults res2;
			gss.dc_scan_search(smallTree, bigTree, objTree, Output.size() > 1,
					res2);
			if (res2.size() != res.size())
			{
				cerr << "Scanning found different number\n";
			}
		}
		for (unsigned i = 0, n = res.size(); i < n; i++)
		{
			cout << i << "\t" << res.getString(i) << "\t" << res.getScore(i)
					<< "\n";
		}
	}
		break;
	case BatchMiraSearch:
		{
		//read in database
		filesystem::path dbfile(Database.c_str());
		GSSTreeSearcher gss(Verbose);

		if (!gss.load(dbfile))
		{
			cerr << "Could not read database " << Database << "\n";
			exit(-1);
		}
		double resolution = gss.getResolution();

		setDistance(ShapeDist);

		//read in each line of the batch file which should be
		//cmd in_ligand in_receptor(for DC Search)
		ifstream batch(Input.c_str());
		if (!batch)
		{
			cerr << "Could not read batch file " << Input << "\n";
			exit(-1);
		}

		string line;
		while (getline(batch, line))
		{
			stringstream toks(line);
			string cmd, mira;
			toks >> cmd;

			if (!toks)
				break;

			double less = 0, more = 0;
			unsigned k = 1;
			string mivfile, msvfile;

			if (cmd == "DCSearch")
			{
				toks >> mira;
				toks >> less;
				toks >> more;
			}
			else if (cmd == "NNSearch")
			{
				toks >> mira;
				toks >> k;
			}
			else if(cmd == "DCSearch2")
bool LowerEmExceptions::runOnModule(Module &M) {
  TheModule = &M;

  // Add functions

  Type *i32 = Type::getInt32Ty(M.getContext());
  Type *i8 = Type::getInt8Ty(M.getContext());
  Type *i1 = Type::getInt1Ty(M.getContext());
  Type *i8P = i8->getPointerTo();
  Type *Void = Type::getVoidTy(M.getContext());

  if (!(GetHigh = TheModule->getFunction("getHigh32"))) {
    FunctionType *GetHighFunc = FunctionType::get(i32, false);
    GetHigh = Function::Create(GetHighFunc, GlobalValue::ExternalLinkage,
                               "getHigh32", TheModule);
  }

  if (!(PreInvoke = TheModule->getFunction("emscripten_preinvoke"))) {
    FunctionType *VoidFunc = FunctionType::get(Void, false);
    PreInvoke = Function::Create(VoidFunc, GlobalValue::ExternalLinkage, "emscripten_preinvoke", TheModule);
  }

  if (!(PostInvoke = TheModule->getFunction("emscripten_postinvoke"))) {
    FunctionType *IntFunc = FunctionType::get(i32, false);
    PostInvoke = Function::Create(IntFunc, GlobalValue::ExternalLinkage, "emscripten_postinvoke", TheModule);
  }

  FunctionType *LandingPadFunc = FunctionType::get(i8P, true);
  LandingPad = Function::Create(LandingPadFunc, GlobalValue::ExternalLinkage, "emscripten_landingpad", TheModule);

  FunctionType *ResumeFunc = FunctionType::get(Void, true);
  Resume = Function::Create(ResumeFunc, GlobalValue::ExternalLinkage, "emscripten_resume", TheModule);
  
  // Process

  bool HasWhitelist = Whitelist.size() > 0;
  std::string WhitelistChecker;
  if (HasWhitelist) WhitelistChecker = "," + Whitelist + ",";

  bool Changed = false;

  for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) {
    Function *F = Iter++;

    std::vector<Instruction*> ToErase;
    std::set<LandingPadInst*> LandingPads;

    bool AllowExceptionsInFunc = !HasWhitelist || int(WhitelistChecker.find(F->getName())) > 0;

    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      // check terminator for invokes
      if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
        LandingPads.insert(II->getLandingPadInst());

        bool NeedInvoke = AllowExceptionsInFunc && canThrow(II->getCalledValue());

        if (NeedInvoke) {
          // Insert a normal call instruction folded in between pre- and post-invoke
          CallInst::Create(PreInvoke, "", II);

          SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
          CallInst *NewCall = CallInst::Create(II->getCalledValue(),
                                               CallArgs, "", II);
          NewCall->takeName(II);
          NewCall->setCallingConv(II->getCallingConv());
          NewCall->setAttributes(II->getAttributes());
          NewCall->setDebugLoc(II->getDebugLoc());
          II->replaceAllUsesWith(NewCall);
          ToErase.push_back(II);

          CallInst *Post = CallInst::Create(PostInvoke, "", II);
          Instruction *Post1 = new TruncInst(Post, i1, "", II);

          // Insert a branch based on the postInvoke
          BranchInst::Create(II->getUnwindDest(), II->getNormalDest(), Post1, II);
        } else {
          // This can't throw, and we don't need this invoke, just replace it with a call+branch
          SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
          CallInst *NewCall = CallInst::Create(II->getCalledValue(),
                                               CallArgs, "", II);
          NewCall->takeName(II);
          NewCall->setCallingConv(II->getCallingConv());
          NewCall->setAttributes(II->getAttributes());
          NewCall->setDebugLoc(II->getDebugLoc());
          II->replaceAllUsesWith(NewCall);
          ToErase.push_back(II);

          BranchInst::Create(II->getNormalDest(), II);

          // Remove any PHI node entries from the exception destination.
          II->getUnwindDest()->removePredecessor(BB);
        }

        Changed = true;
      }
      // scan the body of the basic block for resumes
      for (BasicBlock::iterator Iter = BB->begin(), E = BB->end();
           Iter != E; ) {
        Instruction *I = Iter++;
        if (ResumeInst *R = dyn_cast<ResumeInst>(I)) {
          // split the input into legal values
          Value *Input = R->getValue();
          ExtractValueInst *Low = ExtractValueInst::Create(Input, 0, "", R);
          ExtractValueInst *High = ExtractValueInst::Create(Input, 1, "", R);

          // create a resume call
          SmallVector<Value*,2> CallArgs;
          CallArgs.push_back(Low);
          CallArgs.push_back(High);
          CallInst::Create(Resume, CallArgs, "", R);

          new UnreachableInst(TheModule->getContext(), R); // add a terminator to the block

          ToErase.push_back(R);
        }
      }
    }

    // Look for orphan landingpads, can occur in blocks with no predecesors
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      Instruction *I = BB->getFirstNonPHI();
      if (LandingPadInst *LP = dyn_cast<LandingPadInst>(I)) {
        LandingPads.insert(LP);
      }
    }

    // Handle all the landingpad for this function together, as multiple invokes may share a single lp
    for (std::set<LandingPadInst*>::iterator I = LandingPads.begin(); I != LandingPads.end(); I++) {
      // Replace the landingpad with a landingpad call to get the low part, and a getHigh for the high
      LandingPadInst *LP = *I;
      unsigned Num = LP->getNumClauses();
      SmallVector<Value*,16> NewLPArgs;
      NewLPArgs.push_back(LP->getPersonalityFn());
      for (unsigned i = 0; i < Num; i++) {
        Value *Arg = LP->getClause(i);
        // As a temporary workaround for the lack of aggregate varargs support
        // in the varargs lowering code, break out filter operands into their
        // component elements.
        if (LP->isFilter(i)) {
          ArrayType *ATy = cast<ArrayType>(Arg->getType());
          for (unsigned elem = 0, elemEnd = ATy->getNumElements(); elem != elemEnd; ++elem) {
            Instruction *EE = ExtractValueInst::Create(Arg, makeArrayRef(elem), "", LP);
            NewLPArgs.push_back(EE);
          }
        } else {
          NewLPArgs.push_back(Arg);
        }
      }
      NewLPArgs.push_back(LP->isCleanup() ? ConstantInt::getTrue(i1) : ConstantInt::getFalse(i1));
      CallInst *NewLP = CallInst::Create(LandingPad, NewLPArgs, "", LP);

      Instruction *High = CallInst::Create(GetHigh, "", LP);

      // New recreate an aggregate for them, which will be all simplified later (simplification cannot handle landingpad, hence all this)
      InsertValueInst *IVA = InsertValueInst::Create(UndefValue::get(LP->getType()), NewLP, 0, "", LP);
      InsertValueInst *IVB = InsertValueInst::Create(IVA, High, 1, "", LP);

      LP->replaceAllUsesWith(IVB);
      ToErase.push_back(LP);
    }

    // erase everything we no longer need in this function
    for (unsigned i = 0; i < ToErase.size(); i++) ToErase[i]->eraseFromParent();
  }

  return Changed;
}
Пример #13
0
/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings.  The strings are added to the CheckStrings vector.
static bool ReadCheckFile(SourceMgr &SM,
                          std::vector<CheckString> &CheckStrings) {
  // Open the check file, and tell SourceMgr about it.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open check file '" << CheckFilename << "': "
           << ErrorStr << '\n';
    return true;
  }

  // If we want to canonicalize whitespace, strip excess whitespace from the
  // buffer containing the CHECK lines.
  if (!NoCanonicalizeWhiteSpace)
    F = CanonicalizeInputFile(F);

  SM.AddNewSourceBuffer(F, SMLoc());

  // Find all instances of CheckPrefix followed by : in the file.
  StringRef Buffer = F->getBuffer();

  std::vector<std::pair<SMLoc, Pattern> > NotMatches;

  while (1) {
    // See if Prefix occurs in the memory buffer.
    Buffer = Buffer.substr(Buffer.find(CheckPrefix));

    // If we didn't find a match, we're done.
    if (Buffer.empty())
      break;

    const char *CheckPrefixStart = Buffer.data();

    // When we find a check prefix, keep track of whether we find CHECK: or
    // CHECK-NEXT:
    bool IsCheckNext = false, IsCheckNot = false;

    // Verify that the : is present after the prefix.
    if (Buffer[CheckPrefix.size()] == ':') {
      Buffer = Buffer.substr(CheckPrefix.size()+1);
    } else if (Buffer.size() > CheckPrefix.size()+6 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+7);
      IsCheckNext = true;
    } else if (Buffer.size() > CheckPrefix.size()+5 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+6);
      IsCheckNot = true;
    } else {
      Buffer = Buffer.substr(1);
      continue;
    }

    // Okay, we found the prefix, yay.  Remember the rest of the line, but
    // ignore leading and trailing whitespace.
    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));

    // Scan ahead to the end of line.
    size_t EOL = Buffer.find_first_of("\n\r");

    // Remember the location of the start of the pattern, for diagnostics.
    SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());

    // Parse the pattern.
    Pattern P;
    if (P.ParsePattern(Buffer.substr(0, EOL), SM))
      return true;

    Buffer = Buffer.substr(EOL);


    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
    if (IsCheckNext && CheckStrings.empty()) {
      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
                      CheckPrefix+ ": line", "error");
      return true;
    }

    // Handle CHECK-NOT.
    if (IsCheckNot) {
      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
                                          P));
      continue;
    }


    // Okay, add the string we captured to the output vector and move on.
    CheckStrings.push_back(CheckString(P,
                                       PatternLoc,
                                       IsCheckNext));
    std::swap(NotMatches, CheckStrings.back().NotStrings);
  }

  if (CheckStrings.empty()) {
    errs() << "error: no check strings found with prefix '" << CheckPrefix
           << ":'\n";
    return true;
  }

  if (!NotMatches.empty()) {
    errs() << "error: '" << CheckPrefix
           << "-NOT:' not supported after last check line.\n";
    return true;
  }

  return false;
}
Пример #14
0
// 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;
}
Пример #15
0
bool DelinkPass::runOnModule(Module& M) {

  if(DelinkExcept.size()) {

    std::ifstream RFI(DelinkExcept.c_str());

    DenseSet<GlobalValue*> Keep;
  
    while(!RFI.eof()) {

      std::string line;
      std::getline(RFI, line);

      trim(line);

      if(line.empty())
	continue;

      GlobalValue* GV = M.getNamedValue(line);
      if(!GV) {
	
	errs() << "Warning: Skipped " << line << "\n";
	continue;

      }

      Keep.insert(GV);
  
    }

    for(Module::iterator it = M.begin(), itend = M.end(); it != itend; ++it) {

      if(!Keep.count(it))
	it->deleteBody();

    }

  }
  else {

    std::ifstream RFI(DelinkSymbols.c_str());
  
    while(!RFI.eof()) {

      std::string line;
      std::getline(RFI, line);

      trim(line);

      if(line.empty())
	continue;

      if(line == "__uClibc_main" || line == "__uClibc_main_spec")
	continue;
    
      GlobalValue* GV = M.getNamedValue(line);
      if(!GV) {

	errs() << "Warning: Skipped " << line << "\n";
	continue;

      }
    
      if(Function* F = dyn_cast<Function>(GV))
	F->deleteBody();

    }

  }

  return true;

}