Skip to content

Commit 4753a69

Browse files
committed
[Remarks] Provide more information about auto-init stores
This adds support for analyzing the instruction with the !annotation "auto-init" in order to generate a more user-friendly remark. For now, support the store size, and whether it's atomic/volatile. Example: ``` auto-init.c:4:7: remark: Store inserted by -ftrivial-auto-var-init.Store size: 4 bytes. [-Rpass-missed=annotation-remarks] int var; ^ ``` Differential Revision: https://reviews.llvm.org/D97412
1 parent c49b600 commit 4753a69

File tree

5 files changed

+172
-22
lines changed

5 files changed

+172
-22
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===- AutoInitRemark.h - Auto-init remark analysis -*- C++ -------------*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// Provide more information about instructions with a "auto-init"
11+
// !annotation metadata.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_TRANSFORMS_UTILS_AUTOINITREMARK_H
16+
#define LLVM_TRANSFORMS_UTILS_AUTOINITREMARK_H
17+
18+
#include "llvm/ADT/StringRef.h"
19+
20+
namespace llvm {
21+
22+
class StoreInst;
23+
class Instruction;
24+
class OptimizationRemarkEmitter;
25+
class DataLayout;
26+
27+
// FIXME: Once we get to more remarks like this one, we need to re-evaluate how
28+
// much of this logic should actually go into the remark emitter.
29+
struct AutoInitRemark {
30+
OptimizationRemarkEmitter &ORE;
31+
StringRef RemarkPass;
32+
const DataLayout &DL;
33+
34+
AutoInitRemark(OptimizationRemarkEmitter &ORE, StringRef RemarkPass,
35+
const DataLayout &DL)
36+
: ORE(ORE), RemarkPass(RemarkPass), DL(DL) {}
37+
38+
void inspectStore(StoreInst &SI);
39+
void inspectUnknown(Instruction &I);
40+
};
41+
42+
} // namespace llvm
43+
44+
#endif

llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
#include "llvm/Analysis/TargetLibraryInfo.h"
1717
#include "llvm/IR/Function.h"
1818
#include "llvm/IR/InstIterator.h"
19+
#include "llvm/IR/Instructions.h"
1920
#include "llvm/InitializePasses.h"
2021
#include "llvm/Pass.h"
2122
#include "llvm/Support/Debug.h"
2223
#include "llvm/Transforms/Scalar.h"
24+
#include "llvm/Transforms/Utils/AutoInitRemark.h"
2325

2426
using namespace llvm;
2527
using namespace llvm::ore;
@@ -38,9 +40,20 @@ static void tryEmitAutoInitRemark(ArrayRef<Instruction *> Instructions,
3840
if (cast<MDString>(Op.get())->getString() != "auto-init")
3941
continue;
4042

41-
ORE.emit(
42-
OptimizationRemarkMissed(REMARK_PASS, "AutoInitUnknownInstruction", I)
43-
<< "Initialization inserted by -ftrivial-auto-var-init.");
43+
Function &F = *I->getParent()->getParent();
44+
const DataLayout &DL = F.getParent()->getDataLayout();
45+
AutoInitRemark Remark(ORE, REMARK_PASS, DL);
46+
// For some of them, we can provide more information:
47+
48+
// For stores:
49+
// * size
50+
// * volatile / atomic
51+
if (auto *SI = dyn_cast<StoreInst>(I)) {
52+
Remark.inspectStore(*SI);
53+
continue;
54+
}
55+
56+
Remark.inspectUnknown(*I);
4457
}
4558
}
4659
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===-- AutoInitRemark.cpp - Auto-init remark analysis---------------------===//
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+
// Implementation of the analysis for the "auto-init" remark.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/Transforms/Utils/AutoInitRemark.h"
14+
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
15+
#include "llvm/IR/Instructions.h"
16+
17+
using namespace llvm;
18+
using namespace llvm::ore;
19+
20+
void AutoInitRemark::inspectStore(StoreInst &SI) {
21+
bool Volatile = SI.isVolatile();
22+
bool Atomic = SI.isAtomic();
23+
int64_t Size = DL.getTypeStoreSize(SI.getOperand(0)->getType());
24+
25+
OptimizationRemarkMissed R(RemarkPass.data(), "AutoInitStore", &SI);
26+
R << "Store inserted by -ftrivial-auto-var-init.\nStore size: "
27+
<< NV("StoreSize", Size) << " bytes.";
28+
if (Volatile)
29+
R << " Volatile: " << NV("StoreVolatile", true) << ".";
30+
if (Atomic)
31+
R << " Atomic: " << NV("StoreAtomic", true) << ".";
32+
// Emit StoreVolatile: false and StoreAtomic: false under ExtraArgs. This
33+
// won't show them in the remark message but will end up in the serialized
34+
// remarks.
35+
if (!Volatile || !Atomic)
36+
R << setExtraArgs();
37+
if (!Volatile)
38+
R << " Volatile: " << NV("StoreVolatile", false) << ".";
39+
if (!Atomic)
40+
R << " Atomic: " << NV("StoreAtomic", false) << ".";
41+
42+
ORE.emit(R);
43+
}
44+
45+
void AutoInitRemark::inspectUnknown(Instruction &I) {
46+
ORE.emit(OptimizationRemarkMissed(RemarkPass.data(),
47+
"AutoInitUnknownInstruction", &I)
48+
<< "Initialization inserted by -ftrivial-auto-var-init.");
49+
}

llvm/lib/Transforms/Utils/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_llvm_component_library(LLVMTransformUtils
33
AMDGPUEmitPrintf.cpp
44
ASanStackFrameLayout.cpp
55
AssumeBundleBuilder.cpp
6+
AutoInitRemark.cpp
67
BasicBlockUtils.cpp
78
BreakCriticalEdges.cpp
89
BuildLibCalls.cpp

llvm/test/Transforms/Util/trivial-auto-var-init-store.ll

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,59 +3,95 @@
33

44
; Emit a remark that reports a store.
55
define void @store(i32* %dst) {
6-
; CHECK: Initialization inserted by -ftrivial-auto-var-init.
6+
; CHECK: Store inserted by -ftrivial-auto-var-init.
7+
; CHECK-NEXT: Store size: 4 bytes.
78
; YAML-LABEL: --- !Missed
89
; YAML-NEXT: Pass: annotation-remarks
9-
; YAML-NEXT: Name: AutoInitUnknownInstruction
10+
; YAML-NEXT: Name: AutoInitStore
1011
; YAML-NEXT: DebugLoc:
1112
; YAML-NEXT: Function: store
1213
; YAML-NEXT: Args:
13-
; YAML-NEXT: - String: Initialization inserted by -ftrivial-auto-var-init.
14+
; YAML-NEXT: - String: "Store inserted by -ftrivial-auto-var-init.\nStore size: "
15+
; YAML-NEXT: - StoreSize: '4'
16+
; YAML-NEXT: - String: ' bytes.'
17+
; YAML-NEXT: - String: ' Volatile: '
18+
; YAML-NEXT: - StoreVolatile: 'false'
19+
; YAML-NEXT: - String: .
20+
; YAML-NEXT: - String: ' Atomic: '
21+
; YAML-NEXT: - StoreAtomic: 'false'
22+
; YAML-NEXT: - String: .
1423
; YAML-NEXT: ...
1524
store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
1625
ret void
1726
}
1827

1928
; Emit a remark that reports a volatile store.
2029
define void @volatile_store(i32* %dst) {
21-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
30+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
31+
; CHECK-NEXT: Store size: 4 bytes. Volatile: true.
2232
; YAML-LABEL: --- !Missed
2333
; YAML-NEXT: Pass: annotation-remarks
24-
; YAML-NEXT: Name: AutoInitUnknownInstruction
34+
; YAML-NEXT: Name: AutoInitStore
2535
; YAML-NEXT: DebugLoc:
2636
; YAML-NEXT: Function: volatile_store
2737
; YAML-NEXT: Args:
28-
; YAML-NEXT: - String: Initialization inserted by -ftrivial-auto-var-init.
38+
; YAML-NEXT: - String: "Store inserted by -ftrivial-auto-var-init.\nStore size: "
39+
; YAML-NEXT: - StoreSize: '4'
40+
; YAML-NEXT: - String: ' bytes.'
41+
; YAML-NEXT: - String: ' Volatile: '
42+
; YAML-NEXT: - StoreVolatile: 'true'
43+
; YAML-NEXT: - String: .
44+
; YAML-NEXT: - String: ' Atomic: '
45+
; YAML-NEXT: - StoreAtomic: 'false'
46+
; YAML-NEXT: - String: .
2947
; YAML-NEXT: ...
3048
store volatile i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
3149
ret void
3250
}
3351

3452
; Emit a remark that reports an atomic store.
3553
define void @atomic_store(i32* %dst) {
36-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
54+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
55+
; CHECK-NEXT: Store size: 4 bytes. Atomic: true.
3756
; YAML-LABEL: --- !Missed
3857
; YAML-NEXT: Pass: annotation-remarks
39-
; YAML-NEXT: Name: AutoInitUnknownInstruction
58+
; YAML-NEXT: Name: AutoInitStore
4059
; YAML-NEXT: DebugLoc:
4160
; YAML-NEXT: Function: atomic_store
4261
; YAML-NEXT: Args:
43-
; YAML-NEXT: - String: Initialization inserted by -ftrivial-auto-var-init.
62+
; YAML-NEXT: - String: "Store inserted by -ftrivial-auto-var-init.\nStore size: "
63+
; YAML-NEXT: - StoreSize: '4'
64+
; YAML-NEXT: - String: ' bytes.'
65+
; YAML-NEXT: - String: ' Atomic: '
66+
; YAML-NEXT: - StoreAtomic: 'true'
67+
; YAML-NEXT: - String: .
68+
; YAML-NEXT: - String: ' Volatile: '
69+
; YAML-NEXT: - StoreVolatile: 'false'
70+
; YAML-NEXT: - String: .
4471
; YAML-NEXT: ...
4572
store atomic i32 0, i32* %dst unordered, align 4, !annotation !0, !dbg !DILocation(scope: !4)
4673
ret void
4774
}
4875

4976
; Emit a remark that reports a store to an alloca.
5077
define void @store_alloca() {
51-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
78+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
79+
; CHECK-NEXT: Store size: 4 bytes.
5280
; YAML-LABEL: --- !Missed
5381
; YAML-NEXT: Pass: annotation-remarks
54-
; YAML-NEXT: Name: AutoInitUnknownInstruction
82+
; YAML-NEXT: Name: AutoInitStore
5583
; YAML-NEXT: DebugLoc:
5684
; YAML-NEXT: Function: store_alloca
5785
; YAML-NEXT: Args:
58-
; YAML-NEXT: - String: Initialization inserted by -ftrivial-auto-var-init.
86+
; YAML-NEXT: - String: "Store inserted by -ftrivial-auto-var-init.\nStore size: "
87+
; YAML-NEXT: - StoreSize: '4'
88+
; YAML-NEXT: - String: ' bytes.'
89+
; YAML-NEXT: - String: ' Volatile: '
90+
; YAML-NEXT: - StoreVolatile: 'false'
91+
; YAML-NEXT: - String: .
92+
; YAML-NEXT: - String: ' Atomic: '
93+
; YAML-NEXT: - StoreAtomic: 'false'
94+
; YAML-NEXT: - String: .
5995
; YAML-NEXT: ...
6096
%dst = alloca i32
6197
store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
@@ -64,7 +100,8 @@ define void @store_alloca() {
64100

65101
; Emit a remark that reports a store to an alloca through a GEP.
66102
define void @store_alloca_gep() {
67-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
103+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
104+
; CHECK-NEXT: Store size: 4 bytes.
68105
%dst = alloca i32
69106
%gep = getelementptr i32, i32* %dst, i32 0
70107
store i32 0, i32* %gep, !annotation !0, !dbg !DILocation(scope: !4)
@@ -73,7 +110,8 @@ define void @store_alloca_gep() {
73110

74111
; Emit a remark that reports a store to an alloca through a GEP in an array.
75112
define void @store_alloca_gep_array() {
76-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
113+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
114+
; CHECK-NEXT: Store size: 4 bytes.
77115
%dst = alloca [2 x i32]
78116
%gep = getelementptr [2 x i32], [2 x i32]* %dst, i64 0, i64 0
79117
store i32 0, i32* %gep, !annotation !0, !dbg !DILocation(scope: !4)
@@ -82,7 +120,8 @@ define void @store_alloca_gep_array() {
82120

83121
; Emit a remark that reports a store to an alloca through a bitcast.
84122
define void @store_alloca_bitcast() {
85-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
123+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
124+
; CHECK-NEXT: Store size: 4 bytes.
86125
%dst = alloca [2 x i16]
87126
%bc = bitcast [2 x i16]* %dst to i32*
88127
store i32 0, i32* %bc, !annotation !0, !dbg !DILocation(scope: !4)
@@ -92,7 +131,8 @@ define void @store_alloca_bitcast() {
92131
; Emit a remark that reports a store to an alloca that has a DILocalVariable
93132
; attached.
94133
define void @store_alloca_di() {
95-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
134+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
135+
; CHECK-NEXT: Store size: 4 bytes.
96136
%dst = alloca i32
97137
store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
98138
call void @llvm.dbg.declare(metadata i32* %dst, metadata !6, metadata !DIExpression()), !dbg !DILocation(scope: !4)
@@ -102,7 +142,8 @@ define void @store_alloca_di() {
102142
; Emit a remark that reports a store to an alloca that has more than one
103143
; DILocalVariable attached.
104144
define void @store_alloca_di_multiple() {
105-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
145+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
146+
; CHECK-NEXT: Store size: 4 bytes.
106147
%dst = alloca i32
107148
store i32 0, i32* %dst, !annotation !0, !dbg !DILocation(scope: !4)
108149
call void @llvm.dbg.declare(metadata i32* %dst, metadata !6, metadata !DIExpression()), !dbg !DILocation(scope: !4)
@@ -113,7 +154,8 @@ define void @store_alloca_di_multiple() {
113154
; Emit a remark that reports a store to a PHI node that can be two different
114155
; allocas.
115156
define void @store_alloca_phi() {
116-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
157+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
158+
; CHECK-NEXT: Store size: 4 bytes.
117159
entry:
118160
%dst = alloca i32
119161
%dst2 = alloca i32
@@ -132,7 +174,8 @@ l2:
132174
; Emit a remark that reports a store to a PHI node that can be two different
133175
; allocas, where one of it has multiple DILocalVariable.
134176
define void @store_alloca_phi_di_multiple() {
135-
; CHECK-NEXT: Initialization inserted by -ftrivial-auto-var-init.
177+
; CHECK-NEXT: Store inserted by -ftrivial-auto-var-init.
178+
; CHECK-NEXT: Store size: 4 bytes.
136179
entry:
137180
%dst = alloca i32
138181
%dst2 = alloca i32

0 commit comments

Comments
 (0)