xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/InstCount.cpp (revision c989957f28ef5b03f594265612e3437c1e826ed4)
1  //===-- InstCount.cpp - Collects the count of all instructions ------------===//
2  //
3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4  // See https://llvm.org/LICENSE.txt for license information.
5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6  //
7  //===----------------------------------------------------------------------===//
8  //
9  // This pass collects the count of all instructions and reports them
10  //
11  //===----------------------------------------------------------------------===//
12  
13  #include "llvm/Analysis/InstCount.h"
14  #include "llvm/ADT/Statistic.h"
15  #include "llvm/Analysis/Passes.h"
16  #include "llvm/IR/Function.h"
17  #include "llvm/IR/InstVisitor.h"
18  #include "llvm/InitializePasses.h"
19  #include "llvm/Pass.h"
20  #include "llvm/Support/Debug.h"
21  #include "llvm/Support/ErrorHandling.h"
22  #include "llvm/Support/raw_ostream.h"
23  using namespace llvm;
24  
25  #define DEBUG_TYPE "instcount"
26  
27  STATISTIC(TotalInsts, "Number of instructions (of all types)");
28  STATISTIC(TotalBlocks, "Number of basic blocks");
29  STATISTIC(TotalFuncs, "Number of non-external functions");
30  
31  #define HANDLE_INST(N, OPCODE, CLASS)                                          \
32    STATISTIC(Num##OPCODE##Inst, "Number of " #OPCODE " insts");
33  
34  #include "llvm/IR/Instruction.def"
35  
36  namespace {
37  class InstCount : public InstVisitor<InstCount> {
38    friend class InstVisitor<InstCount>;
39  
40    void visitFunction(Function &F) { ++TotalFuncs; }
41    void visitBasicBlock(BasicBlock &BB) { ++TotalBlocks; }
42  
43  #define HANDLE_INST(N, OPCODE, CLASS)                                          \
44    void visit##OPCODE(CLASS &) {                                                \
45      ++Num##OPCODE##Inst;                                                       \
46      ++TotalInsts;                                                              \
47    }
48  
49  #include "llvm/IR/Instruction.def"
50  
51    void visitInstruction(Instruction &I) {
52      errs() << "Instruction Count does not know about " << I;
53      llvm_unreachable(nullptr);
54    }
55  };
56  } // namespace
57  
58  PreservedAnalyses InstCountPass::run(Function &F,
59                                       FunctionAnalysisManager &FAM) {
60    LLVM_DEBUG(dbgs() << "INSTCOUNT: running on function " << F.getName()
61                      << "\n");
62    InstCount().visit(F);
63  
64    return PreservedAnalyses::all();
65  }
66  
67  namespace {
68  class InstCountLegacyPass : public FunctionPass {
69  public:
70    static char ID; // Pass identification, replacement for typeid
71    InstCountLegacyPass() : FunctionPass(ID) {
72      initializeInstCountLegacyPassPass(*PassRegistry::getPassRegistry());
73    }
74  
75    bool runOnFunction(Function &F) override {
76      LLVM_DEBUG(dbgs() << "INSTCOUNT: running on function " << F.getName()
77                        << "\n");
78      InstCount().visit(F);
79      return false;
80    };
81  
82    void getAnalysisUsage(AnalysisUsage &AU) const override {
83      AU.setPreservesAll();
84    }
85  
86    void print(raw_ostream &O, const Module *M) const override {}
87  };
88  } // namespace
89  
90  char InstCountLegacyPass::ID = 0;
91  INITIALIZE_PASS(InstCountLegacyPass, "instcount",
92                  "Counts the various types of Instructions", false, true)
93  
94  FunctionPass *llvm::createInstCountPass() { return new InstCountLegacyPass(); }
95