Beispiel #1
0
// Out of line constructor provides default values for pass options and
// registers all common codegen passes.
TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
    : ImmutablePass(ID), PM(&pm), TM(&TM) {
  Impl = new PassConfigImpl();

  // Register all target independent codegen passes to activate their PassIDs,
  // including this pass itself.
  initializeCodeGen(*PassRegistry::getPassRegistry());

  // Also register alias analysis passes required by codegen passes.
  initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry());
  initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());

  if (StringRef(PrintMachineInstrs.getValue()).equals(""))
    TM.Options.PrintMachineCode = true;

  if (EnableIPRA.getNumOccurrences())
    TM.Options.EnableIPRA = EnableIPRA;
  else {
    // If not explicitly specified, use target default.
    TM.Options.EnableIPRA |= TM.useIPRA();
  }

  if (TM.Options.EnableIPRA)
    setRequiresCodeGenSCCOrder();

  if (EnableGlobalISelAbort.getNumOccurrences())
    TM.Options.GlobalISelAbort = EnableGlobalISelAbort;

  setStartStopPasses();
}
int main(int argc, char **argv) {

  sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);

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

  cl::ParseCommandLineOptions(argc, argv, "Bitcode strip tool\n");

  int input_fd = open(InputFilename.c_str(), O_RDONLY);

  unsigned char *wrapper = NULL;
  char *bitcode = NULL;

  // Read bitcode wrapper
  size_t bitcode_size = 0;
  size_t wrapper_size = ReadBitcodeWrapper(input_fd, &wrapper, bitcode_size);

  // Read bitcode
  bitcode = (char*) calloc(1, bitcode_size);
  size_t nread = read(input_fd, (void*) bitcode, bitcode_size);
  if (nread != bitcode_size) {
    errs() << "Could not read bitcode\n";
    return 1;
  }

  // Strip bitcode
  std::string BCString;
  StripBitcode(bitcode, bitcode_size, BCString, Context);

  // Update bitcode size
  WriteInt32(wrapper, 12, BCString.length());

  // Default to input filename
  if (OutputFilename.empty())
    OutputFilename.getValue() = InputFilename;

  // Output stripped bitcode
  std::error_code EC;
  tool_output_file Out(OutputFilename.c_str(), EC, sys::fs::F_None);
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  Out.os().write((const char *) wrapper, wrapper_size);
  Out.os().write(BCString.c_str(), BCString.length());
  Out.keep();

  // Clean up
  free((void *) wrapper);
  free((void *) bitcode);
  close(input_fd);

  return 0;
}
int main(int argc, const char **argv) {
    CommonOptionsParser OptionsParser(argc, argv, NoGlobalStyleCategory);
    ClangTool Tool(OptionsParser.getCompilations(),
                   OptionsParser.getSourcePathList());
    
    MatchFinder finder;

    // Snarf abstract-only namespaces from the environment.
    std::vector<std::string> abstract_namespaces_v, banned_namespaces_v;
    std::copy(abstract_namespaces.begin(), abstract_namespaces.end(), std::back_inserter(abstract_namespaces_v));
    std::copy(banned_namespaces.begin(), banned_namespaces.end(), std::back_inserter(banned_namespaces_v));
    std::unique_ptr<RuleCheckerBase> rules[] = {
        make_unique<DisallowNew>(),
        make_unique<DisallowDelete>(),
        make_unique<DisallowGlobals>(),
        make_unique<DisallowNonAbstract>(abstract_namespaces_v),
        make_unique<DisallowCoupling>(banned_namespaces_v)
    };
    size_t rules_size = sizeof(rules) / sizeof(rules[0]);
    auto rules_begin = &rules[0];
    auto rules_end = &rules[rules_size];

    std::vector<std::string> analyze_paths_v;
    std::copy(analyze_paths.begin(), analyze_paths.end(), std::back_inserter(analyze_paths_v));

    for (size_t i = 0; i < sizeof(rules) / sizeof(rules[0]); ++i) {
        auto &rule = rules[i];
        rule->setAnalyzePaths(analyze_paths_v);
        rule->SetupMatches(finder);
        rule->getPrinter().setDebug(Debug.getValue());
    }
    
#ifndef NDEBUG
    llvm::DebugFlag = Debug.getValue();
#endif

    return Tool.run(newFrontendActionFactory(&finder).get()) || 
        (Werror.getValue() && 
         std::any_of
         (rules_begin, rules_end, 
          [] (const std::unique_ptr<RuleCheckerBase> &rule) {
             return rule->getPrinter().getWarnings();
         }));
}
Beispiel #4
0
/*!
 * Initialization of pointer analysis
 */
void PointerAnalysis::initialize(Module& module) {

    /// whether we have already built PAG
    if(pag == NULL) {

        /// run class hierarchy analysis
        chgraph = new CHGraph();
        chgraph->buildCHG(module);

        DBOUT(DGENERAL, outs() << pasMsg("Building Symbol table ...\n"));
        SymbolTableInfo* symTable = SymbolTableInfo::Symbolnfo();
        symTable->buildMemModel(module);

        DBOUT(DGENERAL, outs() << pasMsg("Building PAG ...\n"));
        if (!Graphtxt.getValue().empty()) {
            PAGBuilderFromFile fileBuilder(Graphtxt.getValue());
            pag = fileBuilder.build();

        } else {
            PAGBuilder builder;
            pag = builder.build(module);
        }

        // dump the PAG graph
        if (dumpGraph())
            PAG::getPAG()->dump("pag_initial");

        // print to command line of the PAG graph
        if (PAGPrint)
            pag->print();
    }

    typeSystem = new TypeSystem(pag);

    mod = &module;

    /// initialise pta call graph
    if(EnableThreadCallGraph)
        ptaCallGraph = new ThreadCallGraph(mod);
    else
        ptaCallGraph = new PTACallGraph(mod);
    callGraphSCCDetection();
}
Beispiel #5
0
bool TFA::runOnModule(Module &M) {
	if (Input.getValue() == llvm::cl::BOU_UNSET || Input.getValue()
			== llvm::cl::BOU_TRUE) {
		InputValues &IV = getAnalysis<InputValues> ();
		inputDepValues = IV.getInputDepValues();
	} else {
		InputDep &IV = getAnalysis<InputDep> ();
		inputDepValues = IV.getInputDepValues();
	}
	bSSA &bssa = getAnalysis<bSSA> ();
	depGraph = bssa.newGraph;
	DEBUG( // display dependence graph
	string Error;
	std::string tmp = M.getModuleIdentifier();
	replace(tmp.begin(), tmp.end(), '\\', '_');
	std::string Filename = "/tmp/" + tmp + ".dot";

	//Print dependency graph (in dot format)
	depGraph->toDot(M.getModuleIdentifier(), Filename);
	DisplayGraph(Filename, true, GraphProgram::DOT);
	);
Beispiel #6
0
void Executor::initTimers() {
  static bool first = true;

  if (first) {
    first = false;
    setupHandler();
  }

  if (MaxTime) {
    addTimer(new HaltTimer(this), MaxTime.getValue());
  }
}
Beispiel #7
0
/// \brief Emit an inline hint if \p F is globally hot or cold.
///
/// If \p F consumes a significant fraction of samples (indicated by
/// SampleProfileGlobalHotThreshold), apply the InlineHint attribute for the
/// inliner to consider the function hot.
///
/// If \p F consumes a small fraction of samples (indicated by
/// SampleProfileGlobalColdThreshold), apply the Cold attribute for the inliner
/// to consider the function cold.
///
/// FIXME - This setting of inline hints is sub-optimal. Instead of marking a
/// function globally hot or cold, we should be annotating individual callsites.
/// This is not currently possible, but work on the inliner will eventually
/// provide this ability. See http://reviews.llvm.org/D15003 for details and
/// discussion.
///
/// \returns True if either attribute was applied to \p F.
bool SampleProfileLoader::emitInlineHints(Function &F) {
  if (TotalCollectedSamples == 0)
    return false;

  uint64_t FunctionSamples = Samples->getTotalSamples();
  double SamplesPercent =
      (double)FunctionSamples / (double)TotalCollectedSamples * 100.0;

  // If the function collected more samples than the hot threshold, mark
  // it globally hot.
  if (SamplesPercent >= SampleProfileGlobalHotThreshold) {
    F.addFnAttr(llvm::Attribute::InlineHint);
    std::string Msg;
    raw_string_ostream S(Msg);
    S << "Applied inline hint to globally hot function '" << F.getName()
      << "' with " << format("%.2f", SamplesPercent)
      << "% of samples (threshold: "
      << format("%.2f", SampleProfileGlobalHotThreshold.getValue()) << "%)";
    S.flush();
    emitOptimizationRemark(F.getContext(), DEBUG_TYPE, F, DebugLoc(), Msg);
    return true;
  }

  // If the function collected fewer samples than the cold threshold, mark
  // it globally cold.
  if (SamplesPercent <= SampleProfileGlobalColdThreshold) {
    F.addFnAttr(llvm::Attribute::Cold);
    std::string Msg;
    raw_string_ostream S(Msg);
    S << "Applied cold hint to globally cold function '" << F.getName()
      << "' with " << format("%.2f", SamplesPercent)
      << "% of samples (threshold: "
      << format("%.2f", SampleProfileGlobalColdThreshold.getValue()) << "%)";
    S.flush();
    emitOptimizationRemark(F.getContext(), DEBUG_TYPE, F, DebugLoc(), Msg);
    return true;
  }

  return false;
}
// This checks whether the transformation is legal.
// Also returns false in cases where it's potentially legal, but
// we don't even want to try.
bool X86CallFrameOptimization::isLegal(MachineFunction &MF) {
  if (NoX86CFOpt.getValue())
    return false;

  // We currently only support call sequences where *all* parameters.
  // are passed on the stack.
  // No point in running this in 64-bit mode, since some arguments are
  // passed in-register in all common calling conventions, so the pattern
  // we're looking for will never match.
  if (STI->is64Bit())
    return false;

  // We can't encode multiple DW_CFA_GNU_args_size or DW_CFA_def_cfa_offset
  // in the compact unwind encoding that Darwin uses. So, bail if there
  // is a danger of that being generated.
  if (STI->isTargetDarwin() && 
     (!MF.getMMI().getLandingPads().empty() || 
       (MF.getFunction()->needsUnwindTableEntry() && !TFL->hasFP(MF))))
    return false;

  // You would expect straight-line code between call-frame setup and
  // call-frame destroy. You would be wrong. There are circumstances (e.g.
  // CMOV_GR8 expansion of a select that feeds a function call!) where we can
  // end up with the setup and the destroy in different basic blocks.
  // This is bad, and breaks SP adjustment.
  // So, check that all of the frames in the function are closed inside
  // the same block, and, for good measure, that there are no nested frames.
  unsigned FrameSetupOpcode = TII->getCallFrameSetupOpcode();
  unsigned FrameDestroyOpcode = TII->getCallFrameDestroyOpcode();
  for (MachineBasicBlock &BB : MF) {
    bool InsideFrameSequence = false;
    for (MachineInstr &MI : BB) {
      if (MI.getOpcode() == FrameSetupOpcode) {
        if (InsideFrameSequence)
          return false;
        InsideFrameSequence = true;
      } else if (MI.getOpcode() == FrameDestroyOpcode) {
        if (!InsideFrameSequence)
          return false;
        InsideFrameSequence = false;
      }
    }

    if (InsideFrameSequence)
      return false;
  }

  return true;
}
// This checks whether the transformation is legal.
// Also returns false in cases where it's potentially legal, but
// we don't even want to try.
bool X86CallFrameOptimization::isLegal(MachineFunction &MF) {
  if (NoX86CFOpt.getValue())
    return false;

  // We can't encode multiple DW_CFA_GNU_args_size or DW_CFA_def_cfa_offset
  // in the compact unwind encoding that Darwin uses. So, bail if there
  // is a danger of that being generated.
  if (STI->isTargetDarwin() &&
      (!MF.getLandingPads().empty() ||
       (MF.getFunction().needsUnwindTableEntry() && !TFL->hasFP(MF))))
    return false;

  // It is not valid to change the stack pointer outside the prolog/epilog
  // on 64-bit Windows.
  if (STI->isTargetWin64())
    return false;

  // You would expect straight-line code between call-frame setup and
  // call-frame destroy. You would be wrong. There are circumstances (e.g.
  // CMOV_GR8 expansion of a select that feeds a function call!) where we can
  // end up with the setup and the destroy in different basic blocks.
  // This is bad, and breaks SP adjustment.
  // So, check that all of the frames in the function are closed inside
  // the same block, and, for good measure, that there are no nested frames.
  unsigned FrameSetupOpcode = TII->getCallFrameSetupOpcode();
  unsigned FrameDestroyOpcode = TII->getCallFrameDestroyOpcode();
  for (MachineBasicBlock &BB : MF) {
    bool InsideFrameSequence = false;
    for (MachineInstr &MI : BB) {
      if (MI.getOpcode() == FrameSetupOpcode) {
        if (InsideFrameSequence)
          return false;
        InsideFrameSequence = true;
      } else if (MI.getOpcode() == FrameDestroyOpcode) {
        if (!InsideFrameSequence)
          return false;
        InsideFrameSequence = false;
      }
    }

    if (InsideFrameSequence)
      return false;
  }

  return true;
}
// This checks whether the transformation is legal.
// Also returns false in cases where it's potentially legal, but
// we don't even want to try.
bool X86CallFrameOptimization::isLegal(MachineFunction &MF) {
    if (NoX86CFOpt.getValue())
        return false;

    // We currently only support call sequences where *all* parameters.
    // are passed on the stack.
    // No point in running this in 64-bit mode, since some arguments are
    // passed in-register in all common calling conventions, so the pattern
    // we're looking for will never match.
    const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
    if (STI.is64Bit())
        return false;

    // You would expect straight-line code between call-frame setup and
    // call-frame destroy. You would be wrong. There are circumstances (e.g.
    // CMOV_GR8 expansion of a select that feeds a function call!) where we can
    // end up with the setup and the destroy in different basic blocks.
    // This is bad, and breaks SP adjustment.
    // So, check that all of the frames in the function are closed inside
    // the same block, and, for good measure, that there are no nested frames.
    unsigned FrameSetupOpcode = TII->getCallFrameSetupOpcode();
    unsigned FrameDestroyOpcode = TII->getCallFrameDestroyOpcode();
    for (MachineBasicBlock &BB : MF) {
        bool InsideFrameSequence = false;
        for (MachineInstr &MI : BB) {
            if (MI.getOpcode() == FrameSetupOpcode) {
                if (InsideFrameSequence)
                    return false;
                InsideFrameSequence = true;
            } else if (MI.getOpcode() == FrameDestroyOpcode) {
                if (!InsideFrameSequence)
                    return false;
                InsideFrameSequence = false;
            }
        }

        if (InsideFrameSequence)
            return false;
    }

    return true;
}
int main(int argc, const char *argv[]) {
  cl::ParseCommandLineOptions(argc, argv, "SPIR verifier");

  if (InputFilename.empty()) {
    errs() << HelpMessage;
    return 1;
  }

  StringRef Path = InputFilename;
  LLVMContext Ctx;
  OwningPtr<MemoryBuffer> result;

  // Parse the bitcode file into a module.
  error_code ErrCode = MemoryBuffer::getFile(Path, result);

  if (!result.get()) {
    errs() << "Buffer Creation Error. " << ErrCode.message() << "\n";
    return 1;
  }

  std::string ErrMsg;
  Module *M = ParseBitcodeFile(result.get(), Ctx, &ErrMsg);
  if (!M) {
    outs() << "According to this SPIR Verifier, " << Path << " is an invalid SPIR module.\n";
    errs() << "Bitcode parsing error. " << ErrMsg << "\n";
    return 1;
  }

  // Run the verification pass, and report errors if necessary.
  SpirValidation Validation;
  Validation.runOnModule(*M);
  const ErrorPrinter *EP = Validation.getErrorPrinter();
  if (EP->hasErrors()) {
    outs() << "According to this SPIR Verifier, " << Path << " is an invalid SPIR module.\n";
    errs() << "The module contains the following errors:\n\n";
    EP->print(errs(), LITMode.getValue());
    return 1;
  }

  outs() << "According to this SPIR Verifier, " << Path << " is a valid SPIR module.\n";
  return 0;
}
// Out of line constructor provides default values for pass options and
// registers all common codegen passes.
TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm)
    : ImmutablePass(ID), PM(&pm), Started(true), Stopped(false),
      AddingMachinePasses(false), TM(tm), Impl(nullptr), Initialized(false),
      DisableVerify(false), EnableTailMerge(true) {

  Impl = new PassConfigImpl();

  // Register all target independent codegen passes to activate their PassIDs,
  // including this pass itself.
  initializeCodeGen(*PassRegistry::getPassRegistry());

  // Also register alias analysis passes required by codegen passes.
  initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry());
  initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());

  // Substitute Pseudo Pass IDs for real ones.
  substitutePass(&EarlyTailDuplicateID, &TailDuplicateID);
  substitutePass(&PostRAMachineLICMID, &MachineLICMID);

  if (StringRef(PrintMachineInstrs.getValue()).equals(""))
    TM->Options.PrintMachineCode = true;
}
Beispiel #13
0
void RegionInfo::print(raw_ostream &OS, const Module *) const {
  OS << "Region tree:\n";
  TopLevelRegion->print(OS, true, 0, printStyle.getValue());
  OS << "End region tree\n";
}
Beispiel #14
0
void Region::dump() const {
  print(dbgs(), true, getDepth(), printStyle.getValue());
}
Beispiel #15
0
/// Add the complete set of target-independent postISel code generator passes.
///
/// This can be read as the standard order of major LLVM CodeGen stages. Stages
/// with nontrivial configuration or multiple passes are broken out below in
/// add%Stage routines.
///
/// Any TargetPassConfig::addXX routine may be overriden by the Target. The
/// addPre/Post methods with empty header implementations allow injecting
/// target-specific fixups just before or after major stages. Additionally,
/// targets have the flexibility to change pass order within a stage by
/// overriding default implementation of add%Stage routines below. Each
/// technique has maintainability tradeoffs because alternate pass orders are
/// not well supported. addPre/Post works better if the target pass is easily
/// tied to a common pass. But if it has subtle dependencies on multiple passes,
/// the target should override the stage instead.
///
/// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
/// before/after any target-independent pass. But it's currently overkill.
void TargetPassConfig::addMachinePasses() {
  // Insert a machine instr printer pass after the specified pass.
  // If -print-machineinstrs specified, print machineinstrs after all passes.
  if (StringRef(PrintMachineInstrs.getValue()).equals(""))
    TM->Options.PrintMachineCode = true;
  else if (!StringRef(PrintMachineInstrs.getValue())
           .equals("option-unspecified")) {
    const PassRegistry *PR = PassRegistry::getPassRegistry();
    const PassInfo *TPI = PR->getPassInfo(PrintMachineInstrs.getValue());
    const PassInfo *IPI = PR->getPassInfo(StringRef("print-machineinstrs"));
    assert (TPI && IPI && "Pass ID not registered!");
    const char *TID = (const char *)(TPI->getTypeInfo());
    const char *IID = (const char *)(IPI->getTypeInfo());
    insertPass(TID, IID);
  }

  // Print the instruction selected machine code...
  printAndVerify("After Instruction Selection");

  // Expand pseudo-instructions emitted by ISel.
  if (addPass(&ExpandISelPseudosID))
    printAndVerify("After ExpandISelPseudos");

  // Add passes that optimize machine instructions in SSA form.
  if (getOptLevel() != CodeGenOpt::None) {
    addMachineSSAOptimization();
  } else {
    // If the target requests it, assign local variables to stack slots relative
    // to one another and simplify frame index references where possible.
    addPass(&LocalStackSlotAllocationID);
  }

  // Run pre-ra passes.
  if (addPreRegAlloc())
    printAndVerify("After PreRegAlloc passes");

  // Run register allocation and passes that are tightly coupled with it,
  // including phi elimination and scheduling.
  if (getOptimizeRegAlloc())
    addOptimizedRegAlloc(createRegAllocPass(true));
  else
    addFastRegAlloc(createRegAllocPass(false));

  // Run post-ra passes.
  if (addPostRegAlloc())
    printAndVerify("After PostRegAlloc passes");

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  addPass(&PrologEpilogCodeInserterID);
  printAndVerify("After PrologEpilogCodeInserter");

  /// Add passes that optimize machine instructions after register allocation.
  if (getOptLevel() != CodeGenOpt::None)
    addMachineLateOptimization();

  // Expand pseudo instructions before second scheduling pass.
  addPass(&ExpandPostRAPseudosID);
  printAndVerify("After ExpandPostRAPseudos");

  // Run pre-sched2 passes.
  if (addPreSched2())
    printAndVerify("After PreSched2 passes");

  // Second pass scheduler.
  if (getOptLevel() != CodeGenOpt::None) {
    if (MISchedPostRA)
      addPass(&PostMachineSchedulerID);
    else
      addPass(&PostRASchedulerID);
    printAndVerify("After PostRAScheduler");
  }

  // GC
  if (addGCPasses()) {
    if (PrintGCInfo)
      addPass(createGCInfoPrinter(dbgs()));
  }

  // Basic block placement.
  if (getOptLevel() != CodeGenOpt::None)
    addBlockPlacement();

  if (addPreEmitPass())
    printAndVerify("After PreEmit passes");

  addPass(&StackMapLivenessID);
}
 RegisterArguments() :
   SpecializeArguments(ArgumentsFileName == "" ? "arguments" : ArgumentsFileName.getValue().c_str(),
                       SpecializeProgName.getValue() == "" ? NULL : SpecializeProgName.getValue().c_str())
 {
 }
Beispiel #17
0
void LatencyAccountant::exportStats(const XRayFileHeader &Header, F Fn) const {
  std::vector<TupleType> Results;
  Results.reserve(FunctionLatencies.size());
  for (auto FT : FunctionLatencies) {
    const auto &FuncId = FT.first;
    auto &Timings = FT.second;
    Results.emplace_back(FuncId, Timings.size(), getStats(Timings));
    auto &Row = std::get<2>(Results.back());
    if (Header.CycleFrequency) {
      double CycleFrequency = Header.CycleFrequency;
      Row.Min /= CycleFrequency;
      Row.Median /= CycleFrequency;
      Row.Pct90 /= CycleFrequency;
      Row.Pct99 /= CycleFrequency;
      Row.Max /= CycleFrequency;
      Row.Sum /= CycleFrequency;
    }

    Row.Function = FuncIdHelper.SymbolOrNumber(FuncId);
    Row.DebugInfo = FuncIdHelper.FileLineAndColumn(FuncId);
  }

  // Sort the data according to user-provided flags.
  switch (AccountSortOutput) {
  case SortField::FUNCID:
    sortByKey(Results, [](const TupleType &X) { return std::get<0>(X); });
    break;
  case SortField::COUNT:
    sortByKey(Results, [](const TupleType &X) { return std::get<1>(X); });
    break;
  case SortField::MIN:
    sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Min; });
    break;
  case SortField::MED:
    sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Median; });
    break;
  case SortField::PCT90:
    sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Pct90; });
    break;
  case SortField::PCT99:
    sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Pct99; });
    break;
  case SortField::MAX:
    sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Max; });
    break;
  case SortField::SUM:
    sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Sum; });
    break;
  case SortField::FUNC:
    llvm_unreachable("Not implemented");
  }

  if (AccountTop > 0) {
    auto MaxTop =
        std::min(AccountTop.getValue(), static_cast<int>(Results.size()));
    Results.erase(Results.begin() + MaxTop, Results.end());
  }

  for (const auto &R : Results)
    Fn(std::get<0>(R), std::get<1>(R), std::get<2>(R));
}
Beispiel #18
0
/// Add the complete set of target-independent postISel code generator passes.
///
/// This can be read as the standard order of major LLVM CodeGen stages. Stages
/// with nontrivial configuration or multiple passes are broken out below in
/// add%Stage routines.
///
/// Any TargetPassConfig::addXX routine may be overriden by the Target. The
/// addPre/Post methods with empty header implementations allow injecting
/// target-specific fixups just before or after major stages. Additionally,
/// targets have the flexibility to change pass order within a stage by
/// overriding default implementation of add%Stage routines below. Each
/// technique has maintainability tradeoffs because alternate pass orders are
/// not well supported. addPre/Post works better if the target pass is easily
/// tied to a common pass. But if it has subtle dependencies on multiple passes,
/// the target should override the stage instead.
///
/// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
/// before/after any target-independent pass. But it's currently overkill.
void TargetPassConfig::addMachinePasses() {
  AddingMachinePasses = true;

  // Insert a machine instr printer pass after the specified pass.
  StringRef PrintMachineInstrsPassName = PrintMachineInstrs.getValue();
  if (!PrintMachineInstrsPassName.equals("") &&
      !PrintMachineInstrsPassName.equals("option-unspecified")) {
    if (const PassInfo *TPI = getPassInfo(PrintMachineInstrsPassName)) {
      const PassRegistry *PR = PassRegistry::getPassRegistry();
      const PassInfo *IPI = PR->getPassInfo(StringRef("machineinstr-printer"));
      assert(IPI && "failed to get \"machineinstr-printer\" PassInfo!");
      const char *TID = (const char *)(TPI->getTypeInfo());
      const char *IID = (const char *)(IPI->getTypeInfo());
      insertPass(TID, IID);
    }
  }

  // Print the instruction selected machine code...
  printAndVerify("After Instruction Selection");

  // Expand pseudo-instructions emitted by ISel.
  addPass(&ExpandISelPseudosID);

  // Add passes that optimize machine instructions in SSA form.
  if (getOptLevel() != CodeGenOpt::None) {
    addMachineSSAOptimization();
  } else {
    // If the target requests it, assign local variables to stack slots relative
    // to one another and simplify frame index references where possible.
    addPass(&LocalStackSlotAllocationID, false);
  }

  if (TM->Options.EnableIPRA)
    addPass(createRegUsageInfoPropPass());

  // Run pre-ra passes.
  addPreRegAlloc();

  // Run register allocation and passes that are tightly coupled with it,
  // including phi elimination and scheduling.
  if (getOptimizeRegAlloc())
    addOptimizedRegAlloc(createRegAllocPass(true));
  else {
    if (RegAlloc != &useDefaultRegisterAllocator &&
        RegAlloc != &createFastRegisterAllocator)
      report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc.");
    addFastRegAlloc(createRegAllocPass(false));
  }

  // Run post-ra passes.
  addPostRegAlloc();

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  if (getOptLevel() != CodeGenOpt::None) {
    addPass(&PostRAMachineSinkingID);
    addPass(&ShrinkWrapID);
  }

  // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only
  // do so if it hasn't been disabled, substituted, or overridden.
  if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID))
      addPass(createPrologEpilogInserterPass());

  /// Add passes that optimize machine instructions after register allocation.
  if (getOptLevel() != CodeGenOpt::None)
    addMachineLateOptimization();

  // Expand pseudo instructions before second scheduling pass.
  addPass(&ExpandPostRAPseudosID);

  // Run pre-sched2 passes.
  addPreSched2();

  if (EnableImplicitNullChecks)
    addPass(&ImplicitNullChecksID);

  // Second pass scheduler.
  // Let Target optionally insert this pass by itself at some other
  // point.
  if (getOptLevel() != CodeGenOpt::None &&
      !TM->targetSchedulesPostRAScheduling()) {
    if (MISchedPostRA)
      addPass(&PostMachineSchedulerID);
    else
      addPass(&PostRASchedulerID);
  }

  // GC
  if (addGCPasses()) {
    if (PrintGCInfo)
      addPass(createGCInfoPrinter(dbgs()), false, false);
  }

  // Basic block placement.
  if (getOptLevel() != CodeGenOpt::None)
    addBlockPlacement();

  addPreEmitPass();

  if (TM->Options.EnableIPRA)
    // Collect register usage information and produce a register mask of
    // clobbered registers, to be used to optimize call sites.
    addPass(createRegUsageInfoCollector());

  addPass(&FuncletLayoutID, false);

  addPass(&StackMapLivenessID, false);
  addPass(&LiveDebugValuesID, false);

  // Insert before XRay Instrumentation.
  addPass(&FEntryInserterID, false);

  addPass(&XRayInstrumentationID, false);
  addPass(&PatchableFunctionID, false);

  if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
      EnableMachineOutliner != NeverOutline) {
    bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline);
    bool AddOutliner = RunOnAllFunctions ||
                       TM->Options.SupportsDefaultOutlining;
    if (AddOutliner)
      addPass(createMachineOutlinerPass(RunOnAllFunctions));
  }

  // Add passes that directly emit MI after all other MI passes.
  addPreEmitPass2();

  AddingMachinePasses = false;
}
Beispiel #19
0
//Command line decoder control
void startCmdLine(){
    LLVMContext &Context = getGlobalContext();

    for (unsigned int i =0 ; i < PassList.size(); i++ ){
        cout << "Pass added: "<< PassList[i]->getPassName() << endl;
        cout << "Argument name :" << PassList[i]->getPassArgument() << endl;
    }

    clock_t timer = clock();

    //Parsing XDF file
    std::cout << "Parsing file " << XDFFile.getValue() << "." << endl;

    XDFParser xdfParser(Verbose);
    Network* network = xdfParser.parseFile(XDFFile, Context);

    cout << "Network parsed in : "<< (clock() - timer) * 1000 / CLOCKS_PER_SEC << " ms, start engine" << endl;

    //Parsing XCF file if needed
    if(XCFFile != "") {
        std::cout << "Parsing file " << XCFFile.getValue() << "." << endl;

        XCFParser xcfParser(Verbose);
        map<string, string>* mapping = xcfParser.parseFile(XCFFile);
        network->setMapping(mapping);
    }

    if (enableTrace){
        setTraces(network);
    }

    //Load network
    engine->load(network);

    // Optimizing decoder
    if (optLevel > 0){
        engine->optimize(network, optLevel);
    }

    // Verify the given decoder if needed
    if (Verify){
        engine->verify(network, "error.txt");
    }

    // Set input file
    input_file = (char*)VidFile.c_str();

    // Print the given decoder if needed
    if (OutputDir != ""){
        engine->print(network);
    }

    //Run network
    engine->run(network);

    cout << "End of Jade" << endl;
    cout << "Total time: " << (clock() - timer) * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    if(XCFFile != "") {
        cout << "Note: This execution time is calculated from CPU clock. When more than 1 thread were run, "
                "the value displayed is higher than the real execution time." << endl;
    }
}
static int compileModule(char **argv, LLVMContext &Context) {
  // Load the module to be compiled...
  SMDiagnostic Err;
  std::unique_ptr<Module> M;
  std::unique_ptr<MIRParser> MIR;
  Triple TheTriple;

  bool SkipModule = MCPU == "help" ||
                    (!MAttrs.empty() && MAttrs.front() == "help");

  // If user just wants to list available options, skip module loading
  if ((!SkipModule) && (!PrintInstructions.getValue())) {
    if (StringRef(InputFilename).endswith_lower(".mir")) {
      MIR = createMIRParserFromFile(InputFilename, Err, Context);
      if (MIR) {
        M = MIR->parseLLVMModule();
        assert(M && "parseLLVMModule should exit on failure");
      }
    } else
      M = parseIRFile(InputFilename, Err, Context);
    if (!M) {
      Err.print(argv[0], errs());
      return 1;
    }

    // Verify module immediately to catch problems before doInitialization() is
    // called on any passes.
    if (!NoVerify && verifyModule(*M, &errs())) {
      errs() << argv[0] << ": " << InputFilename
             << ": error: input module is broken!\n";
      return 1;
    }

    // If we are supposed to override the target triple, do so now.
    if (!TargetTriple.empty())
      M->setTargetTriple(Triple::normalize(TargetTriple));
    TheTriple = Triple(M->getTargetTriple());
  } else {
    TheTriple = Triple(Triple::normalize(TargetTriple));
  }

  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getDefaultTargetTriple());

  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
                                                         Error);
  if (!TheTarget) {
    errs() << argv[0] << ": " << Error;
    return 1;
  }

  std::string CPUStr = getCPUStr(), FeaturesStr = getFeaturesStr();

  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;
  }

  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  Options.DisableIntegratedAS = NoIntegratedAssembler;
  Options.MCOptions.ShowMCEncoding = ShowMCEncoding;
  Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory;
  Options.MCOptions.AsmVerbose = AsmVerbose;

  std::unique_ptr<TargetMachine> Target(
      TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr, FeaturesStr,
                                     Options, RelocModel, CMModel, OLvl));

  assert(Target && "Could not allocate target machine!");

  // If we don't have a module then just exit now. We do this down
  // here since the CPU/Feature help is underneath the target machine
  // creation.
  if (SkipModule)
    return 0;
  
  // Figure out where we are going to send the output.
  std::unique_ptr<tool_output_file> Out =
      GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]);
  if (!Out) return 1;

  {
    raw_pwrite_stream *OS = &Out->os();
    std::unique_ptr<buffer_ostream> BOS;
    if (FileType != TargetMachine::CGFT_AssemblyFile &&
        !Out->os().supportsSeeking()) {
      BOS = make_unique<buffer_ostream>(*OS);
      OS = BOS.get();
    }
    

  if (PrintInstructions.getValue()) {
    printInstructions(TheTarget, OS);
    Out->keep();
    return 0;
  }


  assert(M && "Should have exited if we didn't have a module!");
  if (FloatABIForCalls != FloatABI::Default)
    Options.FloatABIType = FloatABIForCalls;

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

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));

  // The -disable-simplify-libcalls flag actually disables all builtin optzns.
  if (DisableSimplifyLibCalls)
    TLII.disableAllFunctions();
  PM.add(new TargetLibraryInfoWrapperPass(TLII));

  // Add the target data from the target machine, if it exists, or the module.
  M->setDataLayout(Target->createDataLayout());

  // Override function attributes based on CPUStr, FeaturesStr, and command line
  // flags.
  setFunctionAttributes(CPUStr, FeaturesStr, *M);

  if (RelaxAll.getNumOccurrences() > 0 &&
      FileType != TargetMachine::CGFT_ObjectFile)
    errs() << argv[0]
             << ": warning: ignoring -mc-relax-all because filetype != obj";


    AnalysisID StartBeforeID = nullptr;
    AnalysisID StartAfterID = nullptr;
    AnalysisID StopAfterID = nullptr;
    const PassRegistry *PR = PassRegistry::getPassRegistry();
    if (!RunPass.empty()) {
      if (!StartAfter.empty() || !StopAfter.empty()) {
        errs() << argv[0] << ": start-after and/or stop-after passes are "
                             "redundant when run-pass is specified.\n";
        return 1;
      }
      const PassInfo *PI = PR->getPassInfo(RunPass);
      if (!PI) {
        errs() << argv[0] << ": run-pass pass is not registered.\n";
        return 1;
      }
      StopAfterID = StartBeforeID = PI->getTypeInfo();
    } else {
      if (!StartAfter.empty()) {
        const PassInfo *PI = PR->getPassInfo(StartAfter);
        if (!PI) {
          errs() << argv[0] << ": start-after pass is not registered.\n";
          return 1;
        }
        StartAfterID = PI->getTypeInfo();
      }
      if (!StopAfter.empty()) {
        const PassInfo *PI = PR->getPassInfo(StopAfter);
        if (!PI) {
          errs() << argv[0] << ": stop-after pass is not registered.\n";
          return 1;
        }
        StopAfterID = PI->getTypeInfo();
      }
    }

    // Ask the target to add backend passes as necessary.
    if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, StartBeforeID,
                                    StartAfterID, StopAfterID, MIR.get())) {
      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(*M);
  }

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

  return 0;
}
Beispiel #21
0
static void processOptionImpl(cl::opt<bool> &O, const cl::opt<bool> &Default) {
  if (!O.getNumOccurrences() || O.getPosition() < Default.getPosition())
    O = Default.getValue();
}
// This checks whether the transformation is legal and profitable
bool X86CallFrameOptimization::shouldPerformTransformation(MachineFunction &MF) {
  if (NoX86CFOpt.getValue())
    return false;

  // We currently only support call sequences where *all* parameters.
  // are passed on the stack.
  // No point in running this in 64-bit mode, since some arguments are
  // passed in-register in all common calling conventions, so the pattern
  // we're looking for will never match.
  const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
  if (STI.is64Bit())
    return false;

  // You would expect straight-line code between call-frame setup and
  // call-frame destroy. You would be wrong. There are circumstances (e.g.
  // CMOV_GR8 expansion of a select that feeds a function call!) where we can
  // end up with the setup and the destroy in different basic blocks.
  // This is bad, and breaks SP adjustment.
  // So, check that all of the frames in the function are closed inside
  // the same block, and, for good measure, that there are no nested frames.
  int FrameSetupOpcode = TII->getCallFrameSetupOpcode();
  int FrameDestroyOpcode = TII->getCallFrameDestroyOpcode();
  for (MachineBasicBlock &BB : MF) {
    bool InsideFrameSequence = false;
    for (MachineInstr &MI : BB) {
      if (MI.getOpcode() == FrameSetupOpcode) {
        if (InsideFrameSequence)
          return false;
        InsideFrameSequence = true;
      }
      else if (MI.getOpcode() == FrameDestroyOpcode) {
        if (!InsideFrameSequence)
          return false;
        InsideFrameSequence = false;
      }
    }

    if (InsideFrameSequence)
      return false;
  }

  // Now that we know the transformation is legal, check if it is
  // profitable.
  // TODO: Add a heuristic that actually looks at the function,
  //       and enable this for more cases.

  // This transformation is always a win when we expected to have
  // a reserved call frame. Under other circumstances, it may be either 
  // a win or a loss, and requires a heuristic.
  // For now, enable it only for the relatively clear win cases.
  bool CannotReserveFrame = MF.getFrameInfo()->hasVarSizedObjects();
  if (CannotReserveFrame)
    return true;

  // Don't do this when not optimizing for size.
  bool OptForSize =
      MF.getFunction()->hasFnAttribute(Attribute::OptimizeForSize) ||
      MF.getFunction()->hasFnAttribute(Attribute::MinSize);

  if (!OptForSize)
    return false;

  // Stack re-alignment can make this unprofitable even in terms of size.
  // As mentioned above, a better heuristic is needed. For now, don't do this
  // when the required alignment is above 8. (4 would be the safe choice, but
  // some experimentation showed 8 is generally good).
  if (TFL->getStackAlignment() > 8)
    return false;

  return true;
}
Beispiel #23
0
int main(int argc, char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;
  cl::ParseCommandLineOptions(argc, argv, "linker script randomizer\n");

  sys::Path ldPath = sys::Program::FindProgramByName("ld");
  if (ldPath.isEmpty()) {
    errs() << "Couldn't find system linker";
    llvm_shutdown();
    return 1;
  }

  sys::Path scriptPath = sys::Path::GetTemporaryDirectory();
  if (scriptPath.isEmpty()) {
    errs() << "Error accessing temporary directory";
    llvm_shutdown();
    return 1;
  }
  scriptPath.appendComponent("ld_script");
  scriptPath.makeUnique(false, NULL);

  sys::Path devNull;
  std::string errMsg;
  const char *ldArgs[] = { ldPath.c_str(), "--verbose", NULL };
  const sys::Path *redirects[] = { &devNull, &scriptPath, &scriptPath, NULL };
  if (sys::Program::ExecuteAndWait(ldPath, ldArgs, 0, redirects, 0, 0, &errMsg)) {
    errs() << "Error executing linker";
    llvm_shutdown();
    return 1;
  }

  OwningPtr< MemoryBuffer > scriptFile;
  error_code ec = MemoryBuffer::getFile(scriptPath.c_str(), scriptFile);
  if (ec) {
    errs() << "Error reading script file: " << ec.message();
    llvm_shutdown();
    return 1;
  }
 
  uint32_t minPage = (MinBaseAddress + PAGE_SIZE - 1) / PAGE_SIZE,
           maxPage = MaxBaseAddress / PAGE_SIZE;
  if (minPage > maxPage) {
    errs() << "Base address interval is empty";
    llvm_shutdown();
    return 1;
  }
  uint32_t newAddr = PAGE_SIZE * (minPage + 
    RandomNumberGenerator::Generator().Random(maxPage - minPage + 1));

  char oldAddrStr[12];
  sprintf(oldAddrStr, "0x%08x", OldBaseAddress.getValue());

  llvm::Regex oldAddrRegex(oldAddrStr);
  StringRef scriptText = scriptFile->getBuffer();
  StringRef oldScriptText = scriptText;
  char newAddrStr[12];
  sprintf(newAddrStr, "0x%08x", newAddr);
  do {
    // Replace one occurrence of old address with new one
    oldScriptText = scriptText;
    scriptText = oldAddrRegex.sub(newAddrStr, scriptText);
  } while (!scriptText.equals(oldScriptText));
  std::cout << scriptText.str();
  return 0;
}
static std::unique_ptr<tool_output_file>
GetOutputStream(const char *TargetName, Triple::OSType OS,
                const char *ProgName) {
  // If we don't yet have an output filename, make one.
  if (PrintInstructions.getValue()) {
    if (OutputFilename.empty()) {
        OutputFilename = "hotspot.out";
    } 
  } else {  if (OutputFilename.empty()) {
    if (InputFilename == "-")
      OutputFilename = "-";
    else {
      // If InputFilename ends in .bc or .ll, remove it.
      StringRef IFN = InputFilename;
      if (IFN.endswith(".bc") || IFN.endswith(".ll"))
        OutputFilename = IFN.drop_back(3);
      else if (IFN.endswith(".mir"))
        OutputFilename = IFN.drop_back(4);
      else
        OutputFilename = IFN;

      switch (FileType) {
      case TargetMachine::CGFT_AssemblyFile:
        if (TargetName[0] == 'c') {
          if (TargetName[1] == 0)
            OutputFilename += ".cbe.c";
          else if (TargetName[1] == 'p' && TargetName[2] == 'p')
            OutputFilename += ".cpp";
          else
            OutputFilename += ".s";
        } else
          OutputFilename += ".s";
        break;
      case TargetMachine::CGFT_ObjectFile:
        if (OS == Triple::Win32)
          OutputFilename += ".obj";
        else
          OutputFilename += ".o";
        break;
      case TargetMachine::CGFT_Null:
        OutputFilename += ".null";
        break;
      }
    }
  }
  }

  // Decide if we need "binary" output.
  bool Binary = false;
  switch (FileType) {
  case TargetMachine::CGFT_AssemblyFile:
    break;
  case TargetMachine::CGFT_ObjectFile:
  case TargetMachine::CGFT_Null:
    Binary = true;
    break;
  }

  // Open the file.
  std::error_code EC;
  sys::fs::OpenFlags OpenFlags = sys::fs::F_None;
  if (!Binary)
    OpenFlags |= sys::fs::F_Text;
  auto FDOut = llvm::make_unique<tool_output_file>(OutputFilename, EC,
                                                   OpenFlags);
  if (EC) {
    errs() << EC.message() << '\n';
    return nullptr;
  }

  return FDOut;
}