-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[Opened-by-mistake] BPU Machine basic block placement fuzz #116492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
block frequency inversion added under special flag
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Dmitriy Sokolov (dee-tree) Changes
Patch is 20.87 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/116492.diff 13 Files Affected:
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 97573fcf20c1fb..73766d45c29a58 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -826,6 +826,12 @@ def warn_android_unversioned_fallback : Warning<
def err_drv_triple_version_invalid : Error<
"version '%0' in target triple '%1' is invalid">;
+def err_empty_option_value : Error<
+ "empty value for %0 option">;
+
+def warn_use_fseed : Warning<"fuzzing with seed: %0">,
+ InGroup<DiagGroup<"fuzzing">>;
+
def warn_missing_include_dirs : Warning<
"no such include directory: '%0'">, InGroup<MissingIncludeDirs>, DefaultIgnore;
}
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 23bd686a85f526..502826ff325524 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6730,6 +6730,33 @@ let Flags = [TargetSpecific] in {
defm android_pad_segment : BooleanFFlag<"android-pad-segment">, Group<f_Group>;
} // let Flags = [TargetSpecific]
+// Compiler-assisted fuzzing options
+def fuzz_EQ : Joined<["--"], "fuzz=">,
+ Flags<[NoXarchOption, HelpHidden]>, Group<f_Group>,
+ HelpText<"Fuzz selected compiler components, RISC-V only."
+ "Usage: --fuzz=\"<component1>[|<component2>...]\"">,
+ Values<"all, scheduler, mbb-placement, regalloc, isel, alloca, bpu">;
+
+def fseed_EQ : Joined<["--"], "fseed=">,
+ Flags<[NoXarchOption, HelpHidden]>, Group<f_Group>,
+ HelpText<"Specify fuzzing seed. (RISC-V only)">;
+
+def fseed_dump : Flag<["-"], "fseed-dump">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<sycl_Group>, HelpText<"Dump fuzz seed. (RISC-V only)">;
+
+def fno_fseed_dump : Flag<["-"], "fno-fseed-dump">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<sycl_Group>, HelpText<"Disable fuzz seed dump. (RISC-V only)">;
+
+def fuzz_stats_dump : Flag<["-"], "fuzz-stats-dump">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<sycl_Group>, HelpText<"Dump only fuzz statistics.">;
+
+def fno_fuzz_stats_dump : Flag<["-"], "fno-fuzz-stats-dump">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<sycl_Group>, HelpText<"Dump not only fuzz statistics.">;
+
//===----------------------------------------------------------------------===//
// FLangOption + NoXarchOption
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 0bab48caf1a5e2..563adaa813eb09 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7646,10 +7646,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Setup statistics file output.
SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
- if (!StatsFile.empty()) {
- CmdArgs.push_back(Args.MakeArgString(Twine("-stats-file=") + StatsFile));
- if (D.CCPrintInternalStats)
- CmdArgs.push_back("-stats-file-append");
+ auto FuzzStatsDump = Args.hasFlag(options::OPT_fuzz_stats_dump,
+ options::OPT_fno_fuzz_stats_dump, false);
+ if (!StatsFile.empty() || FuzzStatsDump) {
+ if (FuzzStatsDump) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-fuzz-only-stats");
+ }
+ if (StatsFile.empty()) {
+ StatsFile.assign(Output.getFilename());
+ llvm::sys::path::replace_extension(StatsFile, "stats");
+ }
}
// Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
@@ -8050,6 +8057,61 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Input.getInputArg().renderAsInput(Args, CmdArgs);
}
+ // Handle --fuzz=<fuzz options>
+ StringRef FuzzOptions = Args.getLastArgValue(options::OPT_fuzz_EQ).trim();
+ if (!FuzzOptions.empty()) {
+ auto Tail = FuzzOptions;
+ llvm::SmallVector<StringRef> ActualOpts;
+
+ do {
+ auto Pair = Tail.split('|');
+
+ StringRef Fst = Pair.first.trim();
+ Tail = Pair.second.trim();
+
+ if (!Fst.empty()) {
+ ActualOpts.push_back(Fst);
+ }
+ } while (!Tail.empty());
+
+ if (ActualOpts.empty()) {
+ D.Diag(diag::err_empty_option_value) << "fuzz";
+ }
+
+ llvm::SmallVector<StringRef> CorrectOpts = {
+ "all", "scheduler", "mbb-placement", "regalloc", "isel", "alloca", "bpu"};
+
+ for (const auto &ActualOpt : ActualOpts)
+ if (llvm::find(CorrectOpts, ActualOpt) == CorrectOpts.end())
+ D.Diag(diag::err_analyzer_checker_option_unknown)
+ << "fuzzer" << ActualOpt;
+
+ // Pass correct arguments to LLVM
+ CmdArgs.push_back("-mllvm");
+ std::string FuzzComponentsArgStr = "-fuzz-components=";
+ const char *FuzzComponentsArg =
+ Args.MakeArgStringRef(FuzzComponentsArgStr + FuzzOptions.data());
+ CmdArgs.push_back(FuzzComponentsArg);
+
+ StringRef FuzzSeedStr = Args.getLastArgValue(options::OPT_fseed_EQ).trim();
+ int64_t SeedValue;
+ if (FuzzSeedStr.empty() ||
+ FuzzSeedStr.getAsInteger<int64_t>(0, SeedValue)) {
+ SeedValue = std::chrono::system_clock::now().time_since_epoch().count();
+ }
+
+ auto StrSeed = std::to_string(SeedValue);
+
+ if (Args.hasFlag(options::OPT_fseed_dump, options::OPT_fno_fseed_dump,
+ false))
+ D.Diag(diag::warn_use_fseed) << StrSeed;
+
+ CmdArgs.push_back("-mllvm");
+ std::string FuzzSeedArgStr = "-fuzz-seed=";
+ const char *FuzzSeedArg = Args.MakeArgStringRef(FuzzSeedArgStr + StrSeed);
+ CmdArgs.push_back(FuzzSeedArg);
+ }
+
if (D.CC1Main && !D.CCGenDiagnostics) {
// Invoke the CC1 directly in this process
C.addCommand(std::make_unique<CC1Command>(
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 330db65e85cabb..5bcfc6cac475f4 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -1242,6 +1242,7 @@ endif()
# Put this before tblgen. Else we have a circular dependence.
add_subdirectory(lib/Demangle)
add_subdirectory(lib/Support)
+add_subdirectory(lib/CompilerAssistedFuzzing)
add_subdirectory(lib/TableGen)
add_subdirectory(utils/TableGen)
diff --git a/llvm/include/llvm/CompilerAssistedFuzzing/FuzzInfo.h b/llvm/include/llvm/CompilerAssistedFuzzing/FuzzInfo.h
new file mode 100644
index 00000000000000..1d2cf45103ba3a
--- /dev/null
+++ b/llvm/include/llvm/CompilerAssistedFuzzing/FuzzInfo.h
@@ -0,0 +1,44 @@
+#ifndef LLVM_FUZZINFO_H
+#define LLVM_FUZZINFO_H
+
+#include "llvm/ADT/Statistic.h"
+#include <functional>
+#include <string>
+#include <vector>
+
+namespace fuzz {
+using StatRefWrapper = std::reference_wrapper<llvm::TrackingStatistic>;
+
+class Component final {
+ std::string Name;
+ std::vector<StatRefWrapper> Stats;
+
+public:
+ Component(std::string &&n) noexcept : Name(std::move(n)) {}
+
+ Component &operator=(const Component &) = delete;
+ Component(const Component &) = delete;
+
+ Component &operator=(Component &&) = delete;
+ Component(Component &&) = delete;
+
+ const Component &operator+=(llvm::TrackingStatistic &Stat);
+ const std::string &GetName() const { return Name; }
+ const std::vector<StatRefWrapper> &GetStats() const { return Stats; }
+};
+
+extern Component Scheduler;
+extern Component MBBPlacement;
+extern Component RegAlloc;
+extern Component ISel;
+extern Component Alloca;
+extern Component BPU;
+
+bool isFuzzed(fuzz::Component &Comp, llvm::TrackingStatistic &Stat);
+int64_t fuzzedIntRange(fuzz::Component &Comp, llvm::TrackingStatistic &Stat,
+ int64_t Start, int64_t End, int64_t Default);
+
+bool CheckStat(const llvm::TrackingStatistic &Stat);
+} // namespace fuzz
+
+#endif // LLVM_FUZZINFO_H
diff --git a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
index 9f6e53ba15b6a6..40b028ca225125 100644
--- a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
+++ b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/BlockFrequency.h"
@@ -62,6 +63,13 @@ cl::opt<double> IterativeBFIPrecision(
"typically lead to better results at the cost of worsen runtime"));
} // namespace llvm
+static cl::opt<bool> BFIInverse("bfi-invert",
+ cl::desc("Force inverting of BFI values during computation."),
+ cl::init(false), cl::Hidden);
+
+ALWAYS_ENABLED_STATISTIC(NumInvertedBFI, "BFI: inverted frequences amount");
+
+
ScaledNumber<uint64_t> BlockMass::toScaled() const {
if (isFull())
return ScaledNumber<uint64_t>(1, 0);
@@ -554,6 +562,14 @@ void BlockFrequencyInfoImplBase::finalizeMetrics() {
Max = std::max(Max, Freqs[Index].Scaled);
}
+ if (BFIInverse) {
+ for (size_t Index = 0; Index < Working.size(); ++Index) {
+ Freqs[Index].Scaled = Max + Min - Freqs[Index].Scaled;
+ NumInvertedBFI++;
+ }
+ }
+
+
// Convert to integers.
convertFloatingToInteger(*this, Min, Max);
diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt
index 503c77cb13bd07..f8bbec50153c5e 100644
--- a/llvm/lib/CMakeLists.txt
+++ b/llvm/lib/CMakeLists.txt
@@ -1,6 +1,6 @@
include(LLVM-Build)
-# `Demangle', `Support' and `TableGen' libraries are added on the top-level
+# `CompilerAssistedFuzzing`, `Demangle', `Support' and `TableGen' libraries are added on the top-level
# CMakeLists.txt
add_subdirectory(IR)
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 5a17944db0ae03..ba573578a68887 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -270,6 +270,7 @@ add_llvm_component_library(LLVMCodeGen
BitWriter
CGData
CodeGenTypes
+ CompilerAssistedFuzzing
Core
MC
ObjCARC
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index a52c82d77ca644..0a9316ffeae0ce 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -48,6 +48,7 @@
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CompilerAssistedFuzzing/FuzzInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/PrintPasses.h"
@@ -84,6 +85,14 @@ STATISTIC(CondBranchTakenFreq,
STATISTIC(UncondBranchTakenFreq,
"Potential frequency of taking unconditional branches");
+ALWAYS_ENABLED_STATISTIC(NumHasBadCfgConflict, "Machine Basic Block Placement num of bad layout predecessors found");
+ALWAYS_ENABLED_STATISTIC(NumSingleSuccessorTailDup, "Machine Basic Block Placement: tail duplication if BB has a single successor");
+ALWAYS_ENABLED_STATISTIC(NumBestNonConflictingEdgesComparatorGet, "Machine Basic Block Placement: best non-conflicting edges comparator get");
+ALWAYS_ENABLED_STATISTIC(NumBestNonConflictingEdgesExchange, "Machine Basic Block Placement: best non-conflicting edges exchange");
+ALWAYS_ENABLED_STATISTIC(NumBestSuccessorCheck, "Machine Basic Block Placement: best successor search");
+ALWAYS_ENABLED_STATISTIC(NumSuitableTailDupCheck, "Machine Basic Block Placement: best candidate for tail dup check");
+ALWAYS_ENABLED_STATISTIC(NumSelectBestCandidateBlock, "Machine Basic Block Placement: best candidate block selection");
+
static cl::opt<unsigned> AlignAllBlock(
"align-all-blocks",
cl::desc("Force the alignment of all blocks in the function in log2 format "
@@ -799,7 +808,7 @@ bool MachineBlockPlacement::shouldTailDuplicate(MachineBasicBlock *BB) {
bool IsSimple = TailDup.isSimpleBB(BB);
if (BB->succ_size() == 1)
- return false;
+ return isFuzzed(fuzz::BPU, NumSingleSuccessorTailDup); // return false;
return TailDup.shouldTailDuplicate(IsSimple, *BB);
}
@@ -1037,7 +1046,7 @@ MachineBlockPlacement::getBestNonConflictingEdges(
// compare which combination is better overall.
// Sort for highest frequency.
- auto Cmp = [](WeightedEdge A, WeightedEdge B) { return A.Weight > B.Weight; };
+ auto Cmp = isFuzzed(fuzz::BPU, NumBestNonConflictingEdgesComparatorGet) ? [](WeightedEdge A, WeightedEdge B) { return A.Weight < B.Weight; } : [](WeightedEdge A, WeightedEdge B) { return A.Weight > B.Weight; };
llvm::stable_sort(Edges[0], Cmp);
llvm::stable_sort(Edges[1], Cmp);
@@ -1051,10 +1060,18 @@ MachineBlockPlacement::getBestNonConflictingEdges(
auto SecondBestB = std::next(BestB);
BlockFrequency BestAScore = BestA->Weight + SecondBestB->Weight;
BlockFrequency BestBScore = BestB->Weight + SecondBestA->Weight;
- if (BestAScore < BestBScore)
- BestA = SecondBestA;
- else
- BestB = SecondBestB;
+
+ if (isFuzzed(fuzz::BPU, NumBestNonConflictingEdgesExchange)) {
+ if (BestAScore > BestBScore)
+ BestA = SecondBestA;
+ else
+ BestB = SecondBestB;
+ } else {
+ if (BestAScore < BestBScore)
+ BestA = SecondBestA;
+ else
+ BestB = SecondBestB;
+ }
}
// Arrange for the BB edge to be in BestA if it exists.
if (BestB->Src == BB)
@@ -1576,7 +1593,9 @@ bool MachineBlockPlacement::hasBetterLayoutPredecessor(
BlockFrequency PredEdgeFreq =
MBFI->getBlockFreq(Pred) * MBPI->getEdgeProbability(Pred, Succ);
if (PredEdgeFreq * HotProb >= CandidateEdgeFreq * HotProb.getCompl()) {
- BadCFGConflict = true;
+ if (!isFuzzed(fuzz::BPU, NumHasBadCfgConflict)) {
+ BadCFGConflict = true;
+ }
break;
}
}
@@ -1661,9 +1680,16 @@ MachineBlockPlacement::selectBestSuccessor(const MachineBasicBlock *BB,
<< (SuccChain.UnscheduledPredecessors != 0 ? " (CFG break)" : "")
<< "\n");
- if (BestSucc.BB && BestProb >= SuccProb) {
- LLVM_DEBUG(dbgs() << " Not the best candidate, continuing\n");
- continue;
+ if (isFuzzed(fuzz::BPU, NumBestSuccessorCheck)) {
+ if (BestSucc.BB && BestProb <= SuccProb) {
+ LLVM_DEBUG(dbgs() << " Not the worst candidate, continuing\n");
+ continue;
+ }
+ } else {
+ if (BestSucc.BB && BestProb >= SuccProb) {
+ LLVM_DEBUG(dbgs() << " Not the best candidate, continuing\n");
+ continue;
+ }
}
LLVM_DEBUG(dbgs() << " Setting it as best candidate\n");
@@ -1684,7 +1710,7 @@ MachineBlockPlacement::selectBestSuccessor(const MachineBasicBlock *BB,
BranchProbability DupProb;
MachineBasicBlock *Succ;
std::tie(DupProb, Succ) = Tup;
- if (DupProb < BestProb)
+ if (DupProb < BestProb && !isFuzzed(fuzz::BPU, NumSuitableTailDupCheck))
break;
if (canTailDuplicateUnplacedPreds(BB, Succ, Chain, BlockFilter) &&
(isProfitableToTailDup(BB, Succ, BestProb, Chain, BlockFilter))) {
@@ -1764,8 +1790,13 @@ MachineBasicBlock *MachineBlockPlacement::selectBestCandidateBlock(
// +-------------------------------------+
// V |
// OuterLp -> OuterCleanup -> Resume InnerLp -> InnerCleanup
- if (BestBlock && (IsEHPad ^ (BestFreq >= CandidateFreq)))
- continue;
+ if (isFuzzed(fuzz::BPU, NumSelectBestCandidateBlock)) {
+ if (BestBlock && (IsEHPad ^ (BestFreq <= CandidateFreq)))
+ continue;
+ } else {
+ if (BestBlock && (IsEHPad ^ (BestFreq >= CandidateFreq)))
+ continue;
+ }
BestBlock = MBB;
BestFreq = CandidateFreq;
diff --git a/llvm/lib/CompilerAssistedFuzzing/CMakeLists.txt b/llvm/lib/CompilerAssistedFuzzing/CMakeLists.txt
new file mode 100644
index 00000000000000..25e8eba2eeb871
--- /dev/null
+++ b/llvm/lib/CompilerAssistedFuzzing/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_llvm_component_library(LLVMCompilerAssistedFuzzing
+ FuzzInfo.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ "${LLVM_MAIN_INCLUDE_DIR}/llvm/CompilerAssistedFuzzing"
+
+ LINK_COMPONENTS
+ Support
+)
diff --git a/llvm/lib/CompilerAssistedFuzzing/FuzzInfo.cpp b/llvm/lib/CompilerAssistedFuzzing/FuzzInfo.cpp
new file mode 100644
index 00000000000000..17df4e399299ce
--- /dev/null
+++ b/llvm/lib/CompilerAssistedFuzzing/FuzzInfo.cpp
@@ -0,0 +1,82 @@
+#include "llvm/CompilerAssistedFuzzing/FuzzInfo.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <cassert>
+#include <cmath>
+
+#define DEBUG_TYPE "fuzz"
+
+using namespace llvm;
+
+std::string FuzzComponents;
+static cl::opt<std::string, true>
+ FuzzingComponents("fuzz-components",
+ cl::desc("Compiler components to fuzz."),
+ cl::location(FuzzComponents), cl::init(""));
+
+int64_t FuzzSeed;
+static cl::opt<int64_t, true> FuzzingSeed("fuzz-seed",
+ cl::desc("Compiler fuzzing seed."),
+ cl::location(FuzzSeed), cl::init(0));
+
+using fuzz::Component;
+
+Component fuzz::Scheduler("scheduler");
+Component fuzz::MBBPlacement("mbb-placement");
+Component fuzz::BPU("bpu");
+Component fuzz::RegAlloc("regalloc");
+Component fuzz::ISel("isel");
+Component fuzz::Alloca("alloca");
+std::array<std::reference_wrapper<Component>, 6> Components{
+ fuzz::Scheduler, fuzz::MBBPlacement, fuzz::RegAlloc, fuzz::ISel,
+ fuzz::Alloca, fuzz::BPU};
+
+inline bool isCompUsed(const Component &Comp) {
+ if (FuzzComponents.find("all") != std::string::npos)
+ return true;
+
+ return FuzzComponents.find(Comp.GetName()) != std::string::npos;
+}
+
+const Component &Component::operator+=(llvm::TrackingStatistic &Stat) {
+ if (llvm::find_if(Stats, [&Stat](const fuzz::StatRefWrapper &St) -> bool {
+ return St.get().getName() == Stat.getName();
+ }) == Stats.end()) {
+ Stats.emplace_back(Stat);
+ }
+ Stat++;
+ return *this;
+}
+
+bool fuzz::isFuzzed(Component &Comp, llvm::TrackingStatistic &Stat) {
+ if (isCompUsed(Comp)) {
+ Comp += Stat;
+ return true;
+ }
+
+ return false;
+}
+
+int64_t fuzz::fuzzedIntRange(Component &Comp, llvm::TrackingStatistic &Stat,
+ int64_t Start, int64_t End, int64_t Default) {
+ if (!isFuzzed(Comp, Stat)) {
+ return Default;
+ }
+
+ int64_t Length = End - Start;
+ assert(Length > 0 && "Length must be non negative");
+
+ return (std::abs(FuzzSeed) % Length) + Start;
+}
+
+bool fuzz::CheckStat(const llvm::TrackingStatistic &Stat) {
+ for (const auto &C : Components) {
+ for (const auto &St : C.get().GetStats()) {
+ if (Stat.getName() == St.get().getName())
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 97188b0672f032..ee7df40ba1de5c 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -299,6 +299,7 @@ add_llvm_component_library(LLVMSupport
LINK_COMPONENTS
Demangle
+ CompilerAssistedFuzzing
)
set(llvm_system_libs ${system_libs})
diff --git a/llvm/lib/Support/Statistic.cpp b/llvm/lib/Support/Statistic.cpp
index 24ef3e9abaebce..7961a68adc0c56 100644
--- a/llvm/lib/Support/Statistic.cpp
+++ b/llvm/lib/Support/Statistic.cpp
@@ -25,6 +25,7 @@
#include "DebugOptions.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/CompilerAssistedFuzzing/FuzzInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
@@ -45,6 +46,7 @@ static bool EnableStats;
static bool StatsAsJSON;
static bool Enabled;
static bool PrintOnExit;
+static bool FuzzOnlyStats;
void llvm::initStatisticOptions() {
static cl::opt<bool, true> registerEnableStats{
@@ -55,6 +57,9 @@ void llvm::initStatisticOptions() {
static cl::opt<bool, true> registerStatsAsJson{
"stats-json", cl::desc("Display statistics as json data"),
cl::location(StatsAsJSON), cl::Hidden};
+ static cl::opt<bool, true> registerFuzzOnlyStats{
+ "fuzz-only-stats", cl::desc("Dump only fuzz stats."),
+ cl::location(FuzzOnlyStats), cl::Hidden};
}
namespace {
@@ -173,6 +178,14 @@ void StatisticInfo::reset() {
Stats.clear();
}
+static bool isPrintValid(const TrackingStatistic *Stat) {
+ if (!FuzzOnlyStats) {
+ return true;
+ }
+
+ return fuzz::CheckStat(*Stat);
+}
+
void llvm::PrintStatistics(raw_ostream &OS) {
StatisticInfo &Stats = *StatInfo;...
[truncated]
|
|
@llvm/pr-subscribers-llvm-analysis Author: Dmitriy Sokolov (dee-tree) Changes
Patch is 20.87 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/116492.diff 13 Files Affected:
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 97573fcf20c1fb..73766d45c29a58 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -826,6 +826,12 @@ def warn_android_unversioned_fallback : Warning<
def err_drv_triple_version_invalid : Error<
"version '%0' in target triple '%1' is invalid">;
+def err_empty_option_value : Error<
+ "empty value for %0 option">;
+
+def warn_use_fseed : Warning<"fuzzing with seed: %0">,
+ InGroup<DiagGroup<"fuzzing">>;
+
def warn_missing_include_dirs : Warning<
"no such include directory: '%0'">, InGroup<MissingIncludeDirs>, DefaultIgnore;
}
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 23bd686a85f526..502826ff325524 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6730,6 +6730,33 @@ let Flags = [TargetSpecific] in {
defm android_pad_segment : BooleanFFlag<"android-pad-segment">, Group<f_Group>;
} // let Flags = [TargetSpecific]
+// Compiler-assisted fuzzing options
+def fuzz_EQ : Joined<["--"], "fuzz=">,
+ Flags<[NoXarchOption, HelpHidden]>, Group<f_Group>,
+ HelpText<"Fuzz selected compiler components, RISC-V only."
+ "Usage: --fuzz=\"<component1>[|<component2>...]\"">,
+ Values<"all, scheduler, mbb-placement, regalloc, isel, alloca, bpu">;
+
+def fseed_EQ : Joined<["--"], "fseed=">,
+ Flags<[NoXarchOption, HelpHidden]>, Group<f_Group>,
+ HelpText<"Specify fuzzing seed. (RISC-V only)">;
+
+def fseed_dump : Flag<["-"], "fseed-dump">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<sycl_Group>, HelpText<"Dump fuzz seed. (RISC-V only)">;
+
+def fno_fseed_dump : Flag<["-"], "fno-fseed-dump">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<sycl_Group>, HelpText<"Disable fuzz seed dump. (RISC-V only)">;
+
+def fuzz_stats_dump : Flag<["-"], "fuzz-stats-dump">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<sycl_Group>, HelpText<"Dump only fuzz statistics.">;
+
+def fno_fuzz_stats_dump : Flag<["-"], "fno-fuzz-stats-dump">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<sycl_Group>, HelpText<"Dump not only fuzz statistics.">;
+
//===----------------------------------------------------------------------===//
// FLangOption + NoXarchOption
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 0bab48caf1a5e2..563adaa813eb09 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7646,10 +7646,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Setup statistics file output.
SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
- if (!StatsFile.empty()) {
- CmdArgs.push_back(Args.MakeArgString(Twine("-stats-file=") + StatsFile));
- if (D.CCPrintInternalStats)
- CmdArgs.push_back("-stats-file-append");
+ auto FuzzStatsDump = Args.hasFlag(options::OPT_fuzz_stats_dump,
+ options::OPT_fno_fuzz_stats_dump, false);
+ if (!StatsFile.empty() || FuzzStatsDump) {
+ if (FuzzStatsDump) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-fuzz-only-stats");
+ }
+ if (StatsFile.empty()) {
+ StatsFile.assign(Output.getFilename());
+ llvm::sys::path::replace_extension(StatsFile, "stats");
+ }
}
// Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
@@ -8050,6 +8057,61 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Input.getInputArg().renderAsInput(Args, CmdArgs);
}
+ // Handle --fuzz=<fuzz options>
+ StringRef FuzzOptions = Args.getLastArgValue(options::OPT_fuzz_EQ).trim();
+ if (!FuzzOptions.empty()) {
+ auto Tail = FuzzOptions;
+ llvm::SmallVector<StringRef> ActualOpts;
+
+ do {
+ auto Pair = Tail.split('|');
+
+ StringRef Fst = Pair.first.trim();
+ Tail = Pair.second.trim();
+
+ if (!Fst.empty()) {
+ ActualOpts.push_back(Fst);
+ }
+ } while (!Tail.empty());
+
+ if (ActualOpts.empty()) {
+ D.Diag(diag::err_empty_option_value) << "fuzz";
+ }
+
+ llvm::SmallVector<StringRef> CorrectOpts = {
+ "all", "scheduler", "mbb-placement", "regalloc", "isel", "alloca", "bpu"};
+
+ for (const auto &ActualOpt : ActualOpts)
+ if (llvm::find(CorrectOpts, ActualOpt) == CorrectOpts.end())
+ D.Diag(diag::err_analyzer_checker_option_unknown)
+ << "fuzzer" << ActualOpt;
+
+ // Pass correct arguments to LLVM
+ CmdArgs.push_back("-mllvm");
+ std::string FuzzComponentsArgStr = "-fuzz-components=";
+ const char *FuzzComponentsArg =
+ Args.MakeArgStringRef(FuzzComponentsArgStr + FuzzOptions.data());
+ CmdArgs.push_back(FuzzComponentsArg);
+
+ StringRef FuzzSeedStr = Args.getLastArgValue(options::OPT_fseed_EQ).trim();
+ int64_t SeedValue;
+ if (FuzzSeedStr.empty() ||
+ FuzzSeedStr.getAsInteger<int64_t>(0, SeedValue)) {
+ SeedValue = std::chrono::system_clock::now().time_since_epoch().count();
+ }
+
+ auto StrSeed = std::to_string(SeedValue);
+
+ if (Args.hasFlag(options::OPT_fseed_dump, options::OPT_fno_fseed_dump,
+ false))
+ D.Diag(diag::warn_use_fseed) << StrSeed;
+
+ CmdArgs.push_back("-mllvm");
+ std::string FuzzSeedArgStr = "-fuzz-seed=";
+ const char *FuzzSeedArg = Args.MakeArgStringRef(FuzzSeedArgStr + StrSeed);
+ CmdArgs.push_back(FuzzSeedArg);
+ }
+
if (D.CC1Main && !D.CCGenDiagnostics) {
// Invoke the CC1 directly in this process
C.addCommand(std::make_unique<CC1Command>(
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 330db65e85cabb..5bcfc6cac475f4 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -1242,6 +1242,7 @@ endif()
# Put this before tblgen. Else we have a circular dependence.
add_subdirectory(lib/Demangle)
add_subdirectory(lib/Support)
+add_subdirectory(lib/CompilerAssistedFuzzing)
add_subdirectory(lib/TableGen)
add_subdirectory(utils/TableGen)
diff --git a/llvm/include/llvm/CompilerAssistedFuzzing/FuzzInfo.h b/llvm/include/llvm/CompilerAssistedFuzzing/FuzzInfo.h
new file mode 100644
index 00000000000000..1d2cf45103ba3a
--- /dev/null
+++ b/llvm/include/llvm/CompilerAssistedFuzzing/FuzzInfo.h
@@ -0,0 +1,44 @@
+#ifndef LLVM_FUZZINFO_H
+#define LLVM_FUZZINFO_H
+
+#include "llvm/ADT/Statistic.h"
+#include <functional>
+#include <string>
+#include <vector>
+
+namespace fuzz {
+using StatRefWrapper = std::reference_wrapper<llvm::TrackingStatistic>;
+
+class Component final {
+ std::string Name;
+ std::vector<StatRefWrapper> Stats;
+
+public:
+ Component(std::string &&n) noexcept : Name(std::move(n)) {}
+
+ Component &operator=(const Component &) = delete;
+ Component(const Component &) = delete;
+
+ Component &operator=(Component &&) = delete;
+ Component(Component &&) = delete;
+
+ const Component &operator+=(llvm::TrackingStatistic &Stat);
+ const std::string &GetName() const { return Name; }
+ const std::vector<StatRefWrapper> &GetStats() const { return Stats; }
+};
+
+extern Component Scheduler;
+extern Component MBBPlacement;
+extern Component RegAlloc;
+extern Component ISel;
+extern Component Alloca;
+extern Component BPU;
+
+bool isFuzzed(fuzz::Component &Comp, llvm::TrackingStatistic &Stat);
+int64_t fuzzedIntRange(fuzz::Component &Comp, llvm::TrackingStatistic &Stat,
+ int64_t Start, int64_t End, int64_t Default);
+
+bool CheckStat(const llvm::TrackingStatistic &Stat);
+} // namespace fuzz
+
+#endif // LLVM_FUZZINFO_H
diff --git a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
index 9f6e53ba15b6a6..40b028ca225125 100644
--- a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
+++ b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/BlockFrequency.h"
@@ -62,6 +63,13 @@ cl::opt<double> IterativeBFIPrecision(
"typically lead to better results at the cost of worsen runtime"));
} // namespace llvm
+static cl::opt<bool> BFIInverse("bfi-invert",
+ cl::desc("Force inverting of BFI values during computation."),
+ cl::init(false), cl::Hidden);
+
+ALWAYS_ENABLED_STATISTIC(NumInvertedBFI, "BFI: inverted frequences amount");
+
+
ScaledNumber<uint64_t> BlockMass::toScaled() const {
if (isFull())
return ScaledNumber<uint64_t>(1, 0);
@@ -554,6 +562,14 @@ void BlockFrequencyInfoImplBase::finalizeMetrics() {
Max = std::max(Max, Freqs[Index].Scaled);
}
+ if (BFIInverse) {
+ for (size_t Index = 0; Index < Working.size(); ++Index) {
+ Freqs[Index].Scaled = Max + Min - Freqs[Index].Scaled;
+ NumInvertedBFI++;
+ }
+ }
+
+
// Convert to integers.
convertFloatingToInteger(*this, Min, Max);
diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt
index 503c77cb13bd07..f8bbec50153c5e 100644
--- a/llvm/lib/CMakeLists.txt
+++ b/llvm/lib/CMakeLists.txt
@@ -1,6 +1,6 @@
include(LLVM-Build)
-# `Demangle', `Support' and `TableGen' libraries are added on the top-level
+# `CompilerAssistedFuzzing`, `Demangle', `Support' and `TableGen' libraries are added on the top-level
# CMakeLists.txt
add_subdirectory(IR)
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 5a17944db0ae03..ba573578a68887 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -270,6 +270,7 @@ add_llvm_component_library(LLVMCodeGen
BitWriter
CGData
CodeGenTypes
+ CompilerAssistedFuzzing
Core
MC
ObjCARC
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index a52c82d77ca644..0a9316ffeae0ce 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -48,6 +48,7 @@
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CompilerAssistedFuzzing/FuzzInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/PrintPasses.h"
@@ -84,6 +85,14 @@ STATISTIC(CondBranchTakenFreq,
STATISTIC(UncondBranchTakenFreq,
"Potential frequency of taking unconditional branches");
+ALWAYS_ENABLED_STATISTIC(NumHasBadCfgConflict, "Machine Basic Block Placement num of bad layout predecessors found");
+ALWAYS_ENABLED_STATISTIC(NumSingleSuccessorTailDup, "Machine Basic Block Placement: tail duplication if BB has a single successor");
+ALWAYS_ENABLED_STATISTIC(NumBestNonConflictingEdgesComparatorGet, "Machine Basic Block Placement: best non-conflicting edges comparator get");
+ALWAYS_ENABLED_STATISTIC(NumBestNonConflictingEdgesExchange, "Machine Basic Block Placement: best non-conflicting edges exchange");
+ALWAYS_ENABLED_STATISTIC(NumBestSuccessorCheck, "Machine Basic Block Placement: best successor search");
+ALWAYS_ENABLED_STATISTIC(NumSuitableTailDupCheck, "Machine Basic Block Placement: best candidate for tail dup check");
+ALWAYS_ENABLED_STATISTIC(NumSelectBestCandidateBlock, "Machine Basic Block Placement: best candidate block selection");
+
static cl::opt<unsigned> AlignAllBlock(
"align-all-blocks",
cl::desc("Force the alignment of all blocks in the function in log2 format "
@@ -799,7 +808,7 @@ bool MachineBlockPlacement::shouldTailDuplicate(MachineBasicBlock *BB) {
bool IsSimple = TailDup.isSimpleBB(BB);
if (BB->succ_size() == 1)
- return false;
+ return isFuzzed(fuzz::BPU, NumSingleSuccessorTailDup); // return false;
return TailDup.shouldTailDuplicate(IsSimple, *BB);
}
@@ -1037,7 +1046,7 @@ MachineBlockPlacement::getBestNonConflictingEdges(
// compare which combination is better overall.
// Sort for highest frequency.
- auto Cmp = [](WeightedEdge A, WeightedEdge B) { return A.Weight > B.Weight; };
+ auto Cmp = isFuzzed(fuzz::BPU, NumBestNonConflictingEdgesComparatorGet) ? [](WeightedEdge A, WeightedEdge B) { return A.Weight < B.Weight; } : [](WeightedEdge A, WeightedEdge B) { return A.Weight > B.Weight; };
llvm::stable_sort(Edges[0], Cmp);
llvm::stable_sort(Edges[1], Cmp);
@@ -1051,10 +1060,18 @@ MachineBlockPlacement::getBestNonConflictingEdges(
auto SecondBestB = std::next(BestB);
BlockFrequency BestAScore = BestA->Weight + SecondBestB->Weight;
BlockFrequency BestBScore = BestB->Weight + SecondBestA->Weight;
- if (BestAScore < BestBScore)
- BestA = SecondBestA;
- else
- BestB = SecondBestB;
+
+ if (isFuzzed(fuzz::BPU, NumBestNonConflictingEdgesExchange)) {
+ if (BestAScore > BestBScore)
+ BestA = SecondBestA;
+ else
+ BestB = SecondBestB;
+ } else {
+ if (BestAScore < BestBScore)
+ BestA = SecondBestA;
+ else
+ BestB = SecondBestB;
+ }
}
// Arrange for the BB edge to be in BestA if it exists.
if (BestB->Src == BB)
@@ -1576,7 +1593,9 @@ bool MachineBlockPlacement::hasBetterLayoutPredecessor(
BlockFrequency PredEdgeFreq =
MBFI->getBlockFreq(Pred) * MBPI->getEdgeProbability(Pred, Succ);
if (PredEdgeFreq * HotProb >= CandidateEdgeFreq * HotProb.getCompl()) {
- BadCFGConflict = true;
+ if (!isFuzzed(fuzz::BPU, NumHasBadCfgConflict)) {
+ BadCFGConflict = true;
+ }
break;
}
}
@@ -1661,9 +1680,16 @@ MachineBlockPlacement::selectBestSuccessor(const MachineBasicBlock *BB,
<< (SuccChain.UnscheduledPredecessors != 0 ? " (CFG break)" : "")
<< "\n");
- if (BestSucc.BB && BestProb >= SuccProb) {
- LLVM_DEBUG(dbgs() << " Not the best candidate, continuing\n");
- continue;
+ if (isFuzzed(fuzz::BPU, NumBestSuccessorCheck)) {
+ if (BestSucc.BB && BestProb <= SuccProb) {
+ LLVM_DEBUG(dbgs() << " Not the worst candidate, continuing\n");
+ continue;
+ }
+ } else {
+ if (BestSucc.BB && BestProb >= SuccProb) {
+ LLVM_DEBUG(dbgs() << " Not the best candidate, continuing\n");
+ continue;
+ }
}
LLVM_DEBUG(dbgs() << " Setting it as best candidate\n");
@@ -1684,7 +1710,7 @@ MachineBlockPlacement::selectBestSuccessor(const MachineBasicBlock *BB,
BranchProbability DupProb;
MachineBasicBlock *Succ;
std::tie(DupProb, Succ) = Tup;
- if (DupProb < BestProb)
+ if (DupProb < BestProb && !isFuzzed(fuzz::BPU, NumSuitableTailDupCheck))
break;
if (canTailDuplicateUnplacedPreds(BB, Succ, Chain, BlockFilter) &&
(isProfitableToTailDup(BB, Succ, BestProb, Chain, BlockFilter))) {
@@ -1764,8 +1790,13 @@ MachineBasicBlock *MachineBlockPlacement::selectBestCandidateBlock(
// +-------------------------------------+
// V |
// OuterLp -> OuterCleanup -> Resume InnerLp -> InnerCleanup
- if (BestBlock && (IsEHPad ^ (BestFreq >= CandidateFreq)))
- continue;
+ if (isFuzzed(fuzz::BPU, NumSelectBestCandidateBlock)) {
+ if (BestBlock && (IsEHPad ^ (BestFreq <= CandidateFreq)))
+ continue;
+ } else {
+ if (BestBlock && (IsEHPad ^ (BestFreq >= CandidateFreq)))
+ continue;
+ }
BestBlock = MBB;
BestFreq = CandidateFreq;
diff --git a/llvm/lib/CompilerAssistedFuzzing/CMakeLists.txt b/llvm/lib/CompilerAssistedFuzzing/CMakeLists.txt
new file mode 100644
index 00000000000000..25e8eba2eeb871
--- /dev/null
+++ b/llvm/lib/CompilerAssistedFuzzing/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_llvm_component_library(LLVMCompilerAssistedFuzzing
+ FuzzInfo.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ "${LLVM_MAIN_INCLUDE_DIR}/llvm/CompilerAssistedFuzzing"
+
+ LINK_COMPONENTS
+ Support
+)
diff --git a/llvm/lib/CompilerAssistedFuzzing/FuzzInfo.cpp b/llvm/lib/CompilerAssistedFuzzing/FuzzInfo.cpp
new file mode 100644
index 00000000000000..17df4e399299ce
--- /dev/null
+++ b/llvm/lib/CompilerAssistedFuzzing/FuzzInfo.cpp
@@ -0,0 +1,82 @@
+#include "llvm/CompilerAssistedFuzzing/FuzzInfo.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <cassert>
+#include <cmath>
+
+#define DEBUG_TYPE "fuzz"
+
+using namespace llvm;
+
+std::string FuzzComponents;
+static cl::opt<std::string, true>
+ FuzzingComponents("fuzz-components",
+ cl::desc("Compiler components to fuzz."),
+ cl::location(FuzzComponents), cl::init(""));
+
+int64_t FuzzSeed;
+static cl::opt<int64_t, true> FuzzingSeed("fuzz-seed",
+ cl::desc("Compiler fuzzing seed."),
+ cl::location(FuzzSeed), cl::init(0));
+
+using fuzz::Component;
+
+Component fuzz::Scheduler("scheduler");
+Component fuzz::MBBPlacement("mbb-placement");
+Component fuzz::BPU("bpu");
+Component fuzz::RegAlloc("regalloc");
+Component fuzz::ISel("isel");
+Component fuzz::Alloca("alloca");
+std::array<std::reference_wrapper<Component>, 6> Components{
+ fuzz::Scheduler, fuzz::MBBPlacement, fuzz::RegAlloc, fuzz::ISel,
+ fuzz::Alloca, fuzz::BPU};
+
+inline bool isCompUsed(const Component &Comp) {
+ if (FuzzComponents.find("all") != std::string::npos)
+ return true;
+
+ return FuzzComponents.find(Comp.GetName()) != std::string::npos;
+}
+
+const Component &Component::operator+=(llvm::TrackingStatistic &Stat) {
+ if (llvm::find_if(Stats, [&Stat](const fuzz::StatRefWrapper &St) -> bool {
+ return St.get().getName() == Stat.getName();
+ }) == Stats.end()) {
+ Stats.emplace_back(Stat);
+ }
+ Stat++;
+ return *this;
+}
+
+bool fuzz::isFuzzed(Component &Comp, llvm::TrackingStatistic &Stat) {
+ if (isCompUsed(Comp)) {
+ Comp += Stat;
+ return true;
+ }
+
+ return false;
+}
+
+int64_t fuzz::fuzzedIntRange(Component &Comp, llvm::TrackingStatistic &Stat,
+ int64_t Start, int64_t End, int64_t Default) {
+ if (!isFuzzed(Comp, Stat)) {
+ return Default;
+ }
+
+ int64_t Length = End - Start;
+ assert(Length > 0 && "Length must be non negative");
+
+ return (std::abs(FuzzSeed) % Length) + Start;
+}
+
+bool fuzz::CheckStat(const llvm::TrackingStatistic &Stat) {
+ for (const auto &C : Components) {
+ for (const auto &St : C.get().GetStats()) {
+ if (Stat.getName() == St.get().getName())
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 97188b0672f032..ee7df40ba1de5c 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -299,6 +299,7 @@ add_llvm_component_library(LLVMSupport
LINK_COMPONENTS
Demangle
+ CompilerAssistedFuzzing
)
set(llvm_system_libs ${system_libs})
diff --git a/llvm/lib/Support/Statistic.cpp b/llvm/lib/Support/Statistic.cpp
index 24ef3e9abaebce..7961a68adc0c56 100644
--- a/llvm/lib/Support/Statistic.cpp
+++ b/llvm/lib/Support/Statistic.cpp
@@ -25,6 +25,7 @@
#include "DebugOptions.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/CompilerAssistedFuzzing/FuzzInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
@@ -45,6 +46,7 @@ static bool EnableStats;
static bool StatsAsJSON;
static bool Enabled;
static bool PrintOnExit;
+static bool FuzzOnlyStats;
void llvm::initStatisticOptions() {
static cl::opt<bool, true> registerEnableStats{
@@ -55,6 +57,9 @@ void llvm::initStatisticOptions() {
static cl::opt<bool, true> registerStatsAsJson{
"stats-json", cl::desc("Display statistics as json data"),
cl::location(StatsAsJSON), cl::Hidden};
+ static cl::opt<bool, true> registerFuzzOnlyStats{
+ "fuzz-only-stats", cl::desc("Dump only fuzz stats."),
+ cl::location(FuzzOnlyStats), cl::Hidden};
}
namespace {
@@ -173,6 +178,14 @@ void StatisticInfo::reset() {
Stats.clear();
}
+static bool isPrintValid(const TrackingStatistic *Stat) {
+ if (!FuzzOnlyStats) {
+ return true;
+ }
+
+ return fuzz::CheckStat(*Stat);
+}
+
void llvm::PrintStatistics(raw_ostream &OS) {
StatisticInfo &Stats = *StatInfo;...
[truncated]
|
Do not consider this PR seriously
It should be open in the local fork as part of research.