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

source code of llvm/include/llvm/Transforms/Utils/MemoryOpRemark.h