2019-10-03 16:20:50 +02:00
|
|
|
//=== 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;
|
|
|
|
|
2020-05-27 19:13:33 +02:00
|
|
|
extern cl::opt<bool> MemOPOptMemcmpBcmp;
|
|
|
|
|
2019-10-03 16:20:50 +02:00
|
|
|
///--------------------------- MemIntrinsicPlugin ------------------------------
|
|
|
|
class MemIntrinsicPlugin : public InstVisitor<MemIntrinsicPlugin> {
|
|
|
|
Function &F;
|
2020-02-05 00:19:33 +01:00
|
|
|
TargetLibraryInfo &TLI;
|
2019-10-03 16:20:50 +02:00
|
|
|
std::vector<CandidateInfo> *Candidates;
|
|
|
|
|
|
|
|
public:
|
|
|
|
static constexpr InstrProfValueKind Kind = IPVK_MemOPSize;
|
|
|
|
|
2020-02-05 00:19:33 +01:00
|
|
|
MemIntrinsicPlugin(Function &Fn, TargetLibraryInfo &TLI)
|
|
|
|
: F(Fn), TLI(TLI), Candidates(nullptr) {}
|
2019-10-03 16:20:50 +02:00
|
|
|
|
|
|
|
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.
|
2021-01-30 08:23:37 +01:00
|
|
|
if (isa<ConstantInt>(Length))
|
2019-10-03 16:20:50 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
Instruction *InsertPt = &MI;
|
|
|
|
Instruction *AnnotatedInst = &MI;
|
|
|
|
Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst});
|
|
|
|
}
|
2020-02-05 00:19:33 +01:00
|
|
|
void visitCallInst(CallInst &CI) {
|
2020-05-27 19:13:33 +02:00
|
|
|
if (!MemOPOptMemcmpBcmp)
|
|
|
|
return;
|
2020-02-05 00:19:33 +01:00
|
|
|
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.
|
2021-01-30 08:23:37 +01:00
|
|
|
if (isa<ConstantInt>(Length))
|
2020-02-05 00:19:33 +01:00
|
|
|
return;
|
|
|
|
Instruction *InsertPt = &CI;
|
|
|
|
Instruction *AnnotatedInst = &CI;
|
|
|
|
Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst});
|
|
|
|
}
|
|
|
|
}
|
2019-10-03 16:20:50 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
///------------------------ IndirectCallPromotionPlugin ------------------------
|
|
|
|
class IndirectCallPromotionPlugin {
|
|
|
|
Function &F;
|
|
|
|
|
|
|
|
public:
|
|
|
|
static constexpr InstrProfValueKind Kind = IPVK_IndirectCallTarget;
|
|
|
|
|
2020-02-05 00:19:33 +01:00
|
|
|
IndirectCallPromotionPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {}
|
2019-10-03 16:20:50 +02:00
|
|
|
|
|
|
|
void run(std::vector<CandidateInfo> &Candidates) {
|
2020-04-28 19:25:13 +02:00
|
|
|
std::vector<CallBase *> Result = findIndirectCalls(F);
|
2019-10-03 16:20:50 +02:00
|
|
|
for (Instruction *I : Result) {
|
2020-04-28 05:15:59 +02:00
|
|
|
Value *Callee = cast<CallBase>(I)->getCalledOperand();
|
2019-10-03 16:20:50 +02:00
|
|
|
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
|