15#ifdef LLVM_HAVE_TFLITE 
   26#ifdef LLVM_HAVE_TFLITE 
   41    cl::desc(
"Path to saved model evaluating native size from IR."));
 
   43#define DEBUG_TYPE "inline-size-estimator" 
   45unsigned getMaxInstructionID() {
 
   46#define LAST_OTHER_INST(NR) return NR; 
   47#include "llvm/IR/Instruction.def" 
   50class IRToNativeSizeLearning {
 
   52  enum class NamedFeatureIndex : 
size_t {
 
   65  static const size_t NumNamedFeatures =
 
   66      static_cast<size_t>(NamedFeatureIndex::NumNamedFeatures);
 
   67  struct FunctionFeatures {
 
   70    std::array<int32_t, NumNamedFeatures> NamedFeatures = {0};
 
   71    std::vector<int32_t> InstructionHistogram;
 
   72    std::vector<int32_t> InstructionPairHistogram;
 
   74    void fillTensor(int32_t *
Ptr) 
const;
 
   75    int32_t &operator[](NamedFeatureIndex Pos) {
 
   76      return NamedFeatures[
static_cast<size_t>(Pos)];
 
   79  IRToNativeSizeLearning() = 
default;
 
   81  static FunctionFeatures getFunctionFeatures(Function &
F,
 
   93static const std::array<std::pair<size_t, size_t>, 137>
 
   94    ImportantInstructionSuccessions{
 
   95        {{1, 1},   {1, 4},   {1, 5},   {1, 7},   {1, 8},   {1, 9},   {1, 11},
 
   96         {1, 12},  {1, 13},  {1, 14},  {1, 18},  {1, 20},  {1, 22},  {1, 24},
 
   97         {1, 25},  {1, 26},  {1, 27},  {1, 28},  {1, 29},  {1, 30},  {1, 31},
 
   98         {1, 32},  {1, 33},  {1, 34},  {1, 39},  {1, 40},  {1, 42},  {1, 45},
 
   99         {2, 1},   {2, 2},   {2, 13},  {2, 28},  {2, 29},  {2, 32},  {2, 33},
 
  100         {2, 34},  {2, 38},  {2, 48},  {2, 49},  {2, 53},  {2, 55},  {2, 56},
 
  101         {13, 2},  {13, 13}, {13, 26}, {13, 33}, {13, 34}, {13, 56}, {15, 27},
 
  102         {28, 2},  {28, 48}, {28, 53}, {29, 2},  {29, 33}, {29, 56}, {31, 31},
 
  103         {31, 33}, {31, 34}, {31, 49}, {32, 1},  {32, 2},  {32, 13}, {32, 15},
 
  104         {32, 28}, {32, 29}, {32, 32}, {32, 33}, {32, 34}, {32, 39}, {32, 40},
 
  105         {32, 48}, {32, 49}, {32, 53}, {32, 56}, {33, 1},  {33, 2},  {33, 32},
 
  106         {33, 33}, {33, 34}, {33, 49}, {33, 53}, {33, 56}, {34, 1},  {34, 2},
 
  107         {34, 32}, {34, 33}, {34, 34}, {34, 49}, {34, 53}, {34, 56}, {38, 34},
 
  108         {39, 57}, {40, 34}, {47, 15}, {47, 49}, {48, 2},  {48, 34}, {48, 56},
 
  109         {49, 1},  {49, 2},  {49, 28}, {49, 32}, {49, 33}, {49, 34}, {49, 39},
 
  110         {49, 49}, {49, 56}, {53, 1},  {53, 2},  {53, 28}, {53, 34}, {53, 53},
 
  111         {53, 57}, {55, 1},  {55, 28}, {55, 34}, {55, 53}, {55, 55}, {55, 56},
 
  112         {56, 1},  {56, 2},  {56, 7},  {56, 13}, {56, 32}, {56, 33}, {56, 34},
 
  113         {56, 49}, {56, 53}, {56, 56}, {56, 64}, {57, 34}, {57, 56}, {57, 57},
 
  114         {64, 1},  {64, 64}, {65, 1},  {65, 65}}};
 
  123const size_t IRToNativeSizeLearning::FunctionFeatures::FeatureCount =
 
  124    ImportantInstructionSuccessions.size() + getMaxInstructionID() + 1 +
 
  125    IRToNativeSizeLearning::NumNamedFeatures;
 
  129  for (
const auto &BB : 
F)
 
  130    for (
const auto &
I : BB)
 
  131      Ret += 
TTI.getInstructionCost(
 
  142unsigned getMaxDominatorTreeDepth(
const Function &
F,
 
  145  for (
const auto &BB : 
F)
 
  146    if (
const auto *TN = Tree.
getNode(&BB))
 
  147      Ret = std::max(Ret, TN->getLevel());
 
  152IRToNativeSizeLearning::FunctionFeatures
 
  153IRToNativeSizeLearning::getFunctionFeatures(
Function &
F,
 
  156         "expected function features are sorted");
 
  160  size_t InstrCount = getMaxInstructionID() + 1;
 
  163  FF.InstructionPairHistogram.resize(ImportantInstructionSuccessions.size());
 
  166  int LastID = StartID;
 
  167  auto getPairIndex = [](
size_t a, 
size_t b) {
 
  168    auto I = 
llvm::find(ImportantInstructionSuccessions, std::make_pair(a, b));
 
  169    if (
I == ImportantInstructionSuccessions.end())
 
  171    return static_cast<int>(
 
  172        std::distance(ImportantInstructionSuccessions.begin(), 
I));
 
  176  for (
const auto &BB : 
F) {
 
  177    for (
const auto &
I : BB.instructionsWithoutDebug()) {
 
  178      auto ID = 
I.getOpcode();
 
  180      ++FF.InstructionHistogram[
ID];
 
  181      int PairIndex = getPairIndex(LastID, 
ID);
 
  183        ++FF.InstructionPairHistogram[PairIndex];
 
  186        ++FF[NamedFeatureIndex::Calls];
 
  190  FF[NamedFeatureIndex::InitialSize] = 
getSize(
F, 
FAM);
 
  191  FF[NamedFeatureIndex::IsLocal] = 
F.hasLocalLinkage();
 
  192  FF[NamedFeatureIndex::IsLinkOnceODR] = 
F.hasLinkOnceODRLinkage();
 
  193  FF[NamedFeatureIndex::IsLinkOnce] = 
F.hasLinkOnceLinkage();
 
  194  FF[NamedFeatureIndex::Blocks] = 
F.size();
 
  196  FF[NamedFeatureIndex::Loops] = std::distance(LI.begin(), LI.end());
 
  198    FF[NamedFeatureIndex::MaxLoopDepth] =
 
  199        std::max(FF[NamedFeatureIndex::MaxLoopDepth],
 
  200                 static_cast<int32_t
>(
L->getLoopDepth()));
 
  201  FF[NamedFeatureIndex::MaxDomTreeLevel] = getMaxDominatorTreeDepth(
F, DomTree);
 
  205void IRToNativeSizeLearning::FunctionFeatures::fillTensor(int32_t *
Ptr)
 const {
 
  206  std::copy(NamedFeatures.begin(), NamedFeatures.end(), 
Ptr);
 
  207  Ptr += NamedFeatures.size();
 
  208  std::copy(InstructionHistogram.begin(), InstructionHistogram.end(), 
Ptr);
 
  209  Ptr += InstructionHistogram.size();
 
  210  std::copy(InstructionPairHistogram.begin(), InstructionPairHistogram.end(),
 
  215  return !TFIR2NativeModelPath.empty();
 
  223      "serving_default_input_1",
 
  224      {1, 
static_cast<int64_t
>(
 
  225              IRToNativeSizeLearning::FunctionFeatures::FeatureCount)})};
 
  226  std::vector<TensorSpec> OutputSpecs{
 
  228  Evaluator = std::make_unique<TFModelEvaluator>(
 
  229      TFIR2NativeModelPath.getValue().c_str(), InputSpecs, OutputSpecs);
 
  230  if (!Evaluator || !Evaluator->isValid()) {
 
  241  auto Features = IRToNativeSizeLearning::getFunctionFeatures(
 
  243  int32_t *
V = Evaluator->getInput<int32_t>(0);
 
  244  Features.fillTensor(V);
 
  245  auto ER = Evaluator->evaluate();
 
  248  float Ret = *ER->getTensorValue<
float>(0);
 
  251  return static_cast<size_t>(
Ret);
 
  264InlineSizeEstimatorAnalysis ::InlineSizeEstimatorAnalysis(
 
 
  278  OS << 
"[InlineSizeEstimatorAnalysis] size estimate for " << 
F.getName()
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static unsigned InstrCount
 
This header defines various interfaces for pass management in LLVM.
 
FunctionAnalysisManager FAM
 
static unsigned getSize(unsigned Kind)
 
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
 
Analysis pass which computes a DominatorTree.
 
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
 
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
 
This class evaluates LLVM IR, producing the Constant representing each SSA instruction.
 
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
 
InlineSizeEstimatorAnalysis()
 
~InlineSizeEstimatorAnalysis()
 
Result run(const Function &F, FunctionAnalysisManager &FAM)
 
static bool isEvaluatorRequested()
 
std::optional< size_t > Result
 
Analysis pass that exposes the LoopInfo for a function.
 
A set of analyses that are preserved following a run of a transformation pass.
 
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
 
Analysis pass providing the TargetTransformInfo.
 
static TensorSpec createSpec(const std::string &Name, const std::vector< int64_t > &Shape, int Port=0)
 
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
 
This is an optimization pass for GlobalISel generic memory operations.
 
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
 
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
 
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
 
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
 
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
 
A special type used by analysis passes to provide an address that identifies that particular analysis...