Ejemplo n.º 1
0
/// definedInCaller - Return true if the specified value is defined in the
/// function being code extracted, but not in the region being extracted.
/// These values must be passed in as live-ins to the function.
static bool definedInCaller(const SetVector<BasicBlock *> &Blocks, Value *V) {
  if (isa<Argument>(V)) return true;
  if (Instruction *I = dyn_cast<Instruction>(V))
    if (!Blocks.count(I->getParent()))
      return true;
  return false;
}
Ejemplo n.º 2
0
/// \brief Build a set of blocks to extract if the input blocks are viable.
static SetVector<BasicBlock *>
buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs, DominatorTree *DT) {
  assert(!BBs.empty() && "The set of blocks to extract must be non-empty");
  SetVector<BasicBlock *> Result;

  // Loop over the blocks, adding them to our set-vector, and aborting with an
  // empty set if we encounter invalid blocks.
  for (BasicBlock *BB : BBs) {

    // If this block is dead, don't process it.
    if (DT && !DT->isReachableFromEntry(BB))
      continue;

    if (!Result.insert(BB))
      llvm_unreachable("Repeated basic blocks in extraction input");
    if (!CodeExtractor::isBlockValidForExtraction(*BB)) {
      Result.clear();
      return Result;
    }
  }

#ifndef NDEBUG
  for (SetVector<BasicBlock *>::iterator I = std::next(Result.begin()),
                                         E = Result.end();
       I != E; ++I)
    for (pred_iterator PI = pred_begin(*I), PE = pred_end(*I);
         PI != PE; ++PI)
      assert(Result.count(*PI) &&
             "No blocks in this region may have entries from outside the region"
             " except for the first block!");
#endif

  return Result;
}
Ejemplo n.º 3
0
static SetVector<BasicBlock *> buildExtractionBlockSet(IteratorT BBBegin,
                                                       IteratorT BBEnd) {
  SetVector<BasicBlock *> Result;

  assert(BBBegin != BBEnd);

  // Loop over the blocks, adding them to our set-vector, and aborting with an
  // empty set if we encounter invalid blocks.
  do {
    if (!Result.insert(*BBBegin))
      llvm_unreachable("Repeated basic blocks in extraction input");

    if (!isBlockValidForExtraction(**BBBegin)) {
      Result.clear();
      return Result;
    }
  } while (++BBBegin != BBEnd);

#ifndef NDEBUG
  for (SetVector<BasicBlock *>::iterator I = std::next(Result.begin()),
                                         E = Result.end();
       I != E; ++I)
    for (pred_iterator PI = pred_begin(*I), PE = pred_end(*I);
         PI != PE; ++PI)
      assert(Result.count(*PI) &&
             "No blocks in this region may have entries from outside the region"
             " except for the first block!");
#endif

  return Result;
}
Ejemplo n.º 4
0
BitVector CodeGenRegBank::computeCoveredRegisters(ArrayRef<Record*> Regs) {
  SetVector<const CodeGenRegister*> Set;

  // First add Regs with all sub-registers.
  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
    CodeGenRegister *Reg = getReg(Regs[i]);
    if (Set.insert(Reg))
      // Reg is new, add all sub-registers.
      // The pre-ordering is not important here.
      Reg->addSubRegsPreOrder(Set, *this);
  }

  // Second, find all super-registers that are completely covered by the set.
  for (unsigned i = 0; i != Set.size(); ++i) {
    const CodeGenRegister::SuperRegList &SR = Set[i]->getSuperRegs();
    for (unsigned j = 0, e = SR.size(); j != e; ++j) {
      const CodeGenRegister *Super = SR[j];
      if (!Super->CoveredBySubRegs || Set.count(Super))
        continue;
      // This new super-register is covered by its sub-registers.
      bool AllSubsInSet = true;
      const CodeGenRegister::SubRegMap &SRM = Super->getSubRegs();
      for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(),
             E = SRM.end(); I != E; ++I)
        if (!Set.count(I->second)) {
          AllSubsInSet = false;
          break;
        }
      // All sub-registers in Set, add Super as well.
      // We will visit Super later to recheck its super-registers.
      if (AllSubsInSet)
        Set.insert(Super);
    }
  }

  // Convert to BitVector.
  BitVector BV(Registers.size() + 1);
  for (unsigned i = 0, e = Set.size(); i != e; ++i)
    BV.set(Set[i]->EnumValue);
  return BV;
}
Ejemplo n.º 5
0
APInt GraphNode::findShortestPath(GraphNode *Dest, SetVector<GraphNode*> Visited) {
  if (Dest == this) {
    DEBUG(dbgs() << "IneqGraph: Reached: " << *Dest->getValue() << "\n");
    return APInt(64, 0, true);
  }

  DEBUG(dbgs() << "IneqGraph: Node: " << *V << "\n");

  if (Visited.count(this)) {
    DEBUG(dbgs() << "IneqGraph: Visited\n");
    return APInt::getSignedMaxValue(64); //(64, , true);
  }
  Visited.insert(this);

  APInt MayMin = APInt::getSignedMaxValue(64);
  for (may_iterator It = may_begin(), E = may_end();
       It != E; ++It) {
    APInt Total = It->getToEdge()->findShortestPath(Dest, Visited);
    if (Total.slt(MayMin))
      MayMin = Total + It->getWeight();
  }
  //DEBUG(dbgs() << "IneqGraph: Node: " << *V << ", MayMin: " << MayMin << "\n");

  APInt MustMax = APInt::getSignedMinValue(64);
  for (must_iterator It = must_begin(), E = must_end();
       It != E; ++It) {
    APInt Total = It->getToEdge()->findShortestPath(Dest, Visited);
    if (MustMax.slt(Total))
      MustMax = Total;
  }
 // DEBUG(dbgs() << "IneqGraph: Node: " << *V << ", MustMax: " << MustMax << "\n");

  if (MustMax.isMinSignedValue()) {
    //DEBUG(dbgs() << "IneqGraph: Node: " << *V << ", Distance: " << MayMin << "\n");
    DEBUG(dbgs() << "IneqGraph: Ret: " << MayMin << "\n");
    return MayMin;
  } else {
    APInt Min = MustMax.slt(MayMin) ? MustMax : MayMin;
    //DEBUG(dbgs() << "IneqGraph: Node: " << *V << ", Distance: " << Min << "\n");
    DEBUG(dbgs() << "IneqGraph: Ret: " << Min << "\n");
    return Min;
  }
}
Ejemplo n.º 6
0
NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
      NodeAddr<RefNode*> RefA, bool FullChain, const RegisterSet &DefRRs) {
  SetVector<NodeId> DefQ;
  SetVector<NodeId> Owners;

  // The initial queue should not have reaching defs for shadows. The
  // whole point of a shadow is that it will have a reaching def that
  // is not aliased to the reaching defs of the related shadows.
  NodeId Start = RefA.Id;
  auto SNA = DFG.addr<RefNode*>(Start);
  if (NodeId RD = SNA.Addr->getReachingDef())
    DefQ.insert(RD);

  // Collect all the reaching defs, going up until a phi node is encountered,
  // or there are no more reaching defs. From this set, the actual set of
  // reaching defs will be selected.
  // The traversal upwards must go on until a covering def is encountered.
  // It is possible that a collection of non-covering (individually) defs
  // will be sufficient, but keep going until a covering one is found.
  for (unsigned i = 0; i < DefQ.size(); ++i) {
    auto TA = DFG.addr<DefNode*>(DefQ[i]);
    if (TA.Addr->getFlags() & NodeAttrs::PhiRef)
      continue;
    // Stop at the covering/overwriting def of the initial register reference.
    RegisterRef RR = TA.Addr->getRegRef();
    if (RAI.covers(RR, RefRR)) {
      uint16_t Flags = TA.Addr->getFlags();
      if (!(Flags & NodeAttrs::Preserving))
        continue;
    }
    // Get the next level of reaching defs. This will include multiple
    // reaching defs for shadows.
    for (auto S : DFG.getRelatedRefs(TA.Addr->getOwner(DFG), TA))
      if (auto RD = NodeAddr<RefNode*>(S).Addr->getReachingDef())
        DefQ.insert(RD);
  }

  // Remove all non-phi defs that are not aliased to RefRR, and collect
  // the owners of the remaining defs.
  SetVector<NodeId> Defs;
  for (auto N : DefQ) {
    auto TA = DFG.addr<DefNode*>(N);
    bool IsPhi = TA.Addr->getFlags() & NodeAttrs::PhiRef;
    if (!IsPhi && !RAI.alias(RefRR, TA.Addr->getRegRef()))
      continue;
    Defs.insert(TA.Id);
    Owners.insert(TA.Addr->getOwner(DFG).Id);
  }

  // Return the MachineBasicBlock containing a given instruction.
  auto Block = [this] (NodeAddr<InstrNode*> IA) -> MachineBasicBlock* {
    if (IA.Addr->getKind() == NodeAttrs::Stmt)
      return NodeAddr<StmtNode*>(IA).Addr->getCode()->getParent();
    assert(IA.Addr->getKind() == NodeAttrs::Phi);
    NodeAddr<PhiNode*> PA = IA;
    NodeAddr<BlockNode*> BA = PA.Addr->getOwner(DFG);
    return BA.Addr->getCode();
  };
  // Less(A,B) iff instruction A is further down in the dominator tree than B.
  auto Less = [&Block,this] (NodeId A, NodeId B) -> bool {
    if (A == B)
      return false;
    auto OA = DFG.addr<InstrNode*>(A), OB = DFG.addr<InstrNode*>(B);
    MachineBasicBlock *BA = Block(OA), *BB = Block(OB);
    if (BA != BB)
      return MDT.dominates(BB, BA);
    // They are in the same block.
    bool StmtA = OA.Addr->getKind() == NodeAttrs::Stmt;
    bool StmtB = OB.Addr->getKind() == NodeAttrs::Stmt;
    if (StmtA) {
      if (!StmtB)   // OB is a phi and phis dominate statements.
        return true;
      auto CA = NodeAddr<StmtNode*>(OA).Addr->getCode();
      auto CB = NodeAddr<StmtNode*>(OB).Addr->getCode();
      // The order must be linear, so tie-break such equalities.
      if (CA == CB)
        return A < B;
      return MDT.dominates(CB, CA);
    } else {
      // OA is a phi.
      if (StmtB)
        return false;
      // Both are phis. There is no ordering between phis (in terms of
      // the data-flow), so tie-break this via node id comparison.
      return A < B;
    }
  };

  std::vector<NodeId> Tmp(Owners.begin(), Owners.end());
  std::sort(Tmp.begin(), Tmp.end(), Less);

  // The vector is a list of instructions, so that defs coming from
  // the same instruction don't need to be artificially ordered.
  // Then, when computing the initial segment, and iterating over an
  // instruction, pick the defs that contribute to the covering (i.e. is
  // not covered by previously added defs). Check the defs individually,
  // i.e. first check each def if is covered or not (without adding them
  // to the tracking set), and then add all the selected ones.

  // The reason for this is this example:
  // *d1<A>, *d2<B>, ... Assume A and B are aliased (can happen in phi nodes).
  // *d3<C>              If A \incl BuC, and B \incl AuC, then *d2 would be
  //                     covered if we added A first, and A would be covered
  //                     if we added B first.

  NodeList RDefs;
  RegisterSet RRs = DefRRs;

  auto DefInSet = [&Defs] (NodeAddr<RefNode*> TA) -> bool {
    return TA.Addr->getKind() == NodeAttrs::Def &&
           Defs.count(TA.Id);
  };
  for (auto T : Tmp) {
    if (!FullChain && RAI.covers(RRs, RefRR))
      break;
    auto TA = DFG.addr<InstrNode*>(T);
    bool IsPhi = DFG.IsCode<NodeAttrs::Phi>(TA);
    NodeList Ds;
    for (NodeAddr<DefNode*> DA : TA.Addr->members_if(DefInSet, DFG)) {
      auto QR = DA.Addr->getRegRef();
      // Add phi defs even if they are covered by subsequent defs. This is
      // for cases where the reached use is not covered by any of the defs
      // encountered so far: the phi def is needed to expose the liveness
      // of that use to the entry of the block.
      // Example:
      //   phi d1<R3>(,d2,), ...  Phi def d1 is covered by d2.
      //   d2<R3>(d1,,u3), ...
      //   ..., u3<D1>(d2)        This use needs to be live on entry.
      if (FullChain || IsPhi || !RAI.covers(RRs, QR))
        Ds.push_back(DA);
    }
    RDefs.insert(RDefs.end(), Ds.begin(), Ds.end());
    for (NodeAddr<DefNode*> DA : Ds) {
      // When collecting a full chain of definitions, do not consider phi
      // defs to actually define a register.
      uint16_t Flags = DA.Addr->getFlags();
      if (!FullChain || !(Flags & NodeAttrs::PhiRef))
        if (!(Flags & NodeAttrs::Preserving))
          RRs.insert(DA.Addr->getRegRef());
    }
  }

  return RDefs;
}
Ejemplo n.º 7
0
/// definedInRegion - Return true if the specified value is defined in the
/// extracted region.
static bool definedInRegion(const SetVector<BasicBlock *> &Blocks, Value *V) {
  if (Instruction *I = dyn_cast<Instruction>(V))
    if (Blocks.count(I->getParent()))
      return true;
  return false;
}
Ejemplo n.º 8
0
int main(int argc, char **argv) {
  InitLLVM X(argc, argv);

  LLVMContext Context;
  cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n");

  // Use lazy loading, since we only care about selected global values.
  SMDiagnostic Err;
  std::unique_ptr<Module> M = getLazyIRFileModule(InputFilename, Err, Context);

  if (!M.get()) {
    Err.print(argv[0], errs());
    return 1;
  }

  // Use SetVector to avoid duplicates.
  SetVector<GlobalValue *> GVs;

  // Figure out which aliases we should extract.
  for (size_t i = 0, e = ExtractAliases.size(); i != e; ++i) {
    GlobalAlias *GA = M->getNamedAlias(ExtractAliases[i]);
    if (!GA) {
      errs() << argv[0] << ": program doesn't contain alias named '"
             << ExtractAliases[i] << "'!\n";
      return 1;
    }
    GVs.insert(GA);
  }

  // Extract aliases via regular expression matching.
  for (size_t i = 0, e = ExtractRegExpAliases.size(); i != e; ++i) {
    std::string Error;
    Regex RegEx(ExtractRegExpAliases[i]);
    if (!RegEx.isValid(Error)) {
      errs() << argv[0] << ": '" << ExtractRegExpAliases[i] << "' "
        "invalid regex: " << Error;
    }
    bool match = false;
    for (Module::alias_iterator GA = M->alias_begin(), E = M->alias_end();
         GA != E; GA++) {
      if (RegEx.match(GA->getName())) {
        GVs.insert(&*GA);
        match = true;
      }
    }
    if (!match) {
      errs() << argv[0] << ": program doesn't contain global named '"
             << ExtractRegExpAliases[i] << "'!\n";
      return 1;
    }
  }

  // Figure out which globals we should extract.
  for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) {
    GlobalValue *GV = M->getNamedGlobal(ExtractGlobals[i]);
    if (!GV) {
      errs() << argv[0] << ": program doesn't contain global named '"
             << ExtractGlobals[i] << "'!\n";
      return 1;
    }
    GVs.insert(GV);
  }

  // Extract globals via regular expression matching.
  for (size_t i = 0, e = ExtractRegExpGlobals.size(); i != e; ++i) {
    std::string Error;
    Regex RegEx(ExtractRegExpGlobals[i]);
    if (!RegEx.isValid(Error)) {
      errs() << argv[0] << ": '" << ExtractRegExpGlobals[i] << "' "
        "invalid regex: " << Error;
    }
    bool match = false;
    for (auto &GV : M->globals()) {
      if (RegEx.match(GV.getName())) {
        GVs.insert(&GV);
        match = true;
      }
    }
    if (!match) {
      errs() << argv[0] << ": program doesn't contain global named '"
             << ExtractRegExpGlobals[i] << "'!\n";
      return 1;
    }
  }

  // Figure out which functions we should extract.
  for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) {
    GlobalValue *GV = M->getFunction(ExtractFuncs[i]);
    if (!GV) {
      errs() << argv[0] << ": program doesn't contain function named '"
             << ExtractFuncs[i] << "'!\n";
      return 1;
    }
    GVs.insert(GV);
  }
  // Extract functions via regular expression matching.
  for (size_t i = 0, e = ExtractRegExpFuncs.size(); i != e; ++i) {
    std::string Error;
    StringRef RegExStr = ExtractRegExpFuncs[i];
    Regex RegEx(RegExStr);
    if (!RegEx.isValid(Error)) {
      errs() << argv[0] << ": '" << ExtractRegExpFuncs[i] << "' "
        "invalid regex: " << Error;
    }
    bool match = false;
    for (Module::iterator F = M->begin(), E = M->end(); F != E;
         F++) {
      if (RegEx.match(F->getName())) {
        GVs.insert(&*F);
        match = true;
      }
    }
    if (!match) {
      errs() << argv[0] << ": program doesn't contain global named '"
             << ExtractRegExpFuncs[i] << "'!\n";
      return 1;
    }
  }

  // Figure out which BasicBlocks we should extract.
  SmallVector<BasicBlock *, 4> BBs;
  for (StringRef StrPair : ExtractBlocks) {
    auto BBInfo = StrPair.split(':');
    // Get the function.
    Function *F = M->getFunction(BBInfo.first);
    if (!F) {
      errs() << argv[0] << ": program doesn't contain a function named '"
             << BBInfo.first << "'!\n";
      return 1;
    }
    // Do not materialize this function.
    GVs.insert(F);
    // Get the basic block.
    auto Res = llvm::find_if(*F, [&](const BasicBlock &BB) {
      return BB.getName().equals(BBInfo.second);
    });
    if (Res == F->end()) {
      errs() << argv[0] << ": function " << F->getName()
             << " doesn't contain a basic block named '" << BBInfo.second
             << "'!\n";
      return 1;
    }
    BBs.push_back(&*Res);
  }

  // Use *argv instead of argv[0] to work around a wrong GCC warning.
  ExitOnError ExitOnErr(std::string(*argv) + ": error reading input: ");

  if (Recursive) {
    std::vector<llvm::Function *> Workqueue;
    for (GlobalValue *GV : GVs) {
      if (auto *F = dyn_cast<Function>(GV)) {
        Workqueue.push_back(F);
      }
    }
    while (!Workqueue.empty()) {
      Function *F = &*Workqueue.back();
      Workqueue.pop_back();
      ExitOnErr(F->materialize());
      for (auto &BB : *F) {
        for (auto &I : BB) {
          auto *CI = dyn_cast<CallInst>(&I);
          if (!CI)
            continue;
          Function *CF = CI->getCalledFunction();
          if (!CF)
            continue;
          if (CF->isDeclaration() || GVs.count(CF))
            continue;
          GVs.insert(CF);
          Workqueue.push_back(CF);
        }
      }
    }
  }

  auto Materialize = [&](GlobalValue &GV) { ExitOnErr(GV.materialize()); };

  // Materialize requisite global values.
  if (!DeleteFn) {
    for (size_t i = 0, e = GVs.size(); i != e; ++i)
      Materialize(*GVs[i]);
  } else {
    // Deleting. Materialize every GV that's *not* in GVs.
    SmallPtrSet<GlobalValue *, 8> GVSet(GVs.begin(), GVs.end());
    for (auto &F : *M) {
      if (!GVSet.count(&F))
        Materialize(F);
    }
  }

  {
    std::vector<GlobalValue *> Gvs(GVs.begin(), GVs.end());
    legacy::PassManager Extract;
    Extract.add(createGVExtractionPass(Gvs, DeleteFn));
    Extract.run(*M);

    // Now that we have all the GVs we want, mark the module as fully
    // materialized.
    // FIXME: should the GVExtractionPass handle this?
    ExitOnErr(M->materializeAll());
  }

  // Extract the specified basic blocks from the module and erase the existing
  // functions.
  if (!ExtractBlocks.empty()) {
    legacy::PassManager PM;
    PM.add(createBlockExtractorPass(BBs, true));
    PM.run(*M);
  }

  // In addition to deleting all other functions, we also want to spiff it
  // up a little bit.  Do this now.
  legacy::PassManager Passes;

  if (!DeleteFn)
    Passes.add(createGlobalDCEPass());           // Delete unreachable globals
  Passes.add(createStripDeadDebugInfoPass());    // Remove dead debug info
  Passes.add(createStripDeadPrototypesPass());   // Remove dead func decls

  std::error_code EC;
  ToolOutputFile Out(OutputFilename, EC, sys::fs::F_None);
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  if (OutputAssembly)
    Passes.add(
        createPrintModulePass(Out.os(), "", PreserveAssemblyUseListOrder));
  else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
    Passes.add(createBitcodeWriterPass(Out.os(), PreserveBitcodeUseListOrder));

  Passes.run(*M.get());

  // Declare success.
  Out.keep();

  return 0;
}