Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions llvm/include/llvm/Transforms/Utils/CountInstructions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===- CountInstructions.h --------------------------------------------*- C++
//-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_UTILS_COUNTINSTRUCTIONS_H
#define LLVM_TRANSFORMS_UTILS_COUNTINSTRUCTIONS_H

#include "llvm/ADT/StringMap.h"
#include "llvm/IR/PassManager.h"

namespace llvm {

class Function;

struct CountInstructionsPass : PassInfoMixin<CountInstructionsPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &);

private:
StringMap<uint32_t> Counts;
};

} // end namespace llvm

#endif // LLVM_TRANSFORMS_UTILS_COUNTINSTRUCTIONS_H
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@
#include "llvm/Transforms/Utils/BreakCriticalEdges.h"
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
#include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
#include "llvm/Transforms/Utils/CountInstructions.h"
#include "llvm/Transforms/Utils/CountVisits.h"
#include "llvm/Transforms/Utils/DXILUpgrade.h"
#include "llvm/Transforms/Utils/Debugify.h"
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Passes/PassBuilderPipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
#include "llvm/Transforms/Utils/AddDiscriminators.h"
#include "llvm/Transforms/Utils/AssumeBundleBuilder.h"
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
#include "llvm/Transforms/Utils/CountInstructions.h"
#include "llvm/Transforms/Utils/CountVisits.h"
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
#include "llvm/Transforms/Utils/ExtraPassManager.h"
Expand Down Expand Up @@ -1737,6 +1738,7 @@ PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
// Emit annotation remarks.
addAnnotationRemarksPass(MPM);

MPM.addPass(createModuleToFunctionPassAdaptor(CountInstructionsPass()));
if (isLTOPreLink(Phase))
addRequiredLTOPreLinkPasses(MPM);
return MPM;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ FUNCTION_PASS("consthoist", ConstantHoistingPass())
FUNCTION_PASS("constraint-elimination", ConstraintEliminationPass())
FUNCTION_PASS("coro-elide", CoroElidePass())
FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass())
FUNCTION_PASS("count-instructions", CountInstructionsPass())
FUNCTION_PASS("count-visits", CountVisitsPass())
FUNCTION_PASS("dce", DCEPass())
FUNCTION_PASS("declare-to-assign", llvm::AssignmentTrackingPass())
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/Utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ add_llvm_component_library(LLVMTransformUtils
CodeMoverUtils.cpp
ControlFlowUtils.cpp
CtorUtils.cpp
CountInstructions.cpp
CountVisits.cpp
Debugify.cpp
DebugSSAUpdater.cpp
Expand Down
63 changes: 63 additions & 0 deletions llvm/lib/Transforms/Utils/CountInstructions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//===- CountInstructions.cpp
//----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/CountInstructions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Casting.h"
#include <cstdint>

using namespace llvm;

#define DEBUG_TYPE "count-instructions"

STATISTIC(TotalBasicBlocks, "Number of basic blocks");
STATISTIC(TotalInstructions, "Number of total instructions");
STATISTIC(TotalBranchInstructions, "Number of branch instructions");
STATISTIC(TotalSwitchInstructions, "Number of switch instructions");
STATISTIC(TotalSuccessors, "Number of basic block successors");
STATISTIC(TotalBranchSuccessors, "Number of branch successors");
STATISTIC(TotalSwitchSuccessors, "Number of switch successors");
PreservedAnalyses CountInstructionsPass::run(Function &F,
FunctionAnalysisManager &) {
uint32_t CountBasicBlocks = 0;
uint32_t CountInstructions = 0;
uint32_t CountBranchInstructions = 0;
uint32_t CountSwitchInstructions = 0;
uint32_t CountSuccessors = 0;
uint32_t CountBranchSuccessors = 0;
uint32_t CountSwitchSuccessors = 0;

for (BasicBlock &BB : F) {
CountBasicBlocks++;
Instruction *I = BB.getTerminator();
CountSuccessors += I->getNumSuccessors();
if (isa<BranchInst>(I)) {
CountBranchInstructions++;
CountBranchSuccessors += I->getNumSuccessors();
} else if (isa<SwitchInst>(I)) {
CountSwitchInstructions++;
CountSwitchSuccessors += I->getNumSuccessors();
}
CountInstructions += BB.size();
}
TotalInstructions += CountInstructions;
TotalBasicBlocks += CountBasicBlocks;
TotalBranchInstructions += CountBranchInstructions;
TotalSwitchInstructions += CountSwitchInstructions;
TotalSuccessors += CountSuccessors;
TotalBranchSuccessors += CountBranchSuccessors;
TotalSwitchSuccessors += CountSwitchSuccessors;

return PreservedAnalyses::all();
}
104 changes: 104 additions & 0 deletions llvm/test/Other/count-instructions.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
; REQUIRES: asserts, stats
; RUN: opt -stats -passes=count-instructions < %s

define dso_local noundef i32 @add(i32 noundef %n) {
entry:
%n.addr = alloca i32, align 4
store i32 %n, ptr %n.addr, align 4
%0 = load i32, ptr %n.addr, align 4
%add = add nsw i32 %0, 1
ret i32 %add
}

define dso_local void @f(i32 noundef %i) {
entry:
%i.addr = alloca i32, align 4
%x = alloca i32, align 4
store i32 %i, ptr %i.addr, align 4
store i32 0, ptr %x, align 4
%0 = load i32, ptr %i.addr, align 4
switch i32 %0, label %sw.epilog [
i32 0, label %sw.bb
i32 10, label %sw.bb9
i32 1, label %sw.bb9
i32 2, label %sw.bb10
i32 3, label %sw.bb11
i32 4, label %sw.bb12
]

sw.bb:
%call = call noundef i32 @add(i32 noundef 9)
store i32 %call, ptr %x, align 4
%1 = load i32, ptr %x, align 4
%cmp = icmp eq i32 %1, 0
br i1 %cmp, label %if.then, label %if.end

if.then:
store i32 1, ptr %x, align 4
br label %if.end

if.end:
%2 = load i32, ptr %x, align 4
%call1 = call noundef i32 @add(i32 noundef %2)
store i32 %call1, ptr %x, align 4
%3 = load i32, ptr %x, align 4
%cmp2 = icmp eq i32 %3, 0
br i1 %cmp2, label %if.then3, label %if.else

if.then3:
store i32 1, ptr %x, align 4
br label %if.end8

if.else:
%4 = load i32, ptr %x, align 4
%cmp4 = icmp eq i32 %4, 1
br i1 %cmp4, label %if.then5, label %if.else6

if.then5:
store i32 0, ptr %x, align 4
br label %if.end7

if.else6:
store i32 2, ptr %x, align 4
br label %if.end7

if.end7:
br label %if.end8

if.end8:
br label %sw.epilog

sw.bb9:
call void @h()
br label %sw.epilog

sw.bb10:
call void @h()
br label %sw.epilog

sw.bb11:
call void @j()
br label %sw.bb12

sw.bb12:
call void @k()
br label %if.end15

sw.epilog:
%5 = load i32, ptr %x, align 4
%cmp13 = icmp eq i32 %5, 0
br i1 %cmp13, label %if.then14, label %if.end15

if.then14:
store i32 1, ptr %x, align 4
br label %if.end15

if.end15:
ret void
}

declare void @h() #2

declare void @j() #2

declare void @k() #2
Loading