Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions llvm/test/tools/llvm-snippy/calls/erase-calls-from-histogram.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# COM: This test checks that when calls can't be generated, they are removed
# from the histogram.

# RUN: llvm-snippy %s -model-plugin None \
# RUN: |& FileCheck %s

options:
mtriple: riscv64
num-instrs: 1000
dump-mf: on

include:
- ../Inputs/sections.yaml

histogram:
- [ADD, 1.0]
- [JALR, 1.0]
- [JAL, 1.0]

# CHECK: ADD
# CHECK-NOT: CALL
20 changes: 12 additions & 8 deletions llvm/tools/llvm-snippy/include/snippy/Config/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ class DefaultPolicyConfig {
DefaultPolicyConfig(const CommonPolicyConfig &Common) : Common(&Common) {}

Expected<OpcGenHolder>
createOpcodeGenerator(const OpcodeCache &OpCC,
const std::function<bool(unsigned)> &OpcMask) const {
createOpcodeGenerator(const std::function<bool(unsigned)> &OpcMask) const {

assert(!DataFlowHistogram.empty());
if (DataFlowHistogram.empty())
snippy::fatal(
"OpcodeGenerator initialization failure: empty histogram specified.");

std::map<unsigned, double> DFHCopy;
llvm::copy_if(DataFlowHistogram, std::inserter(DFHCopy, DFHCopy.end()),
Expand Down Expand Up @@ -348,11 +349,14 @@ class Config final {

~Config() = default;

// FIXME: legacy that must be removed
// FIXME: this should return OpcGenHolder
std::unique_ptr<DefaultOpcodeGenerator> createDefaultOpcodeGenerator() const {
return std::make_unique<DefaultOpcodeGenerator>(Histogram.begin(),
Histogram.end());
std::map<unsigned /* Opcode */, double /* probability */>
getOpcodeProbabilities() const {
std::map<unsigned, double> OpcodeProb;
transform(Histogram, std::inserter(OpcodeProb, OpcodeProb.end()),
[TotalWeight = Histogram.getTotalWeight()](auto &Elem) {
return std::make_pair(Elem.first, Elem.second / TotalWeight);
});
return OpcodeProb;
}

const OpcodeHistogram &getOpcodeHistogram() const { return Histogram; }
Expand Down
12 changes: 12 additions & 0 deletions llvm/tools/llvm-snippy/include/snippy/Config/OpcodeHistogram.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ class OpcodeHistogram : private std::map<unsigned, double> {
});
}

// FIXME: We are waiting for C++20.
auto erase_if(std::function<bool(unsigned)> Pred) {
auto OldSize = size();
for (auto Hist = begin(), Last = end(); Hist != Last;) {
if (Pred(Hist->first))
Hist = erase(Hist, std::next(Hist));
else
++Hist;
}
return OldSize - size();
}

double getTotalWeight() const {
return getOpcodesWeight([](unsigned) { return true; });
}
Expand Down
6 changes: 0 additions & 6 deletions llvm/tools/llvm-snippy/include/snippy/Generator/Policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,6 @@ struct EmptyFinalizeMixin {
};
} // namespace detail

OpcGenHolder createDefaultOpcGenerator(
SnippyProgramContext &ProgCtx, const Config &Cfg,
std::function<bool(unsigned)> Filter, bool MustHavePrimaryInstrs,
ArrayRef<OpcodeHistogramEntry> Overrides,
const std::unordered_map<unsigned, double> &WeightOverrides = {});

// This policy is used to insert mode changing instructions and provide context
// for other policies that follow it.
class ModeChangingInstPolicy final : public detail::EmptyFinalizeMixin {
Expand Down
11 changes: 0 additions & 11 deletions llvm/tools/llvm-snippy/include/snippy/Support/OpcodeGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,6 @@ class DefaultOpcodeGenerator final : public OpcodeGeneratorInterface {

const OpcodeList &getOpcodesList() const { return Opcodes; }

std::map<unsigned /* Opcode */, double /* probability */>
getProbabilities() const {
std::map<unsigned, double> Output;
const auto OpcodeWeight = zip(Opcodes, OpcodeDist.probabilities());
for (const auto [Opcode, Weight] : OpcodeWeight) {
assert(Output.count(Opcode) == 0);
Output[Opcode] = Weight;
}
return Output;
}

void print(llvm::raw_ostream &OS) const override;

void dump() const override { print(dbgs()); }
Expand Down
43 changes: 22 additions & 21 deletions llvm/tools/llvm-snippy/lib/Config/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1158,38 +1158,38 @@ static bool hasCallees(const FunctionDesc &FuncDesc) {
return FuncDesc.Callees.size();
}

static void checkCallRequirements(
const SnippyTarget &Tgt, const OpcodeHistogram &Histogram,
static void deleteCallsIfNeeded(
const SnippyTarget &Tgt, OpcodeHistogram &Histogram,
const std::variant<CallGraphLayout, FunctionDescs> &CGLayout) {
bool HasCalls = Histogram.getOpcodesWeight([&Tgt](unsigned Opcode) {
return Tgt.isCall(Opcode);
}) > 0.0;
bool HasNonCalls = Histogram.getOpcodesWeight([&Tgt](unsigned Opcode) {
return !Tgt.isCall(Opcode);
}) > 0.0;
if (HasCalls && !HasNonCalls)
auto IsCall = [&Tgt](unsigned Opcode) { return Tgt.isCall(Opcode); };
auto CallsWeight = Histogram.getOpcodesWeight(IsCall);
if (CallsWeight < std::numeric_limits<decltype(CallsWeight)>::epsilon())
return;
if (std::abs(Histogram.getTotalWeight() - CallsWeight) <
std::numeric_limits<decltype(CallsWeight)>::epsilon())
snippy::fatal(
"for using calls you need to add to histogram non-call instructions");

if (!HasCalls)
return;

std::visit(OverloadedCallable(
[](const FunctionDescs &Descs) -> void {
[&Histogram, IsCall](const FunctionDescs &Descs) -> void {
if (!std::any_of(Descs.Descs.begin(), Descs.Descs.end(),
hasCallees))
hasCallees)) {
snippy::warn(
WarningName::CannotGenerateCalls,
"Provided call-graph doesn't allow generation of "
"calls as no callees were found",
"no calls will be generated");
Histogram.erase_if(IsCall);
}
},
[](const CallGraphLayout &CGLayout) -> void {
if (auto NumFunc = CGLayout.FunctionNumber; NumFunc < 2)
[&Histogram, IsCall](const CallGraphLayout &CGLayout) -> void {
if (auto NumFunc = CGLayout.FunctionNumber; NumFunc < 2) {
snippy::warn(WarningName::CannotGenerateCalls,
"Not enough functions specified to generate "
"calls (required at least 2)",
"-function-number is " + Twine(NumFunc));
Histogram.erase_if(IsCall);
}
}),
CGLayout);
}
Expand Down Expand Up @@ -1478,7 +1478,6 @@ void Config::validateAll(LLVMState &State, const OpcodeCache &OpCC,
"it is required to enable selfcheck");
if (BurstConfig)
checkBurstGram(Ctx, Histogram, OpCC, BurstConfig->Burst);
checkCallRequirements(Tgt, Histogram, CGLayout);
checkMemoryRegions(Tgt, *this);
Tgt.checkInstrTargetDependency(Histogram, OpCC);
if (hasTrackingMode())
Expand Down Expand Up @@ -1606,10 +1605,12 @@ void Config::complete(LLVMState &State, const OpcodeCache &OpCC) {
auto BurstOpcodes = BCfg.Burst.getAllBurstOpcodes();
return BurstOpcodes.count(Opc);
};
auto &DFHistogram = DefFlowConfig.DataFlowHistogram;
DFHistogram.clear();
std::copy_if(Histogram.begin(), Histogram.end(),
std::inserter(DFHistogram, DFHistogram.end()),
auto DFHistogram = Histogram;
deleteCallsIfNeeded(State.getSnippyTarget(), DFHistogram, PassCfg.CGLayout);
DefFlowConfig.DataFlowHistogram.clear();
std::copy_if(DFHistogram.begin(), DFHistogram.end(),
std::inserter(DefFlowConfig.DataFlowHistogram,
DefFlowConfig.DataFlowHistogram.end()),
[&](const auto &Hist) {
auto *Desc = OpCC.desc(Hist.first);
assert(Desc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,7 @@ void ValuegramGenPolicy::initialize(InstructionGenerationContext &InstrGenCtx,
const auto &Filter = ModeChangingPolicy
? ModeChangingPolicy->getOpcodeFilter()
: getDefaultFilter(Tgt);
auto Err =
Cfg->createOpcodeGenerator(InstrGenCtx.ProgCtx.getOpcodeCache(), Filter)
.moveInto(OpcGen);
auto Err = Cfg->createOpcodeGenerator(Filter).moveInto(OpcGen);
if (Err)
snippy::fatal(
Twine("Failed to create OpcodeGenerator in ValuegramGenPolicy: ") +
Expand Down
4 changes: 1 addition & 3 deletions llvm/tools/llvm-snippy/lib/Generator/Policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,7 @@ void DefaultGenPolicy::initialize(InstructionGenerationContext &InstrGenCtx,
const auto &Filter = ModeChangingPolicy
? ModeChangingPolicy->getOpcodeFilter()
: getDefaultFilter(Tgt);
auto Err =
Cfg->createOpcodeGenerator(InstrGenCtx.ProgCtx.getOpcodeCache(), Filter)
.moveInto(OpcGen);
auto Err = Cfg->createOpcodeGenerator(Filter).moveInto(OpcGen);
if (Err)
snippy::fatal(
Twine("Failed to create OpcodeGenerator in DefaultGenPolicy: ") +
Expand Down
3 changes: 1 addition & 2 deletions llvm/tools/llvm-snippy/lib/PostGenVerifierPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,7 @@ void PostGenVerifier::printData(const MachineFunction &MF) const {
const GeneratorContext &SGCtx = CtxWrapper.getContext();
const OpcodeCache &OpCache = SGCtx.getProgramContext().getOpcodeCache();

auto ExpectedDist =
SGCtx.getConfig().createDefaultOpcodeGenerator()->getProbabilities();
auto ExpectedDist = SGCtx.getConfig().getOpcodeProbabilities();

auto &Output = outs();
constexpr unsigned OpcodeWidth = 12;
Expand Down
5 changes: 2 additions & 3 deletions llvm/tools/llvm-snippy/lib/Support/OpcodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ namespace snippy {

void DefaultOpcodeGenerator::print(llvm::raw_ostream &OS) const {
OS << "OpcodeGen:\n";
auto Prob = getProbabilities();
for (const auto &[Opcode, P] : Prob)
OS << " Opcode: " << Opcode << ": " << floatToString(P, 3) << "\n";
for (const auto &[Opcode, Prob] : zip(Opcodes, OpcodeDist.probabilities()))
OS << " Opcode: " << Opcode << ": " << floatToString(Prob, 3) << "\n";
}

unsigned DefaultOpcodeGenerator::generate() {
Expand Down
4 changes: 0 additions & 4 deletions llvm/tools/llvm-snippy/lib/Target/RISCV/RVVUnitConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,6 @@ static auto extractElementsWithProbabilities(const SliceType &ConfSlice) {

ModeChangeInfo deriveModeSwitchingProbability(const Config &Cfg,
const ModeChangeBias &Bias) {
// FIXME: This is here only to cause fatal errors in case we can't create
// OpcGen (e.g. empty histogram)
Cfg.createDefaultOpcodeGenerator();

const auto &Hist = Cfg.Histogram;
double TotalWeight = Hist.getTotalWeight();
ModeChangeInfo Result;
Expand Down