| //=== ValueProfilePlugins.inc - set of plugins used by ValueProfileCollector =// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains a set of plugin classes used in ValueProfileCollectorImpl. |
| // Each plugin is responsible for collecting Value Profiling candidates for a |
| // particular optimization. |
| // Each plugin must satisfy the interface described in ValueProfileCollector.cpp |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "ValueProfileCollector.h" |
| #include "llvm/Analysis/IndirectCallVisitor.h" |
| #include "llvm/IR/InstVisitor.h" |
| |
| using namespace llvm; |
| using CandidateInfo = ValueProfileCollector::CandidateInfo; |
| |
| extern cl::opt<bool> MemOPOptMemcmpBcmp; |
| |
| ///--------------------------- MemIntrinsicPlugin ------------------------------ |
| class MemIntrinsicPlugin : public InstVisitor<MemIntrinsicPlugin> { |
| Function &F; |
| TargetLibraryInfo &TLI; |
| std::vector<CandidateInfo> *Candidates; |
| |
| public: |
| static constexpr InstrProfValueKind Kind = IPVK_MemOPSize; |
| |
| MemIntrinsicPlugin(Function &Fn, TargetLibraryInfo &TLI) |
| : F(Fn), TLI(TLI), Candidates(nullptr) {} |
| |
| void run(std::vector<CandidateInfo> &Cs) { |
| Candidates = &Cs; |
| visit(F); |
| Candidates = nullptr; |
| } |
| void visitMemIntrinsic(MemIntrinsic &MI) { |
| Value *Length = MI.getLength(); |
| // Not instrument constant length calls. |
| if (isa<ConstantInt>(Length)) |
| return; |
| |
| Instruction *InsertPt = &MI; |
| Instruction *AnnotatedInst = &MI; |
| Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst}); |
| } |
| void visitCallInst(CallInst &CI) { |
| if (!MemOPOptMemcmpBcmp) |
| return; |
| auto *F = CI.getCalledFunction(); |
| if (!F) |
| return; |
| LibFunc Func; |
| if (TLI.getLibFunc(CI, Func) && |
| (Func == LibFunc_memcmp || Func == LibFunc_bcmp)) { |
| Value *Length = CI.getArgOperand(2); |
| // Not instrument constant length calls. |
| if (isa<ConstantInt>(Length)) |
| return; |
| Instruction *InsertPt = &CI; |
| Instruction *AnnotatedInst = &CI; |
| Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst}); |
| } |
| } |
| }; |
| |
| ///------------------------ IndirectCallPromotionPlugin ------------------------ |
| class IndirectCallPromotionPlugin { |
| Function &F; |
| |
| public: |
| static constexpr InstrProfValueKind Kind = IPVK_IndirectCallTarget; |
| |
| IndirectCallPromotionPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {} |
| |
| void run(std::vector<CandidateInfo> &Candidates) { |
| std::vector<CallBase *> Result = findIndirectCalls(F); |
| for (Instruction *I : Result) { |
| Value *Callee = cast<CallBase>(I)->getCalledOperand(); |
| Instruction *InsertPt = I; |
| Instruction *AnnotatedInst = I; |
| Candidates.emplace_back(CandidateInfo{Callee, InsertPt, AnnotatedInst}); |
| } |
| } |
| }; |
| |
| ///----------------------- Registration of the plugins ------------------------- |
| /// For now, registering a plugin with the ValueProfileCollector is done by |
| /// adding the plugin type to the VP_PLUGIN_LIST macro. |
| #define VP_PLUGIN_LIST \ |
| MemIntrinsicPlugin, \ |
| IndirectCallPromotionPlugin |