Jeremy Morse 40f9bb9e25
[DebugInfo][RemoveDIs] Eliminate another debug-info variation flag (#133917)
The "preserve input debug-info format" flag allowed some tooling to opt
into not seeing the new debug records yet, and to not autoupgrade. This
was good at the time, but un-necessary now that we'll be ditching
intrinsics shortly.

It also hides errors now: verify-uselistorder was hardcoding this flag
to on, and as a result it hasn't seen debug records before. Thus, we
missed a uselistorder variation: constant-expressions such as GEPs can
be contained within debug records and completely isolated from the value
hierachy, see the metadata-use-uselistorder.ll test. These Values didn't
get ordered, but were legitimate uses of constants like "i64 0", and we
now run into difficulty handling that. The patch to AsmWriter seeks
Values to order even through debug-info now.

Finally there are a few intrinsics-tests relying on this flag that we
can just delete, such as one in llvm-reduce and another few in the
LocalTest unit tests. For the fast-isel test, it was added in
https://reviews.llvm.org/D67703 explicitly for checking the size of
blocks without debug-info and in 1525abb9c94 the codepath it tests moved
towards being sunsetted. It'll be totally redundant once RemoveDIs is on
permanently.

Note that there's now no explicit test for the textual-IR autoupgrade
path. I submit that we can rely on the thousands of .ll files where
we've only been bothered to update the outputs, not the inputs, to debug
records.
2025-04-09 18:00:28 +01:00

217 lines
7.4 KiB
C++

//===- llvm-reduce.cpp - The LLVM Delta Reduction utility -----------------===//
//
// 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 program tries to reduce an IR test case for a given interesting-ness
// test. It runs multiple delta debugging passes in order to minimize the input
// file. It's worth noting that this is a part of the bugpoint redesign
// proposal, and thus a *temporary* tool that will eventually be integrated
// into the bugpoint tool itself.
//
//===----------------------------------------------------------------------===//
#include "DeltaManager.h"
#include "ReducerWorkItem.h"
#include "TestRunner.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBufferRef.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <system_error>
#ifdef _WIN32
#include <windows.h>
#endif
using namespace llvm;
cl::OptionCategory LLVMReduceOptions("llvm-reduce options");
static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden,
cl::cat(LLVMReduceOptions));
static cl::opt<bool> Version("v", cl::desc("Alias for -version"), cl::Hidden,
cl::cat(LLVMReduceOptions));
static cl::opt<bool> PreserveDebugEnvironment(
"preserve-debug-environment",
cl::desc("Don't disable features used for crash "
"debugging (crash reports, llvm-symbolizer and core dumps)"),
cl::cat(LLVMReduceOptions));
static cl::opt<bool>
PrintDeltaPasses("print-delta-passes",
cl::desc("Print list of delta passes, passable to "
"--delta-passes as a comma separated list"),
cl::cat(LLVMReduceOptions));
static cl::opt<std::string> InputFilename(cl::Positional,
cl::desc("<input llvm ll/bc file>"),
cl::cat(LLVMReduceOptions));
static cl::opt<std::string>
TestFilename("test",
cl::desc("Name of the interesting-ness test to be run"),
cl::cat(LLVMReduceOptions));
static cl::list<std::string>
TestArguments("test-arg",
cl::desc("Arguments passed onto the interesting-ness test"),
cl::cat(LLVMReduceOptions));
static cl::opt<std::string> OutputFilename(
"output",
cl::desc("Specify the output file. default: reduced.ll|.bc|.mir"));
static cl::alias OutputFileAlias("o", cl::desc("Alias for -output"),
cl::aliasopt(OutputFilename),
cl::cat(LLVMReduceOptions));
static cl::opt<bool>
ReplaceInput("in-place",
cl::desc("WARNING: This option will replace your input file "
"with the reduced version!"),
cl::cat(LLVMReduceOptions));
enum class InputLanguages { None, IR, MIR };
static cl::opt<InputLanguages>
InputLanguage("x", cl::ValueOptional,
cl::desc("Input language ('ir' or 'mir')"),
cl::init(InputLanguages::None),
cl::values(clEnumValN(InputLanguages::IR, "ir", ""),
clEnumValN(InputLanguages::MIR, "mir", "")),
cl::cat(LLVMReduceOptions));
static cl::opt<bool> ForceOutputBitcode(
"output-bitcode",
cl::desc("Emit final result as bitcode instead of text IR"), cl::Hidden,
cl::cat(LLVMReduceOptions));
static cl::opt<int>
MaxPassIterations("max-pass-iterations",
cl::desc("Maximum number of times to run the full set "
"of delta passes (default=5)"),
cl::init(5), cl::cat(LLVMReduceOptions));
static codegen::RegisterCodeGenFlags CGF;
/// Turn off crash debugging features
///
/// Crash is expected, so disable crash reports and symbolization to reduce
/// output clutter and avoid potentially slow symbolization.
static void disableEnvironmentDebugFeatures() {
sys::Process::PreventCoreFiles();
// TODO: Copied from not. Should have a wrapper around setenv.
#ifdef _WIN32
SetEnvironmentVariableA("LLVM_DISABLE_CRASH_REPORT", "1");
SetEnvironmentVariableA("LLVM_DISABLE_SYMBOLIZATION", "1");
#else
setenv("LLVM_DISABLE_CRASH_REPORT", "1", /*overwrite=*/1);
setenv("LLVM_DISABLE_SYMBOLIZATION", "1", /*overwrite=*/1);
#endif
}
static std::pair<StringRef, bool> determineOutputType(bool IsMIR,
bool InputIsBitcode) {
bool OutputBitcode = ForceOutputBitcode || InputIsBitcode;
if (ReplaceInput) { // In-place
OutputFilename = InputFilename.c_str();
} else if (OutputFilename.empty()) {
// Default to producing bitcode if the input was bitcode, if not explicitly
// requested.
OutputFilename =
IsMIR ? "reduced.mir" : (OutputBitcode ? "reduced.bc" : "reduced.ll");
}
return {OutputFilename, OutputBitcode};
}
int main(int Argc, char **Argv) {
InitLLVM X(Argc, Argv);
const StringRef ToolName(Argv[0]);
cl::HideUnrelatedOptions({&LLVMReduceOptions, &getColorCategory()});
cl::ParseCommandLineOptions(Argc, Argv, "LLVM automatic testcase reducer.\n");
if (Argc == 1) {
cl::PrintHelpMessage();
return 0;
}
if (PrintDeltaPasses) {
printDeltaPasses(outs());
return 0;
}
bool ReduceModeMIR = false;
if (InputLanguage != InputLanguages::None) {
if (InputLanguage == InputLanguages::MIR)
ReduceModeMIR = true;
} else if (StringRef(InputFilename).ends_with(".mir")) {
ReduceModeMIR = true;
}
if (InputFilename.empty()) {
WithColor::error(errs(), ToolName)
<< "reduction testcase positional argument must be specified\n";
return 1;
}
if (TestFilename.empty()) {
WithColor::error(errs(), ToolName) << "--test option must be specified\n";
return 1;
}
if (!PreserveDebugEnvironment)
disableEnvironmentDebugFeatures();
LLVMContext Context;
std::unique_ptr<TargetMachine> TM;
auto [OriginalProgram, InputIsBitcode] =
parseReducerWorkItem(ToolName, InputFilename, Context, TM, ReduceModeMIR);
if (!OriginalProgram) {
return 1;
}
StringRef OutputFilename;
bool OutputBitcode;
std::tie(OutputFilename, OutputBitcode) =
determineOutputType(ReduceModeMIR, InputIsBitcode);
// Initialize test environment
TestRunner Tester(TestFilename, TestArguments, std::move(OriginalProgram),
std::move(TM), ToolName, OutputFilename, InputIsBitcode,
OutputBitcode);
// This parses and writes out the testcase into a temporary file copy for the
// test, rather than evaluating the source IR directly. This is for the
// convenience of lit tests; the stripped out comments may have broken the
// interestingness checks.
if (!Tester.getProgram().isReduced(Tester)) {
errs() << "\nInput isn't interesting! Verify interesting-ness test\n";
return 2;
}
// Try to reduce code
runDeltaPasses(Tester, MaxPassIterations);
// Print reduced file to STDOUT
if (OutputFilename == "-")
Tester.getProgram().print(outs(), nullptr);
else
Tester.writeOutput("Done reducing! Reduced testcase: ");
return 0;
}