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