Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 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 | |||
| 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 | |||
| 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 | |||
| 58 | 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; |
||
| 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. |
||
| 97 | struct 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 | |||
| 105 | protected: |
||
| 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 |