1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#pragma once
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//===- MemoryOpRemark.h - Memory operation remark analysis -*- 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
//
//===----------------------------------------------------------------------===//
//
// Provide more information about instructions that copy, move, or initialize
// memory, including those with a "auto-init" !annotation metadata.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_UTILS_MEMORYOPREMARK_H
#define LLVM_TRANSFORMS_UTILS_MEMORYOPREMARK_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
#include <optional>
namespace llvm {
class CallInst;
class DataLayout;
class DiagnosticInfoIROptimization;
class Instruction;
class IntrinsicInst;
class Value;
class OptimizationRemarkEmitter;
class StoreInst;
// FIXME: Once we get to more remarks like this one, we need to re-evaluate how
// much of this logic should actually go into the remark emitter.
struct MemoryOpRemark {
OptimizationRemarkEmitter &ORE;
StringRef RemarkPass;
const DataLayout &DL;
const TargetLibraryInfo &TLI;
MemoryOpRemark(OptimizationRemarkEmitter &ORE, StringRef RemarkPass,
const DataLayout &DL, const TargetLibraryInfo &TLI)
: ORE(ORE), RemarkPass(RemarkPass), DL(DL), TLI(TLI) {}
virtual ~MemoryOpRemark();
/// \return true iff the instruction is understood by MemoryOpRemark.
static bool canHandle(const Instruction *I, const TargetLibraryInfo &TLI);
void visit(const Instruction *I);
protected:
virtual std::string explainSource(StringRef Type) const;
enum RemarkKind { RK_Store, RK_Unknown, RK_IntrinsicCall, RK_Call };
virtual StringRef remarkName(RemarkKind RK) const;
virtual DiagnosticKind diagnosticKind() const { return DK_OptimizationRemarkAnalysis; }
private:
template<typename ...Ts>
std::unique_ptr<DiagnosticInfoIROptimization> makeRemark(Ts... Args);
/// Emit a remark using information from the store's destination, size, etc.
void visitStore(const StoreInst &SI);
/// Emit a generic auto-init remark.
void visitUnknown(const Instruction &I);
/// Emit a remark using information from known intrinsic calls.
void visitIntrinsicCall(const IntrinsicInst &II);
/// Emit a remark using information from known function calls.
void visitCall(const CallInst &CI);
/// Add callee information to a remark: whether it's known, the function name,
/// etc.
template <typename FTy>
void visitCallee(FTy F, bool KnownLibCall, DiagnosticInfoIROptimization &R);
/// Add operand information to a remark based on knowledge we have for known
/// libcalls.
void visitKnownLibCall(const CallInst &CI, LibFunc LF,
DiagnosticInfoIROptimization &R);
/// Add the memory operation size to a remark.
void visitSizeOperand(Value *V, DiagnosticInfoIROptimization &R);
struct VariableInfo {
std::optional<StringRef> Name;
std::optional<uint64_t> Size;
bool isEmpty() const { return !Name && !Size; }
};
/// Gather more information about \p V as a variable. This can be debug info,
/// information from the alloca, etc. Since \p V can represent more than a
/// single variable, they will all be added to the remark.
void visitPtr(Value *V, bool IsSrc, DiagnosticInfoIROptimization &R);
void visitVariable(const Value *V, SmallVectorImpl<VariableInfo> &Result);
};
/// Special case for -ftrivial-auto-var-init remarks.
struct AutoInitRemark : public MemoryOpRemark {
AutoInitRemark(OptimizationRemarkEmitter &ORE, StringRef RemarkPass,
const DataLayout &DL, const TargetLibraryInfo &TLI)
: MemoryOpRemark(ORE, RemarkPass, DL, TLI) {}
/// \return true iff the instruction is understood by AutoInitRemark.
static bool canHandle(const Instruction *I);
protected:
std::string explainSource(StringRef Type) const override;
StringRef remarkName(RemarkKind RK) const override;
DiagnosticKind diagnosticKind() const override {
return DK_OptimizationRemarkMissed;
}
};
} // namespace llvm
#endif
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
|