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