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 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 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. 35 struct MemoryOpRemark { 36 OptimizationRemarkEmitter &ORE; 37 StringRef RemarkPass; 38 const DataLayout &DL; 39 const TargetLibraryInfo &TLI; 40 MemoryOpRemarkMemoryOpRemark41 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 52 protected: 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 diagnosticKindMemoryOpRemark58 virtual DiagnosticKind diagnosticKind() const { return DK_OptimizationRemarkAnalysis; } 59 60 private: 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; isEmptyMemoryOpRemark::VariableInfo87 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. 97 struct AutoInitRemark : public MemoryOpRemark { AutoInitRemarkAutoInitRemark98 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 105 protected: 106 std::string explainSource(StringRef Type) const override; 107 StringRef remarkName(RemarkKind RK) const override; diagnosticKindAutoInitRemark108 DiagnosticKind diagnosticKind() const override { 109 return DK_OptimizationRemarkMissed; 110 } 111 }; 112 113 } // namespace llvm 114 115 #endif 116