Skip to content

Commit fee9abe

Browse files
committed
[Remarks] Provide more information about auto-init calls
This now analyzes calls to both intrinsics and functions. For intrinsics, grab the ones we know and care about (mem* family) and analyze the arguments. For calls, use TLI to get more information about the libcalls, then analyze the arguments if known. ``` auto-init.c:4:7: remark: Call to memset inserted by -ftrivial-auto-var-init. Memory operation size: 4096 bytes. [-Rpass-missed=annotation-remarks] int var[1024]; ^ ``` Differential Revision: https://reviews.llvm.org/D97489
1 parent 4753a69 commit fee9abe

File tree

6 files changed

+388
-117
lines changed

6 files changed

+388
-117
lines changed

llvm/include/llvm/Transforms/Utils/AutoInitRemark.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,42 @@
1616
#define LLVM_TRANSFORMS_UTILS_AUTOINITREMARK_H
1717

1818
#include "llvm/ADT/StringRef.h"
19+
#include "llvm/Analysis/TargetLibraryInfo.h"
1920

2021
namespace llvm {
2122

22-
class StoreInst;
23+
class CallInst;
24+
class DataLayout;
2325
class Instruction;
26+
class IntrinsicInst;
27+
class Value;
2428
class OptimizationRemarkEmitter;
25-
class DataLayout;
29+
class OptimizationRemarkMissed;
30+
class StoreInst;
2631

2732
// FIXME: Once we get to more remarks like this one, we need to re-evaluate how
2833
// much of this logic should actually go into the remark emitter.
2934
struct AutoInitRemark {
3035
OptimizationRemarkEmitter &ORE;
3136
StringRef RemarkPass;
3237
const DataLayout &DL;
38+
const TargetLibraryInfo &TLI;
3339

3440
AutoInitRemark(OptimizationRemarkEmitter &ORE, StringRef RemarkPass,
35-
const DataLayout &DL)
36-
: ORE(ORE), RemarkPass(RemarkPass), DL(DL) {}
41+
const DataLayout &DL, const TargetLibraryInfo &TLI)
42+
: ORE(ORE), RemarkPass(RemarkPass), DL(DL), TLI(TLI) {}
3743

3844
void inspectStore(StoreInst &SI);
3945
void inspectUnknown(Instruction &I);
46+
void inspectIntrinsicCall(IntrinsicInst &II);
47+
void inspectCall(CallInst &CI);
48+
49+
private:
50+
template <typename FTy>
51+
void inspectCallee(FTy F, bool KnownLibCall, OptimizationRemarkMissed &R);
52+
void inspectKnownLibCall(CallInst &CI, LibFunc LF,
53+
OptimizationRemarkMissed &R);
54+
void inspectSizeOperand(Value *V, OptimizationRemarkMissed &R);
4055
};
4156

4257
} // namespace llvm

llvm/lib/Transforms/Scalar/AnnotationRemarks.cpp

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/IR/Function.h"
1818
#include "llvm/IR/InstIterator.h"
1919
#include "llvm/IR/Instructions.h"
20+
#include "llvm/IR/IntrinsicInst.h"
2021
#include "llvm/InitializePasses.h"
2122
#include "llvm/Pass.h"
2223
#include "llvm/Support/Debug.h"
@@ -30,7 +31,8 @@ using namespace llvm::ore;
3031
#define REMARK_PASS DEBUG_TYPE
3132

3233
static void tryEmitAutoInitRemark(ArrayRef<Instruction *> Instructions,
33-
OptimizationRemarkEmitter &ORE) {
34+
OptimizationRemarkEmitter &ORE,
35+
const TargetLibraryInfo &TLI) {
3436
// For every auto-init annotation generate a separate remark.
3537
for (Instruction *I : Instructions) {
3638
if (!I->hasMetadata(LLVMContext::MD_annotation))
@@ -42,7 +44,7 @@ static void tryEmitAutoInitRemark(ArrayRef<Instruction *> Instructions,
4244

4345
Function &F = *I->getParent()->getParent();
4446
const DataLayout &DL = F.getParent()->getDataLayout();
45-
AutoInitRemark Remark(ORE, REMARK_PASS, DL);
47+
AutoInitRemark Remark(ORE, REMARK_PASS, DL, TLI);
4648
// For some of them, we can provide more information:
4749

4850
// For stores:
@@ -53,12 +55,29 @@ static void tryEmitAutoInitRemark(ArrayRef<Instruction *> Instructions,
5355
continue;
5456
}
5557

58+
// For intrinsics:
59+
// * user-friendly name
60+
// * size
61+
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
62+
Remark.inspectIntrinsicCall(*II);
63+
continue;
64+
}
65+
66+
// For calls:
67+
// * known/unknown function (e.g. the compiler knows bzero, but it doesn't
68+
// know my_bzero)
69+
// * memory operation size
70+
if (auto *CI = dyn_cast<CallInst>(I)) {
71+
Remark.inspectCall(*CI);
72+
continue;
73+
}
74+
5675
Remark.inspectUnknown(*I);
5776
}
5877
}
5978
}
6079

61-
static void runImpl(Function &F) {
80+
static void runImpl(Function &F, const TargetLibraryInfo &TLI) {
6281
if (!OptimizationRemarkEmitter::allowExtraAnalysis(F, REMARK_PASS))
6382
return;
6483

@@ -94,7 +113,7 @@ static void runImpl(Function &F) {
94113
if (!KV.first)
95114
continue;
96115

97-
tryEmitAutoInitRemark(KV.second, ORE);
116+
tryEmitAutoInitRemark(KV.second, ORE, TLI);
98117
}
99118
}
100119

@@ -108,12 +127,15 @@ struct AnnotationRemarksLegacy : public FunctionPass {
108127
}
109128

110129
bool runOnFunction(Function &F) override {
111-
runImpl(F);
130+
const TargetLibraryInfo &TLI =
131+
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
132+
runImpl(F, TLI);
112133
return false;
113134
}
114135

115136
void getAnalysisUsage(AnalysisUsage &AU) const override {
116137
AU.setPreservesAll();
138+
AU.addRequired<TargetLibraryInfoWrapperPass>();
117139
}
118140
};
119141

@@ -123,6 +145,7 @@ char AnnotationRemarksLegacy::ID = 0;
123145

124146
INITIALIZE_PASS_BEGIN(AnnotationRemarksLegacy, "annotation-remarks",
125147
"Annotation Remarks", false, false)
148+
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
126149
INITIALIZE_PASS_END(AnnotationRemarksLegacy, "annotation-remarks",
127150
"Annotation Remarks", false, false)
128151

@@ -132,6 +155,7 @@ FunctionPass *llvm::createAnnotationRemarksLegacyPass() {
132155

133156
PreservedAnalyses AnnotationRemarksPass::run(Function &F,
134157
FunctionAnalysisManager &AM) {
135-
runImpl(F);
158+
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
159+
runImpl(F, TLI);
136160
return PreservedAnalyses::all();
137161
}

llvm/lib/Transforms/Utils/AutoInitRemark.cpp

Lines changed: 93 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,13 @@
1313
#include "llvm/Transforms/Utils/AutoInitRemark.h"
1414
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
1515
#include "llvm/IR/Instructions.h"
16+
#include "llvm/IR/IntrinsicInst.h"
1617

1718
using namespace llvm;
1819
using namespace llvm::ore;
1920

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.";
21+
static void volatileOrAtomicWithExtraArgs(bool Volatile, bool Atomic,
22+
OptimizationRemarkMissed &R) {
2823
if (Volatile)
2924
R << " Volatile: " << NV("StoreVolatile", true) << ".";
3025
if (Atomic)
@@ -38,7 +33,17 @@ void AutoInitRemark::inspectStore(StoreInst &SI) {
3833
R << " Volatile: " << NV("StoreVolatile", false) << ".";
3934
if (!Atomic)
4035
R << " Atomic: " << NV("StoreAtomic", false) << ".";
36+
}
37+
38+
void AutoInitRemark::inspectStore(StoreInst &SI) {
39+
bool Volatile = SI.isVolatile();
40+
bool Atomic = SI.isAtomic();
41+
int64_t Size = DL.getTypeStoreSize(SI.getOperand(0)->getType());
4142

43+
OptimizationRemarkMissed R(RemarkPass.data(), "AutoInitStore", &SI);
44+
R << "Store inserted by -ftrivial-auto-var-init.\nStore size: "
45+
<< NV("StoreSize", Size) << " bytes.";
46+
volatileOrAtomicWithExtraArgs(Volatile, Atomic, R);
4247
ORE.emit(R);
4348
}
4449

@@ -47,3 +52,83 @@ void AutoInitRemark::inspectUnknown(Instruction &I) {
4752
"AutoInitUnknownInstruction", &I)
4853
<< "Initialization inserted by -ftrivial-auto-var-init.");
4954
}
55+
56+
void AutoInitRemark::inspectIntrinsicCall(IntrinsicInst &II) {
57+
SmallString<32> CallTo;
58+
bool Atomic = false;
59+
switch (II.getIntrinsicID()) {
60+
case Intrinsic::memcpy:
61+
CallTo = "memcpy";
62+
break;
63+
case Intrinsic::memmove:
64+
CallTo = "memmove";
65+
break;
66+
case Intrinsic::memset:
67+
CallTo = "memset";
68+
break;
69+
case Intrinsic::memcpy_element_unordered_atomic:
70+
CallTo = "memcpy";
71+
Atomic = true;
72+
break;
73+
case Intrinsic::memmove_element_unordered_atomic:
74+
CallTo = "memmove";
75+
Atomic = true;
76+
break;
77+
case Intrinsic::memset_element_unordered_atomic:
78+
CallTo = "memset";
79+
Atomic = true;
80+
break;
81+
default:
82+
return inspectUnknown(II);
83+
}
84+
85+
OptimizationRemarkMissed R(RemarkPass.data(), "AutoInitIntrinsic", &II);
86+
inspectCallee(StringRef(CallTo), /*KnownLibCall=*/true, R);
87+
inspectSizeOperand(II.getOperand(2), R);
88+
89+
auto *CIVolatile = dyn_cast<ConstantInt>(II.getOperand(3));
90+
// No such thing as a memory intrinsic that is both atomic and volatile.
91+
bool Volatile = !Atomic && CIVolatile && CIVolatile->getZExtValue();
92+
volatileOrAtomicWithExtraArgs(Volatile, Atomic, R);
93+
ORE.emit(R);
94+
}
95+
96+
void AutoInitRemark::inspectCall(CallInst &CI) {
97+
Function *F = CI.getCalledFunction();
98+
if (!F)
99+
return inspectUnknown(CI);
100+
101+
LibFunc LF;
102+
bool KnownLibCall = TLI.getLibFunc(*F, LF) && TLI.has(LF);
103+
OptimizationRemarkMissed R(RemarkPass.data(), "AutoInitCall", &CI);
104+
inspectCallee(F, KnownLibCall, R);
105+
inspectKnownLibCall(CI, LF, R);
106+
ORE.emit(R);
107+
}
108+
109+
template <typename FTy>
110+
void AutoInitRemark::inspectCallee(FTy F, bool KnownLibCall,
111+
OptimizationRemarkMissed &R) {
112+
R << "Call to ";
113+
if (!KnownLibCall)
114+
R << NV("UnknownLibCall", "unknown") << " function ";
115+
R << NV("Callee", F) << " inserted by -ftrivial-auto-var-init.";
116+
}
117+
118+
void AutoInitRemark::inspectKnownLibCall(CallInst &CI, LibFunc LF,
119+
OptimizationRemarkMissed &R) {
120+
switch (LF) {
121+
default:
122+
return;
123+
case LibFunc_bzero:
124+
inspectSizeOperand(CI.getOperand(1), R);
125+
break;
126+
}
127+
}
128+
129+
void AutoInitRemark::inspectSizeOperand(Value *V, OptimizationRemarkMissed &R) {
130+
if (auto *Len = dyn_cast<ConstantInt>(V)) {
131+
uint64_t Size = Len->getZExtValue();
132+
R << " Memory operation size: " << NV("StoreSize", Size) << " bytes.";
133+
}
134+
}

llvm/test/Other/new-pm-O0-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
; CHECK-LTO-NEXT: Running pass: LowerTypeTestsPass
4545
; CHECK-LTO-NEXT: Running pass: LowerTypeTestsPass
4646
; CHECK-LTO-NEXT: Running pass: AnnotationRemarksPass
47+
; CHECK-LTO-NEXT: Running analysis: TargetLibraryAnalysis
4748
; CHECK-NEXT: Running pass: PrintModulePass
4849

4950
; Make sure we get the IR back out without changes when we print the module.

0 commit comments

Comments
 (0)