| //=== 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/Analysis/TargetLibraryInfo.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 |