Skip to content

Commit a6096d9

Browse files
committed
[AsmPrinter] Add per BB instruction mix remark.
This patch adds a remarks that provides counts for each opcode per basic block. An snippet of the generated information can be seen below. The current implementation uses the target specific opcode for the counts. For example, on AArch64 this means we currently get 2 entries for `add` instructions if the block contains 32 and 64 bit adds. Similarly, immediate version are treated differently. Unfortunately there seems to be no convenient way to get only the mnemonic part of the instruction as a string AFAIK. This could be improved in the future. ``` --- !Analysis Pass: asm-printer Name: InstructionMix DebugLoc: { File: arm64-instruction-mix-remarks.ll, Line: 30, Column: 30 } Function: foo Args: - String: 'BasicBlock: ' - BasicBlock: else - String: "\n" - String: INST_MADDWrrr - String: ': ' - INST_MADDWrrr: '2' - String: "\n" - String: INST_MOVZWi - String: ': ' - INST_MOVZWi: '1' ``` Reviewed By: anemet, thegameg, paquette Differential Revision: https://reviews.llvm.org/D89892
1 parent 9d725b5 commit a6096d9

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,9 +1094,12 @@ void AsmPrinter::emitFunctionBody() {
10941094
bool HasAnyRealCode = false;
10951095
int NumInstsInFunction = 0;
10961096

1097+
bool CanDoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
1098+
const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
10971099
for (auto &MBB : *MF) {
10981100
// Print a label for the basic block.
10991101
emitBasicBlockStart(MBB);
1102+
DenseMap<unsigned, unsigned> OpcodeCounts;
11001103
for (auto &MI : MBB) {
11011104
// Print the assembly for the instruction.
11021105
if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&
@@ -1157,6 +1160,10 @@ void AsmPrinter::emitFunctionBody() {
11571160
break;
11581161
default:
11591162
emitInstruction(&MI);
1163+
if (CanDoExtraAnalysis) {
1164+
auto I = OpcodeCounts.insert({MI.getOpcode(), 0u});
1165+
I.first->second++;
1166+
}
11601167
break;
11611168
}
11621169

@@ -1212,6 +1219,35 @@ void AsmPrinter::emitFunctionBody() {
12121219
}
12131220
}
12141221
emitBasicBlockEnd(MBB);
1222+
1223+
if (CanDoExtraAnalysis) {
1224+
// Skip empty blocks.
1225+
if (MBB.empty())
1226+
continue;
1227+
1228+
MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionMix",
1229+
MBB.begin()->getDebugLoc(), &MBB);
1230+
1231+
// Generate instruction mix remark. First, convert opcodes to string
1232+
// names, then sort them in descending order by count and name.
1233+
SmallVector<std::pair<std::string, unsigned>, 128> OpcodeCountsVec;
1234+
for (auto &KV : OpcodeCounts) {
1235+
auto Name = (Twine("INST_") + TII->getName(KV.first)).str();
1236+
OpcodeCountsVec.emplace_back(Name, KV.second);
1237+
}
1238+
sort(OpcodeCountsVec, [](const std::pair<std::string, unsigned> &A,
1239+
const std::pair<std::string, unsigned> &B) {
1240+
if (A.second > B.second)
1241+
return true;
1242+
if (A.second == B.second)
1243+
return A.first < B.first;
1244+
return false;
1245+
});
1246+
R << "BasicBlock: " << ore::NV("BasicBlock", MBB.getName()) << "\n";
1247+
for (auto &KV : OpcodeCountsVec)
1248+
R << KV.first << ": " << ore::NV(KV.first, KV.second) << "\n";
1249+
ORE->emit(R);
1250+
}
12151251
}
12161252

12171253
EmittedInsts += NumInstsInFunction;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
; RUN: llc -mtriple=arm64-apple-ios7.0 -pass-remarks-output=%t -pass-remarks=asm-printer -o - %s | FileCheck %s
2+
; RUN: FileCheck --input-file=%t --check-prefix=YAML %s
3+
4+
; CHECK-LABEL: %entry
5+
; CHECK-NEXT: ldr w8, [x0]
6+
; CHECK-NEXT: add w8, w8, w1
7+
; CHECK-NEXT: cmp w8, #100
8+
; CHECK-NEXT: b.ne LBB0_2
9+
10+
; YAML: Name: InstructionMix
11+
; YAML-NEXT: DebugLoc: { File: arm64-instruction-mix-remarks.ll, Line: 10, Column: 10 }
12+
; YAML-NEXT: Function: foo
13+
; YAML-NEXT: Args:
14+
; YAML: - BasicBlock: entry
15+
; YAML: - INST_ADDWrs: '1'
16+
; YAML: - INST_Bcc: '1'
17+
; YAML: - INST_LDRWui: '1'
18+
; YAML: - INST_SUBSWri: '1'
19+
20+
21+
; CHECK-LABEL: %then
22+
; CHECK-NEXT: mov w0, w8
23+
; CHECK-NEXT: ret
24+
25+
; YAML: Name: InstructionMix
26+
; YAML-NEXT: DebugLoc: { File: arm64-instruction-mix-remarks.ll, Line: 20, Column: 20 }
27+
; YAML-NEXT: Function: foo
28+
; YAML-NEXT: Args:
29+
; YAML: - BasicBlock: then
30+
; YAML: - INST_ORRWrs: '1'
31+
; YAML: - INST_RET: '1'
32+
33+
; CHECK-LABEL: %else
34+
; CHECK-NEXT: mul w8, w8, w1
35+
; CHECK-NEXT: mov w9, #10
36+
; CHECK-NEXT: mul w8, w8, w1
37+
; CHECK-NEXT: str w9, [x0]
38+
; CHECK-NEXT: mov w0, w8
39+
; CHECK-NEXT: ret
40+
41+
; YAML: Name: InstructionMix
42+
; YAML-NEXT: DebugLoc: { File: arm64-instruction-mix-remarks.ll, Line: 30, Column: 30 }
43+
; YAML-NEXT: Function: foo
44+
; YAML-NEXT: Args:
45+
; YAML: - BasicBlock: else
46+
; YAML: - INST_MADDWrrr: '2'
47+
; YAML: - INST_ORRWrs: '1'
48+
; YAML: - INST_RET: '1'
49+
; YAML: - INST_STRWui: '1'
50+
define i32 @foo(i32* %ptr, i32 %x) !dbg !3 {
51+
entry:
52+
%l = load i32, i32* %ptr, !dbg !4
53+
%add = add i32 %l, %x, !dbg !4
54+
%c = icmp eq i32 %add, 100, !dbg !4
55+
br i1 %c, label %then, label %else, !dbg !4
56+
57+
then:
58+
ret i32 %add, !dbg !5
59+
60+
else:
61+
store i32 10, i32* %ptr, !dbg !6
62+
%res = mul i32 %add, %x, !dbg !6
63+
%res.2 = mul i32 %res, %x, !dbg !6
64+
ret i32 %res.2, !dbg !6
65+
}
66+
!llvm.dbg.cu = !{!0}
67+
!llvm.module.flags = !{!2}
68+
69+
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1)
70+
!1 = !DIFile(filename: "arm64-instruction-mix-remarks.ll", directory: "")
71+
!2 = !{i32 2, !"Debug Info Version", i32 3}
72+
!3 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 5, scopeLine: 5, unit: !0)
73+
!4 = distinct !DILocation(line: 10, column: 10, scope: !3)
74+
!5 = distinct !DILocation(line: 20, column: 20, scope: !3)
75+
!6 = distinct !DILocation(line: 30, column: 30, scope: !3)

0 commit comments

Comments
 (0)