Skip to content

Commit b2bec7c

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 a094b4f commit b2bec7c

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
@@ -1134,9 +1134,12 @@ void AsmPrinter::emitFunctionBody() {
11341134
bool HasAnyRealCode = false;
11351135
int NumInstsInFunction = 0;
11361136

1137+
bool CanDoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
1138+
const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
11371139
for (auto &MBB : *MF) {
11381140
// Print a label for the basic block.
11391141
emitBasicBlockStart(MBB);
1142+
DenseMap<unsigned, unsigned> OpcodeCounts;
11401143
for (auto &MI : MBB) {
11411144
// Print the assembly for the instruction.
11421145
if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&
@@ -1202,6 +1205,10 @@ void AsmPrinter::emitFunctionBody() {
12021205
break;
12031206
default:
12041207
emitInstruction(&MI);
1208+
if (CanDoExtraAnalysis) {
1209+
auto I = OpcodeCounts.insert({MI.getOpcode(), 0u});
1210+
I.first->second++;
1211+
}
12051212
break;
12061213
}
12071214

@@ -1245,6 +1252,35 @@ void AsmPrinter::emitFunctionBody() {
12451252
}
12461253
}
12471254
emitBasicBlockEnd(MBB);
1255+
1256+
if (CanDoExtraAnalysis) {
1257+
// Skip empty blocks.
1258+
if (MBB.empty())
1259+
continue;
1260+
1261+
MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionMix",
1262+
MBB.begin()->getDebugLoc(), &MBB);
1263+
1264+
// Generate instruction mix remark. First, convert opcodes to string
1265+
// names, then sort them in descending order by count and name.
1266+
SmallVector<std::pair<std::string, unsigned>, 128> OpcodeCountsVec;
1267+
for (auto &KV : OpcodeCounts) {
1268+
auto Name = (Twine("INST_") + TII->getName(KV.first)).str();
1269+
OpcodeCountsVec.emplace_back(Name, KV.second);
1270+
}
1271+
sort(OpcodeCountsVec, [](const std::pair<std::string, unsigned> &A,
1272+
const std::pair<std::string, unsigned> &B) {
1273+
if (A.second > B.second)
1274+
return true;
1275+
if (A.second == B.second)
1276+
return A.first < B.first;
1277+
return false;
1278+
});
1279+
R << "BasicBlock: " << ore::NV("BasicBlock", MBB.getName()) << "\n";
1280+
for (auto &KV : OpcodeCountsVec)
1281+
R << KV.first << ": " << ore::NV(KV.first, KV.second) << "\n";
1282+
ORE->emit(R);
1283+
}
12481284
}
12491285

12501286
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)