aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/bugpoint/BugDriver.h5
-rw-r--r--llvm/tools/bugpoint/ExecutionDriver.cpp17
-rw-r--r--llvm/tools/bugpoint/ExtractFunction.cpp3
-rw-r--r--llvm/tools/bugpoint/ListReducer.h2
-rw-r--r--llvm/tools/bugpoint/Miscompilation.cpp5
-rw-r--r--llvm/tools/bugpoint/OptimizerDriver.cpp4
-rw-r--r--llvm/tools/bugpoint/ToolRunner.h2
-rw-r--r--llvm/tools/dsymutil/BinaryHolder.h2
-rw-r--r--llvm/tools/dsymutil/DwarfLinkerForBinary.cpp8
-rw-r--r--llvm/tools/dsymutil/LinkUtils.h7
-rw-r--r--llvm/tools/dsymutil/MachOUtils.cpp8
-rw-r--r--llvm/tools/dsymutil/Options.td10
-rw-r--r--llvm/tools/dsymutil/dsymutil.cpp4
-rw-r--r--llvm/tools/gold/gold-plugin.cpp1
-rw-r--r--llvm/tools/llc/NewPMDriver.cpp19
-rw-r--r--llvm/tools/llc/NewPMDriver.h1
-rw-r--r--llvm/tools/llc/llc.cpp46
-rw-r--r--llvm/tools/lli/lli.cpp9
-rw-r--r--llvm/tools/llvm-c-test/attributes.c8
-rw-r--r--llvm/tools/llvm-c-test/calc.c17
-rw-r--r--llvm/tools/llvm-c-test/debuginfo.c109
-rw-r--r--llvm/tools/llvm-c-test/diagnostic.c5
-rw-r--r--llvm/tools/llvm-c-test/echo.cpp8
-rw-r--r--llvm/tools/llvm-c-test/metadata.c34
-rw-r--r--llvm/tools/llvm-c-test/module.c12
-rw-r--r--llvm/tools/llvm-c-test/object.c10
-rw-r--r--llvm/tools/llvm-cas/CMakeLists.txt17
-rw-r--r--llvm/tools/llvm-cas/Options.td63
-rw-r--r--llvm/tools/llvm-cas/llvm-cas.cpp405
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h1
-rw-r--r--llvm/tools/llvm-config/llvm-config.cpp87
-rw-r--r--llvm/tools/llvm-cov/CoverageExporter.h2
-rw-r--r--llvm/tools/llvm-cov/CoverageFilters.h2
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.h4
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp4
-rw-r--r--llvm/tools/llvm-diff/lib/DiffConsumer.h2
-rw-r--r--llvm/tools/llvm-diff/lib/DifferenceEngine.h3
-rw-r--r--llvm/tools/llvm-diff/llvm-diff.cpp4
-rw-r--r--llvm/tools/llvm-dis/llvm-dis.cpp13
-rw-r--r--llvm/tools/llvm-dwarfdump/CMakeLists.txt1
-rw-r--r--llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp18
-rw-r--r--llvm/tools/llvm-dwp/Opts.td15
-rw-r--r--llvm/tools/llvm-dwp/llvm-dwp.cpp27
-rw-r--r--llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp2
-rw-r--r--llvm/tools/llvm-exegesis/lib/Analysis.cpp2
-rw-r--r--llvm/tools/llvm-exegesis/lib/Assembler.cpp4
-rw-r--r--llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp12
-rw-r--r--llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp5
-rw-r--r--llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h4
-rw-r--r--llvm/tools/llvm-exegesis/lib/Clustering.h8
-rw-r--r--llvm/tools/llvm-exegesis/lib/Error.cpp1
-rw-r--r--llvm/tools/llvm-exegesis/lib/Error.h2
-rw-r--r--llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp3
-rw-r--r--llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp2
-rw-r--r--llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.h2
-rw-r--r--llvm/tools/llvm-exegesis/lib/PerfHelper.h1
-rw-r--r--llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp16
-rw-r--r--llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp7
-rw-r--r--llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp14
-rw-r--r--llvm/tools/llvm-exegesis/lib/SnippetGenerator.h1
-rw-r--r--llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp2
-rw-r--r--llvm/tools/llvm-exegesis/lib/SubprocessMemory.h4
-rw-r--r--llvm/tools/llvm-exegesis/lib/Target.cpp4
-rw-r--r--llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h2
-rw-r--r--llvm/tools/llvm-exegesis/lib/X86/Target.cpp17
-rw-r--r--llvm/tools/llvm-exegesis/lib/X86/X86Counter.cpp1
-rw-r--r--llvm/tools/llvm-gpu-loader/amdhsa.cpp1
-rw-r--r--llvm/tools/llvm-ifs/ErrorCollector.cpp1
-rw-r--r--llvm/tools/llvm-ifs/llvm-ifs.cpp1
-rw-r--r--llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp12
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp1
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink.cpp20
-rw-r--r--llvm/tools/llvm-libtool-darwin/DependencyInfo.h2
-rw-r--r--llvm/tools/llvm-lto/llvm-lto.cpp3
-rw-r--r--llvm/tools/llvm-mc/Disassembler.h2
-rw-r--r--llvm/tools/llvm-mca/CodeRegionGenerator.cpp2
-rw-r--r--llvm/tools/llvm-mca/CodeRegionGenerator.h2
-rw-r--r--llvm/tools/llvm-objcopy/ObjcopyOptions.cpp6
-rw-r--r--llvm/tools/llvm-objdump/OtoolOpts.td2
-rw-r--r--llvm/tools/llvm-objdump/SourcePrinter.cpp259
-rw-r--r--llvm/tools/llvm-objdump/SourcePrinter.h55
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp10
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h2
-rw-r--r--llvm/tools/llvm-offload-wrapper/llvm-offload-wrapper.cpp2
-rw-r--r--llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp2
-rw-r--r--llvm/tools/llvm-pdbutil/DumpOutputStyle.h2
-rw-r--r--llvm/tools/llvm-pdbutil/OutputStyle.h2
-rw-r--r--llvm/tools/llvm-pdbutil/PdbYaml.cpp45
-rw-r--r--llvm/tools/llvm-pdbutil/PdbYaml.h21
-rw-r--r--llvm/tools/llvm-pdbutil/PrettyClassDefinitionDumper.h2
-rw-r--r--llvm/tools/llvm-pdbutil/PrettyCompilandDumper.cpp2
-rw-r--r--llvm/tools/llvm-pdbutil/StreamUtil.h2
-rw-r--r--llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp18
-rw-r--r--llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp22
-rw-r--r--llvm/tools/llvm-pdbutil/llvm-pdbutil.h1
-rw-r--r--llvm/tools/llvm-profdata/llvm-profdata.cpp6
-rw-r--r--llvm/tools/llvm-profgen/MissingFrameInferrer.cpp1
-rw-r--r--llvm/tools/llvm-profgen/Options.h1
-rw-r--r--llvm/tools/llvm-profgen/PerfReader.cpp7
-rw-r--r--llvm/tools/llvm-profgen/ProfileGenerator.cpp15
-rw-r--r--llvm/tools/llvm-profgen/ProfiledBinary.cpp175
-rw-r--r--llvm/tools/llvm-profgen/ProfiledBinary.h27
-rw-r--r--llvm/tools/llvm-rc/ResourceFileWriter.h2
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptStmt.h10
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptToken.cpp44
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptToken.h3
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptTokenList.def2
-rw-r--r--llvm/tools/llvm-rc/ResourceVisitor.h2
-rw-r--r--llvm/tools/llvm-rc/llvm-rc.cpp3
-rw-r--r--llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp32
-rw-r--r--llvm/tools/llvm-readobj/COFFDumper.cpp3
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp1
-rw-r--r--llvm/tools/llvm-readobj/MachODumper.cpp31
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.cpp3
-rw-r--r--llvm/tools/llvm-readtapi/DiffEngine.h2
-rw-r--r--llvm/tools/llvm-reduce/CMakeLists.txt1
-rw-r--r--llvm/tools/llvm-reduce/DeltaManager.cpp1
-rw-r--r--llvm/tools/llvm-reduce/DeltaPasses.def1
-rw-r--r--llvm/tools/llvm-reduce/TestRunner.h1
-rw-r--r--llvm/tools/llvm-reduce/deltas/ReduceSinkDefsToUses.cpp61
-rw-r--r--llvm/tools/llvm-reduce/deltas/ReduceSinkDefsToUses.h18
-rw-r--r--llvm/tools/llvm-stress/llvm-stress.cpp1
-rw-r--r--llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp14
-rw-r--r--llvm/tools/llvm-xray/trie-node.h1
-rw-r--r--llvm/tools/llvm-xray/xray-extract.cpp2
-rw-r--r--llvm/tools/llvm-xray/xray-graph.h2
-rw-r--r--llvm/tools/lto/lto.cpp43
-rw-r--r--llvm/tools/obj2yaml/macho2yaml.cpp1
-rw-r--r--llvm/tools/opt-viewer/optrecord.py4
-rw-r--r--llvm/tools/opt/NewPMDriver.cpp19
-rw-r--r--llvm/tools/opt/optdriver.cpp54
131 files changed, 1826 insertions, 410 deletions
diff --git a/llvm/tools/bugpoint/BugDriver.h b/llvm/tools/bugpoint/BugDriver.h
index ca57405..71a5aa1 100644
--- a/llvm/tools/bugpoint/BugDriver.h
+++ b/llvm/tools/bugpoint/BugDriver.h
@@ -16,6 +16,7 @@
#define LLVM_TOOLS_BUGPOINT_BUGDRIVER_H
#include "llvm/IR/ValueMap.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
@@ -41,6 +42,10 @@ extern bool DisableSimplifyCFG;
///
extern bool BugpointIsInterrupted;
+/// Command line options used across files.
+extern cl::list<std::string> InputArgv;
+extern cl::opt<std::string> OutputPrefix;
+
class BugDriver {
LLVMContext &Context;
const char *ToolName; // argv[0] of bugpoint
diff --git a/llvm/tools/bugpoint/ExecutionDriver.cpp b/llvm/tools/bugpoint/ExecutionDriver.cpp
index 8c6b7fb..96eeb35 100644
--- a/llvm/tools/bugpoint/ExecutionDriver.cpp
+++ b/llvm/tools/bugpoint/ExecutionDriver.cpp
@@ -13,7 +13,6 @@
#include "BugDriver.h"
#include "ToolRunner.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Program.h"
@@ -102,15 +101,13 @@ static cl::opt<std::string> CustomExecCommand(
// Anything specified after the --args option are taken as arguments to the
// program being debugged.
-namespace llvm {
-cl::list<std::string> InputArgv("args", cl::Positional,
- cl::desc("<program arguments>..."),
- cl::PositionalEatsArgs);
-
-cl::opt<std::string>
- OutputPrefix("output-prefix", cl::init("bugpoint"),
- cl::desc("Prefix to use for outputs (default: 'bugpoint')"));
-} // namespace llvm
+cl::list<std::string> llvm::InputArgv("args", cl::Positional,
+ cl::desc("<program arguments>..."),
+ cl::PositionalEatsArgs);
+
+cl::opt<std::string> llvm::OutputPrefix(
+ "output-prefix", cl::init("bugpoint"),
+ cl::desc("Prefix to use for outputs (default: 'bugpoint')"));
static cl::list<std::string> ToolArgv("tool-args", cl::Positional,
cl::desc("<tool arguments>..."),
diff --git a/llvm/tools/bugpoint/ExtractFunction.cpp b/llvm/tools/bugpoint/ExtractFunction.cpp
index 3206589..31cdd0d 100644
--- a/llvm/tools/bugpoint/ExtractFunction.cpp
+++ b/llvm/tools/bugpoint/ExtractFunction.cpp
@@ -36,9 +36,6 @@ using namespace llvm;
#define DEBUG_TYPE "bugpoint"
bool llvm::DisableSimplifyCFG = false;
-namespace llvm {
-extern cl::opt<std::string> OutputPrefix;
-} // namespace llvm
static cl::opt<bool>
NoDCE("disable-dce",
diff --git a/llvm/tools/bugpoint/ListReducer.h b/llvm/tools/bugpoint/ListReducer.h
index 06f8ddb2..ceee853 100644
--- a/llvm/tools/bugpoint/ListReducer.h
+++ b/llvm/tools/bugpoint/ListReducer.h
@@ -32,7 +32,7 @@ template <typename ElTy> struct ListReducer {
KeepPrefix // The prefix alone satisfies the predicate
};
- virtual ~ListReducer() {}
+ virtual ~ListReducer() = default;
/// This virtual function should be overriden by subclasses to implement the
/// test desired. The testcase is only required to test to see if the Kept
diff --git a/llvm/tools/bugpoint/Miscompilation.cpp b/llvm/tools/bugpoint/Miscompilation.cpp
index a7f1643..dcad126 100644
--- a/llvm/tools/bugpoint/Miscompilation.cpp
+++ b/llvm/tools/bugpoint/Miscompilation.cpp
@@ -28,11 +28,6 @@
using namespace llvm;
-namespace llvm {
-extern cl::opt<std::string> OutputPrefix;
-extern cl::list<std::string> InputArgv;
-} // end namespace llvm
-
static cl::opt<bool> DisableLoopExtraction(
"disable-loop-extraction",
cl::desc("Don't extract loops when searching for miscompilations"),
diff --git a/llvm/tools/bugpoint/OptimizerDriver.cpp b/llvm/tools/bugpoint/OptimizerDriver.cpp
index bf2e8c0..191f87c 100644
--- a/llvm/tools/bugpoint/OptimizerDriver.cpp
+++ b/llvm/tools/bugpoint/OptimizerDriver.cpp
@@ -34,10 +34,6 @@ using namespace llvm;
#define DEBUG_TYPE "bugpoint"
-namespace llvm {
-extern cl::opt<std::string> OutputPrefix;
-}
-
static cl::opt<std::string>
OptCmd("opt-command", cl::init(""),
cl::desc("Path to opt. (default: search path "
diff --git a/llvm/tools/bugpoint/ToolRunner.h b/llvm/tools/bugpoint/ToolRunner.h
index c9da9af..9ff0663 100644
--- a/llvm/tools/bugpoint/ToolRunner.h
+++ b/llvm/tools/bugpoint/ToolRunner.h
@@ -105,7 +105,7 @@ public:
createCustomExecutor(const char *Argv0, std::string &Message,
const std::string &ExecCommandLine);
- virtual ~AbstractInterpreter() {}
+ virtual ~AbstractInterpreter() = default;
/// compileProgram - Compile the specified program from bitcode to executable
/// code. This does not produce any output, it is only used when debugging
diff --git a/llvm/tools/dsymutil/BinaryHolder.h b/llvm/tools/dsymutil/BinaryHolder.h
index cb5bd95..27d7151 100644
--- a/llvm/tools/dsymutil/BinaryHolder.h
+++ b/llvm/tools/dsymutil/BinaryHolder.h
@@ -110,7 +110,7 @@ public:
std::string Filename;
TimestampTy Timestamp;
- KeyTy() {}
+ KeyTy() = default;
KeyTy(StringRef Filename, TimestampTy Timestamp)
: Filename(Filename.str()), Timestamp(Timestamp) {}
};
diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
index b91c27e..1fc5bba 100644
--- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
+++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
@@ -90,7 +90,6 @@
#include <cstdlib>
#include <cstring>
#include <limits>
-#include <map>
#include <memory>
#include <optional>
#include <string>
@@ -794,9 +793,10 @@ bool DwarfLinkerForBinary::linkImpl(
reportWarning("Could not parse binary Swift module: " +
toString(FromInterfaceOrErr.takeError()),
Obj->getObjectFilename());
- // Only skip swiftmodules that could be parsed and are
- // positively identified as textual.
- } else if (*FromInterfaceOrErr) {
+ // Only skip swiftmodules that could be parsed and are positively
+ // identified as textual. Do so only when the option allows.
+ } else if (*FromInterfaceOrErr &&
+ !Options.IncludeSwiftModulesFromInterface) {
if (Options.Verbose)
outs() << "Skipping compiled textual Swift interface: "
<< Obj->getObjectFilename() << "\n";
diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h
index ad5515a..c333a3d 100644
--- a/llvm/tools/dsymutil/LinkUtils.h
+++ b/llvm/tools/dsymutil/LinkUtils.h
@@ -114,6 +114,13 @@ struct LinkOptions {
/// Whether all remarks should be kept or only remarks with valid debug
/// locations.
bool RemarksKeepAll = true;
+
+ /// Whether or not to copy binary swiftmodules built from textual
+ /// .swiftinterface files into the dSYM bundle. These typically come only
+ /// from the SDK (since textual interfaces require library evolution) and
+ /// thus are a waste of space to copy into the bundle. Turn this on if the
+ /// swiftmodules are different from those in the SDK.
+ bool IncludeSwiftModulesFromInterface = false;
/// @}
LinkOptions() = default;
diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp
index 362a999..fba6988 100644
--- a/llvm/tools/dsymutil/MachOUtils.cpp
+++ b/llvm/tools/dsymutil/MachOUtils.cpp
@@ -339,11 +339,11 @@ static bool createDwarfSegment(const MCAssembler& Asm,uint64_t VMAddr, uint64_t
if (Alignment > 1) {
VMAddr = alignTo(VMAddr, Alignment);
FileOffset = alignTo(FileOffset, Alignment);
- if (FileOffset > UINT32_MAX)
- return error("section " + Sec->getName() +
- "'s file offset exceeds 4GB."
- " Refusing to produce an invalid Mach-O file.");
}
+ if (FileOffset > UINT32_MAX)
+ return error("section " + Sec->getName() +
+ "'s file offset exceeds 4GB."
+ " Refusing to produce an invalid Mach-O file.");
Writer.writeSection(Asm, *Sec, VMAddr, FileOffset, 0, 0, 0);
FileOffset += Asm.getSectionAddressSize(*Sec);
diff --git a/llvm/tools/dsymutil/Options.td b/llvm/tools/dsymutil/Options.td
index ad35e55..571f90c 100644
--- a/llvm/tools/dsymutil/Options.td
+++ b/llvm/tools/dsymutil/Options.td
@@ -94,7 +94,7 @@ def: Flag<["-"], "s">,
Group<grp_general>;
def flat: F<"flat">,
- HelpText<"Produce a flat dSYM file (not a bundle).">,
+ HelpText<"Produce a flat dSYM file (not a bundle). Intended for testing and generally unsupported by tools that consume dSYMs.">,
Group<grp_general>;
def: Flag<["-"], "f">,
Alias<flat>,
@@ -202,6 +202,14 @@ def remarks_drop_without_debug: Flag<["--", "-"], "remarks-drop-without-debug">,
"all remarks are kept.">,
Group<grp_general>;
+def include_swiftmodules_from_interface: Flag<["--", "-"], "include-swiftmodules-from-interface">,
+ HelpText<"Whether or not to copy binary swiftmodules built from textual "
+ ".swiftinterface files into the dSYM bundle. These typically come only "
+ "from the SDK (since textual interfaces require library evolution) and "
+ "thus are a waste of space to copy into the bundle. Turn this on if the "
+ "swiftmodules are different from those in the SDK.">,
+ Group<grp_general>;
+
def linker: Separate<["--", "-"], "linker">,
MetaVarName<"<DWARF linker type>">,
HelpText<"Specify the desired type of DWARF linker. Defaults to 'classic'">,
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index 913077e..a71c57c 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -391,6 +391,9 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
Options.LinkOpts.RemarksKeepAll =
!Args.hasArg(OPT_remarks_drop_without_debug);
+ Options.LinkOpts.IncludeSwiftModulesFromInterface =
+ Args.hasArg(OPT_include_swiftmodules_from_interface);
+
if (opt::Arg *BuildVariantSuffix = Args.getLastArg(OPT_build_variant_suffix))
Options.LinkOpts.BuildVariantSuffix = BuildVariantSuffix->getValue();
@@ -870,7 +873,6 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
"-fat64 flag to force a 64-bit header and silence this "
"warning.",
FileOffset);
- return EXIT_FAILURE;
}
FileOffset += stat->getSize();
}
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
index 256933d..06045a6 100644
--- a/llvm/tools/gold/gold-plugin.cpp
+++ b/llvm/tools/gold/gold-plugin.cpp
@@ -36,7 +36,6 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Host.h"
#include <list>
-#include <map>
#include <plugin-api.h>
#include <string>
#include <system_error>
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index fa82689..6d4989e 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -14,8 +14,10 @@
#include "NewPMDriver.h"
#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/CommandFlags.h"
+#include "llvm/CodeGen/LibcallLoweringInfo.h"
#include "llvm/CodeGen/MIRParser/MIRParser.h"
#include "llvm/CodeGen/MIRPrinter.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
@@ -101,6 +103,13 @@ int llvm::compileModuleWithNewPM(
raw_pwrite_stream *OS = &Out->os();
+ std::unique_ptr<buffer_ostream> BOS;
+ if (codegen::getFileType() != CodeGenFileType::AssemblyFile &&
+ !Out->os().supportsSeeking()) {
+ BOS = std::make_unique<buffer_ostream>(Out->os());
+ OS = BOS.get();
+ }
+
// Fetch options from TargetPassConfig
CGPassBuilderOption Opt = getCGPassBuilderOption();
Opt.DisableVerify = VK != VerifierKind::InputOutput;
@@ -129,6 +138,16 @@ int llvm::compileModuleWithNewPM(
SI.registerCallbacks(PIC, &MAM);
FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
+
+ MAM.registerPass([&] {
+ const TargetOptions &Options = Target->Options;
+ return RuntimeLibraryAnalysis(
+ M->getTargetTriple(), Target->Options.ExceptionModel,
+ Target->Options.FloatABIType, Target->Options.EABIVersion,
+ Options.MCOptions.ABIName, Target->Options.VecLib);
+ });
+ MAM.registerPass([&] { return LibcallLoweringModuleAnalysis(); });
+
MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
ModulePassManager MPM;
diff --git a/llvm/tools/llc/NewPMDriver.h b/llvm/tools/llc/NewPMDriver.h
index c8a6022..0dbd467 100644
--- a/llvm/tools/llc/NewPMDriver.h
+++ b/llvm/tools/llc/NewPMDriver.h
@@ -22,7 +22,6 @@
#include "llvm/IR/DiagnosticHandler.h"
#include "llvm/Support/CodeGen.h"
#include <memory>
-#include <vector>
namespace llvm {
class Module;
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index 152f7db..613780e 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -15,6 +15,8 @@
#include "NewPMDriver.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
@@ -45,6 +47,7 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/PGOOptions.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
@@ -57,11 +60,13 @@
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/Utils/Cloning.h"
+#include <cassert>
#include <memory>
#include <optional>
using namespace llvm;
static codegen::RegisterCodeGenFlags CGF;
+static codegen::RegisterSaveStatsFlag SSF;
// General options for llc. Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
@@ -281,7 +286,8 @@ static void setPGOOptions(TargetMachine &TM) {
TM.setPGOOption(PGOOpt);
}
-static int compileModule(char **, LLVMContext &);
+static int compileModule(char **argv, LLVMContext &Context,
+ std::string &OutputFilename);
[[noreturn]] static void reportError(Twine Msg, StringRef Filename = "") {
SmallString<256> Prefix;
@@ -301,9 +307,7 @@ static int compileModule(char **, LLVMContext &);
llvm_unreachable("reportError() should not return");
}
-static std::unique_ptr<ToolOutputFile> GetOutputStream(const char *TargetName,
- Triple::OSType OS,
- const char *ProgName) {
+static std::unique_ptr<ToolOutputFile> GetOutputStream(Triple::OSType OS) {
// If we don't yet have an output filename, make one.
if (OutputFilename.empty()) {
if (InputFilename == "-")
@@ -352,11 +356,8 @@ static std::unique_ptr<ToolOutputFile> GetOutputStream(const char *TargetName,
if (!Binary)
OpenFlags |= sys::fs::OF_TextWithCRLF;
auto FDOut = std::make_unique<ToolOutputFile>(OutputFilename, EC, OpenFlags);
- if (EC) {
+ if (EC)
reportError(EC.message());
- return nullptr;
- }
-
return FDOut;
}
@@ -437,18 +438,22 @@ int main(int argc, char **argv) {
reportError(std::move(E), RemarksFilename);
LLVMRemarkFileHandle RemarksFile = std::move(*RemarksFileOrErr);
+ codegen::MaybeEnableStatistics();
+ std::string OutputFilename;
+
if (InputLanguage != "" && InputLanguage != "ir" && InputLanguage != "mir")
reportError("input language must be '', 'IR' or 'MIR'");
// Compile the module TimeCompilations times to give better compile time
// metrics.
for (unsigned I = TimeCompilations; I; --I)
- if (int RetVal = compileModule(argv, Context))
+ if (int RetVal = compileModule(argv, Context, OutputFilename))
return RetVal;
if (RemarksFile)
RemarksFile->keep();
- return 0;
+
+ return codegen::MaybeSaveStatistics(OutputFilename, "llc");
}
static bool addPass(PassManagerBase &PM, const char *argv0, StringRef PassName,
@@ -480,7 +485,8 @@ static bool addPass(PassManagerBase &PM, const char *argv0, StringRef PassName,
return false;
}
-static int compileModule(char **argv, LLVMContext &Context) {
+static int compileModule(char **argv, LLVMContext &Context,
+ std::string &OutputFilename) {
// Load the module to be compiled...
SMDiagnostic Err;
std::unique_ptr<Module> M;
@@ -541,6 +547,12 @@ static int compileModule(char **argv, LLVMContext &Context) {
InputFilename);
}
+ if (TheTriple.isX86() &&
+ codegen::getFuseFPOps() != FPOpFusion::FPOpFusionMode::Standard)
+ WithColor::warning(errs(), argv[0])
+ << "X86 backend ignores --fp-contract setting; use IR fast-math "
+ "flags instead.";
+
Options.BinutilsVersion =
TargetMachine::parseBinutilsVersion(BinutilsVersion);
Options.MCOptions.ShowMCEncoding = ShowMCEncoding;
@@ -656,14 +668,16 @@ static int compileModule(char **argv, LLVMContext &Context) {
Target->Options.FloatABIType = codegen::getFloatABIForCalls();
// Figure out where we are going to send the output.
- std::unique_ptr<ToolOutputFile> Out =
- GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]);
+ std::unique_ptr<ToolOutputFile> Out = GetOutputStream(TheTriple.getOS());
if (!Out)
return 1;
// Ensure the filename is passed down to CodeViewDebug.
Target->Options.ObjectFilenameForDebug = Out->outputFilename();
+ // Return a copy of the output filename via the output param
+ OutputFilename = Out->outputFilename();
+
// Tell target that this tool is not necessarily used with argument ABI
// compliance (i.e. narrow integer argument extensions).
Target->Options.VerifyArgABICompliance = 0;
@@ -678,7 +692,7 @@ static int compileModule(char **argv, LLVMContext &Context) {
}
// Add an appropriate TargetLibraryInfo pass for the module's triple.
- TargetLibraryInfoImpl TLII(M->getTargetTriple());
+ TargetLibraryInfoImpl TLII(M->getTargetTriple(), Target->Options.VecLib);
// The -disable-simplify-libcalls flag actually disables all builtin optzns.
if (DisableSimplifyLibCalls)
@@ -714,6 +728,10 @@ static int compileModule(char **argv, LLVMContext &Context) {
// Build up all of the passes that we want to do to the module.
legacy::PassManager PM;
PM.add(new TargetLibraryInfoWrapperPass(TLII));
+ PM.add(new RuntimeLibraryInfoWrapper(
+ M->getTargetTriple(), Target->Options.ExceptionModel,
+ Target->Options.FloatABIType, Target->Options.EABIVersion,
+ Options.MCOptions.ABIName, Target->Options.VecLib));
{
raw_pwrite_stream *OS = &Out->os();
diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp
index 7fee06b..847ee32 100644
--- a/llvm/tools/lli/lli.cpp
+++ b/llvm/tools/lli/lli.cpp
@@ -283,7 +283,6 @@ static ExitOnError ExitOnErr;
LLVM_ATTRIBUTE_USED static void linkComponents() {
errs() << (void *)&llvm_orc_registerEHFrameSectionAllocAction
<< (void *)&llvm_orc_deregisterEHFrameSectionAllocAction
- << (void *)&llvm_orc_registerJITLoaderGDBWrapper
<< (void *)&llvm_orc_registerJITLoaderGDBAllocAction;
}
@@ -305,7 +304,7 @@ public:
this->CacheDir[this->CacheDir.size() - 1] != '/')
this->CacheDir += '/';
}
- ~LLIObjectCache() override {}
+ ~LLIObjectCache() override = default;
void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override {
const std::string &ModuleID = M->getModuleIdentifier();
@@ -1228,15 +1227,15 @@ static Expected<std::unique_ptr<orc::ExecutorProcessControl>> launchRemote() {
std::unique_ptr<char[]> ChildPath, ChildIn, ChildOut;
{
ChildPath.reset(new char[ChildExecPath.size() + 1]);
- std::copy(ChildExecPath.begin(), ChildExecPath.end(), &ChildPath[0]);
+ llvm::copy(ChildExecPath, &ChildPath[0]);
ChildPath[ChildExecPath.size()] = '\0';
std::string ChildInStr = utostr(PipeFD[0][0]);
ChildIn.reset(new char[ChildInStr.size() + 1]);
- std::copy(ChildInStr.begin(), ChildInStr.end(), &ChildIn[0]);
+ llvm::copy(ChildInStr, &ChildIn[0]);
ChildIn[ChildInStr.size()] = '\0';
std::string ChildOutStr = utostr(PipeFD[1][1]);
ChildOut.reset(new char[ChildOutStr.size() + 1]);
- std::copy(ChildOutStr.begin(), ChildOutStr.end(), &ChildOut[0]);
+ llvm::copy(ChildOutStr, &ChildOut[0]);
ChildOut[ChildOutStr.size()] = '\0';
}
diff --git a/llvm/tools/llvm-c-test/attributes.c b/llvm/tools/llvm-c-test/attributes.c
index 088684c..8d1735f 100644
--- a/llvm/tools/llvm-c-test/attributes.c
+++ b/llvm/tools/llvm-c-test/attributes.c
@@ -20,7 +20,8 @@
int llvm_test_function_attributes(void) {
LLVMEnablePrettyStackTrace();
- LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), false, true);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = llvm_load_module(C, false, true);
LLVMValueRef F = LLVMGetFirstFunction(M);
while (F) {
@@ -42,6 +43,7 @@ int llvm_test_function_attributes(void) {
}
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
return 0;
}
@@ -49,7 +51,8 @@ int llvm_test_function_attributes(void) {
int llvm_test_callsite_attributes(void) {
LLVMEnablePrettyStackTrace();
- LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), false, true);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = llvm_load_module(C, false, true);
LLVMValueRef F = LLVMGetFirstFunction(M);
while (F) {
@@ -81,6 +84,7 @@ int llvm_test_callsite_attributes(void) {
}
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
return 0;
}
diff --git a/llvm/tools/llvm-c-test/calc.c b/llvm/tools/llvm-c-test/calc.c
index 267397a..2fc0cae 100644
--- a/llvm/tools/llvm-c-test/calc.c
+++ b/llvm/tools/llvm-c-test/calc.c
@@ -45,6 +45,8 @@ static LLVMValueRef build_from_tokens(char **tokens, int ntokens,
int depth = 0;
int i;
+ LLVMContextRef C = LLVMGetBuilderContext(builder);
+
for (i = 0; i < ntokens; i++) {
char tok = tokens[i][0];
switch (tok) {
@@ -74,7 +76,7 @@ static LLVMValueRef build_from_tokens(char **tokens, int ntokens,
return NULL;
}
- LLVMTypeRef ty = LLVMInt64Type();
+ LLVMTypeRef ty = LLVMInt64TypeInContext(C);
off = LLVMBuildGEP2(builder, ty, param, &stack[depth - 1], 1, "");
stack[depth - 1] = LLVMBuildLoad2(builder, ty, off, "");
@@ -94,7 +96,7 @@ static LLVMValueRef build_from_tokens(char **tokens, int ntokens,
return NULL;
}
- stack[depth++] = LLVMConstInt(LLVMInt64Type(), val, 1);
+ stack[depth++] = LLVMConstInt(LLVMInt64TypeInContext(C), val, 1);
break;
}
}
@@ -115,15 +117,17 @@ static void handle_line(char **tokens, int ntokens) {
LLVMValueRef param;
LLVMValueRef res;
- LLVMModuleRef M = LLVMModuleCreateWithName(name);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = LLVMModuleCreateWithNameInContext(name, C);
- LLVMTypeRef I64ty = LLVMInt64Type();
+ LLVMTypeRef I64ty = LLVMInt64TypeInContext(C);
LLVMTypeRef I64Ptrty = LLVMPointerType(I64ty, 0);
LLVMTypeRef Fty = LLVMFunctionType(I64ty, &I64Ptrty, 1, 0);
LLVMValueRef F = LLVMAddFunction(M, name, Fty);
- LLVMBuilderRef builder = LLVMCreateBuilder();
- LLVMPositionBuilderAtEnd(builder, LLVMAppendBasicBlock(F, "entry"));
+ LLVMBuilderRef builder = LLVMCreateBuilderInContext(C);
+ LLVMPositionBuilderAtEnd(builder,
+ LLVMAppendBasicBlockInContext(C, F, "entry"));
LLVMGetParams(F, &param);
LLVMSetValueName(param, "in");
@@ -138,6 +142,7 @@ static void handle_line(char **tokens, int ntokens) {
LLVMDisposeBuilder(builder);
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
}
int llvm_calc(void) {
diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c
index 9db7aa0..44d1f9c 100644
--- a/llvm/tools/llvm-c-test/debuginfo.c
+++ b/llvm/tools/llvm-c-test/debuginfo.c
@@ -33,7 +33,8 @@ declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) {
int llvm_test_dibuilder(void) {
const char *Filename = "debuginfo.c";
- LLVMModuleRef M = LLVMModuleCreateWithName(Filename);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = LLVMModuleCreateWithNameInContext(Filename, C);
LLVMSetIsNewDbgInfoFormat(M, true);
assert(LLVMIsNewDbgInfoFormat(M));
@@ -101,15 +102,16 @@ int llvm_test_dibuilder(void) {
LLVMAddNamedMetadataOperand(M, "FooType",
LLVMMetadataAsValue(LLVMGetModuleContext(M), StructDbgPtrTy));
-
+ LLVMTypeRef I64Ty = LLVMInt64TypeInContext(C);
LLVMTypeRef FooParamTys[] = {
- LLVMInt64Type(),
- LLVMInt64Type(),
- LLVMVectorType(LLVMInt64Type(), 10),
+ I64Ty,
+ I64Ty,
+ LLVMVectorType(I64Ty, 10),
};
- LLVMTypeRef FooFuncTy = LLVMFunctionType(LLVMInt64Type(), FooParamTys, 3, 0);
+ LLVMTypeRef FooFuncTy = LLVMFunctionType(I64Ty, FooParamTys, 3, 0);
LLVMValueRef FooFunction = LLVMAddFunction(M, "foo", FooFuncTy);
- LLVMBasicBlockRef FooEntryBlock = LLVMAppendBasicBlock(FooFunction, "entry");
+ LLVMBasicBlockRef FooEntryBlock =
+ LLVMAppendBasicBlockInContext(C, FooFunction, "entry");
LLVMMetadataRef Subscripts[] = {
LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10),
@@ -130,9 +132,8 @@ int llvm_test_dibuilder(void) {
LLVMDIFlagFwdDecl,
"", 0);
- LLVMMetadataRef FooParamLocation =
- LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 42, 0,
- ReplaceableFunctionMetadata, NULL);
+ LLVMMetadataRef FooParamLocation = LLVMDIBuilderCreateDebugLocation(
+ C, 42, 0, ReplaceableFunctionMetadata, NULL);
LLVMMetadataRef FunctionMetadata = LLVMDIBuilderCreateFunction(
DIB, File, "foo", 3, "foo", 3, File, 42, NULL, true, true, 42, 0, false);
LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata, FunctionMetadata);
@@ -145,24 +146,24 @@ int llvm_test_dibuilder(void) {
LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "a", 1, 1, File,
42, Int64Ty, true, 0);
- LLVMDIBuilderInsertDeclareRecordAtEnd(
- DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar1,
- FooParamExpression, FooParamLocation, FooEntryBlock);
+ LLVMDIBuilderInsertDeclareRecordAtEnd(DIB, LLVMConstInt(I64Ty, 0, false),
+ FooParamVar1, FooParamExpression,
+ FooParamLocation, FooEntryBlock);
LLVMMetadataRef FooParamVar2 =
LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "b", 1, 2, File,
42, Int64Ty, true, 0);
- LLVMDIBuilderInsertDeclareRecordAtEnd(
- DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar2,
- FooParamExpression, FooParamLocation, FooEntryBlock);
+ LLVMDIBuilderInsertDeclareRecordAtEnd(DIB, LLVMConstInt(I64Ty, 0, false),
+ FooParamVar2, FooParamExpression,
+ FooParamLocation, FooEntryBlock);
LLVMMetadataRef FooParamVar3 = LLVMDIBuilderCreateParameterVariable(
DIB, FunctionMetadata, "c", 1, 3, File, 42, VectorTy, true, 0);
- LLVMDIBuilderInsertDeclareRecordAtEnd(
- DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar3,
- FooParamExpression, FooParamLocation, FooEntryBlock);
+ LLVMDIBuilderInsertDeclareRecordAtEnd(DIB, LLVMConstInt(I64Ty, 0, false),
+ FooParamVar3, FooParamExpression,
+ FooParamLocation, FooEntryBlock);
LLVMSetSubprogram(FooFunction, FunctionMetadata);
@@ -174,14 +175,14 @@ int llvm_test_dibuilder(void) {
LLVMMetadataRef FooLexicalBlock =
LLVMDIBuilderCreateLexicalBlock(DIB, FunctionMetadata, File, 42, 0);
- LLVMBasicBlockRef FooVarBlock = LLVMAppendBasicBlock(FooFunction, "vars");
+ LLVMBasicBlockRef FooVarBlock =
+ LLVMAppendBasicBlockInContext(C, FooFunction, "vars");
LLVMMetadataRef FooVarsLocation =
- LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 43, 0,
- FunctionMetadata, NULL);
+ LLVMDIBuilderCreateDebugLocation(C, 43, 0, FunctionMetadata, NULL);
LLVMMetadataRef FooVar1 =
LLVMDIBuilderCreateAutoVariable(DIB, FooLexicalBlock, "d", 1, File,
43, Int64Ty, true, 0, 0);
- LLVMValueRef FooVal1 = LLVMConstInt(LLVMInt64Type(), 0, false);
+ LLVMValueRef FooVal1 = LLVMConstInt(I64Ty, 0, false);
LLVMMetadataRef FooVarValueExpr1 =
LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
@@ -190,7 +191,7 @@ int llvm_test_dibuilder(void) {
LLVMMetadataRef FooVar2 = LLVMDIBuilderCreateAutoVariable(
DIB, FooLexicalBlock, "e", 1, File, 44, Int64Ty, true, 0, 0);
- LLVMValueRef FooVal2 = LLVMConstInt(LLVMInt64Type(), 1, false);
+ LLVMValueRef FooVal2 = LLVMConstInt(I64Ty, 1, false);
LLVMMetadataRef FooVarValueExpr2 =
LLVMDIBuilderCreateConstantValueExpression(DIB, 1);
@@ -238,8 +239,8 @@ int llvm_test_dibuilder(void) {
M, "LargeEnumTest",
LLVMMetadataAsValue(LLVMGetModuleContext(M), LargeEnumTest));
- LLVMValueRef FooVal3 = LLVMConstInt(LLVMInt64Type(), 8, false);
- LLVMValueRef FooVal4 = LLVMConstInt(LLVMInt64Type(), 4, false);
+ LLVMValueRef FooVal3 = LLVMConstInt(I64Ty, 8, false);
+ LLVMValueRef FooVal4 = LLVMConstInt(I64Ty, 4, false);
LLVMMetadataRef lo = LLVMValueAsMetadata(FooVal1);
LLVMMetadataRef hi = LLVMValueAsMetadata(FooVal2);
LLVMMetadataRef strd = LLVMValueAsMetadata(FooVal3);
@@ -364,6 +365,43 @@ int llvm_test_dibuilder(void) {
assert(AddDbgRecordUnderTheRange == NULL);
(void)AddDbgRecordUnderTheRange;
+ // Test that we can read the first debug record.
+ LLVMMetadataRef AddDbgRecordFirstDebugLoc =
+ LLVMDbgRecordGetDebugLoc(AddDbgRecordFirst);
+ (void)AddDbgRecordFirstDebugLoc;
+ assert(LLVMDILocationGetLine(AddDbgRecordFirstDebugLoc) == 43);
+ assert(LLVMDbgRecordGetKind(AddDbgRecordFirst) == LLVMDbgRecordValue);
+ LLVMValueRef AddDbgRecordFirstValue =
+ LLVMDbgVariableRecordGetValue(AddDbgRecordFirst, 0);
+ (void)AddDbgRecordFirstValue;
+ assert(LLVMGetValueKind(AddDbgRecordFirstValue) == LLVMConstantIntValueKind);
+ assert(LLVMConstIntGetZExtValue(AddDbgRecordFirstValue) == 0);
+ LLVMMetadataRef AddDbgRecordFirstVariable =
+ LLVMDbgVariableRecordGetVariable(AddDbgRecordFirst);
+ (void)AddDbgRecordFirstVariable;
+ assert(LLVMGetMetadataKind(AddDbgRecordFirstVariable) ==
+ LLVMDILocalVariableMetadataKind);
+ // TODO: For now, there is no way to get the name.
+ LLVMMetadataRef AddDbgRecordFirstVariableScope =
+ LLVMDIVariableGetScope(AddDbgRecordFirstVariable);
+ (void)AddDbgRecordFirstVariableScope;
+ assert(LLVMGetMetadataKind(AddDbgRecordFirstVariableScope) ==
+ LLVMDILexicalBlockMetadataKind);
+ LLVMMetadataRef AddDbgRecordFirstVariableFile =
+ LLVMDIScopeGetFile(AddDbgRecordFirstVariableScope);
+ (void)AddDbgRecordFirstVariableFile;
+ assert(LLVMGetMetadataKind(AddDbgRecordFirstVariableFile) ==
+ LLVMDIFileMetadataKind);
+ unsigned FileLen = 0;
+ assert(strcmp(LLVMDIFileGetFilename(AddDbgRecordFirstVariableFile, &FileLen),
+ "debuginfo.c") == 0);
+ (void)FileLen;
+ LLVMMetadataRef AddDbgRecordFirstExpr =
+ LLVMDbgVariableRecordGetExpression(AddDbgRecordFirst);
+ assert(LLVMGetMetadataKind(AddDbgRecordFirstExpr) ==
+ LLVMDIExpressionMetadataKind);
+ (void)AddDbgRecordFirstExpr;
+
char *MStr = LLVMPrintModuleToString(M);
puts(MStr);
LLVMDisposeMessage(MStr);
@@ -371,13 +409,14 @@ int llvm_test_dibuilder(void) {
LLVMDisposeBuilder(Builder);
LLVMDisposeDIBuilder(DIB);
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
return 0;
}
int llvm_get_di_tag(void) {
- LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
- LLVMContextRef Context = LLVMGetModuleContext(M);
+ LLVMContextRef Context = LLVMContextCreate();
+ LLVMModuleRef M = LLVMModuleCreateWithNameInContext("Mod", Context);
const char String[] = "foo";
LLVMMetadataRef StringMD =
@@ -400,12 +439,14 @@ int llvm_get_di_tag(void) {
LLVMDisposeDIBuilder(Builder);
LLVMDisposeModule(M);
+ LLVMContextDispose(Context);
return 0;
}
int llvm_di_type_get_name(void) {
- LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = LLVMModuleCreateWithNameInContext("Mod", C);
LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
const char Filename[] = "metadata.c";
@@ -425,13 +466,15 @@ int llvm_di_type_get_name(void) {
LLVMDisposeDIBuilder(Builder);
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
return 0;
}
int llvm_add_globaldebuginfo(void) {
const char *Filename = "debuginfo.c";
- LLVMModuleRef M = LLVMModuleCreateWithName(Filename);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = LLVMModuleCreateWithNameInContext(Filename, C);
LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
LLVMMetadataRef File =
LLVMDIBuilderCreateFile(Builder, Filename, strlen(Filename), ".", 1);
@@ -447,13 +490,12 @@ int llvm_add_globaldebuginfo(void) {
Builder, File, "global", 6, "", 0, File, 1, Int64TypeDef, true,
GlobalVarValueExpr, NULL, 0);
- LLVMTypeRef RecType =
- LLVMStructCreateNamed(LLVMGetModuleContext(M), "struct");
+ LLVMTypeRef RecType = LLVMStructCreateNamed(C, "struct");
LLVMValueRef Global = LLVMAddGlobal(M, RecType, "global");
LLVMGlobalAddDebugInfo(Global, GVE);
// use AddMetadata to add twice
- int kindId = LLVMGetMDKindID("dbg", 3);
+ int kindId = LLVMGetMDKindIDInContext(C, "dbg", 3);
LLVMGlobalAddMetadata(Global, kindId, GVE);
size_t numEntries;
LLVMValueMetadataEntry *ME = LLVMGlobalCopyAllMetadata(Global, &numEntries);
@@ -463,6 +505,7 @@ int llvm_add_globaldebuginfo(void) {
LLVMDisposeValueMetadataEntries(ME);
LLVMDisposeDIBuilder(Builder);
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
return 0;
}
diff --git a/llvm/tools/llvm-c-test/diagnostic.c b/llvm/tools/llvm-c-test/diagnostic.c
index 0f9b48b..49b37cd 100644
--- a/llvm/tools/llvm-c-test/diagnostic.c
+++ b/llvm/tools/llvm-c-test/diagnostic.c
@@ -45,7 +45,7 @@ static void diagnosticHandler(LLVMDiagnosticInfoRef DI, void *C) {
static int handlerCalled = 0;
int llvm_test_diagnostic_handler(void) {
- LLVMContextRef C = LLVMGetGlobalContext();
+ LLVMContextRef C = LLVMContextCreate();
LLVMContextSetDiagnosticHandler(C, diagnosticHandler, &handlerCalled);
if (LLVMContextGetDiagnosticHandler(C) != diagnosticHandler) {
@@ -69,7 +69,7 @@ int llvm_test_diagnostic_handler(void) {
LLVMModuleRef M;
- int Ret = LLVMGetBitcodeModule2(MB, &M);
+ int Ret = LLVMGetBitcodeModuleInContext2(C, MB, &M);
if (Ret)
LLVMDisposeMemoryBuffer(MB);
@@ -79,5 +79,6 @@ int llvm_test_diagnostic_handler(void) {
fprintf(stderr, "Diagnostic handler was not called while loading module\n");
}
+ LLVMContextDispose(C);
return 0;
}
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index 026d815..bd640cd 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -986,9 +986,10 @@ struct FunCloner {
for (unsigned i = 0; i < NumMaskElts; i++) {
int Val = LLVMGetMaskValue(Src, i);
if (Val == LLVMGetUndefMaskElem()) {
- MaskElts.push_back(LLVMGetUndef(LLVMInt64Type()));
+ MaskElts.push_back(LLVMGetUndef(LLVMInt64TypeInContext(Ctx)));
} else {
- MaskElts.push_back(LLVMConstInt(LLVMInt64Type(), Val, true));
+ MaskElts.push_back(
+ LLVMConstInt(LLVMInt64TypeInContext(Ctx), Val, true));
}
}
LLVMValueRef Mask = LLVMConstVector(MaskElts.data(), NumMaskElts);
@@ -1115,7 +1116,8 @@ struct FunCloner {
if (Name != VName)
report_fatal_error("Basic block name mismatch");
- LLVMBasicBlockRef BB = LLVMAppendBasicBlock(Fun, Name);
+ LLVMContextRef Ctx = LLVMGetModuleContext(M);
+ LLVMBasicBlockRef BB = LLVMAppendBasicBlockInContext(Ctx, Fun, Name);
return BBMap[Src] = BB;
}
diff --git a/llvm/tools/llvm-c-test/metadata.c b/llvm/tools/llvm-c-test/metadata.c
index 4fe8c00..6dd18d1 100644
--- a/llvm/tools/llvm-c-test/metadata.c
+++ b/llvm/tools/llvm-c-test/metadata.c
@@ -19,37 +19,41 @@
#include <string.h>
int llvm_add_named_metadata_operand(void) {
- LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
- LLVMValueRef Int = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = LLVMModuleCreateWithNameInContext("Mod", C);
+ LLVMValueRef Int = LLVMConstInt(LLVMInt32TypeInContext(C), 0, 0);
// This used to trigger an assertion
- LLVMAddNamedMetadataOperand(M, "name", LLVMMDNode(&Int, 1));
+ LLVMAddNamedMetadataOperand(M, "name", LLVMMDNodeInContext(C, &Int, 1));
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
return 0;
}
int llvm_set_metadata(void) {
- LLVMBuilderRef Builder = LLVMCreateBuilder();
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMBuilderRef Builder = LLVMCreateBuilderInContext(C);
// This used to trigger an assertion
LLVMValueRef Return = LLVMBuildRetVoid(Builder);
const char Name[] = "kind";
- LLVMValueRef Int = LLVMConstInt(LLVMInt32Type(), 0, 0);
- LLVMSetMetadata(Return, LLVMGetMDKindID(Name, strlen(Name)),
- LLVMMDNode(&Int, 1));
+ LLVMValueRef Int = LLVMConstInt(LLVMInt32TypeInContext(C), 0, 0);
+ LLVMSetMetadata(Return, LLVMGetMDKindIDInContext(C, Name, strlen(Name)),
+ LLVMMDNodeInContext(C, &Int, 1));
LLVMDisposeBuilder(Builder);
LLVMDeleteInstruction(Return);
+ LLVMContextDispose(C);
return 0;
}
int llvm_replace_md_operand(void) {
- LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
- LLVMContextRef Context = LLVMGetModuleContext(M);
+ LLVMContextRef Context = LLVMContextCreate();
+ LLVMModuleRef M = LLVMModuleCreateWithNameInContext("Mod", Context);
const char String1[] = "foo";
LLVMMetadataRef String1MD =
@@ -71,17 +75,18 @@ int llvm_replace_md_operand(void) {
(void)String;
LLVMDisposeModule(M);
+ LLVMContextDispose(Context);
return 0;
}
int llvm_is_a_value_as_metadata(void) {
- LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
- LLVMContextRef Context = LLVMGetModuleContext(M);
+ LLVMContextRef Context = LLVMContextCreate();
+ LLVMModuleRef M = LLVMModuleCreateWithNameInContext("Mod", Context);
{
- LLVMValueRef Int = LLVMConstInt(LLVMInt32Type(), 0, 0);
- LLVMValueRef NodeMD = LLVMMDNode(&Int, 1);
+ LLVMValueRef Int = LLVMConstInt(LLVMInt32TypeInContext(Context), 0, 0);
+ LLVMValueRef NodeMD = LLVMMDNodeInContext(Context, &Int, 1);
assert(LLVMIsAValueAsMetadata(NodeMD) == NodeMD);
(void)NodeMD;
}
@@ -96,5 +101,8 @@ int llvm_is_a_value_as_metadata(void) {
(void)Value;
}
+ LLVMDisposeModule(M);
+ LLVMContextDispose(Context);
+
return 0;
}
diff --git a/llvm/tools/llvm-c-test/module.c b/llvm/tools/llvm-c-test/module.c
index 9698f09..daa97bb 100644
--- a/llvm/tools/llvm-c-test/module.c
+++ b/llvm/tools/llvm-c-test/module.c
@@ -61,19 +61,22 @@ LLVMModuleRef llvm_load_module(LLVMContextRef C, bool Lazy, bool New) {
}
int llvm_module_dump(bool Lazy, bool New) {
- LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), Lazy, New);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = llvm_load_module(C, Lazy, New);
char *irstr = LLVMPrintModuleToString(M);
puts(irstr);
LLVMDisposeMessage(irstr);
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
return 0;
}
int llvm_module_list_functions(void) {
- LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), false, false);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = llvm_load_module(C, false, false);
LLVMValueRef f;
f = LLVMGetFirstFunction(M);
@@ -109,12 +112,14 @@ int llvm_module_list_functions(void) {
}
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
return 0;
}
int llvm_module_list_globals(void) {
- LLVMModuleRef M = llvm_load_module(LLVMGetGlobalContext(), false, false);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMModuleRef M = llvm_load_module(C, false, false);
LLVMValueRef g;
g = LLVMGetFirstGlobal(M);
@@ -132,6 +137,7 @@ int llvm_module_list_globals(void) {
}
LLVMDisposeModule(M);
+ LLVMContextDispose(C);
return 0;
}
diff --git a/llvm/tools/llvm-c-test/object.c b/llvm/tools/llvm-c-test/object.c
index 53ffb1a..8948f23 100644
--- a/llvm/tools/llvm-c-test/object.c
+++ b/llvm/tools/llvm-c-test/object.c
@@ -19,7 +19,6 @@
int llvm_object_list_sections(void) {
LLVMMemoryBufferRef MB;
- LLVMBinaryRef O;
LLVMSectionIteratorRef sect;
char *outBufferErr = NULL;
@@ -30,7 +29,8 @@ int llvm_object_list_sections(void) {
}
char *outBinaryErr = NULL;
- O = LLVMCreateBinary(MB, LLVMGetGlobalContext(), &outBinaryErr);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMBinaryRef O = LLVMCreateBinary(MB, C, &outBinaryErr);
if (!O || outBinaryErr) {
fprintf(stderr, "Error reading object: %s\n", outBinaryErr);
free(outBinaryErr);
@@ -50,13 +50,13 @@ int llvm_object_list_sections(void) {
LLVMDisposeBinary(O);
LLVMDisposeMemoryBuffer(MB);
+ LLVMContextDispose(C);
return 0;
}
int llvm_object_list_symbols(void) {
LLVMMemoryBufferRef MB;
- LLVMBinaryRef O;
LLVMSectionIteratorRef sect;
LLVMSymbolIteratorRef sym;
@@ -68,7 +68,8 @@ int llvm_object_list_symbols(void) {
}
char *outBinaryErr = NULL;
- O = LLVMCreateBinary(MB, LLVMGetGlobalContext(), &outBinaryErr);
+ LLVMContextRef C = LLVMContextCreate();
+ LLVMBinaryRef O = LLVMCreateBinary(MB, C, &outBinaryErr);
if (!O || outBinaryErr) {
fprintf(stderr, "Error reading object: %s\n", outBinaryErr);
free(outBinaryErr);
@@ -92,6 +93,7 @@ int llvm_object_list_symbols(void) {
LLVMDisposeBinary(O);
LLVMDisposeMemoryBuffer(MB);
+ LLVMContextDispose(C);
return 0;
}
diff --git a/llvm/tools/llvm-cas/CMakeLists.txt b/llvm/tools/llvm-cas/CMakeLists.txt
new file mode 100644
index 0000000..e9d40cb
--- /dev/null
+++ b/llvm/tools/llvm-cas/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(LLVM_TARGET_DEFINITIONS Options.td)
+tablegen(LLVM Options.inc -gen-opt-parser-defs)
+add_public_tablegen_target(LLVMCASToolTableGen)
+
+set(LLVM_LINK_COMPONENTS
+ Support
+ CAS
+ Option
+ )
+
+add_llvm_tool(llvm-cas
+ llvm-cas.cpp
+
+ DEPENDS
+ ${tablegen_deps}
+ LLVMCASToolTableGen
+ )
diff --git a/llvm/tools/llvm-cas/Options.td b/llvm/tools/llvm-cas/Options.td
new file mode 100644
index 0000000..5ae64c1
--- /dev/null
+++ b/llvm/tools/llvm-cas/Options.td
@@ -0,0 +1,63 @@
+include "llvm/Option/OptParser.td"
+
+class F<string name> : Flag<["--", "-"], name>;
+
+def grp_action : OptionGroup<"Actions">, HelpText<"llvm-cas actions">;
+
+def help : F<"help">, HelpText<"Prints this help output">;
+def : Flag<["-"], "h">, Alias<help>, HelpText<"Alias for --help">;
+
+// Tool actions
+
+def cas_dump : F<"dump">, HelpText<"Dump internal contents">, Group<grp_action>;
+def cat_node_data : F<"cat-node-data">,
+ HelpText<"Cat node data">,
+ Group<grp_action>;
+def make_blob : F<"make-blob">, HelpText<"Make blob">, Group<grp_action>;
+def make_node : F<"make-node">, HelpText<"Make node">, Group<grp_action>;
+def ls_node_refs : F<"ls-node-refs">,
+ HelpText<"List node refs">,
+ Group<grp_action>;
+def import : F<"import">,
+ HelpText<"Import objects from another CAS">,
+ Group<grp_action>;
+def put_cache_key : F<"put-cache-key">,
+ HelpText<"Set a value for a cache key">,
+ Group<grp_action>;
+def get_cache_result : F<"get-cache-result">,
+ HelpText<"Get the result value from a cache key">,
+ Group<grp_action>;
+def validate : F<"validate">,
+ HelpText<"Validate ObjectStore">,
+ Group<grp_action>;
+def validate_object : F<"validate-object">,
+ HelpText<"Validate the object for CASID">,
+ Group<grp_action>;
+def validate_if_needed : F<"validate-if-needed">,
+ HelpText<"Validate cas contents if needed">,
+ Group<grp_action>;
+def prune : F<"prune">, HelpText<"Prune local cas storage">, Group<grp_action>;
+
+// Tool options
+
+def cas_path : Separate<["-", "--"], "cas">,
+ MetaVarName<"<path>">,
+ HelpText<"Path to CAS on disk">;
+
+def upstream_cas : Separate<["-", "--"], "upstream-cas">,
+ MetaVarName<"<path>">,
+ HelpText<"Path to another upstream CAS">;
+
+def data : Separate<["-", "--"], "data">,
+ MetaVarName<"<path>">,
+ HelpText<"Path to data or '-' for stdin">;
+
+def check_hash : F<"check-hash">,
+ HelpText<"Check all hashes during validation">;
+
+def allow_recovery : F<"allow-recovery">,
+ HelpText<"Allow recovery of CAS data">;
+
+def force : F<"force">, HelpText<"Force validation even if unnecessary">;
+
+def in_process : F<"in-process">, HelpText<"Validation in-process">;
diff --git a/llvm/tools/llvm-cas/llvm-cas.cpp b/llvm/tools/llvm-cas/llvm-cas.cpp
new file mode 100644
index 0000000..e72ee47
--- /dev/null
+++ b/llvm/tools/llvm-cas/llvm-cas.cpp
@@ -0,0 +1,405 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file A utility for operating on LLVM CAS.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CAS/ActionCache.h"
+#include "llvm/CAS/BuiltinUnifiedCASDatabases.h"
+#include "llvm/CAS/ObjectStore.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace llvm::cas;
+
+namespace {
+enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
+#include "Options.inc"
+#undef OPTION
+};
+
+#define OPTTABLE_STR_TABLE_CODE
+#include "Options.inc"
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Options.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
+
+using namespace llvm::opt;
+static constexpr opt::OptTable::Info InfoTable[] = {
+#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
+#include "Options.inc"
+#undef OPTION
+};
+
+class LLVMCASOptTable : public opt::GenericOptTable {
+public:
+ LLVMCASOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
+};
+
+enum class CommandKind {
+ Invalid,
+ Dump,
+ CatNodeData,
+ MakeBlob,
+ MakeNode,
+ ListObjectReferences,
+ Import,
+ PutCacheKey,
+ GetCacheResult,
+ Validate,
+ ValidateObject,
+ ValidateIfNeeded,
+ Prune,
+};
+
+struct CommandOptions {
+ CommandKind Command = CommandKind::Invalid;
+ std::vector<std::string> Inputs;
+ std::string CASPath;
+ std::string UpstreamCASPath;
+ std::string DataPath;
+ bool CheckHash;
+ bool AllowRecovery;
+ bool Force;
+ bool InProcess;
+
+ static CommandKind getCommandKind(opt::Arg &A) {
+ switch (A.getOption().getID()) {
+ case OPT_cas_dump:
+ return CommandKind::Dump;
+ case OPT_cat_node_data:
+ return CommandKind::CatNodeData;
+ case OPT_make_blob:
+ return CommandKind::MakeBlob;
+ case OPT_make_node:
+ return CommandKind::MakeNode;
+ case OPT_ls_node_refs:
+ return CommandKind::ListObjectReferences;
+ case OPT_import:
+ return CommandKind::Import;
+ case OPT_put_cache_key:
+ return CommandKind::PutCacheKey;
+ case OPT_get_cache_result:
+ return CommandKind::GetCacheResult;
+ case OPT_validate:
+ return CommandKind::Validate;
+ case OPT_validate_object:
+ return CommandKind::ValidateObject;
+ case OPT_validate_if_needed:
+ return CommandKind::ValidateIfNeeded;
+ case OPT_prune:
+ return CommandKind::Prune;
+ }
+ return CommandKind::Invalid;
+ }
+
+ // Command requires input.
+ static bool requiresInput(CommandKind Kind) {
+ return Kind != CommandKind::ValidateIfNeeded &&
+ Kind != CommandKind::Validate && Kind != CommandKind::MakeBlob &&
+ Kind != CommandKind::MakeNode && Kind != CommandKind::Dump &&
+ Kind != CommandKind::Prune;
+ }
+};
+} // namespace
+
+static int dump(ObjectStore &CAS);
+static int listObjectReferences(ObjectStore &CAS, const CASID &ID);
+static int catNodeData(ObjectStore &CAS, const CASID &ID);
+static int makeBlob(ObjectStore &CAS, StringRef DataPath);
+static int makeNode(ObjectStore &CAS, ArrayRef<std::string> References,
+ StringRef DataPath);
+static int import(ObjectStore &FromCAS, ObjectStore &ToCAS,
+ ArrayRef<std::string> Objects);
+static int putCacheKey(ObjectStore &CAS, ActionCache &AC,
+ ArrayRef<std::string> Objects);
+static int getCacheResult(ObjectStore &CAS, ActionCache &AC, const CASID &ID);
+static int validateObject(ObjectStore &CAS, const CASID &ID);
+static int validate(ObjectStore &CAS, ActionCache &AC, bool CheckHash);
+static int validateIfNeeded(StringRef Path, bool CheckHash, bool Force,
+ bool AllowRecovery, bool InProcess,
+ const char *Argv0);
+static int prune(cas::ObjectStore &CAS);
+
+static Expected<CommandOptions> parseOptions(int Argc, char **Argv) {
+ BumpPtrAllocator Alloc;
+ StringSaver Saver(Alloc);
+ SmallVector<const char *> ExpanedArgs;
+ if (!cl::expandResponseFiles(Argc, Argv, nullptr, Saver, ExpanedArgs))
+ return createStringError("cannot expand response file");
+
+ LLVMCASOptTable T;
+ unsigned MI, MC;
+ opt::InputArgList Args = T.ParseArgs(ExpanedArgs, MI, MC);
+
+ for (auto *Arg : Args.filtered(OPT_UNKNOWN)) {
+ llvm::errs() << "ignoring unknown option: " << Arg->getSpelling() << '\n';
+ }
+
+ if (Args.hasArg(OPT_help)) {
+ T.printHelp(
+ outs(),
+ (std::string(Argv[0]) + " [action] [options] <input files>").c_str(),
+ "llvm-cas tool that performs CAS actions.", false);
+ exit(0);
+ }
+
+ CommandOptions Opts;
+ for (auto *A : Args.filtered(OPT_grp_action))
+ Opts.Command = CommandOptions::getCommandKind(*A);
+
+ if (Opts.Command == CommandKind::Invalid)
+ return createStringError("no command action is specified");
+
+ for (auto *File : Args.filtered(OPT_INPUT))
+ Opts.Inputs.push_back(File->getValue());
+ Opts.CASPath = Args.getLastArgValue(OPT_cas_path);
+ Opts.UpstreamCASPath = Args.getLastArgValue(OPT_upstream_cas);
+ Opts.DataPath = Args.getLastArgValue(OPT_data);
+ Opts.CheckHash = Args.hasArg(OPT_check_hash);
+ Opts.AllowRecovery = Args.hasArg(OPT_allow_recovery);
+ Opts.Force = Args.hasArg(OPT_force);
+ Opts.InProcess = Args.hasArg(OPT_in_process);
+
+ // Validate options.
+ if (Opts.CASPath.empty())
+ return createStringError("missing --cas <path>");
+
+ if (Opts.Inputs.empty() && CommandOptions::requiresInput(Opts.Command))
+ return createStringError("missing <input> to operate on");
+
+ return Opts;
+}
+
+int main(int Argc, char **Argv) {
+ InitLLVM X(Argc, Argv);
+
+ ExitOnError ExitOnErr;
+ auto Opts = ExitOnErr(parseOptions(Argc, Argv));
+
+ if (Opts.Command == CommandKind::ValidateIfNeeded)
+ return validateIfNeeded(Opts.CASPath, Opts.CheckHash, Opts.Force,
+ Opts.AllowRecovery, Opts.InProcess, Argv[0]);
+
+ auto [CAS, AC] = ExitOnErr(createOnDiskUnifiedCASDatabases(Opts.CASPath));
+ assert(CAS);
+
+ if (Opts.Command == CommandKind::Dump)
+ return dump(*CAS);
+
+ if (Opts.Command == CommandKind::Validate)
+ return validate(*CAS, *AC, Opts.CheckHash);
+
+ if (Opts.Command == CommandKind::MakeBlob)
+ return makeBlob(*CAS, Opts.DataPath);
+
+ if (Opts.Command == CommandKind::MakeNode)
+ return makeNode(*CAS, Opts.Inputs, Opts.DataPath);
+
+ if (Opts.Command == CommandKind::Prune)
+ return prune(*CAS);
+
+ if (Opts.Command == CommandKind::Import) {
+ if (Opts.UpstreamCASPath.empty())
+ ExitOnErr(createStringError("missing '-upstream-cas'"));
+
+ auto [UpstreamCAS, _] =
+ ExitOnErr(createOnDiskUnifiedCASDatabases(Opts.UpstreamCASPath));
+ return import(*UpstreamCAS, *CAS, Opts.Inputs);
+ }
+
+ if (Opts.Command == CommandKind::PutCacheKey ||
+ Opts.Command == CommandKind::GetCacheResult) {
+ if (!AC)
+ ExitOnErr(createStringError("no action-cache available"));
+ }
+
+ if (Opts.Command == CommandKind::PutCacheKey)
+ return putCacheKey(*CAS, *AC, Opts.Inputs);
+
+ // Remaining commands need exactly one CAS object.
+ if (Opts.Inputs.size() > 1)
+ ExitOnErr(createStringError("too many <object>s, expected 1"));
+ CASID ID = ExitOnErr(CAS->parseID(Opts.Inputs.front()));
+
+ if (Opts.Command == CommandKind::GetCacheResult)
+ return getCacheResult(*CAS, *AC, ID);
+
+ if (Opts.Command == CommandKind::ListObjectReferences)
+ return listObjectReferences(*CAS, ID);
+
+ if (Opts.Command == CommandKind::CatNodeData)
+ return catNodeData(*CAS, ID);
+
+ assert(Opts.Command == CommandKind::ValidateObject);
+ return validateObject(*CAS, ID);
+}
+
+static Expected<std::unique_ptr<MemoryBuffer>> openBuffer(StringRef DataPath) {
+ if (DataPath.empty())
+ return createStringError("--data missing");
+ return errorOrToExpected(DataPath == "-"
+ ? llvm::MemoryBuffer::getSTDIN()
+ : llvm::MemoryBuffer::getFile(DataPath));
+}
+
+int dump(ObjectStore &CAS) {
+ ExitOnError ExitOnErr("llvm-cas: dump: ");
+ CAS.print(llvm::outs());
+ return 0;
+}
+
+int makeBlob(ObjectStore &CAS, StringRef DataPath) {
+ ExitOnError ExitOnErr("llvm-cas: make-blob: ");
+ std::unique_ptr<MemoryBuffer> Buffer = ExitOnErr(openBuffer(DataPath));
+
+ ObjectProxy Blob = ExitOnErr(CAS.createProxy({}, Buffer->getBuffer()));
+ llvm::outs() << Blob.getID() << "\n";
+ return 0;
+}
+
+int catNodeData(ObjectStore &CAS, const CASID &ID) {
+ ExitOnError ExitOnErr("llvm-cas: cat-node-data: ");
+ llvm::outs() << ExitOnErr(CAS.getProxy(ID)).getData();
+ return 0;
+}
+
+int listObjectReferences(ObjectStore &CAS, const CASID &ID) {
+ ExitOnError ExitOnErr("llvm-cas: ls-node-refs: ");
+
+ ObjectProxy Object = ExitOnErr(CAS.getProxy(ID));
+ ExitOnErr(Object.forEachReference([&](ObjectRef Ref) -> Error {
+ llvm::outs() << CAS.getID(Ref) << "\n";
+ return Error::success();
+ }));
+
+ return 0;
+}
+
+static int makeNode(ObjectStore &CAS, ArrayRef<std::string> Objects,
+ StringRef DataPath) {
+ std::unique_ptr<MemoryBuffer> Data =
+ ExitOnError("llvm-cas: make-node: data: ")(openBuffer(DataPath));
+
+ SmallVector<ObjectRef> IDs;
+ for (StringRef Object : Objects) {
+ ExitOnError ObjectErr("llvm-cas: make-node: ref: ");
+ std::optional<ObjectRef> ID =
+ CAS.getReference(ObjectErr(CAS.parseID(Object)));
+ if (!ID)
+ ObjectErr(createStringError("unknown object '" + Object + "'"));
+ IDs.push_back(*ID);
+ }
+
+ ExitOnError ExitOnErr("llvm-cas: make-node: ");
+ ObjectProxy Object = ExitOnErr(CAS.createProxy(IDs, Data->getBuffer()));
+ llvm::outs() << Object.getID() << "\n";
+ return 0;
+}
+
+static int import(ObjectStore &FromCAS, ObjectStore &ToCAS,
+ ArrayRef<std::string> Objects) {
+ ExitOnError ExitOnErr("llvm-cas: import: ");
+
+ for (StringRef Object : Objects) {
+ CASID ID = ExitOnErr(FromCAS.parseID(Object));
+ auto Ref = FromCAS.getReference(ID);
+ if (!Ref)
+ ExitOnErr(createStringError("input not found: " + ID.toString()));
+
+ auto Imported = ExitOnErr(ToCAS.importObject(FromCAS, *Ref));
+ llvm::outs() << ToCAS.getID(Imported).toString() << "\n";
+ }
+ return 0;
+}
+
+static int putCacheKey(ObjectStore &CAS, ActionCache &AC,
+ ArrayRef<std::string> Objects) {
+ ExitOnError ExitOnErr("llvm-cas: put-cache-key: ");
+
+ if (Objects.size() % 2 != 0)
+ ExitOnErr(createStringError("expected pairs of inputs"));
+ while (!Objects.empty()) {
+ CASID Key = ExitOnErr(CAS.parseID(Objects[0]));
+ CASID Result = ExitOnErr(CAS.parseID(Objects[1]));
+ Objects = Objects.drop_front(2);
+ ExitOnErr(AC.put(Key, Result));
+ }
+ return 0;
+}
+
+static int getCacheResult(ObjectStore &CAS, ActionCache &AC, const CASID &ID) {
+ ExitOnError ExitOnErr("llvm-cas: get-cache-result: ");
+
+ auto Result = ExitOnErr(AC.get(ID));
+ if (!Result) {
+ outs() << "result not found\n";
+ return 1;
+ }
+ outs() << *Result << "\n";
+ return 0;
+}
+
+int validateObject(ObjectStore &CAS, const CASID &ID) {
+ ExitOnError ExitOnErr("llvm-cas: validate-object: ");
+ ExitOnErr(CAS.validateObject(ID));
+ outs() << ID << ": validated successfully\n";
+ return 0;
+}
+
+int validate(ObjectStore &CAS, ActionCache &AC, bool CheckHash) {
+ ExitOnError ExitOnErr("llvm-cas: validate: ");
+ ExitOnErr(CAS.validate(CheckHash));
+ ExitOnErr(AC.validate());
+ outs() << "validated successfully\n";
+ return 0;
+}
+
+int validateIfNeeded(StringRef Path, bool CheckHash, bool Force,
+ bool AllowRecovery, bool InProcess, const char *Argv0) {
+ ExitOnError ExitOnErr("llvm-cas: validate-if-needed: ");
+ std::string ExecStorage;
+ std::optional<StringRef> Exec;
+ if (!InProcess) {
+ ExecStorage = sys::fs::getMainExecutable(Argv0, (void *)validateIfNeeded);
+ Exec = ExecStorage;
+ }
+ ValidationResult Result = ExitOnErr(validateOnDiskUnifiedCASDatabasesIfNeeded(
+ Path, CheckHash, AllowRecovery, Force, Exec));
+ switch (Result) {
+ case ValidationResult::Valid:
+ outs() << "validated successfully\n";
+ break;
+ case ValidationResult::Recovered:
+ outs() << "recovered from invalid data\n";
+ break;
+ case ValidationResult::Skipped:
+ outs() << "validation skipped\n";
+ break;
+ }
+ return 0;
+}
+
+static int prune(cas::ObjectStore &CAS) {
+ ExitOnError ExitOnErr("llvm-cas: prune: ");
+ ExitOnErr(CAS.pruneStorageData());
+ return 0;
+}
diff --git a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h
index 55e628a..4ee3e7c 100644
--- a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h
+++ b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h
@@ -37,7 +37,6 @@
#include "llvm/Support/raw_ostream.h"
#include <functional>
-#include <set>
using Instr = llvm::cfi_verify::FileAnalysis::Instr;
diff --git a/llvm/tools/llvm-config/llvm-config.cpp b/llvm/tools/llvm-config/llvm-config.cpp
index 020b1b5..5300c5c 100644
--- a/llvm/tools/llvm-config/llvm-config.cpp
+++ b/llvm/tools/llvm-config/llvm-config.cpp
@@ -24,6 +24,7 @@
#include "llvm/Config/config.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
@@ -232,6 +233,7 @@ Options:\n\
--link-static Link the component libraries statically.\n\
--obj-root Print the object root used to build LLVM.\n\
--prefix Print the installation prefix.\n\
+ --quote-paths Quote and escape paths when needed.\n\
--shared-mode Print how the provided components can be collectively linked (`shared` or `static`).\n\
--system-libs System Libraries needed to link against LLVM components.\n\
--targets-built List of all targets currently built.\n\
@@ -324,7 +326,7 @@ int main(int argc, char **argv) {
// information.
std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir,
ActiveCMakeDir;
- std::string ActiveIncludeOption;
+ std::vector<std::string> ActiveIncludeOptions;
if (IsInDevelopmentTree) {
ActiveIncludeDir = std::string(LLVM_SRC_ROOT) + "/include";
ActivePrefix = CurrentExecPrefix;
@@ -350,8 +352,8 @@ int main(int argc, char **argv) {
}
// We need to include files from both the source and object trees.
- ActiveIncludeOption =
- ("-I" + ActiveIncludeDir + " " + "-I" + ActiveObjRoot + "/include");
+ ActiveIncludeOptions.push_back(ActiveIncludeDir);
+ ActiveIncludeOptions.push_back(ActiveObjRoot + "/include");
} else {
ActivePrefix = CurrentExecPrefix;
{
@@ -370,7 +372,7 @@ int main(int argc, char **argv) {
sys::path::make_absolute(ActivePrefix, Path);
ActiveCMakeDir = std::string(Path);
}
- ActiveIncludeOption = "-I" + ActiveIncludeDir;
+ ActiveIncludeOptions.push_back(ActiveIncludeDir);
}
/// We only use `shared library` mode in cases where the static library form
@@ -399,7 +401,9 @@ int main(int argc, char **argv) {
llvm::replace(ActiveBinDir, '/', '\\');
llvm::replace(ActiveLibDir, '/', '\\');
llvm::replace(ActiveCMakeDir, '/', '\\');
- llvm::replace(ActiveIncludeOption, '/', '\\');
+ llvm::replace(ActiveIncludeDir, '/', '\\');
+ for (auto &Include : ActiveIncludeOptions)
+ llvm::replace(Include, '/', '\\');
}
SharedDir = ActiveBinDir;
StaticDir = ActiveLibDir;
@@ -501,6 +505,32 @@ int main(int argc, char **argv) {
};
raw_ostream &OS = outs();
+
+ // Check if we want quoting and escaping.
+ bool QuotePaths = std::any_of(&argv[0], &argv[argc], [](const char *Arg) {
+ return StringRef(Arg) == "--quote-paths";
+ });
+
+ auto MaybePrintQuoted = [&](StringRef Str) {
+ if (QuotePaths)
+ sys::printArg(OS, Str, /*Quote=*/false); // only add quotes if necessary
+ else
+ OS << Str;
+ };
+
+ // Render include paths and associated flags
+ auto RenderFlags = [&](StringRef Flags) {
+ bool First = true;
+ for (auto &Include : ActiveIncludeOptions) {
+ if (!First)
+ OS << ' ';
+ std::string FlagsStr = "-I" + Include;
+ MaybePrintQuoted(FlagsStr);
+ First = false;
+ }
+ OS << ' ' << Flags << '\n';
+ };
+
for (int i = 1; i != argc; ++i) {
StringRef Arg = argv[i];
@@ -509,24 +539,32 @@ int main(int argc, char **argv) {
if (Arg == "--version") {
OS << PACKAGE_VERSION << '\n';
} else if (Arg == "--prefix") {
- OS << ActivePrefix << '\n';
+ MaybePrintQuoted(ActivePrefix);
+ OS << '\n';
} else if (Arg == "--bindir") {
- OS << ActiveBinDir << '\n';
+ MaybePrintQuoted(ActiveBinDir);
+ OS << '\n';
} else if (Arg == "--includedir") {
- OS << ActiveIncludeDir << '\n';
+ MaybePrintQuoted(ActiveIncludeDir);
+ OS << '\n';
} else if (Arg == "--libdir") {
- OS << ActiveLibDir << '\n';
+ MaybePrintQuoted(ActiveLibDir);
+ OS << '\n';
} else if (Arg == "--cmakedir") {
- OS << ActiveCMakeDir << '\n';
+ MaybePrintQuoted(ActiveCMakeDir);
+ OS << '\n';
} else if (Arg == "--cppflags") {
- OS << ActiveIncludeOption << ' ' << LLVM_CPPFLAGS << '\n';
+ RenderFlags(LLVM_CPPFLAGS);
} else if (Arg == "--cflags") {
- OS << ActiveIncludeOption << ' ' << LLVM_CFLAGS << '\n';
+ RenderFlags(LLVM_CFLAGS);
} else if (Arg == "--cxxflags") {
- OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << '\n';
+ RenderFlags(LLVM_CXXFLAGS);
} else if (Arg == "--ldflags") {
- OS << ((HostTriple.isWindowsMSVCEnvironment()) ? "-LIBPATH:" : "-L")
- << ActiveLibDir << ' ' << LLVM_LDFLAGS << '\n';
+ std::string LDFlags =
+ HostTriple.isWindowsMSVCEnvironment() ? "-LIBPATH:" : "-L";
+ LDFlags += ActiveLibDir;
+ MaybePrintQuoted(LDFlags);
+ OS << ' ' << LLVM_LDFLAGS << '\n';
} else if (Arg == "--system-libs") {
PrintSystemLibs = true;
} else if (Arg == "--libs") {
@@ -580,7 +618,8 @@ int main(int argc, char **argv) {
} else if (Arg == "--shared-mode") {
PrintSharedMode = true;
} else if (Arg == "--obj-root") {
- OS << ActivePrefix << '\n';
+ MaybePrintQuoted(ActivePrefix);
+ OS << '\n';
} else if (Arg == "--ignore-libllvm") {
LinkDyLib = false;
LinkMode = BuiltSharedLibs ? LinkModeShared : LinkModeAuto;
@@ -590,6 +629,8 @@ int main(int argc, char **argv) {
LinkMode = LinkModeStatic;
} else if (Arg == "--help") {
usage(false);
+ } else if (Arg == "--quote-paths") {
+ // Was already handled above this loop.
} else {
usage();
}
@@ -682,26 +723,30 @@ int main(int argc, char **argv) {
auto PrintForLib = [&](const StringRef &Lib) {
const bool Shared = LinkMode == LinkModeShared;
+ std::string LibFileName;
if (PrintLibNames) {
- OS << GetComponentLibraryFileName(Lib, Shared);
+ LibFileName = GetComponentLibraryFileName(Lib, Shared);
} else if (PrintLibFiles) {
- OS << GetComponentLibraryPath(Lib, Shared);
+ LibFileName = GetComponentLibraryPath(Lib, Shared);
} else if (PrintLibs) {
// On Windows, output full path to library without parameters.
// Elsewhere, if this is a typical library name, include it using -l.
if (HostTriple.isWindowsMSVCEnvironment()) {
- OS << GetComponentLibraryPath(Lib, Shared);
+ LibFileName = GetComponentLibraryPath(Lib, Shared);
} else {
+ LibFileName = "-l";
StringRef LibName;
if (GetComponentLibraryNameSlice(Lib, LibName)) {
// Extract library name (remove prefix and suffix).
- OS << "-l" << LibName;
+ LibFileName += LibName;
} else {
// Lib is already a library name without prefix and suffix.
- OS << "-l" << Lib;
+ LibFileName += Lib;
}
}
}
+ if (!LibFileName.empty())
+ MaybePrintQuoted(LibFileName);
};
if (LinkMode == LinkModeShared && LinkDyLib)
diff --git a/llvm/tools/llvm-cov/CoverageExporter.h b/llvm/tools/llvm-cov/CoverageExporter.h
index 751e55d..ba946a1 100644
--- a/llvm/tools/llvm-cov/CoverageExporter.h
+++ b/llvm/tools/llvm-cov/CoverageExporter.h
@@ -37,7 +37,7 @@ protected:
: Coverage(CoverageMapping), Options(Options), OS(OS) {}
public:
- virtual ~CoverageExporter(){};
+ virtual ~CoverageExporter() = default;
/// Render the CoverageMapping object.
virtual void renderRoot(const CoverageFilters &IgnoreFilters) = 0;
diff --git a/llvm/tools/llvm-cov/CoverageFilters.h b/llvm/tools/llvm-cov/CoverageFilters.h
index 5345b0c..3cee23a 100644
--- a/llvm/tools/llvm-cov/CoverageFilters.h
+++ b/llvm/tools/llvm-cov/CoverageFilters.h
@@ -28,7 +28,7 @@ struct FunctionRecord;
/// Matches specific functions that pass the requirement of this filter.
class CoverageFilter {
public:
- virtual ~CoverageFilter() {}
+ virtual ~CoverageFilter() = default;
/// Return true if the function passes the requirements of this filter.
virtual bool matches(const coverage::CoverageMapping &CM,
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h
index 43fb890a..bde187e 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.h
+++ b/llvm/tools/llvm-cov/SourceCoverageView.h
@@ -122,7 +122,7 @@ public:
static std::unique_ptr<CoveragePrinter>
create(const CoverageViewOptions &Opts);
- virtual ~CoveragePrinter() {}
+ virtual ~CoveragePrinter() = default;
/// @name File Creation Interface
/// @{
@@ -288,7 +288,7 @@ public:
create(StringRef SourceName, const MemoryBuffer &File,
const CoverageViewOptions &Options, CoverageData &&CoverageInfo);
- virtual ~SourceCoverageView() {}
+ virtual ~SourceCoverageView() = default;
/// Return the source name formatted for the host OS.
std::string getSourceName() const;
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index c94d385..bdef099 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -955,8 +955,8 @@ void SourceCoverageViewHTML::renderLine(raw_ostream &OS, LineRef L,
// 2. Escape all of the snippets.
- for (unsigned I = 0, E = Snippets.size(); I < E; ++I)
- Snippets[I] = escape(Snippets[I], getOptions());
+ for (std::string &Snippet : Snippets)
+ Snippet = escape(Snippet, getOptions());
// 3. Use \p WrappedSegment to set the highlight for snippet 0. Use segment
// 1 to set the highlight for snippet 2, segment 2 to set the highlight for
diff --git a/llvm/tools/llvm-diff/lib/DiffConsumer.h b/llvm/tools/llvm-diff/lib/DiffConsumer.h
index 08c3afc..d4f339b 100644
--- a/llvm/tools/llvm-diff/lib/DiffConsumer.h
+++ b/llvm/tools/llvm-diff/lib/DiffConsumer.h
@@ -49,7 +49,7 @@ class StringRef;
virtual void logd(const DiffLogBuilder &Log) = 0;
protected:
- virtual ~Consumer() {}
+ virtual ~Consumer() = default;
};
class DiffConsumer : public Consumer {
diff --git a/llvm/tools/llvm-diff/lib/DifferenceEngine.h b/llvm/tools/llvm-diff/lib/DifferenceEngine.h
index 436a355..01fd0d95 100644
--- a/llvm/tools/llvm-diff/lib/DifferenceEngine.h
+++ b/llvm/tools/llvm-diff/lib/DifferenceEngine.h
@@ -17,7 +17,6 @@
#include "DiffConsumer.h"
#include "DiffLog.h"
#include "llvm/ADT/StringRef.h"
-#include <utility>
namespace llvm {
class Function;
@@ -54,7 +53,7 @@ namespace llvm {
virtual bool operator()(const Value *L, const Value *R) = 0;
protected:
- virtual ~Oracle() {}
+ virtual ~Oracle() = default;
};
DifferenceEngine(Consumer &consumer)
diff --git a/llvm/tools/llvm-diff/llvm-diff.cpp b/llvm/tools/llvm-diff/llvm-diff.cpp
index 2126b91..45b8ed9 100644
--- a/llvm/tools/llvm-diff/llvm-diff.cpp
+++ b/llvm/tools/llvm-diff/llvm-diff.cpp
@@ -20,11 +20,9 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
#include <string>
-#include <utility>
-
using namespace llvm;
diff --git a/llvm/tools/llvm-dis/llvm-dis.cpp b/llvm/tools/llvm-dis/llvm-dis.cpp
index 35c54096..90ae3ef 100644
--- a/llvm/tools/llvm-dis/llvm-dis.cpp
+++ b/llvm/tools/llvm-dis/llvm-dis.cpp
@@ -101,13 +101,26 @@ static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
}
}
class CommentWriter : public AssemblyAnnotationWriter {
+private:
+ bool canSafelyAccessUses(const Value &V) {
+ // Can't safely access uses, if module not materialized.
+ const GlobalValue *GV = dyn_cast<GlobalValue>(&V);
+ return !GV || (GV->getParent() && GV->getParent()->isMaterialized());
+ }
+
public:
void emitFunctionAnnot(const Function *F,
formatted_raw_ostream &OS) override {
+ if (!canSafelyAccessUses(*F))
+ return;
+
OS << "; [#uses=" << F->getNumUses() << ']'; // Output # uses
OS << '\n';
}
void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
+ if (!canSafelyAccessUses(V))
+ return;
+
bool Padded = false;
if (!V.getType()->isVoidTy()) {
OS.PadToColumn(50);
diff --git a/llvm/tools/llvm-dwarfdump/CMakeLists.txt b/llvm/tools/llvm-dwarfdump/CMakeLists.txt
index aeb1b8f..7a0adf3 100644
--- a/llvm/tools/llvm-dwarfdump/CMakeLists.txt
+++ b/llvm/tools/llvm-dwarfdump/CMakeLists.txt
@@ -1,4 +1,5 @@
set(LLVM_LINK_COMPONENTS
+ BinaryFormat
DebugInfoDWARF
DebugInfoDWARFLowLevel
AllTargetsDescs
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 11eb58e..6f120f9 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
@@ -242,6 +243,15 @@ static opt<bool>
cat(DwarfDumpCategory));
static alias ShowParentsAlias("p", desc("Alias for --show-parents."),
aliasopt(ShowParents), cl::NotHidden);
+
+static list<std::string> FilterChildTag(
+ "filter-child-tag",
+ desc("When --show-children is specified, show only DIEs with the "
+ "specified DWARF tags."),
+ value_desc("list of DWARF tags"), cat(DwarfDumpCategory));
+static alias FilterChildTagAlias("t", desc("Alias for --filter-child-tag."),
+ aliasopt(FilterChildTag), cl::NotHidden);
+
static opt<bool>
ShowForm("show-form",
desc("Show DWARF form types after the DWARF attribute types."),
@@ -330,6 +340,13 @@ static cl::extrahelp
/// @}
//===----------------------------------------------------------------------===//
+static llvm::SmallVector<unsigned>
+makeTagVector(const list<std::string> &TagStrings) {
+ return llvm::map_to_vector(TagStrings, [](const std::string &Tag) {
+ return llvm::dwarf::getTag(Tag);
+ });
+}
+
static void error(Error Err) {
if (!Err)
return;
@@ -356,6 +373,7 @@ static DIDumpOptions getDumpOpts(DWARFContext &C) {
DumpOpts.ShowAddresses = !Diff;
DumpOpts.ShowChildren = ShowChildren;
DumpOpts.ShowParents = ShowParents;
+ DumpOpts.FilterChildTag = makeTagVector(FilterChildTag);
DumpOpts.ShowForm = ShowForm;
DumpOpts.SummarizeTypes = SummarizeTypes;
DumpOpts.Verbose = Verbose;
diff --git a/llvm/tools/llvm-dwp/Opts.td b/llvm/tools/llvm-dwp/Opts.td
index 46593bc..d4474ac 100644
--- a/llvm/tools/llvm-dwp/Opts.td
+++ b/llvm/tools/llvm-dwp/Opts.td
@@ -16,3 +16,18 @@ def continueOnCuIndexOverflow_EQ : Joined<["-", "--"], "continue-on-cu-index-ove
"\t\ttruncated but valid DWP file, discarding any DWO files that would not fit within \n"
"\t\tthe 32 bit/4GB limits of the format.">,
Values<"continue,soft-stop">;
+
+def dwarf64StringOffsets : Flag<["-", "--"], "dwarf64-str-offsets-promotion">;
+def dwarf64StringOffsets_EQ
+ : Joined<["-", "--"], "dwarf64-str-offsets-promotion=">,
+ HelpText<"default = enabled, This allows .debug_str tables to exceed the "
+ "4GB limit\n"
+ "and have any DWARF32 .debug_str_offsets tables converted to "
+ "DWARF64 only for tables\n"
+ "that require 64 bit string offsets. = disabled, This setting "
+ "doesn't convert DWARF32\n"
+ ".debug_str_offsets tables in .dwo files to DWARF64 in the .dwp "
+ "file. = always, This\n"
+ "forces all .debug_str_offsets tables to be emitted as DWARF64. "
+ "This is used for testing.">,
+ Values<"disabled,enabled,always">;
diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp
index 31bad2d..2892450 100644
--- a/llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -125,6 +125,9 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
llvm::BumpPtrAllocator A;
llvm::StringSaver Saver{A};
OnCuIndexOverflow OverflowOptValue = OnCuIndexOverflow::HardStop;
+ Dwarf64StrOffsetsPromotion Dwarf64StrOffsetsValue =
+ Dwarf64StrOffsetsPromotion::Disabled;
+
opt::InputArgList Args =
Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
llvm::errs() << Msg << '\n';
@@ -161,6 +164,27 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
}
}
+ if (Arg *Arg = Args.getLastArg(OPT_dwarf64StringOffsets,
+ OPT_dwarf64StringOffsets_EQ)) {
+ if (Arg->getOption().matches(OPT_dwarf64StringOffsets)) {
+ Dwarf64StrOffsetsValue = Dwarf64StrOffsetsPromotion::Enabled;
+ } else {
+ std::string OptValue = Arg->getValue();
+ if (OptValue == "disabled") {
+ Dwarf64StrOffsetsValue = Dwarf64StrOffsetsPromotion::Disabled;
+ } else if (OptValue == "enabled") {
+ Dwarf64StrOffsetsValue = Dwarf64StrOffsetsPromotion::Enabled;
+ } else if (OptValue == "always") {
+ Dwarf64StrOffsetsValue = Dwarf64StrOffsetsPromotion::Always;
+ } else {
+ llvm::errs()
+ << "invalid value for --dwarf64-str-offsets-promotion. Valid "
+ "values are one of: \"enabled\", \"disabled\" or \"always\".\n";
+ exit(1);
+ }
+ }
+ }
+
for (const llvm::opt::Arg *A : Args.filtered(OPT_execFileNames))
ExecFilenames.emplace_back(A->getValue());
@@ -274,7 +298,8 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
if (!MS)
return error("no object streamer for target " + TripleName, Context);
- if (auto Err = write(*MS, DWOFilenames, OverflowOptValue)) {
+ if (auto Err =
+ write(*MS, DWOFilenames, OverflowOptValue, Dwarf64StrOffsetsValue)) {
logAllUnhandledErrors(std::move(Err), WithColor::error());
return 1;
}
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 2c13dd5..0e73ada 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -112,7 +112,7 @@ namespace {
// Use X19 as the loop counter register since it's a callee-saved register
// that's available for temporary use.
-constexpr const MCPhysReg kDefaultLoopCounterReg = AArch64::X19;
+constexpr MCPhysReg kDefaultLoopCounterReg = AArch64::X19;
class ExegesisAArch64Target : public ExegesisTarget {
public:
diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
index fb84328..f3bf9690 100644
--- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
@@ -446,7 +446,7 @@ void Analysis::printClusterRawHtml(const BenchmarkClustering::ClusterId &Id,
} // namespace exegesis
-static constexpr const char kHtmlHead[] = R"(
+static constexpr char kHtmlHead[] = R"(
<head>
<title>llvm-exegesis Analysis Results</title>
<style>
diff --git a/llvm/tools/llvm-exegesis/lib/Assembler.cpp b/llvm/tools/llvm-exegesis/lib/Assembler.cpp
index fd7924d..163f141 100644
--- a/llvm/tools/llvm-exegesis/lib/Assembler.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Assembler.cpp
@@ -44,8 +44,8 @@
namespace llvm {
namespace exegesis {
-static constexpr const char ModuleID[] = "ExegesisInfoTest";
-static constexpr const char FunctionID[] = "foo";
+static constexpr char ModuleID[] = "ExegesisInfoTest";
+static constexpr char FunctionID[] = "foo";
static const Align kFunctionAlignment(4096);
// Fills the given basic block with register setup code, and returns true if
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index 1823a53..c6164b6 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -21,9 +21,9 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
-static constexpr const char kIntegerPrefix[] = "i_0x";
-static constexpr const char kDoublePrefix[] = "f_";
-static constexpr const char kInvalidOperand[] = "INVALID";
+static constexpr char kIntegerPrefix[] = "i_0x";
+static constexpr char kDoublePrefix[] = "f_";
+static constexpr char kInvalidOperand[] = "INVALID";
namespace llvm {
@@ -202,7 +202,7 @@ struct CustomMappingTraits<std::map<exegesis::ValidationEvent, int64_t>> {
Io.setError("Key is not a valid validation event");
return;
}
- Io.mapRequired(KeyStr.str().c_str(), VI[*Key]);
+ Io.mapRequired(KeyStr, VI[*Key]);
}
static void output(IO &Io, std::map<exegesis::ValidationEvent, int64_t> &VI) {
@@ -245,8 +245,8 @@ template <> struct SequenceElementTraits<exegesis::RegisterValue> {
};
template <> struct ScalarTraits<exegesis::RegisterValue> {
- static constexpr const unsigned kRadix = 16;
- static constexpr const bool kSigned = false;
+ static constexpr unsigned kRadix = 16;
+ static constexpr bool kSigned = false;
static void output(const exegesis::RegisterValue &RV, void *Ctx,
raw_ostream &Out) {
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 1fd0a15..a86be13 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -27,7 +27,6 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Support/SystemZ/zOSSupport.h"
#include <cmath>
#include <memory>
#include <string>
@@ -155,7 +154,7 @@ private:
#ifdef LLVM_ON_UNIX
// See "Exit Status for Commands":
// https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html
- constexpr const int kSigOffset = 128;
+ constexpr int kSigOffset = 128;
return make_error<SnippetSignal>(CRC.RetCode - kSigOffset);
#else
// The exit code of the process on windows is not meaningful as a
@@ -877,7 +876,7 @@ Error BenchmarkRunner::getValidationCountersToRun(
return Error::success();
}
-BenchmarkRunner::FunctionExecutor::~FunctionExecutor() {}
+BenchmarkRunner::FunctionExecutor::~FunctionExecutor() = default;
} // namespace exegesis
} // namespace llvm
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
index e688b81..16d3c9c 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
@@ -73,8 +73,8 @@ public:
// Scratch space to run instructions that touch memory.
struct ScratchSpace {
- static constexpr const size_t kAlignment = 1024;
- static constexpr const size_t kSize = 1 << 20; // 1MB.
+ static constexpr size_t kAlignment = 1024;
+ static constexpr size_t kSize = 1 << 20; // 1MB.
ScratchSpace()
: UnalignedPtr(std::make_unique<char[]>(kSize + kAlignment)),
AlignedPtr(
diff --git a/llvm/tools/llvm-exegesis/lib/Clustering.h b/llvm/tools/llvm-exegesis/lib/Clustering.h
index 9d6c110..2b0f5b4 100644
--- a/llvm/tools/llvm-exegesis/lib/Clustering.h
+++ b/llvm/tools/llvm-exegesis/lib/Clustering.h
@@ -67,11 +67,11 @@ public:
ClusterId(size_t Id, bool IsUnstable = false)
: Id_(Id), IsUnstable_(IsUnstable) {}
- static constexpr const size_t kMaxValid =
+ static constexpr size_t kMaxValid =
(std::numeric_limits<size_t>::max() >> 1) - 4;
- static constexpr const size_t kNoise = kMaxValid + 1;
- static constexpr const size_t kError = kMaxValid + 2;
- static constexpr const size_t kUndef = kMaxValid + 3;
+ static constexpr size_t kNoise = kMaxValid + 1;
+ static constexpr size_t kError = kMaxValid + 2;
+ static constexpr size_t kUndef = kMaxValid + 3;
size_t Id_ : (std::numeric_limits<size_t>::digits - 1);
size_t IsUnstable_ : 1;
diff --git a/llvm/tools/llvm-exegesis/lib/Error.cpp b/llvm/tools/llvm-exegesis/lib/Error.cpp
index 2908df2..9024ba5 100644
--- a/llvm/tools/llvm-exegesis/lib/Error.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Error.cpp
@@ -10,7 +10,6 @@
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
#ifdef LLVM_ON_UNIX
-#include "llvm/Support/SystemZ/zOSSupport.h"
#include <string.h>
#endif // LLVM_ON_UNIX
diff --git a/llvm/tools/llvm-exegesis/lib/Error.h b/llvm/tools/llvm-exegesis/lib/Error.h
index 9b71fe8..c899023 100644
--- a/llvm/tools/llvm-exegesis/lib/Error.h
+++ b/llvm/tools/llvm-exegesis/lib/Error.h
@@ -81,7 +81,7 @@ private:
struct PerfCounterNotFullyEnabled
: public ErrorInfo<PerfCounterNotFullyEnabled> {
static char ID;
- PerfCounterNotFullyEnabled() {}
+ PerfCounterNotFullyEnabled() = default;
void log(raw_ostream &OS) const override;
diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
index 66c770d..b544ae7 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
@@ -8,7 +8,6 @@
#include "MCInstrDescView.h"
-#include <iterator>
#include <tuple>
#include "llvm/ADT/STLExtras.h"
@@ -120,7 +119,7 @@ Instruction::create(const MCInstrInfo &InstrInfo,
Operand.IsDef = (OpIndex < Description->getNumDefs());
Operand.IsEarlyClobber =
(Description->getOperandConstraint(OpIndex, MCOI::EARLY_CLOBBER) != -1);
- // TODO(gchatelet): Handle isLookupPtrRegClass.
+ // TODO(gchatelet): Handle LookupRegClassByHwMode.
if (OpInfo.RegClass >= 0)
Operand.Tracker = &RATC.getRegisterClass(OpInfo.RegClass);
int TiedToIndex = Description->getOperandConstraint(OpIndex, MCOI::TIED_TO);
diff --git a/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp
index 79a585e..aa40913 100644
--- a/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.cpp
@@ -350,7 +350,5 @@ ParallelSnippetGenerator::generateCodeTemplates(
return Result;
}
-constexpr const size_t ParallelSnippetGenerator::kMinNumDifferentAddresses;
-
} // namespace exegesis
} // namespace llvm
diff --git a/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.h b/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.h
index 8a6b856..d3c85c0 100644
--- a/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.h
+++ b/llvm/tools/llvm-exegesis/lib/ParallelSnippetGenerator.h
@@ -28,7 +28,7 @@ public:
generateCodeTemplates(InstructionTemplate Variant,
const BitVector &ForbiddenRegisters) const override;
- static constexpr const size_t kMinNumDifferentAddresses = 6;
+ static constexpr size_t kMinNumDifferentAddresses = 6;
private:
// Instantiates memory operands within a snippet.
diff --git a/llvm/tools/llvm-exegesis/lib/PerfHelper.h b/llvm/tools/llvm-exegesis/lib/PerfHelper.h
index 4a825b2..744e3c2 100644
--- a/llvm/tools/llvm-exegesis/lib/PerfHelper.h
+++ b/llvm/tools/llvm-exegesis/lib/PerfHelper.h
@@ -21,7 +21,6 @@
#include <cstdint>
#include <functional>
-#include <memory>
#ifdef _MSC_VER
typedef int pid_t;
diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
index ea830bd..6eeb07f 100644
--- a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
@@ -819,6 +819,15 @@ void ExegesisRISCVTarget::fillMemoryOperands(InstructionTemplate &IT,
assert(MemOp.isReg() && "Memory operand expected to be register");
+ unsigned Opcode = I.getOpcode();
+ if (Opcode == RISCV::C_LDSP || Opcode == RISCV::C_LWSP ||
+ Opcode == RISCV::C_SDSP || Opcode == RISCV::C_SWSP) {
+ IT.getValueFor(I.Operands[0]) = MCOperand::createReg(RISCV::X2);
+ // Force base register to SP (X2)
+ IT.getValueFor(MemOp) = MCOperand::createReg(RISCV::X2);
+ return;
+ }
+
IT.getValueFor(MemOp) = MCOperand::createReg(Reg);
}
@@ -855,10 +864,17 @@ Error ExegesisRISCVTarget::randomizeTargetMCOperand(
// 5-bit unsigned immediate value.
AssignedValue = MCOperand::createImm(randomIndex(31));
break;
+ case RISCVOp::OPERAND_SIMM12_LO:
+ case RISCVOp::OPERAND_UIMM20_LUI:
+ case RISCVOp::OPERAND_UIMM20_AUIPC:
+ case RISCVOp::OPERAND_BARE_SIMM32:
+ AssignedValue = MCOperand::createImm(0);
+ break;
default:
if (OperandType >= RISCVOp::OPERAND_FIRST_RISCV_IMM &&
OperandType <= RISCVOp::OPERAND_LAST_RISCV_IMM)
AssignedValue = MCOperand::createImm(0);
+ break;
}
return Error::success();
}
diff --git a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
index 707e6ee..71b2d71 100644
--- a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
@@ -142,7 +142,12 @@ static void appendCodeTemplates(const LLVMState &State,
return;
ET.fillMemoryOperands(Variant, ScratchMemoryRegister, 0);
- Variant.getValueFor(DefOp) = MCOperand::createReg(ScratchMemoryRegister);
+
+ // Only force the def register to ScratchMemoryRegister if the target
+ // hasn't assigned a value yet.
+ MCOperand &DefVal = Variant.getValueFor(DefOp);
+ if (!DefVal.isValid())
+ DefVal = MCOperand::createReg(ScratchMemoryRegister);
CodeTemplate CT;
CT.Execution = ExecutionModeBit;
diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
index 7023f1b..86d4e19 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
@@ -21,9 +21,17 @@
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Program.h"
+#define DEBUG_TYPE "snippet-generator"
+
namespace llvm {
namespace exegesis {
+static cl::opt<unsigned>
+ RandomGeneratorSeed("random-generator-seed",
+ cl::desc("The seed value to use for the random number "
+ "generator when generating snippets."),
+ cl::init(0));
+
std::vector<CodeTemplate> getSingleton(CodeTemplate &&CT) {
std::vector<CodeTemplate> Result;
Result.push_back(std::move(CT));
@@ -188,7 +196,11 @@ generateUnconstrainedCodeTemplates(const InstructionTemplate &Variant,
std::mt19937 &randomGenerator() {
static std::random_device RandomDevice;
- static std::mt19937 RandomGenerator(RandomDevice());
+ unsigned RandomSeed = RandomGeneratorSeed.getNumOccurrences()
+ ? RandomGeneratorSeed
+ : RandomDevice();
+ LLVM_DEBUG(dbgs() << "Using random seed " << RandomSeed << ".\n");
+ static std::mt19937 RandomGenerator(RandomSeed);
return RandomGenerator;
}
diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
index 770e4e8..1ef0beb 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
+++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
@@ -25,7 +25,6 @@
#include "llvm/MC/MCInst.h"
#include "llvm/Support/Error.h"
#include <cstdlib>
-#include <memory>
#include <vector>
namespace llvm {
diff --git a/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp b/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp
index 80f5ce4..37dcc7c 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp
@@ -131,7 +131,7 @@ private:
} // namespace
-SnippetRepetitor::~SnippetRepetitor() {}
+SnippetRepetitor::~SnippetRepetitor() = default;
std::unique_ptr<const SnippetRepetitor>
SnippetRepetitor::Create(Benchmark::RepetitionModeE Mode,
diff --git a/llvm/tools/llvm-exegesis/lib/SubprocessMemory.h b/llvm/tools/llvm-exegesis/lib/SubprocessMemory.h
index 572d1085..52ee980 100644
--- a/llvm/tools/llvm-exegesis/lib/SubprocessMemory.h
+++ b/llvm/tools/llvm-exegesis/lib/SubprocessMemory.h
@@ -32,8 +32,8 @@ namespace exegesis {
class SubprocessMemory {
public:
- static constexpr const size_t AuxiliaryMemoryOffset = 1;
- static constexpr const size_t AuxiliaryMemorySize = 4096;
+ static constexpr size_t AuxiliaryMemoryOffset = 1;
+ static constexpr size_t AuxiliaryMemorySize = 4096;
// Gets the thread ID for the calling thread.
static long getCurrentTID();
diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp
index fc5f82f..2ad6c5a 100644
--- a/llvm/tools/llvm-exegesis/lib/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Target.cpp
@@ -23,7 +23,7 @@ cl::OptionCategory Options("llvm-exegesis options");
cl::OptionCategory BenchmarkOptions("llvm-exegesis benchmark options");
cl::OptionCategory AnalysisOptions("llvm-exegesis analysis options");
-ExegesisTarget::~ExegesisTarget() {} // anchor.
+ExegesisTarget::~ExegesisTarget() = default; // anchor.
static ExegesisTarget *FirstTarget = nullptr;
@@ -215,7 +215,7 @@ const PfmCountersInfo &ExegesisTarget::getDummyPfmCounters() const {
return PfmCountersInfo::Dummy;
}
-ExegesisTarget::SavedState::~SavedState() {} // anchor.
+ExegesisTarget::SavedState::~SavedState() = default; // anchor.
namespace {
diff --git a/llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h b/llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h
index ef47b7f..74a18da 100644
--- a/llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h
+++ b/llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h
@@ -30,7 +30,7 @@ public:
ExecutionMode, ValCounters) {}
~UopsBenchmarkRunner() override;
- static constexpr const size_t kMinNumDifferentAddresses = 6;
+ static constexpr size_t kMinNumDifferentAddresses = 6;
private:
Expected<std::vector<BenchmarkMeasure>>
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index b4437f7..3f2b911 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -28,7 +28,6 @@
#include "llvm/TargetParser/Host.h"
#include <memory>
-#include <string>
#include <vector>
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && \
!defined(_M_ARM64EC)
@@ -278,9 +277,9 @@ static Expected<std::vector<CodeTemplate>> generateLEATemplatesCommon(
assert(X86II::getMemoryOperandNo(Instr.Description.TSFlags) == 1 &&
"invalid LEA");
- constexpr const int kDestOp = 0;
- constexpr const int kBaseOp = 1;
- constexpr const int kIndexOp = 3;
+ constexpr int kDestOp = 0;
+ constexpr int kBaseOp = 1;
+ constexpr int kIndexOp = 3;
auto PossibleDestRegs =
Instr.Operands[kDestOp].getRegisterAliasing().sourceBits();
remove(PossibleDestRegs, ForbiddenRegisters);
@@ -548,7 +547,7 @@ private:
void initStack(unsigned Bytes);
- static constexpr const unsigned kF80Bytes = 10; // 80 bits.
+ static constexpr unsigned kF80Bytes = 10; // 80 bits.
APInt Constant_;
std::vector<MCInst> Instructions;
@@ -864,13 +863,13 @@ const MCPhysReg ExegesisX86Target::kUnavailableRegistersSSE[12] = {
// We're using one of R8-R15 because these registers are never hardcoded in
// instructions (e.g. MOVS writes to EDI, ESI, EDX), so they have less
// conflicts.
-constexpr const MCPhysReg kDefaultLoopCounterReg = X86::R8;
+constexpr MCPhysReg kDefaultLoopCounterReg = X86::R8;
} // namespace
void ExegesisX86Target::addTargetSpecificPasses(PassManagerBase &PM) const {
// Lowers FP pseudo-instructions, e.g. ABS_Fp32 -> ABS_F.
- PM.add(createX86FloatingPointStackifierPass());
+ PM.add(createX86FPStackifierLegacyPass());
}
MCRegister ExegesisX86Target::getScratchMemoryRegister(const Triple &TT) const {
@@ -1110,9 +1109,9 @@ std::vector<MCInst> ExegesisX86Target::setRegTo(const MCSubtargetInfo &STI,
#ifdef __linux__
#ifdef __arm__
-static constexpr const uintptr_t VAddressSpaceCeiling = 0xC0000000;
+static constexpr uintptr_t VAddressSpaceCeiling = 0xC0000000;
#else
-static constexpr const uintptr_t VAddressSpaceCeiling = 0x0000800000000000;
+static constexpr uintptr_t VAddressSpaceCeiling = 0x0000800000000000;
#endif
void generateRoundToNearestPage(unsigned int Register,
diff --git a/llvm/tools/llvm-exegesis/lib/X86/X86Counter.cpp b/llvm/tools/llvm-exegesis/lib/X86/X86Counter.cpp
index 05b6562..9dc6c76 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/X86Counter.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/X86Counter.cpp
@@ -27,7 +27,6 @@
#include <cstdint>
#include <limits>
#include <memory>
-#include <vector>
#include <poll.h>
#include <sys/mman.h>
diff --git a/llvm/tools/llvm-gpu-loader/amdhsa.cpp b/llvm/tools/llvm-gpu-loader/amdhsa.cpp
index 5715058..fa9ee18 100644
--- a/llvm/tools/llvm-gpu-loader/amdhsa.cpp
+++ b/llvm/tools/llvm-gpu-loader/amdhsa.cpp
@@ -26,7 +26,6 @@
#include <cstdlib>
#include <cstring>
#include <thread>
-#include <tuple>
#include <utility>
// The implicit arguments of COV5 AMDGPU kernels.
diff --git a/llvm/tools/llvm-ifs/ErrorCollector.cpp b/llvm/tools/llvm-ifs/ErrorCollector.cpp
index 04daa84..7417060 100644
--- a/llvm/tools/llvm-ifs/ErrorCollector.cpp
+++ b/llvm/tools/llvm-ifs/ErrorCollector.cpp
@@ -11,7 +11,6 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
-#include <vector>
using namespace llvm;
using namespace llvm::ifs;
diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp
index e12016c..1244bfb 100644
--- a/llvm/tools/llvm-ifs/llvm-ifs.cpp
+++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp
@@ -34,7 +34,6 @@
#include "llvm/TextAPI/TextAPIReader.h"
#include "llvm/TextAPI/TextAPIWriter.h"
#include <optional>
-#include <set>
#include <string>
#include <vector>
diff --git a/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp b/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp
index 7402782..7b8d3f0 100644
--- a/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp
+++ b/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp
@@ -395,9 +395,7 @@ public:
/// FIXME: Use --target option to get target info directly, avoiding the need
/// to parse machine functions for pre-training operations.
bool initializeVocabularyForLayout(const Module &M) {
- for (const Function &F : M) {
- if (F.isDeclaration())
- continue;
+ for (const Function &F : M.getFunctionDefs()) {
MachineFunction *MF = MMI.getMachineFunction(F);
if (!MF)
@@ -431,9 +429,7 @@ public:
std::string Relationships;
raw_string_ostream RelOS(Relationships);
- for (const Function &F : M) {
- if (F.isDeclaration())
- continue;
+ for (const Function &F : M.getFunctionDefs()) {
MachineFunction *MF = MMI.getMachineFunction(F);
if (!MF) {
@@ -532,9 +528,7 @@ public:
return;
}
- for (const Function &F : M) {
- if (F.isDeclaration())
- continue;
+ for (const Function &F : M.getFunctionDefs()) {
MachineFunction *MF = MMI.getMachineFunction(F);
if (!MF) {
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
index 8d33ae1..2cffca2 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
@@ -44,7 +44,6 @@ ExitOnError ExitOnErr;
LLVM_ATTRIBUTE_USED void linkComponents() {
errs() << (void *)&llvm_orc_registerEHFrameSectionAllocAction
<< (void *)&llvm_orc_deregisterEHFrameSectionAllocAction
- << (void *)&llvm_orc_registerJITLoaderGDBWrapper
<< (void *)&llvm_orc_registerJITLoaderGDBAllocAction;
}
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 79216e8..b8de817 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -17,17 +17,15 @@
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX, LLVM_ENABLE_THREADS
#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"
#include "llvm/ExecutionEngine/Orc/COFFPlatform.h"
-#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"
#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.h"
+#include "llvm/ExecutionEngine/Orc/Debugging/ELFDebugObjectPlugin.h"
#include "llvm/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/EHFrameRegistrationPlugin.h"
#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
-#include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
-#include "llvm/ExecutionEngine/Orc/GetDylibInterface.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"
#include "llvm/ExecutionEngine/Orc/JITLinkReentryTrampolines.h"
@@ -348,7 +346,6 @@ static LLVM_ATTRIBUTE_USED void linkComponents() {
errs() << "Linking in runtime functions\n"
<< (void *)&llvm_orc_registerEHFrameSectionAllocAction << '\n'
<< (void *)&llvm_orc_deregisterEHFrameSectionAllocAction << '\n'
- << (void *)&llvm_orc_registerJITLoaderGDBWrapper << '\n'
<< (void *)&llvm_orc_registerJITLoaderGDBAllocAction << '\n'
<< (void *)&llvm_orc_registerJITLoaderPerfStart << '\n'
<< (void *)&llvm_orc_registerJITLoaderPerfEnd << '\n'
@@ -776,6 +773,7 @@ createSharedMemoryManager(SimpleRemoteEPC &SREPC) {
SlabSize, SREPC, SAs);
}
+#if LLVM_ON_UNIX && LLVM_ENABLE_THREADS
static void setupEPCRemoteMemoryManager(SimpleRemoteEPC::Setup &S) {
switch (UseMemMgr) {
case MemMgr::Default:
@@ -789,6 +787,7 @@ static void setupEPCRemoteMemoryManager(SimpleRemoteEPC::Setup &S) {
break;
}
}
+#endif
static Expected<MaterializationUnit::Interface>
getTestObjectFileInterface(Session &S, MemoryBufferRef O) {
@@ -1295,9 +1294,16 @@ Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err)
} else if (TT.isOSBinFormatELF()) {
if (!NoExec)
ObjLayer.addPlugin(ExitOnErr(EHFrameRegistrationPlugin::Create(ES)));
- if (DebuggerSupport)
- ObjLayer.addPlugin(std::make_unique<DebugObjectManagerPlugin>(
- ES, ExitOnErr(createJITLoaderGDBRegistrar(this->ES)), true, true));
+ if (DebuggerSupport) {
+ Error TargetSymErr = Error::success();
+ auto Plugin =
+ std::make_unique<ELFDebugObjectPlugin>(ES, true, true, TargetSymErr);
+ if (!TargetSymErr)
+ ObjLayer.addPlugin(std::move(Plugin));
+ else
+ logAllUnhandledErrors(std::move(TargetSymErr), errs(),
+ "Debugger support not available: ");
+ }
}
if (auto MainJDOrErr = ES.createJITDylib("main"))
diff --git a/llvm/tools/llvm-libtool-darwin/DependencyInfo.h b/llvm/tools/llvm-libtool-darwin/DependencyInfo.h
index 784ec3f..80bad8f 100644
--- a/llvm/tools/llvm-libtool-darwin/DependencyInfo.h
+++ b/llvm/tools/llvm-libtool-darwin/DependencyInfo.h
@@ -18,7 +18,7 @@ public:
explicit DependencyInfo(std::string DependencyInfoPath)
: DependencyInfoPath(DependencyInfoPath) {}
- virtual ~DependencyInfo(){};
+ virtual ~DependencyInfo() = default;
virtual void addMissingInput(llvm::StringRef Path) {
NotFounds.insert(Path.str());
diff --git a/llvm/tools/llvm-lto/llvm-lto.cpp b/llvm/tools/llvm-lto/llvm-lto.cpp
index 09f7142..30f2e53 100644
--- a/llvm/tools/llvm-lto/llvm-lto.cpp
+++ b/llvm/tools/llvm-lto/llvm-lto.cpp
@@ -45,14 +45,13 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstdlib>
-#include <map>
#include <memory>
#include <string>
#include <system_error>
diff --git a/llvm/tools/llvm-mc/Disassembler.h b/llvm/tools/llvm-mc/Disassembler.h
index dd8525d..76cee9e 100644
--- a/llvm/tools/llvm-mc/Disassembler.h
+++ b/llvm/tools/llvm-mc/Disassembler.h
@@ -14,8 +14,6 @@
#ifndef LLVM_TOOLS_LLVM_MC_DISASSEMBLER_H
#define LLVM_TOOLS_LLVM_MC_DISASSEMBLER_H
-#include <string>
-
namespace llvm {
class MemoryBuffer;
diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
index f7f929e..1469071 100644
--- a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
+++ b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
@@ -26,7 +26,7 @@ namespace llvm {
namespace mca {
// This virtual dtor serves as the anchor for the CodeRegionGenerator class.
-CodeRegionGenerator::~CodeRegionGenerator() {}
+CodeRegionGenerator::~CodeRegionGenerator() = default;
Expected<const CodeRegions &> AsmCodeRegionGenerator::parseCodeRegions(
const std::unique_ptr<MCInstPrinter> &IP, bool SkipFailures) {
diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.h b/llvm/tools/llvm-mca/CodeRegionGenerator.h
index a48c67a..c30f67a 100644
--- a/llvm/tools/llvm-mca/CodeRegionGenerator.h
+++ b/llvm/tools/llvm-mca/CodeRegionGenerator.h
@@ -151,7 +151,7 @@ protected:
bool SkipFailures) = 0;
public:
- CodeRegionGenerator() {}
+ CodeRegionGenerator() = default;
virtual ~CodeRegionGenerator();
};
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 3d7f33c..8aa843b 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -811,12 +811,12 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
.Case("boot_application",
COFF::IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
.Case("console", COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI)
- .Cases("efi_application", "efi-app",
+ .Cases({"efi_application", "efi-app"},
COFF::IMAGE_SUBSYSTEM_EFI_APPLICATION)
- .Cases("efi_boot_service_driver", "efi-bsd",
+ .Cases({"efi_boot_service_driver", "efi-bsd"},
COFF::IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
.Case("efi_rom", COFF::IMAGE_SUBSYSTEM_EFI_ROM)
- .Cases("efi_runtime_driver", "efi-rtd",
+ .Cases({"efi_runtime_driver", "efi-rtd"},
COFF::IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
.Case("native", COFF::IMAGE_SUBSYSTEM_NATIVE)
.Case("posix", COFF::IMAGE_SUBSYSTEM_POSIX_CUI)
diff --git a/llvm/tools/llvm-objdump/OtoolOpts.td b/llvm/tools/llvm-objdump/OtoolOpts.td
index dc7a5b4..706d9e0 100644
--- a/llvm/tools/llvm-objdump/OtoolOpts.td
+++ b/llvm/tools/llvm-objdump/OtoolOpts.td
@@ -14,7 +14,7 @@ def G : Flag<["-"], "G">, HelpText<"print data-in-code table">;
def h : Flag<["-"], "h">, HelpText<"print mach header">;
def I : Flag<["-"], "I">, HelpText<"print indirect symbol table">;
def j : Flag<["-"], "j">, HelpText<"print opcode bytes">;
-def l : Flag<["-"], "l">, HelpText<"print load commnads">;
+def l : Flag<["-"], "l">, HelpText<"print load commands">;
def L : Flag<["-"], "L">, HelpText<"print used shared libraries">;
def mcpu_EQ : Joined<["-"], "mcpu=">, HelpText<"select cpu for disassembly">;
def o : Flag<["-"], "o">, HelpText<"print Objective-C segment">;
diff --git a/llvm/tools/llvm-objdump/SourcePrinter.cpp b/llvm/tools/llvm-objdump/SourcePrinter.cpp
index b0ff89d..a4891a3 100644
--- a/llvm/tools/llvm-objdump/SourcePrinter.cpp
+++ b/llvm/tools/llvm-objdump/SourcePrinter.cpp
@@ -50,11 +50,6 @@ void InlinedFunction::dump(raw_ostream &OS) const {
void InlinedFunction::printElementLine(raw_ostream &OS,
object::SectionedAddress Addr,
bool IsEnd) const {
- bool LiveIn = !IsEnd && Range.LowPC == Addr.Address;
- bool LiveOut = IsEnd && Range.HighPC == Addr.Address;
- if (!(LiveIn || LiveOut))
- return;
-
uint32_t CallFile, CallLine, CallColumn, CallDiscriminator;
InlinedFuncDie.getCallerFrame(CallFile, CallLine, CallColumn,
CallDiscriminator);
@@ -126,8 +121,41 @@ void LiveElementPrinter::addInlinedFunction(DWARFDie FuncDie,
DWARFUnit *U = InlinedFuncDie.getDwarfUnit();
const char *InlinedFuncName = InlinedFuncDie.getName(DINameKind::LinkageName);
DWARFAddressRange Range{FuncLowPC, FuncHighPC, SectionIndex};
+ // Add the new element to the main vector.
LiveElements.emplace_back(std::make_unique<InlinedFunction>(
InlinedFuncName, U, FuncDie, InlinedFuncDie, Range));
+
+ LiveElement *LE = LiveElements.back().get();
+ // Map the element's low address (LowPC) to its pointer for fast range start
+ // lookup.
+ LiveElementsByAddress[FuncLowPC].push_back(LE);
+ // Map the element's high address (HighPC) to its pointer for fast range end
+ // lookup.
+ LiveElementsByEndAddress[FuncHighPC].push_back(LE);
+ // Map the pointer to its DWARF discovery index for deterministic
+ // ordering.
+ ElementPtrToIndex[LE] = LiveElements.size() - 1;
+}
+
+/// Registers the most recently added LiveVariable into all data structures.
+void LiveElementPrinter::registerNewVariable() {
+ assert(
+ !LiveElements.empty() &&
+ "registerNewVariable called before element was added to LiveElements.");
+ LiveVariable *CurrentVar =
+ static_cast<LiveVariable *>(LiveElements.back().get());
+ assert(ElementPtrToIndex.count(CurrentVar) == 0 &&
+ "Element already registered!");
+
+ // Map from a LiveElement pointer to its index in the LiveElements.
+ ElementPtrToIndex[CurrentVar] = LiveElements.size() - 1;
+
+ if (const std::optional<DWARFAddressRange> &Range =
+ CurrentVar->getLocExpr().Range) {
+ // Add the variable to address-based maps.
+ LiveElementsByAddress[Range->LowPC].push_back(CurrentVar);
+ LiveElementsByEndAddress[Range->HighPC].push_back(CurrentVar);
+ }
}
void LiveElementPrinter::addVariable(DWARFDie FuncDie, DWARFDie VarDie) {
@@ -160,6 +188,9 @@ void LiveElementPrinter::addVariable(DWARFDie FuncDie, DWARFDie VarDie) {
LiveElements.emplace_back(
std::make_unique<LiveVariable>(WholeFuncExpr, VarName, U, FuncDie));
}
+
+ // Register the new variable with all data structures.
+ registerNewVariable();
}
}
@@ -205,14 +236,52 @@ unsigned LiveElementPrinter::moveToFirstVarColumn(formatted_raw_ostream &OS) {
return FirstUnprintedLogicalColumn;
}
-unsigned LiveElementPrinter::findFreeColumn() {
- for (unsigned ColIdx = 0; ColIdx < ActiveCols.size(); ++ColIdx)
- if (!ActiveCols[ColIdx].isActive())
- return ColIdx;
+unsigned LiveElementPrinter::getOrCreateColumn(unsigned ElementIdx) {
+ // Check if the element already has an assigned column.
+ auto it = ElementToColumn.find(ElementIdx);
+ if (it != ElementToColumn.end())
+ return it->second;
+
+ unsigned ColIdx;
+ if (!FreeCols.empty()) {
+ // Get the smallest available index from the set.
+ ColIdx = *FreeCols.begin();
+ // Remove the index from the set.
+ FreeCols.erase(FreeCols.begin());
+ } else {
+ // No free columns, so create a new one.
+ ColIdx = ActiveCols.size();
+ ActiveCols.emplace_back();
+ }
- size_t OldSize = ActiveCols.size();
- ActiveCols.grow(std::max<size_t>(OldSize * 2, 1));
- return OldSize;
+ // Assign the element to the column and update the map.
+ ElementToColumn[ElementIdx] = ColIdx;
+ ActiveCols[ColIdx].ElementIdx = ElementIdx;
+ return ColIdx;
+}
+
+void LiveElementPrinter::freeColumn(unsigned ColIdx) {
+ unsigned ElementIdx = ActiveCols[ColIdx].ElementIdx;
+
+ // Clear the column's data.
+ ActiveCols[ColIdx].clear();
+
+ // Remove the element's entry from the map and add the column to the free
+ // list.
+ ElementToColumn.erase(ElementIdx);
+ FreeCols.insert(ColIdx);
+}
+
+std::vector<unsigned>
+LiveElementPrinter::getSortedActiveElementIndices() const {
+ // Get all element indices that currently have an assigned column.
+ std::vector<unsigned> Indices;
+ for (const auto &Pair : ElementToColumn)
+ Indices.push_back(Pair.first);
+
+ // Sort by the DWARF discovery order.
+ llvm::stable_sort(Indices);
+ return Indices;
}
void LiveElementPrinter::dump() const {
@@ -239,57 +308,112 @@ void LiveElementPrinter::addCompileUnit(DWARFDie D) {
void LiveElementPrinter::update(object::SectionedAddress ThisAddr,
object::SectionedAddress NextAddr,
bool IncludeDefinedVars) {
- // Do not create live ranges when debug-inlined-funcs option is provided with
- // line format option.
+ // Exit early if only printing function limits.
if (DbgInlinedFunctions == DFLimitsOnly)
return;
- // First, check variables which have already been assigned a column, so
- // that we don't change their order.
- SmallSet<unsigned, 8> CheckedElementIdxs;
+ // Free columns identified in the previous cycle.
+ for (unsigned ColIdx : ColumnsToFreeNextCycle)
+ freeColumn(ColIdx);
+ ColumnsToFreeNextCycle.clear();
+
+ // Update status of active columns and collect those to free next cycle.
for (unsigned ColIdx = 0, End = ActiveCols.size(); ColIdx < End; ++ColIdx) {
if (!ActiveCols[ColIdx].isActive())
continue;
- CheckedElementIdxs.insert(ActiveCols[ColIdx].ElementIdx);
const std::unique_ptr<LiveElement> &LE =
LiveElements[ActiveCols[ColIdx].ElementIdx];
ActiveCols[ColIdx].LiveIn = LE->liveAtAddress(ThisAddr);
ActiveCols[ColIdx].LiveOut = LE->liveAtAddress(NextAddr);
- std::string Name = Demangle ? demangle(LE->getName()) : LE->getName();
- LLVM_DEBUG(dbgs() << "pass 1, " << ThisAddr.Address << "-"
- << NextAddr.Address << ", " << Name << ", Col " << ColIdx
- << ": LiveIn=" << ActiveCols[ColIdx].LiveIn
- << ", LiveOut=" << ActiveCols[ColIdx].LiveOut << "\n");
- if (!ActiveCols[ColIdx].LiveIn && !ActiveCols[ColIdx].LiveOut)
+ LLVM_DEBUG({
+ std::string Name = Demangle ? demangle(LE->getName()) : LE->getName();
+ dbgs() << "pass 1, " << ThisAddr.Address << "-" << NextAddr.Address
+ << ", " << Name << ", Col " << ColIdx
+ << ": LiveIn=" << ActiveCols[ColIdx].LiveIn
+ << ", LiveOut=" << ActiveCols[ColIdx].LiveOut << "\n";
+ });
+
+ // If element is fully dead, deactivate column immediately.
+ if (!ActiveCols[ColIdx].LiveIn && !ActiveCols[ColIdx].LiveOut) {
ActiveCols[ColIdx].ElementIdx = Column::NullElementIdx;
+ continue;
+ }
+
+ // Mark for cleanup in the next cycle if range ends here.
+ if (ActiveCols[ColIdx].LiveIn && !ActiveCols[ColIdx].LiveOut)
+ ColumnsToFreeNextCycle.push_back(ColIdx);
}
// Next, look for variables which don't already have a column, but which
- // are now live.
+ // are now live (those starting at ThisAddr or NextAddr).
if (IncludeDefinedVars) {
- for (unsigned ElementIdx = 0, End = LiveElements.size(); ElementIdx < End;
- ++ElementIdx) {
- if (CheckedElementIdxs.count(ElementIdx))
+ // Collect all elements starting at ThisAddr and NextAddr.
+ std::vector<std::pair<unsigned, LiveElement *>> NewLiveElements;
+ auto CollectNewElements = [&](const auto &It) {
+ if (It == LiveElementsByAddress.end())
+ return;
+
+ const std::vector<LiveElement *> &ElementList = It->second;
+ for (LiveElement *LE : ElementList) {
+ auto IndexIt = ElementPtrToIndex.find(LE);
+ assert(IndexIt != ElementPtrToIndex.end() &&
+ "LiveElement in address map but missing from index map!");
+
+ // Get the element index for sorting and column management.
+ unsigned ElementIdx = IndexIt->second;
+ // Skip elements that already have a column.
+ if (ElementToColumn.count(ElementIdx))
+ continue;
+
+ bool LiveIn = LE->liveAtAddress(ThisAddr);
+ bool LiveOut = LE->liveAtAddress(NextAddr);
+ if (!LiveIn && !LiveOut)
+ continue;
+
+ NewLiveElements.emplace_back(ElementIdx, LE);
+ }
+ };
+
+ // Collect elements starting at ThisAddr.
+ CollectNewElements(LiveElementsByAddress.find(ThisAddr.Address));
+ // Collect elements starting at NextAddr (the address immediately
+ // following the instruction).
+ CollectNewElements(LiveElementsByAddress.find(NextAddr.Address));
+ // Sort elements by DWARF discovery order for deterministic column
+ // assignment.
+ llvm::stable_sort(NewLiveElements, [](const auto &A, const auto &B) {
+ return A.first < B.first;
+ });
+
+ // Assign columns in deterministic order.
+ for (const auto &ElementPair : NewLiveElements) {
+ unsigned ElementIdx = ElementPair.first;
+ // Skip if element was already added from the first range.
+ if (ElementToColumn.count(ElementIdx))
continue;
- const std::unique_ptr<LiveElement> &LE = LiveElements[ElementIdx];
+ LiveElement *LE = ElementPair.second;
bool LiveIn = LE->liveAtAddress(ThisAddr);
bool LiveOut = LE->liveAtAddress(NextAddr);
- if (!LiveIn && !LiveOut)
- continue;
- unsigned ColIdx = findFreeColumn();
- std::string Name = Demangle ? demangle(LE->getName()) : LE->getName();
- LLVM_DEBUG(dbgs() << "pass 2, " << ThisAddr.Address << "-"
- << NextAddr.Address << ", " << Name << ", Col "
- << ColIdx << ": LiveIn=" << LiveIn
- << ", LiveOut=" << LiveOut << "\n");
- ActiveCols[ColIdx].ElementIdx = ElementIdx;
+ // Assign or create a column.
+ unsigned ColIdx = getOrCreateColumn(ElementIdx);
+ LLVM_DEBUG({
+ std::string Name = Demangle ? demangle(LE->getName()) : LE->getName();
+ dbgs() << "pass 2, " << ThisAddr.Address << "-" << NextAddr.Address
+ << ", " << Name << ", Col " << ColIdx << ": LiveIn=" << LiveIn
+ << ", LiveOut=" << LiveOut << "\n";
+ });
+
ActiveCols[ColIdx].LiveIn = LiveIn;
ActiveCols[ColIdx].LiveOut = LiveOut;
ActiveCols[ColIdx].MustDrawLabel = true;
+
+ // Mark for cleanup next cycle if range ends here.
+ if (ActiveCols[ColIdx].LiveIn && !ActiveCols[ColIdx].LiveOut)
+ ColumnsToFreeNextCycle.push_back(ColIdx);
}
}
}
@@ -360,7 +484,13 @@ void LiveElementPrinter::printAfterOtherLine(formatted_raw_ostream &OS,
void LiveElementPrinter::printBetweenInsts(formatted_raw_ostream &OS,
bool MustPrint) {
bool PrintedSomething = false;
- for (unsigned ColIdx = 0, End = ActiveCols.size(); ColIdx < End; ++ColIdx) {
+ // Get all active elements, sorted by discovery order.
+ std::vector<unsigned> SortedElementIndices = getSortedActiveElementIndices();
+ // The outer loop iterates over the deterministic DWARF discovery order.
+ for (unsigned ElementIdx : SortedElementIndices) {
+ // Look up the physical column index (ColIdx) assigned to this
+ // element. We use .at() because we are certain the element is active.
+ unsigned ColIdx = ElementToColumn.at(ElementIdx);
if (ActiveCols[ColIdx].isActive() && ActiveCols[ColIdx].MustDrawLabel) {
// First we need to print the live range markers for any active
// columns to the left of this one.
@@ -375,8 +505,7 @@ void LiveElementPrinter::printBetweenInsts(formatted_raw_ostream &OS,
OS << " ";
}
- const std::unique_ptr<LiveElement> &LE =
- LiveElements[ActiveCols[ColIdx].ElementIdx];
+ const std::unique_ptr<LiveElement> &LE = LiveElements[ElementIdx];
// Then print the variable name and location of the new live range,
// with box drawing characters joining it to the live range line.
OS << getLineChar(ActiveCols[ColIdx].LiveIn ? LineChar::LabelCornerActive
@@ -438,22 +567,40 @@ void LiveElementPrinter::printAfterInst(formatted_raw_ostream &OS) {
}
}
-void LiveElementPrinter::printStartLine(formatted_raw_ostream &OS,
- object::SectionedAddress Addr) {
- // Print a line to idenfity the start of an inlined function if line format
- // is specified.
- if (DbgInlinedFunctions == DFLimitsOnly)
- for (const std::unique_ptr<LiveElement> &LE : LiveElements)
- LE->printElementLine(OS, Addr, false);
-}
+void LiveElementPrinter::printBoundaryLine(formatted_raw_ostream &OS,
+ object::SectionedAddress Addr,
+ bool IsEnd) {
+ // Only print the start/end line for inlined functions if DFLimitsOnly is
+ // enabled.
+ if (DbgInlinedFunctions != DFLimitsOnly)
+ return;
-void LiveElementPrinter::printEndLine(formatted_raw_ostream &OS,
- object::SectionedAddress Addr) {
- // Print a line to idenfity the end of an inlined function if line format is
- // specified.
- if (DbgInlinedFunctions == DFLimitsOnly)
- for (const std::unique_ptr<LiveElement> &LE : LiveElements)
- LE->printElementLine(OS, Addr, true);
+ // Select the appropriate map based on whether we are checking the start
+ // (LowPC) or end (HighPC) address.
+ const auto &AddressMap =
+ IsEnd ? LiveElementsByEndAddress : LiveElementsByAddress;
+
+ // Use the map to find all elements that start/end at the given address.
+ std::vector<unsigned> ElementIndices;
+ auto It = AddressMap.find(Addr.Address);
+ if (It != AddressMap.end()) {
+ for (LiveElement *LE : It->second) {
+ // Look up the element index from the pointer.
+ auto IndexIt = ElementPtrToIndex.find(LE);
+ assert(IndexIt != ElementPtrToIndex.end() &&
+ "LiveElement found in address map but missing index!");
+ ElementIndices.push_back(IndexIt->second);
+ }
+ }
+
+ // Sort the indices to ensure deterministic output order (by DWARF discovery
+ // order).
+ llvm::stable_sort(ElementIndices);
+
+ for (unsigned ElementIdx : ElementIndices) {
+ LiveElement *LE = LiveElements[ElementIdx].get();
+ LE->printElementLine(OS, Addr, IsEnd);
+ }
}
bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) {
diff --git a/llvm/tools/llvm-objdump/SourcePrinter.h b/llvm/tools/llvm-objdump/SourcePrinter.h
index 5c131a0..ad3ea12 100644
--- a/llvm/tools/llvm-objdump/SourcePrinter.h
+++ b/llvm/tools/llvm-objdump/SourcePrinter.h
@@ -9,13 +9,16 @@
#ifndef LLVM_TOOLS_LLVM_OBJDUMP_SOURCEPRINTER_H
#define LLVM_TOOLS_LLVM_OBJDUMP_SOURCEPRINTER_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/Symbolize/Symbolize.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/FormattedStream.h"
+#include <set>
#include <unordered_map>
#include <vector>
@@ -34,7 +37,7 @@ public:
LiveElement(const char *Name, DWARFUnit *Unit, const DWARFDie FuncDie)
: Name(Name), Unit(Unit), FuncDie(FuncDie) {}
- virtual ~LiveElement() {};
+ virtual ~LiveElement() = default;
const char *getName() const { return Name; }
virtual bool liveAtAddress(object::SectionedAddress Addr) const = 0;
@@ -78,6 +81,7 @@ public:
bool liveAtAddress(object::SectionedAddress Addr) const override;
void print(raw_ostream &OS, const MCRegisterInfo &MRI) const override;
void dump(raw_ostream &OS) const override;
+ const DWARFLocationExpression &getLocExpr() const { return LocExpr; }
};
/// Helper class for printing source locations for variables and inlined
@@ -95,17 +99,39 @@ class LiveElementPrinter {
static constexpr unsigned NullElementIdx =
std::numeric_limits<unsigned>::max();
+
+ // Clear the column's data.
+ void clear() {
+ ElementIdx = NullElementIdx;
+ LiveIn = false;
+ LiveOut = false;
+ MustDrawLabel = false;
+ }
};
- // All live elements we know about in the object/image file.
+ // Vector that owns all LiveElement objects for memory management.
std::vector<std::unique_ptr<LiveElement>> LiveElements;
-
- // The columns we are currently drawing.
- IndexedMap<Column> ActiveCols;
+ // Map for fast lookup of live elements by their starting address (LowPC).
+ llvm::MapVector<uint64_t, std::vector<LiveElement *>> LiveElementsByAddress;
+ // Map for fast lookup of live elements by their ending address (HighPC).
+ llvm::MapVector<uint64_t, std::vector<LiveElement *>>
+ LiveElementsByEndAddress;
+ // Map from a LiveElement pointer to its index in the LiveElements vector.
+ llvm::DenseMap<LiveElement *, unsigned> ElementPtrToIndex;
+ // Map from a live element index to column index for efficient lookup.
+ llvm::DenseMap<unsigned, unsigned> ElementToColumn;
+ // Vector of columns currently used for printing live ranges.
+ std::vector<Column> ActiveCols;
+ // Set of available column indices kept sorted for efficient reuse.
+ std::set<unsigned> FreeCols;
+ // Vector of available column indices that can be reused.
+ std::vector<unsigned> ColumnsToFreeNextCycle;
const MCRegisterInfo &MRI;
const MCSubtargetInfo &STI;
+ void registerNewVariable();
+
void addInlinedFunction(DWARFDie FuncDie, DWARFDie InlinedFuncDie);
void addVariable(DWARFDie FuncDie, DWARFDie VarDie);
@@ -122,11 +148,19 @@ class LiveElementPrinter {
// put live element lines. Pick a less overloaded word.
unsigned moveToFirstVarColumn(formatted_raw_ostream &OS);
- unsigned findFreeColumn();
+ // Get an existing column for a live element, or find a free one.
+ unsigned getOrCreateColumn(unsigned ElementIdx);
+
+ // Free a column when its element is no longer live.
+ void freeColumn(unsigned ColIdx);
+
+ // Returns the indices of all currently active elements, sorted by their DWARF
+ // discovery order.
+ std::vector<unsigned> getSortedActiveElementIndices() const;
public:
LiveElementPrinter(const MCRegisterInfo &MRI, const MCSubtargetInfo &STI)
- : ActiveCols(Column()), MRI(MRI), STI(STI) {}
+ : MRI(MRI), STI(STI) {}
void dump() const;
@@ -170,10 +204,9 @@ public:
/// Print the live element ranges to the right of a disassembled instruction.
void printAfterInst(formatted_raw_ostream &OS);
- /// Print a line to idenfity the start of a live element.
- void printStartLine(formatted_raw_ostream &OS, object::SectionedAddress Addr);
- /// Print a line to idenfity the end of a live element.
- void printEndLine(formatted_raw_ostream &OS, object::SectionedAddress Addr);
+ /// Print a line to idenfity the start/end of a live element.
+ void printBoundaryLine(formatted_raw_ostream &OS,
+ object::SectionedAddress Addr, bool IsEnd);
};
class SourcePrinter {
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 3ec644a..38c3f31 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -688,7 +688,7 @@ public:
LiveElementPrinter &LEP) {
if (SP && (PrintSource || PrintLines))
SP->printSourceLine(OS, Address, ObjectFilename, LEP);
- LEP.printStartLine(OS, Address);
+ LEP.printBoundaryLine(OS, Address, false);
LEP.printBetweenInsts(OS, false);
printRawData(Bytes, Address.Address, OS, STI);
@@ -941,7 +941,7 @@ public:
LiveElementPrinter &LEP) override {
if (SP && (PrintSource || PrintLines))
SP->printSourceLine(OS, Address, ObjectFilename, LEP);
- LEP.printStartLine(OS, Address);
+ LEP.printBoundaryLine(OS, Address, false);
LEP.printBetweenInsts(OS, false);
size_t Start = OS.tell();
@@ -996,7 +996,7 @@ public:
LiveElementPrinter &LEP) override {
if (SP && (PrintSource || PrintLines))
SP->printSourceLine(OS, Address, ObjectFilename, LEP);
- LEP.printStartLine(OS, Address);
+ LEP.printBoundaryLine(OS, Address, false);
LEP.printBetweenInsts(OS, false);
size_t Start = OS.tell();
@@ -1035,7 +1035,7 @@ public:
LiveElementPrinter &LEP) override {
if (SP && (PrintSource || PrintLines))
SP->printSourceLine(OS, Address, ObjectFilename, LEP);
- LEP.printStartLine(OS, Address);
+ LEP.printBoundaryLine(OS, Address, false);
LEP.printBetweenInsts(OS, false);
size_t Start = OS.tell();
@@ -2601,7 +2601,7 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
object::SectionedAddress NextAddr = {
SectionAddr + Index + VMAAdjustment + Size, Section.getIndex()};
- LEP.printEndLine(FOS, NextAddr);
+ LEP.printBoundaryLine(FOS, NextAddr, true);
Index += Size;
}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index 3525be9..bac8589 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -84,7 +84,7 @@ protected:
public:
Dumper(const object::ObjectFile &O);
- virtual ~Dumper() {}
+ virtual ~Dumper() = default;
void reportUniqueWarning(Error Err);
void reportUniqueWarning(const Twine &Msg);
diff --git a/llvm/tools/llvm-offload-wrapper/llvm-offload-wrapper.cpp b/llvm/tools/llvm-offload-wrapper/llvm-offload-wrapper.cpp
index d65b4025..cda59b6 100644
--- a/llvm/tools/llvm-offload-wrapper/llvm-offload-wrapper.cpp
+++ b/llvm/tools/llvm-offload-wrapper/llvm-offload-wrapper.cpp
@@ -64,7 +64,7 @@ static Error wrapImages(ArrayRef<ArrayRef<char>> BuffersToWrap) {
LLVMContext Context;
Module M("offload.wrapper.module", Context);
- M.setTargetTriple(Triple());
+ M.setTargetTriple(llvm::Triple(TheTriple));
switch (Kind) {
case llvm::object::OFK_OpenMP:
diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
index b2362ec..d836d98 100644
--- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
@@ -68,7 +68,7 @@ DumpOutputStyle::DumpOutputStyle(InputFile &File)
RefTracker.reset(new TypeReferenceTracker(File));
}
-DumpOutputStyle::~DumpOutputStyle() {}
+DumpOutputStyle::~DumpOutputStyle() = default;
PDBFile &DumpOutputStyle::getPdb() { return File.pdb(); }
object::COFFObjectFile &DumpOutputStyle::getObj() { return File.obj(); }
diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.h b/llvm/tools/llvm-pdbutil/DumpOutputStyle.h
index 6714a6a..ea4a47f 100644
--- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.h
+++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.h
@@ -29,7 +29,7 @@ class TypeReferenceTracker;
struct StatCollection {
struct Stat {
- Stat() {}
+ Stat() = default;
Stat(uint32_t Count, uint32_t Size) : Count(Count), Size(Size) {}
uint32_t Count = 0;
uint32_t Size = 0;
diff --git a/llvm/tools/llvm-pdbutil/OutputStyle.h b/llvm/tools/llvm-pdbutil/OutputStyle.h
index 8cc9016..a09fb82 100644
--- a/llvm/tools/llvm-pdbutil/OutputStyle.h
+++ b/llvm/tools/llvm-pdbutil/OutputStyle.h
@@ -17,7 +17,7 @@ namespace pdb {
class OutputStyle {
public:
- virtual ~OutputStyle() {}
+ virtual ~OutputStyle() = default;
virtual Error dump() = 0;
};
diff --git a/llvm/tools/llvm-pdbutil/PdbYaml.cpp b/llvm/tools/llvm-pdbutil/PdbYaml.cpp
index fac1d89..4131292 100644
--- a/llvm/tools/llvm-pdbutil/PdbYaml.cpp
+++ b/llvm/tools/llvm-pdbutil/PdbYaml.cpp
@@ -22,6 +22,7 @@ using namespace llvm::pdb;
using namespace llvm::pdb::yaml;
using namespace llvm::yaml;
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::CoffSectionHeader)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::NamedStreamMapping)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbDbiModuleInfo)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
@@ -135,6 +136,49 @@ void MappingTraits<msf::SuperBlock>::mapping(IO &IO, msf::SuperBlock &SB) {
IO.mapOptional("BlockMapAddr", SB.BlockMapAddr, u32(0U));
}
+CoffSectionHeader::CoffSectionHeader() = default;
+
+CoffSectionHeader::CoffSectionHeader(const object::coff_section &Section)
+ : Name(Section.Name), VirtualSize(Section.VirtualSize),
+ VirtualAddress(Section.VirtualAddress),
+ SizeOfRawData(Section.SizeOfRawData),
+ PointerToRawData(Section.PointerToRawData),
+ PointerToRelocations(Section.PointerToRelocations),
+ PointerToLinenumbers(Section.PointerToLinenumbers),
+ NumberOfRelocations(Section.NumberOfRelocations),
+ NumberOfLinenumbers(Section.NumberOfLinenumbers),
+ Characteristics(Section.Characteristics) {}
+
+object::coff_section CoffSectionHeader::toCoffSection() const {
+ object::coff_section Sec;
+ std::memset(Sec.Name, 0, COFF::NameSize);
+ std::memcpy(Sec.Name, Name.data(),
+ std::min(static_cast<size_t>(COFF::NameSize), Name.size()));
+ Sec.VirtualSize = VirtualSize;
+ Sec.VirtualAddress = VirtualAddress;
+ Sec.SizeOfRawData = SizeOfRawData;
+ Sec.PointerToRawData = PointerToRawData;
+ Sec.PointerToRelocations = PointerToRelocations;
+ Sec.PointerToLinenumbers = PointerToLinenumbers;
+ Sec.NumberOfRelocations = NumberOfRelocations;
+ Sec.NumberOfLinenumbers = NumberOfLinenumbers;
+ Sec.Characteristics = Characteristics;
+ return Sec;
+}
+
+void MappingTraits<CoffSectionHeader>::mapping(IO &IO, CoffSectionHeader &Obj) {
+ IO.mapRequired("Name", Obj.Name);
+ IO.mapOptional("VirtualSize", Obj.VirtualSize);
+ IO.mapOptional("VirtualAddress", Obj.VirtualAddress);
+ IO.mapOptional("SizeOfRawData", Obj.SizeOfRawData);
+ IO.mapOptional("PointerToRawData", Obj.PointerToRawData);
+ IO.mapOptional("PointerToRelocations", Obj.PointerToRelocations);
+ IO.mapOptional("PointerToLinenumbers", Obj.PointerToLinenumbers);
+ IO.mapOptional("NumberOfRelocations", Obj.NumberOfRelocations);
+ IO.mapOptional("NumberOfLinenumbers", Obj.NumberOfLinenumbers);
+ IO.mapOptional("Characteristics", Obj.Characteristics);
+}
+
void MappingTraits<StreamBlockList>::mapping(IO &IO, StreamBlockList &SB) {
IO.mapRequired("Stream", SB.Blocks);
}
@@ -163,6 +207,7 @@ void MappingTraits<PdbDbiStream>::mapping(IO &IO, PdbDbiStream &Obj) {
IO.setContext(&Obj.FakeHeader);
}
IO.mapOptional("Modules", Obj.ModInfos);
+ IO.mapOptional("SectionHeaders", Obj.SectionHeaders);
}
void MappingTraits<PdbTpiStream>::mapping(IO &IO,
diff --git a/llvm/tools/llvm-pdbutil/PdbYaml.h b/llvm/tools/llvm-pdbutil/PdbYaml.h
index d5111a9e..8746675 100644
--- a/llvm/tools/llvm-pdbutil/PdbYaml.h
+++ b/llvm/tools/llvm-pdbutil/PdbYaml.h
@@ -18,6 +18,7 @@
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/Object/COFF.h"
#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
@@ -40,6 +41,24 @@ struct MSFHeaders {
uint64_t FileSize = 0;
};
+struct CoffSectionHeader {
+ CoffSectionHeader();
+ CoffSectionHeader(const object::coff_section &Section);
+
+ object::coff_section toCoffSection() const;
+
+ StringRef Name;
+ uint32_t VirtualSize = 0;
+ uint32_t VirtualAddress = 0;
+ uint32_t SizeOfRawData = 0;
+ uint32_t PointerToRawData = 0;
+ uint32_t PointerToRelocations = 0;
+ uint32_t PointerToLinenumbers = 0;
+ uint16_t NumberOfRelocations = 0;
+ uint16_t NumberOfLinenumbers = 0;
+ uint32_t Characteristics = 0;
+};
+
struct StreamBlockList {
std::vector<uint32_t> Blocks;
};
@@ -82,6 +101,7 @@ struct PdbDbiStream {
std::vector<PdbDbiModuleInfo> ModInfos;
COFF::header FakeHeader;
+ std::vector<CoffSectionHeader> SectionHeaders;
};
struct PdbTpiStream {
@@ -113,6 +133,7 @@ struct PdbObject {
}
}
+LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::CoffSectionHeader)
LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::PdbObject)
LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::MSFHeaders)
LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(msf::SuperBlock)
diff --git a/llvm/tools/llvm-pdbutil/PrettyClassDefinitionDumper.h b/llvm/tools/llvm-pdbutil/PrettyClassDefinitionDumper.h
index 50c8f5d..9e492a4 100644
--- a/llvm/tools/llvm-pdbutil/PrettyClassDefinitionDumper.h
+++ b/llvm/tools/llvm-pdbutil/PrettyClassDefinitionDumper.h
@@ -15,8 +15,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
-#include <memory>
-
namespace llvm {
class BitVector;
diff --git a/llvm/tools/llvm-pdbutil/PrettyCompilandDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyCompilandDumper.cpp
index b347cfd..902a1d7 100644
--- a/llvm/tools/llvm-pdbutil/PrettyCompilandDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/PrettyCompilandDumper.cpp
@@ -32,8 +32,6 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/tools/llvm-pdbutil/StreamUtil.h b/llvm/tools/llvm-pdbutil/StreamUtil.h
index 9d6030c..6b8c13f 100644
--- a/llvm/tools/llvm-pdbutil/StreamUtil.h
+++ b/llvm/tools/llvm-pdbutil/StreamUtil.h
@@ -35,7 +35,7 @@ enum class StreamPurpose {
struct StreamInfo {
public:
- StreamInfo() {}
+ StreamInfo() = default;
uint32_t getModuleIndex() const { return *ModuleIndex; }
StreamPurpose getPurpose() const { return Purpose; }
diff --git a/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp b/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp
index ecb4c21..8fe7f60 100644
--- a/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp
@@ -285,6 +285,24 @@ Error YAMLOutputStyle::dumpDbiStream() {
}
}
}
+
+ if (opts::pdb2yaml::DumpSectionHeaders) {
+ for (const auto &Section : DS.getSectionHeaders()) {
+ yaml::CoffSectionHeader Hdr;
+ Hdr.Name = Section.Name;
+ Hdr.VirtualSize = Section.VirtualSize;
+ Hdr.VirtualAddress = Section.VirtualAddress;
+ Hdr.SizeOfRawData = Section.SizeOfRawData;
+ Hdr.PointerToRawData = Section.PointerToRawData;
+ Hdr.PointerToRelocations = Section.PointerToRelocations;
+ Hdr.PointerToLinenumbers = Section.PointerToLinenumbers;
+ Hdr.NumberOfRelocations = Section.NumberOfRelocations;
+ Hdr.NumberOfLinenumbers = Section.NumberOfLinenumbers;
+ Hdr.Characteristics = Section.Characteristics;
+ Obj.DbiStream->SectionHeaders.emplace_back(Hdr);
+ }
+ }
+
return Error::success();
}
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
index a5b8e8b..befd331 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
@@ -716,6 +716,10 @@ cl::list<ModuleSubsection> DumpModuleSubsections(
cl::opt<bool> DumpModuleSyms("module-syms", cl::desc("dump module symbols"),
cl::cat(FileOptions),
cl::sub(PdbToYamlSubcommand));
+cl::opt<bool> DumpSectionHeaders("section-headers",
+ cl::desc("Dump section headers."),
+ cl::cat(FileOptions),
+ cl::sub(PdbToYamlSubcommand));
cl::list<std::string> InputFilename(cl::Positional,
cl::desc("<input PDB file>"), cl::Required,
@@ -865,6 +869,20 @@ static void yamlToPdb(StringRef Path) {
}
}
+ std::vector<object::coff_section> Sections;
+ if (!Dbi.SectionHeaders.empty()) {
+ for (const auto &Hdr : Dbi.SectionHeaders)
+ Sections.emplace_back(Hdr.toCoffSection());
+
+ DbiBuilder.createSectionMap(Sections);
+ ExitOnErr(DbiBuilder.addDbgStream(
+ pdb::DbgHeaderType::SectionHdr,
+ // FIXME: Downcasting to an ArrayRef<uint8_t> should use a helper
+ // function in LLVM
+ ArrayRef<uint8_t>{(const uint8_t *)Sections.data(),
+ Sections.size() * sizeof(object::coff_section)}));
+ }
+
auto &TpiBuilder = Builder.getTpiBuilder();
const auto &Tpi = YamlObj.TpiStream.value_or(DefaultTpiStream);
TpiBuilder.setVersionHeader(Tpi.Version);
@@ -1541,6 +1559,7 @@ int main(int Argc, const char **Argv) {
opts::pdb2yaml::DumpModules = true;
opts::pdb2yaml::DumpModuleFiles = true;
opts::pdb2yaml::DumpModuleSyms = true;
+ opts::pdb2yaml::DumpSectionHeaders = true;
opts::pdb2yaml::DumpModuleSubsections.push_back(
opts::ModuleSubsection::All);
}
@@ -1551,6 +1570,9 @@ int main(int Argc, const char **Argv) {
if (opts::pdb2yaml::DumpModules)
opts::pdb2yaml::DbiStream = true;
+
+ if (opts::pdb2yaml::DumpSectionHeaders)
+ opts::pdb2yaml::DbiStream = true;
}
llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h
index b8c8033..73ff2fe 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h
@@ -201,6 +201,7 @@ extern llvm::cl::opt<bool> DumpModules;
extern llvm::cl::opt<bool> DumpModuleFiles;
extern llvm::cl::list<ModuleSubsection> DumpModuleSubsections;
extern llvm::cl::opt<bool> DumpModuleSyms;
+extern llvm::cl::opt<bool> DumpSectionHeaders;
} // namespace pdb2yaml
namespace explain {
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index 9b853e2..e186c5a 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -2929,9 +2929,9 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
continue;
}
- for (size_t I = 0, E = Func.Counts.size(); I < E; ++I) {
- FuncMax = std::max(FuncMax, Func.Counts[I]);
- FuncSum += Func.Counts[I];
+ for (uint64_t Count : Func.Counts) {
+ FuncMax = std::max(FuncMax, Count);
+ FuncSum += Count;
}
if (FuncMax < ShowValueCutoff) {
diff --git a/llvm/tools/llvm-profgen/MissingFrameInferrer.cpp b/llvm/tools/llvm-profgen/MissingFrameInferrer.cpp
index 7ebca23..d692de7 100644
--- a/llvm/tools/llvm-profgen/MissingFrameInferrer.cpp
+++ b/llvm/tools/llvm-profgen/MissingFrameInferrer.cpp
@@ -14,7 +14,6 @@
#include "llvm/ADT/Statistic.h"
#include <algorithm>
#include <cstdint>
-#include <iterator>
#include <queue>
#include <sys/types.h>
diff --git a/llvm/tools/llvm-profgen/Options.h b/llvm/tools/llvm-profgen/Options.h
index f94cf91..b2c941f 100644
--- a/llvm/tools/llvm-profgen/Options.h
+++ b/llvm/tools/llvm-profgen/Options.h
@@ -22,6 +22,7 @@ extern cl::opt<bool> ShowDetailedWarning;
extern cl::opt<bool> InferMissingFrames;
extern cl::opt<bool> EnableCSPreInliner;
extern cl::opt<bool> UseContextCostForPreInliner;
+extern cl::opt<bool> LoadFunctionFromSymbol;
} // end namespace llvm
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index 183b248..1dc5932 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -1284,6 +1284,7 @@ void PerfScriptReader::warnInvalidRange() {
uint64_t TotalRangeNum = 0;
uint64_t InstNotBoundary = 0;
uint64_t UnmatchedRange = 0;
+ uint64_t RecoveredRange = 0;
uint64_t RangeCrossFunc = 0;
uint64_t BogusRange = 0;
@@ -1309,6 +1310,9 @@ void PerfScriptReader::warnInvalidRange() {
continue;
}
+ if (FRange->Func->NameStatus != DwarfNameStatus::Matched)
+ RecoveredRange += I.second;
+
if (EndAddress >= FRange->EndAddress) {
RangeCrossFunc += I.second;
WarnInvalidRange(StartAddress, EndAddress, RangeCrossFuncMsg);
@@ -1328,6 +1332,9 @@ void PerfScriptReader::warnInvalidRange() {
emitWarningSummary(
UnmatchedRange, TotalRangeNum,
"of samples are from ranges that do not belong to any functions.");
+ emitWarningSummary(RecoveredRange, TotalRangeNum,
+ "of samples are from ranges that belong to functions "
+ "recovered from symbol table.");
emitWarningSummary(
RangeCrossFunc, TotalRangeNum,
"of samples are from ranges that do cross function boundaries.");
diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.cpp b/llvm/tools/llvm-profgen/ProfileGenerator.cpp
index 3b875c5..33931f3 100644
--- a/llvm/tools/llvm-profgen/ProfileGenerator.cpp
+++ b/llvm/tools/llvm-profgen/ProfileGenerator.cpp
@@ -503,8 +503,11 @@ ProfileGenerator::getTopLevelFunctionProfile(FunctionId FuncName) {
void ProfileGenerator::generateProfile() {
collectProfiledFunctions();
- if (Binary->usePseudoProbes())
+ if (Binary->usePseudoProbes()) {
Binary->decodePseudoProbe();
+ if (LoadFunctionFromSymbol)
+ Binary->loadSymbolsFromPseudoProbe();
+ }
if (SampleCounters) {
if (Binary->usePseudoProbes()) {
@@ -732,6 +735,14 @@ ProfileGeneratorBase::getCalleeNameForAddress(uint64_t TargetAddress) {
if (!FRange || !FRange->IsFuncEntry)
return StringRef();
+ // DWARF and symbol table may have mismatching function names. Instead, we'll
+ // try to use its pseudo probe name first.
+ if (Binary->usePseudoProbes()) {
+ auto FuncName = Binary->findPseudoProbeName(FRange->Func);
+ if (FuncName.size())
+ return FunctionSamples::getCanonicalFnName(FuncName);
+ }
+
return FunctionSamples::getCanonicalFnName(FRange->getFuncName());
}
@@ -919,6 +930,8 @@ void CSProfileGenerator::generateProfile() {
Binary->decodePseudoProbe();
if (InferMissingFrames)
initializeMissingFrameInferrer();
+ if (LoadFunctionFromSymbol)
+ Binary->loadSymbolsFromPseudoProbe();
}
if (SampleCounters) {
diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp
index 94728ce..aa16b66 100644
--- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp
+++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp
@@ -37,6 +37,14 @@ cl::opt<bool> ShowSourceLocations("show-source-locations",
cl::desc("Print source locations."),
cl::cat(ProfGenCategory));
+cl::opt<bool> LoadFunctionFromSymbol(
+ "load-function-from-symbol", cl::init(true),
+ cl::desc(
+ "Gather additional binary function info from symbols (e.g. .symtab) in "
+ "case dwarf info is incomplete. Only support binaries in ELF format "
+ "with pseudo probe, for other formats, this flag will be a no-op."),
+ cl::cat(ProfGenCategory));
+
static cl::opt<bool>
ShowCanonicalFnName("show-canonical-fname",
cl::desc("Print canonical function name."),
@@ -187,7 +195,7 @@ ProfiledBinary::ProfiledBinary(const StringRef ExeBinPath,
load();
}
-ProfiledBinary::~ProfiledBinary() {}
+ProfiledBinary::~ProfiledBinary() = default;
void ProfiledBinary::warnNoFuncEntry() {
uint64_t NoFuncEntryNum = 0;
@@ -257,6 +265,9 @@ void ProfiledBinary::load() {
if (ShowDisassemblyOnly)
decodePseudoProbe(Obj);
+ if (LoadFunctionFromSymbol && UsePseudoProbes)
+ loadSymbolsFromSymtab(Obj);
+
// Disassemble the text sections.
disassemble(Obj);
@@ -461,6 +472,13 @@ void ProfiledBinary::decodePseudoProbe(const ObjectFile *Obj) {
} else {
for (auto *F : ProfiledFunctions) {
GuidFilter.insert(Function::getGUIDAssumingExternalLinkage(F->FuncName));
+ // DWARF name might be broken when a DWARF32 .debug_str.dwo section
+ // execeeds 4GB. We expect symbol table to contain the correct function
+ // names which matches the pseudo probe. Adding back all the GUIDs if
+ // possible.
+ auto AltGUIDs = AlternativeFunctionGUIDs.equal_range(F);
+ for (const auto &[_, Func] : make_range(AltGUIDs))
+ GuidFilter.insert(Func);
for (auto &Range : F->Ranges) {
auto GUIDs = StartAddrToSymMap.equal_range(Range.first);
for (const auto &[StartAddr, Func] : make_range(GUIDs))
@@ -522,7 +540,9 @@ void ProfiledBinary::setIsFuncEntry(FuncRange *FuncRange,
// Set IsFuncEntry to ture if there is only one range in the function or the
// RangeSymName from ELF is equal to its DWARF-based function name.
if (FuncRange->Func->Ranges.size() == 1 ||
- (!FuncRange->IsFuncEntry && FuncRange->getFuncName() == RangeSymName))
+ (!FuncRange->IsFuncEntry &&
+ (FuncRange->getFuncName() == RangeSymName ||
+ FuncRange->Func->NameStatus != DwarfNameStatus::Matched)))
FuncRange->IsFuncEntry = true;
}
@@ -604,13 +624,14 @@ bool ProfiledBinary::dissassembleSymbol(std::size_t SI, ArrayRef<uint8_t> Bytes,
// Record potential call targets for tail frame inference later-on.
if (InferMissingFrames && FRange) {
uint64_t Target = 0;
- MIA->evaluateBranch(Inst, Address, Size, Target);
+ [[maybe_unused]] bool Err =
+ MIA->evaluateBranch(Inst, Address, Size, Target);
if (MCDesc.isCall()) {
// Indirect call targets are unknown at this point. Recording the
// unknown target (zero) for further LBR-based refinement.
MissingContextInferrer->CallEdges[Address].insert(Target);
} else if (MCDesc.isUnconditionalBranch()) {
- assert(Target &&
+ assert(Err &&
"target should be known for unconditional direct branch");
// Any inter-function unconditional jump is considered tail call at
// this point. This is not 100% accurate and could further be
@@ -820,6 +841,100 @@ void ProfiledBinary::populateSymbolAddressList(const ObjectFile *Obj) {
}
}
+void ProfiledBinary::loadSymbolsFromSymtab(const ObjectFile *Obj) {
+ // Load binary functions from symbol table when Debug info is incomplete.
+ // Strip the internal suffixes which are not reflected in the DWARF info.
+ const SmallVector<StringRef, 10> Suffixes(
+ {// Internal suffixes from CoroSplit pass
+ ".cleanup", ".destroy", ".resume",
+ // Internal suffixes from Bolt
+ ".cold", ".warm",
+ // Compiler/LTO internal
+ ".llvm.", ".part.", ".isra.", ".constprop.", ".lto_priv."});
+ StringRef FileName = Obj->getFileName();
+ // Only apply this to ELF binary. e.g. COFF file format doesn't have `size`
+ // field in the symbol table.
+ bool IsELFObject = isa<ELFObjectFileBase>(Obj);
+ if (!IsELFObject)
+ return;
+ for (const SymbolRef &Symbol : Obj->symbols()) {
+ const SymbolRef::Type Type = unwrapOrError(Symbol.getType(), FileName);
+ const uint64_t StartAddr = unwrapOrError(Symbol.getAddress(), FileName);
+ const StringRef Name = unwrapOrError(Symbol.getName(), FileName);
+ uint64_t Size = 0;
+ if (LLVM_LIKELY(IsELFObject)) {
+ ELFSymbolRef ElfSymbol(Symbol);
+ Size = ElfSymbol.getSize();
+ }
+
+ if (Size == 0 || Type != SymbolRef::ST_Function)
+ continue;
+
+ const uint64_t EndAddr = StartAddr + Size;
+ const StringRef SymName =
+ FunctionSamples::getCanonicalFnName(Name, Suffixes);
+ assert(StartAddr < EndAddr && StartAddr >= getPreferredBaseAddress() &&
+ "Function range is invalid.");
+
+ auto Range = findFuncRange(StartAddr);
+ if (!Range) {
+ assert(findFuncRange(EndAddr - 1) == nullptr &&
+ "Function range overlaps with existing functions.");
+ // Function from symbol table not found previously in DWARF, store ranges.
+ auto Ret = BinaryFunctions.emplace(SymName, BinaryFunction());
+ auto &Func = Ret.first->second;
+ if (Ret.second) {
+ Func.FuncName = Ret.first->first;
+ HashBinaryFunctions[Function::getGUIDAssumingExternalLinkage(SymName)] =
+ &Func;
+ }
+
+ Func.NameStatus = DwarfNameStatus::Missing;
+ Func.Ranges.emplace_back(StartAddr, EndAddr);
+
+ auto R = StartAddrToFuncRangeMap.emplace(StartAddr, FuncRange());
+ FuncRange &FRange = R.first->second;
+
+ FRange.Func = &Func;
+ FRange.StartAddress = StartAddr;
+ FRange.EndAddress = EndAddr;
+
+ } else if (SymName != Range->getFuncName()) {
+ // Function range already found from DWARF, but the symbol name from
+ // symbol table is inconsistent with debug info. Log this discrepancy and
+ // the alternative function GUID.
+ if (ShowDetailedWarning)
+ WithColor::warning()
+ << "Conflicting name for symbol " << Name << " with range ("
+ << format("%8" PRIx64, StartAddr) << ", "
+ << format("%8" PRIx64, EndAddr) << ")"
+ << ", but the DWARF symbol " << Range->getFuncName()
+ << " indicates an overlapping range ("
+ << format("%8" PRIx64, Range->StartAddress) << ", "
+ << format("%8" PRIx64, Range->EndAddress) << ")\n";
+
+ assert(StartAddr == Range->StartAddress && EndAddr == Range->EndAddress &&
+ "Mismatched function range");
+
+ Range->Func->NameStatus = DwarfNameStatus::Mismatch;
+ AlternativeFunctionGUIDs.emplace(
+ Range->Func, Function::getGUIDAssumingExternalLinkage(SymName));
+
+ } else if (StartAddr != Range->StartAddress &&
+ EndAddr != Range->EndAddress) {
+ // Function already found in DWARF, but the address range from symbol
+ // table conflicts/overlaps with the debug info.
+ WithColor::warning() << "Conflicting range for symbol " << Name
+ << " with range (" << format("%8" PRIx64, StartAddr)
+ << ", " << format("%8" PRIx64, EndAddr) << ")"
+ << ", but the DWARF symbol " << Range->getFuncName()
+ << " indicates another range ("
+ << format("%8" PRIx64, Range->StartAddress) << ", "
+ << format("%8" PRIx64, Range->EndAddress) << ")\n";
+ }
+ }
+}
+
void ProfiledBinary::loadSymbolsFromDWARFUnit(DWARFUnit &CompilationUnit) {
for (const auto &DieInfo : CompilationUnit.dies()) {
llvm::DWARFDie Die(&CompilationUnit, &DieInfo);
@@ -1034,6 +1149,58 @@ void ProfiledBinary::computeInlinedContextSizeForFunc(
}
}
+void ProfiledBinary::loadSymbolsFromPseudoProbe() {
+ if (!UsePseudoProbes)
+ return;
+
+ const AddressProbesMap &Address2ProbesMap = getAddress2ProbesMap();
+ for (auto *Func : ProfiledFunctions) {
+ if (Func->NameStatus != DwarfNameStatus::Mismatch)
+ continue;
+ for (auto &[StartAddr, EndAddr] : Func->Ranges) {
+ auto Range = findFuncRangeForStartAddr(StartAddr);
+ if (!Range->IsFuncEntry)
+ continue;
+ const auto &Probe = Address2ProbesMap.find(StartAddr, EndAddr);
+ if (Probe.begin() != Probe.end()) {
+ const MCDecodedPseudoProbeInlineTree *InlineTreeNode =
+ Probe.begin()->get().getInlineTreeNode();
+ while (!InlineTreeNode->isTopLevelFunc())
+ InlineTreeNode = static_cast<MCDecodedPseudoProbeInlineTree *>(
+ InlineTreeNode->Parent);
+
+ auto TopLevelProbes = InlineTreeNode->getProbes();
+ [[maybe_unused]] auto TopProbe = TopLevelProbes.begin();
+ assert(TopProbe != TopLevelProbes.end() &&
+ TopProbe->getAddress() >= StartAddr &&
+ TopProbe->getAddress() < EndAddr &&
+ "Top level pseudo probe does not match function range");
+
+ const auto *ProbeDesc = getFuncDescForGUID(InlineTreeNode->Guid);
+ auto Ret = PseudoProbeNames.emplace(Func, ProbeDesc->FuncName);
+ if (!Ret.second && Ret.first->second != ProbeDesc->FuncName &&
+ ShowDetailedWarning)
+ WithColor::warning()
+ << "Mismatched pseudo probe names in function " << Func->FuncName
+ << " at range: (" << format("%8" PRIx64, StartAddr) << ", "
+ << format("%8" PRIx64, EndAddr) << "). "
+ << "The previously found pseudo probe name is "
+ << Ret.first->second << " but it conflicts with name "
+ << ProbeDesc->FuncName
+ << " This likely indicates a DWARF error that produces "
+ "conflicting symbols at the same starting address.\n";
+ }
+ }
+ }
+}
+
+StringRef ProfiledBinary::findPseudoProbeName(const BinaryFunction *Func) {
+ auto ProbeName = PseudoProbeNames.find(Func);
+ if (ProbeName == PseudoProbeNames.end())
+ return StringRef();
+ return ProbeName->second;
+}
+
void ProfiledBinary::inferMissingFrames(
const SmallVectorImpl<uint64_t> &Context,
SmallVectorImpl<uint64_t> &NewContext) {
diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.h b/llvm/tools/llvm-profgen/ProfiledBinary.h
index 5a814b7..1a83f82 100644
--- a/llvm/tools/llvm-profgen/ProfiledBinary.h
+++ b/llvm/tools/llvm-profgen/ProfiledBinary.h
@@ -72,10 +72,22 @@ enum SpecialFrameAddr {
using RangesTy = std::vector<std::pair<uint64_t, uint64_t>>;
+enum DwarfNameStatus {
+ // Dwarf name matches with the symbol table (or symbol table just doesn't have
+ // this entry)
+ Matched = 0,
+ // Dwarf name is missing, but we fixed it with the name from symbol table
+ Missing = 1,
+ // Symbol table has different names on this. Log these GUIDs in
+ // AlternativeFunctionGUIDs
+ Mismatch = 2,
+};
+
struct BinaryFunction {
StringRef FuncName;
// End of range is an exclusive bound.
RangesTy Ranges;
+ DwarfNameStatus NameStatus = DwarfNameStatus::Matched;
uint64_t getFuncSize() {
uint64_t Sum = 0;
@@ -231,6 +243,14 @@ class ProfiledBinary {
// GUID to symbol start address map
DenseMap<uint64_t, uint64_t> SymbolStartAddrs;
+ // Binary function to GUID mapping that stores the alternative names in symbol
+ // table, despite the original name from DWARF info
+ std::unordered_multimap<const BinaryFunction *, uint64_t>
+ AlternativeFunctionGUIDs;
+
+ // Mapping of profiled binary function to its pseudo probe name
+ std::unordered_map<const BinaryFunction *, StringRef> PseudoProbeNames;
+
// These maps are for temporary use of warning diagnosis.
DenseSet<int64_t> AddrsWithMultipleSymbols;
DenseSet<std::pair<uint64_t, uint64_t>> AddrsWithInvalidInstruction;
@@ -356,6 +376,9 @@ class ProfiledBinary {
// Create symbol to its start address mapping.
void populateSymbolAddressList(const object::ObjectFile *O);
+ // Load functions from its symbol table (when DWARF info is missing).
+ void loadSymbolsFromSymtab(const object::ObjectFile *O);
+
// A function may be spilt into multiple non-continuous address ranges. We use
// this to set whether start a function range is the real entry of the
// function and also set false to the non-function label.
@@ -599,6 +622,10 @@ public:
void computeInlinedContextSizeForFunc(const BinaryFunction *Func);
+ void loadSymbolsFromPseudoProbe();
+
+ StringRef findPseudoProbeName(const BinaryFunction *Func);
+
const MCDecodedPseudoProbe *getCallProbeForAddr(uint64_t Address) const {
return ProbeDecoder.getCallProbeForAddr(Address);
}
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.h b/llvm/tools/llvm-rc/ResourceFileWriter.h
index 82d3e3b..a13af45 100644
--- a/llvm/tools/llvm-rc/ResourceFileWriter.h
+++ b/llvm/tools/llvm-rc/ResourceFileWriter.h
@@ -19,6 +19,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Endian.h"
+#include <map>
+
namespace llvm {
class MemoryBuffer;
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h
index a81e384f..84da9be 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.h
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h
@@ -242,9 +242,9 @@ public:
virtual raw_ostream &log(raw_ostream &OS) const {
return OS << "Base statement\n";
};
- RCResource() {}
+ RCResource() = default;
RCResource(uint16_t Flags) : MemoryFlags(Flags) {}
- virtual ~RCResource() {}
+ virtual ~RCResource() = default;
virtual Error visit(Visitor *) const {
llvm_unreachable("This is unable to call methods from Visitor base");
@@ -290,7 +290,7 @@ class OptionalStmtList : public OptionalStmt {
std::vector<std::unique_ptr<OptionalStmt>> Statements;
public:
- OptionalStmtList() {}
+ OptionalStmtList() = default;
raw_ostream &log(raw_ostream &OS) const override;
void addStmt(std::unique_ptr<OptionalStmt> Stmt) {
@@ -510,7 +510,7 @@ public:
virtual raw_ostream &log(raw_ostream &OS) const {
return OS << "Base menu definition\n";
}
- virtual ~MenuDefinition() {}
+ virtual ~MenuDefinition() = default;
virtual uint16_t getResFlags() const { return 0; }
virtual MenuDefKind getKind() const { return MkBase; }
@@ -818,7 +818,7 @@ public:
enum StmtKind { StBase = 0, StBlock = 1, StValue = 2 };
virtual raw_ostream &log(raw_ostream &OS) const { return OS << "VI stmt\n"; }
- virtual ~VersionInfoStmt() {}
+ virtual ~VersionInfoStmt() = default;
virtual StmtKind getKind() const { return StBase; }
static bool classof(const VersionInfoStmt *S) {
diff --git a/llvm/tools/llvm-rc/ResourceScriptToken.cpp b/llvm/tools/llvm-rc/ResourceScriptToken.cpp
index 0070037..046a1bf 100644
--- a/llvm/tools/llvm-rc/ResourceScriptToken.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptToken.cpp
@@ -26,11 +26,11 @@ using namespace llvm;
using Kind = RCToken::Kind;
// Checks if Representation is a correct description of an RC integer.
-// It should be a 32-bit unsigned integer, either decimal, octal (0[0-7]+),
-// or hexadecimal (0x[0-9a-f]+). It might be followed by a single 'L'
-// character (that is the difference between our representation and
-// StringRef's one). If Representation is correct, 'true' is returned and
-// the return value is put back in Num.
+// It should be a 32-bit unsigned integer, either decimal or hexadecimal
+// (0x[0-9a-f]+). For Windres mode, it can also be octal (0[0-7]+).
+// It might be followed by a single 'L' character (that is the difference
+// between our representation and StringRef's one). If Representation is
+// correct, 'true' is returned and the return value is put back in Num.
static bool rcGetAsInteger(StringRef Representation, uint32_t &Num) {
size_t Length = Representation.size();
if (Length == 0)
@@ -95,7 +95,8 @@ namespace {
class Tokenizer {
public:
- Tokenizer(StringRef Input) : Data(Input), DataLength(Input.size()), Pos(0) {}
+ Tokenizer(StringRef Input, bool IsWindres)
+ : Data(Input), DataLength(Input.size()), Pos(0), IsWindres(IsWindres) {}
Expected<std::vector<RCToken>> run();
@@ -128,6 +129,7 @@ private:
// character.
bool canStartInt() const;
bool canContinueInt() const;
+ void trimIntString(StringRef &Str) const;
bool canStartString() const;
@@ -153,6 +155,7 @@ private:
StringRef Data;
size_t DataLength, Pos;
+ bool IsWindres;
};
void Tokenizer::skipCurrentLine() {
@@ -187,7 +190,12 @@ Expected<std::vector<RCToken>> Tokenizer::run() {
if (TokenKind == Kind::LineComment || TokenKind == Kind::StartComment)
continue;
- RCToken Token(TokenKind, Data.take_front(Pos).drop_front(TokenStart));
+ StringRef Contents = Data.take_front(Pos).drop_front(TokenStart);
+
+ if (TokenKind == Kind::Int)
+ trimIntString(Contents);
+
+ RCToken Token(TokenKind, Contents);
if (TokenKind == Kind::Identifier) {
processIdentifier(Token);
} else if (TokenKind == Kind::Int) {
@@ -366,12 +374,30 @@ void Tokenizer::processIdentifier(RCToken &Token) const {
Token = RCToken(Kind::BlockEnd, Name);
}
+void Tokenizer::trimIntString(StringRef &Str) const {
+ if (!IsWindres) {
+ // For compatibility with rc.exe, strip leading zeros that make the
+ // integer literal interpreted as octal.
+ //
+ // We do rely on Stringref::getAsInteger for autodetecting between
+ // decimal and hexadecimal literals, but we want to avoid interpreting
+ // literals as octal.
+ //
+ // This omits the leading zeros from the RCToken's value string entirely,
+ // which also has a visible effect when dumping the tokenizer output.
+ // Alternatively, we could store the IsWindres flag in RCToken and defer
+ // the trimming to RCToken::intValue.
+ while (Str.size() >= 2 && Str[0] == '0' && std::isdigit(Str[1]))
+ Str = Str.drop_front(1);
+ }
+}
+
} // anonymous namespace
namespace llvm {
-Expected<std::vector<RCToken>> tokenizeRC(StringRef Input) {
- return Tokenizer(Input).run();
+Expected<std::vector<RCToken>> tokenizeRC(StringRef Input, bool IsWindres) {
+ return Tokenizer(Input, IsWindres).run();
}
} // namespace llvm
diff --git a/llvm/tools/llvm-rc/ResourceScriptToken.h b/llvm/tools/llvm-rc/ResourceScriptToken.h
index 3dcdfaf..4c839a0 100644
--- a/llvm/tools/llvm-rc/ResourceScriptToken.h
+++ b/llvm/tools/llvm-rc/ResourceScriptToken.h
@@ -28,7 +28,6 @@
#include "llvm/Support/Error.h"
#include <cstdint>
-#include <map>
#include <vector>
namespace llvm {
@@ -76,7 +75,7 @@ private:
// Tokens returned by this function hold only references to the parts
// of the Input. Memory buffer containing Input cannot be freed,
// modified or reallocated.
-Expected<std::vector<RCToken>> tokenizeRC(StringRef Input);
+Expected<std::vector<RCToken>> tokenizeRC(StringRef Input, bool IsWindres);
} // namespace llvm
diff --git a/llvm/tools/llvm-rc/ResourceScriptTokenList.def b/llvm/tools/llvm-rc/ResourceScriptTokenList.def
index 6ee13b2..98af23c 100644
--- a/llvm/tools/llvm-rc/ResourceScriptTokenList.def
+++ b/llvm/tools/llvm-rc/ResourceScriptTokenList.def
@@ -14,7 +14,7 @@
// Long tokens. They might consist of more than one character.
TOKEN(Invalid) // Invalid token. Should not occur in a valid script.
-TOKEN(Int) // Integer (decimal, octal or hexadecimal).
+TOKEN(Int) // Integer (decimal or hexadecimal, and possibly octal for windres).
TOKEN(String) // String value.
TOKEN(Identifier) // Script identifier (resource name or type).
TOKEN(LineComment) // Beginning of single-line comment.
diff --git a/llvm/tools/llvm-rc/ResourceVisitor.h b/llvm/tools/llvm-rc/ResourceVisitor.h
index a121a0a..1815c6b 100644
--- a/llvm/tools/llvm-rc/ResourceVisitor.h
+++ b/llvm/tools/llvm-rc/ResourceVisitor.h
@@ -55,7 +55,7 @@ public:
virtual Error visitVersionStmt(const VersionStmt *) = 0;
virtual Error visitMenuStmt(const MenuStmt *) = 0;
- virtual ~Visitor() {}
+ virtual ~Visitor() = default;
};
} // namespace rc
diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp
index f623342..38bf03f 100644
--- a/llvm/tools/llvm-rc/llvm-rc.cpp
+++ b/llvm/tools/llvm-rc/llvm-rc.cpp
@@ -619,7 +619,8 @@ void doRc(std::string Src, std::string Dest, RcOptions &Opts,
StringRef Contents = FileContents->getBuffer();
std::string FilteredContents = filterCppOutput(Contents);
- std::vector<RCToken> Tokens = ExitOnErr(tokenizeRC(FilteredContents));
+ std::vector<RCToken> Tokens =
+ ExitOnErr(tokenizeRC(FilteredContents, Opts.IsWindres));
if (Opts.BeVerbose) {
const Twine TokenNames[] = {
diff --git a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
index c6e409c..32e3d05 100644
--- a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
+++ b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
@@ -1404,6 +1404,12 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
FpSZ += 8;
int SavSZ = (IntSZ + FpSZ + 8 * 8 * RF.H() + 0xf) & ~0xf;
int LocSZ = (RF.FrameSize() << 4) - SavSZ;
+ bool Homing = RF.H();
+
+ if (RF.H() && RF.RegI() == 0 && RF.RegF() == 0 && RF.CR() != 1) {
+ LocSZ += SavSZ;
+ Homing = false;
+ }
if (RF.CR() == 2 || RF.CR() == 3) {
SW.startLine() << "mov x29, sp\n";
@@ -1419,18 +1425,11 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
} else if ((RF.CR() != 3 && RF.CR() != 2 && LocSZ > 0) || LocSZ > 512) {
SW.startLine() << format("sub sp, sp, #%d\n", LocSZ);
}
- if (RF.H()) {
+ if (Homing) {
SW.startLine() << format("stp x6, x7, [sp, #%d]\n", SavSZ - 16);
SW.startLine() << format("stp x4, x5, [sp, #%d]\n", SavSZ - 32);
SW.startLine() << format("stp x2, x3, [sp, #%d]\n", SavSZ - 48);
- if (RF.RegI() > 0 || RF.RegF() > 0 || RF.CR() == 1) {
- SW.startLine() << format("stp x0, x1, [sp, #%d]\n", SavSZ - 64);
- } else {
- // This case isn't documented; if neither RegI nor RegF nor CR=1
- // have decremented the stack pointer by SavSZ, we need to do it here
- // (as the final stack adjustment of LocSZ excludes SavSZ).
- SW.startLine() << format("stp x0, x1, [sp, #-%d]!\n", SavSZ);
- }
+ SW.startLine() << format("stp x0, x1, [sp, #%d]\n", SavSZ - 64);
}
int FloatRegs = RF.RegF() > 0 ? RF.RegF() + 1 : 0;
for (int I = (FloatRegs + 1) / 2 - 1; I >= 0; I--) {
@@ -1457,10 +1456,14 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
// The last register, an odd register without a pair
if (RF.CR() == 1) {
if (I == 0) { // If this is the only register pair
- // CR=1 combined with RegI=1 doesn't map to a documented case;
- // it doesn't map to any regular unwind info opcode, and the
- // actual unwinder doesn't support it.
- SW.startLine() << "INVALID!\n";
+ // CR=1 combined with RegI=1 maps to a special case; there's
+ // no unwind info opcode that saves a GPR together with LR
+ // with writeback to sp (no save_lrpair_x).
+ // Instead, this case expands to two instructions; a preceding
+ // (in prologue execution order) "sub sp, sp, #16", followed
+ // by a regular "stp x19, lr, [sp]" (save_lrpair).
+ SW.startLine() << format("stp x%d, lr, [sp]\n", 19);
+ SW.startLine() << format("sub sp, sp, #%d\n", SavSZ);
} else
SW.startLine() << format("stp x%d, lr, [sp, #%d]\n", 19 + 2 * I,
16 * I);
@@ -1478,9 +1481,6 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
19 + 2 * I + 1, 16 * I);
}
}
- // CR=2 is yet undocumented, see
- // https://github.com/MicrosoftDocs/cpp-docs/pull/4202 for upstream
- // progress on getting it documented.
if (RF.CR() == 2)
SW.startLine() << "pacibsp\n";
SW.startLine() << "end\n";
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 73115fb..55e106d 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -2330,8 +2330,7 @@ void COFFDumper::printResourceDirectoryTable(
std::vector<UTF16> EndianCorrectedNameString;
if (llvm::sys::IsBigEndianHost) {
EndianCorrectedNameString.resize(RawEntryNameString.size() + 1);
- std::copy(RawEntryNameString.begin(), RawEntryNameString.end(),
- EndianCorrectedNameString.begin() + 1);
+ llvm::copy(RawEntryNameString, EndianCorrectedNameString.begin() + 1);
EndianCorrectedNameString[0] = UNI_UTF16_BYTE_ORDER_MARK_SWAPPED;
RawEntryNameString = ArrayRef(EndianCorrectedNameString);
}
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 6f09da5..2b5bc63 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -61,7 +61,6 @@
#include "llvm/Support/RISCVAttributeParser.h"
#include "llvm/Support/RISCVAttributes.h"
#include "llvm/Support/ScopedPrinter.h"
-#include "llvm/Support/SystemZ/zOSSupport.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <array>
diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp
index 0a23ad7..6ba3262 100644
--- a/llvm/tools/llvm-readobj/MachODumper.cpp
+++ b/llvm/tools/llvm-readobj/MachODumper.cpp
@@ -110,17 +110,20 @@ const EnumEntry<uint32_t> MachOHeaderFileTypes[] = {
{ "KextBundle", MachO::MH_KEXT_BUNDLE },
};
+// clang-format off
const EnumEntry<uint32_t> MachOHeaderCpuTypes[] = {
- { "Any" , static_cast<uint32_t>(MachO::CPU_TYPE_ANY) },
- { "X86" , MachO::CPU_TYPE_X86 },
- { "X86-64" , MachO::CPU_TYPE_X86_64 },
- { "Mc98000" , MachO::CPU_TYPE_MC98000 },
- { "Arm" , MachO::CPU_TYPE_ARM },
- { "Arm64" , MachO::CPU_TYPE_ARM64 },
- { "Sparc" , MachO::CPU_TYPE_SPARC },
- { "PowerPC" , MachO::CPU_TYPE_POWERPC },
- { "PowerPC64" , MachO::CPU_TYPE_POWERPC64 },
+ { "Any" , static_cast<uint32_t>(MachO::CPU_TYPE_ANY) },
+ { "X86" , MachO::CPU_TYPE_X86 },
+ { "X86-64" , MachO::CPU_TYPE_X86_64 },
+ { "Mc98000" , MachO::CPU_TYPE_MC98000 },
+ { "Arm" , MachO::CPU_TYPE_ARM },
+ { "Arm64" , MachO::CPU_TYPE_ARM64 },
+ { "Arm64 (ILP32)", MachO::CPU_TYPE_ARM64_32 },
+ { "Sparc" , MachO::CPU_TYPE_SPARC },
+ { "PowerPC" , MachO::CPU_TYPE_POWERPC },
+ { "PowerPC64" , MachO::CPU_TYPE_POWERPC64 },
};
+// clang-format on
const EnumEntry<uint32_t> MachOHeaderCpuSubtypesX86[] = {
LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_I386_ALL),
@@ -166,6 +169,10 @@ const EnumEntry<uint32_t> MachOHeaderCpuSubtypesARM[] = {
LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7EM),
};
+const EnumEntry<uint32_t> MachOHeaderCpuSubtypesARM64_32[] = {
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64_32_V8),
+};
+
const EnumEntry<uint32_t> MachOHeaderCpuSubtypesARM64[] = {
LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64_ALL),
LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64_V8),
@@ -453,9 +460,13 @@ void MachODumper::printFileHeaders(const MachHeader &Header) {
case MachO::CPU_TYPE_ARM64:
W.printEnum("CpuSubType", subtype, ArrayRef(MachOHeaderCpuSubtypesARM64));
break;
+ case MachO::CPU_TYPE_ARM64_32:
+ W.printEnum("CpuSubType", subtype,
+ ArrayRef(MachOHeaderCpuSubtypesARM64_32));
+ break;
case MachO::CPU_TYPE_POWERPC64:
default:
- W.printHex("CpuSubtype", subtype);
+ W.printHex("CpuSubType", subtype);
}
W.printEnum("FileType", Header.filetype, ArrayRef(MachOHeaderFileTypes));
W.printNumber("NumOfLoadCommands", Header.ncmds);
diff --git a/llvm/tools/llvm-readobj/ObjDumper.cpp b/llvm/tools/llvm-readobj/ObjDumper.cpp
index 0b59dd4..1d19357 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.cpp
+++ b/llvm/tools/llvm-readobj/ObjDumper.cpp
@@ -21,7 +21,6 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ScopedPrinter.h"
-#include "llvm/Support/SystemZ/zOSSupport.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
@@ -41,7 +40,7 @@ ObjDumper::ObjDumper(ScopedPrinter &Writer, StringRef ObjName) : W(Writer) {
};
}
-ObjDumper::~ObjDumper() {}
+ObjDumper::~ObjDumper() = default;
void ObjDumper::reportUniqueWarning(Error Err) const {
reportUniqueWarning(toString(std::move(Err)));
diff --git a/llvm/tools/llvm-readtapi/DiffEngine.h b/llvm/tools/llvm-readtapi/DiffEngine.h
index 7ab57d4..b350ceef 100644
--- a/llvm/tools/llvm-readtapi/DiffEngine.h
+++ b/llvm/tools/llvm-readtapi/DiffEngine.h
@@ -39,7 +39,7 @@ enum DiffAttrKind {
class AttributeDiff {
public:
AttributeDiff(DiffAttrKind Kind) : Kind(Kind){};
- virtual ~AttributeDiff(){};
+ virtual ~AttributeDiff() = default;
DiffAttrKind getKind() const { return Kind; }
private:
diff --git a/llvm/tools/llvm-reduce/CMakeLists.txt b/llvm/tools/llvm-reduce/CMakeLists.txt
index c8673b4..cf6701a 100644
--- a/llvm/tools/llvm-reduce/CMakeLists.txt
+++ b/llvm/tools/llvm-reduce/CMakeLists.txt
@@ -60,6 +60,7 @@ add_llvm_tool(llvm-reduce
deltas/ReduceRegisterMasks.cpp
deltas/ReduceRegisterDefs.cpp
deltas/ReduceRegisterUses.cpp
+ deltas/ReduceSinkDefsToUses.cpp
deltas/ReduceTargetFeaturesAttr.cpp
deltas/ReduceUsingSimplifyCFG.cpp
deltas/RunIRPasses.cpp
diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp
index 9b13202..769e8a0 100644
--- a/llvm/tools/llvm-reduce/DeltaManager.cpp
+++ b/llvm/tools/llvm-reduce/DeltaManager.cpp
@@ -45,6 +45,7 @@
#include "deltas/ReduceRegisterDefs.h"
#include "deltas/ReduceRegisterMasks.h"
#include "deltas/ReduceRegisterUses.h"
+#include "deltas/ReduceSinkDefsToUses.h"
#include "deltas/ReduceSpecialGlobals.h"
#include "deltas/ReduceTargetFeaturesAttr.h"
#include "deltas/ReduceUsingSimplifyCFG.h"
diff --git a/llvm/tools/llvm-reduce/DeltaPasses.def b/llvm/tools/llvm-reduce/DeltaPasses.def
index 845b106..1ec7354 100644
--- a/llvm/tools/llvm-reduce/DeltaPasses.def
+++ b/llvm/tools/llvm-reduce/DeltaPasses.def
@@ -59,6 +59,7 @@ DELTA_PASS_IR("atomic-ordering", reduceAtomicOrderingDeltaPass, "Reducing Atomic
DELTA_PASS_IR("syncscopes", reduceAtomicSyncScopesDeltaPass, "Reducing Atomic Sync Scopes")
DELTA_PASS_IR("instruction-flags", reduceInstructionFlagsDeltaPass, "Reducing Instruction Flags")
DELTA_PASS_IR("inline-call-sites", reduceInlineCallSitesDeltaPass, "Inlining callsites")
+DELTA_PASS_IR("sink-defs-to-uses", reduceSinkDefsToUsesDeltaPass, "Sinking defs to uses")
#ifndef DELTA_PASS_MIR
#define DELTA_PASS_MIR(NAME, FUNC, DESC)
diff --git a/llvm/tools/llvm-reduce/TestRunner.h b/llvm/tools/llvm-reduce/TestRunner.h
index 930c324..0218dad 100644
--- a/llvm/tools/llvm-reduce/TestRunner.h
+++ b/llvm/tools/llvm-reduce/TestRunner.h
@@ -16,7 +16,6 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Target/TargetMachine.h"
-#include <vector>
namespace llvm {
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceSinkDefsToUses.cpp b/llvm/tools/llvm-reduce/deltas/ReduceSinkDefsToUses.cpp
new file mode 100644
index 0000000..454a6e4
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceSinkDefsToUses.cpp
@@ -0,0 +1,61 @@
+//===- ReduceSinkDefsToUses.cpp - Specialized Delta Pass ------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Try to move defs to be next to their uses
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceSinkDefsToUses.h"
+#include "Utils.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Instructions.h"
+
+using namespace llvm;
+
+static bool shouldPreserveUsePosition(const Instruction &I) {
+ return isa<AllocaInst>(I) || isa<PHINode>(I) || I.isEHPad();
+}
+
+static bool shouldPreserveDefPosition(const Instruction &I) {
+ return shouldPreserveUsePosition(I) || I.isTerminator();
+}
+
+static void sinkDefsToUsesInFunction(Oracle &O, Function &F) {
+ DominatorTree DT(F);
+
+ for (BasicBlock &BB : F) {
+ for (Instruction &UseInst : make_early_inc_range(reverse(BB))) {
+ if (shouldPreserveUsePosition(UseInst))
+ continue;
+
+ for (Value *UseOp : UseInst.operands()) {
+ Instruction *DefInst = dyn_cast<Instruction>(UseOp);
+ if (!DefInst || shouldPreserveDefPosition(*DefInst))
+ continue;
+
+ if (!all_of(DefInst->users(), [&](const User *DefUser) {
+ return DefUser == &UseInst ||
+ DT.dominates(&UseInst, cast<Instruction>(DefUser));
+ })) {
+ continue;
+ }
+
+ if (!O.shouldKeep())
+ DefInst->moveBeforePreserving(UseInst.getIterator());
+ }
+ }
+ }
+}
+
+void llvm::reduceSinkDefsToUsesDeltaPass(Oracle &O, ReducerWorkItem &WorkItem) {
+ Module &M = WorkItem.getModule();
+ for (Function &F : M) {
+ if (!F.isDeclaration())
+ sinkDefsToUsesInFunction(O, F);
+ }
+}
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceSinkDefsToUses.h b/llvm/tools/llvm-reduce/deltas/ReduceSinkDefsToUses.h
new file mode 100644
index 0000000..422d0ea
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceSinkDefsToUses.h
@@ -0,0 +1,18 @@
+//===- ReduceSinkDefsToUses.h - Specialized Delta Pass ----------*- C++- *-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_SINKDEFSTOUSES_H
+#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_SINKDEFSTOUSES_H
+
+#include "Delta.h"
+
+namespace llvm {
+void reduceSinkDefsToUsesDeltaPass(Oracle &O, ReducerWorkItem &WorkItem);
+} // namespace llvm
+
+#endif
diff --git a/llvm/tools/llvm-stress/llvm-stress.cpp b/llvm/tools/llvm-stress/llvm-stress.cpp
index 133812e..2fe5d6b 100644
--- a/llvm/tools/llvm-stress/llvm-stress.cpp
+++ b/llvm/tools/llvm-stress/llvm-stress.cpp
@@ -40,7 +40,6 @@
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
diff --git a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp
index 0cf8c5c..0b606af 100644
--- a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp
+++ b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp
@@ -113,19 +113,20 @@ static void reportNumberOfEntries(const TargetLibraryInfo &TLI,
// Assume this gets called after initialize(), so we have the above line of
// output as a header. So, for example, no need to repeat the triple.
- for (unsigned FI = 0; FI != LibFunc::NumLibFuncs; ++FI) {
+ for (unsigned FI = LibFunc::Begin_LibFunc; FI != LibFunc::End_LibFunc; ++FI) {
if (TLI.has(static_cast<LibFunc>(FI)))
++NumAvailable;
}
- outs() << "TLI knows " << LibFunc::NumLibFuncs << " symbols, " << NumAvailable
- << " available for '" << TargetTriple << "'\n";
+ outs() << "TLI knows " << (LibFunc::End_LibFunc - LibFunc::Begin_LibFunc)
+ << " symbols, " << NumAvailable << " available for '" << TargetTriple
+ << "'\n";
}
static void dumpTLIEntries(const TargetLibraryInfo &TLI) {
// Assume this gets called after initialize(), so we have the above line of
// output as a header. So, for example, no need to repeat the triple.
- for (unsigned FI = 0; FI != LibFunc::NumLibFuncs; ++FI) {
+ for (unsigned FI = LibFunc::Begin_LibFunc; FI != LibFunc::End_LibFunc; ++FI) {
LibFunc LF = static_cast<LibFunc>(FI);
bool IsAvailable = TLI.has(LF);
StringRef FuncName = TargetLibraryInfo::getStandardName(LF);
@@ -316,7 +317,8 @@ int main(int argc, char *argv[]) {
unsigned TLIandSDKboth = 0;
unsigned TLIandSDKneither = 0;
- for (unsigned FI = 0; FI != LibFunc::NumLibFuncs; ++FI) {
+ for (unsigned FI = LibFunc::Begin_LibFunc; FI != LibFunc::End_LibFunc;
+ ++FI) {
LibFunc LF = static_cast<LibFunc>(FI);
StringRef TLIName = TLI.getStandardName(LF);
@@ -344,7 +346,7 @@ int main(int argc, char *argv[]) {
assert(TLIandSDKboth + TLIandSDKneither + TLIdoesSDKdoesnt +
TLIdoesntSDKdoes ==
- LibFunc::NumLibFuncs);
+ LibFunc::End_LibFunc - LibFunc::Begin_LibFunc);
(void) TLIandSDKneither;
outs() << "<< Total TLI yes SDK no: " << TLIdoesSDKdoesnt
<< "\n>> Total TLI no SDK yes: " << TLIdoesntSDKdoes
diff --git a/llvm/tools/llvm-xray/trie-node.h b/llvm/tools/llvm-xray/trie-node.h
index b42b029..f96be59 100644
--- a/llvm/tools/llvm-xray/trie-node.h
+++ b/llvm/tools/llvm-xray/trie-node.h
@@ -15,7 +15,6 @@
#define LLVM_TOOLS_LLVM_XRAY_STACK_TRIE_H
#include <forward_list>
-#include <numeric>
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
diff --git a/llvm/tools/llvm-xray/xray-extract.cpp b/llvm/tools/llvm-xray/xray-extract.cpp
index 70fe011..5ff8dc1 100644
--- a/llvm/tools/llvm-xray/xray-extract.cpp
+++ b/llvm/tools/llvm-xray/xray-extract.cpp
@@ -57,7 +57,7 @@ static void exportAsYAML(const InstrumentationMap &Map, raw_ostream &OS,
// First we translate the sleds into the YAMLXRaySledEntry objects in a deque.
std::vector<YAMLXRaySledEntry> YAMLSleds;
auto Sleds = Map.sleds();
- YAMLSleds.reserve(std::distance(Sleds.begin(), Sleds.end()));
+ YAMLSleds.reserve(llvm::size(Sleds));
for (const auto &Sled : Sleds) {
auto FuncId = Map.getFunctionId(Sled.Function);
if (!FuncId)
diff --git a/llvm/tools/llvm-xray/xray-graph.h b/llvm/tools/llvm-xray/xray-graph.h
index fd96449..bf25f8d 100644
--- a/llvm/tools/llvm-xray/xray-graph.h
+++ b/llvm/tools/llvm-xray/xray-graph.h
@@ -86,7 +86,7 @@ public:
};
GraphT G;
- using VertexIdentifier = typename decltype(G)::VertexIdentifier;
+ using VertexIdentifier = decltype(G)::VertexIdentifier;
using EdgeIdentifier = decltype(G)::EdgeIdentifier;
/// Use a Map to store the Function stack for each thread whilst building the
diff --git a/llvm/tools/lto/lto.cpp b/llvm/tools/lto/lto.cpp
index 467a4da..513d057 100644
--- a/llvm/tools/lto/lto.cpp
+++ b/llvm/tools/lto/lto.cpp
@@ -24,6 +24,7 @@
#include "llvm/LTO/legacy/LTOCodeGenerator.h"
#include "llvm/LTO/legacy/LTOModule.h"
#include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
@@ -44,6 +45,29 @@ static cl::opt<bool> EnableFreestanding(
"lto-freestanding", cl::init(false),
cl::desc("Enable Freestanding (disable builtins / TLI) during LTO"));
+static cl::opt<std::string> ThinLTOCacheDir(
+ "legacy-thinlto-cache-dir",
+ cl::desc("Experimental option, enable ThinLTO caching. Note: the cache "
+ "currently does not take the mcmodel setting into account, so you "
+ "might get false hits if different mcmodels are used in different "
+ "builds using the same cache directory."));
+
+static cl::opt<int> ThinLTOCachePruningInterval(
+ "legacy-thinlto-cache-pruning-interval", cl::init(1200),
+ cl::desc("Set ThinLTO cache pruning interval (seconds)."));
+
+static cl::opt<uint64_t> ThinLTOCacheMaxSizeBytes(
+ "legacy-thinlto-cache-max-size-bytes",
+ cl::desc("Set ThinLTO cache pruning directory maximum size in bytes."));
+
+static cl::opt<int> ThinLTOCacheMaxSizeFiles(
+ "legacy-thinlto-cache-max-size-files", cl::init(1000000),
+ cl::desc("Set ThinLTO cache pruning directory maximum number of files."));
+
+static cl::opt<unsigned> ThinLTOCacheEntryExpiration(
+ "legacy-thinlto-cache-entry-expiration", cl::init(604800) /* 1w */,
+ cl::desc("Set ThinLTO cache entry expiration time (seconds)."));
+
#ifdef NDEBUG
static bool VerifyByDefault = false;
#else
@@ -543,6 +567,25 @@ thinlto_code_gen_t thinlto_create_codegen(void) {
assert(CGOptLevelOrNone);
CodeGen->setCodeGenOptLevel(*CGOptLevelOrNone);
}
+ if (!ThinLTOCacheDir.empty()) {
+ auto Err = llvm::sys::fs::create_directories(ThinLTOCacheDir);
+ if (Err)
+ report_fatal_error(Twine("Unable to create thinLTO cache directory: ") +
+ Err.message());
+ bool result;
+ Err = llvm::sys::fs::is_directory(ThinLTOCacheDir, result);
+ if (Err || !result)
+ report_fatal_error(Twine("Unable to get status of thinLTO cache path or "
+ "path is not a directory: ") +
+ Err.message());
+ CodeGen->setCacheDir(ThinLTOCacheDir);
+
+ CodeGen->setCachePruningInterval(ThinLTOCachePruningInterval);
+ CodeGen->setCacheEntryExpiration(ThinLTOCacheEntryExpiration);
+ CodeGen->setCacheMaxSizeFiles(ThinLTOCacheMaxSizeFiles);
+ CodeGen->setCacheMaxSizeBytes(ThinLTOCacheMaxSizeBytes);
+ }
+
return wrap(CodeGen);
}
diff --git a/llvm/tools/obj2yaml/macho2yaml.cpp b/llvm/tools/obj2yaml/macho2yaml.cpp
index 0022012..f78ec8f 100644
--- a/llvm/tools/obj2yaml/macho2yaml.cpp
+++ b/llvm/tools/obj2yaml/macho2yaml.cpp
@@ -15,7 +15,6 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
-#include "llvm/Support/SystemZ/zOSSupport.h"
#include <string.h> // for memcpy
diff --git a/llvm/tools/opt-viewer/optrecord.py b/llvm/tools/opt-viewer/optrecord.py
index b9244fd..07e2102 100644
--- a/llvm/tools/opt-viewer/optrecord.py
+++ b/llvm/tools/opt-viewer/optrecord.py
@@ -344,6 +344,8 @@ def find_opt_files(*dirs_or_files):
d for d in subdirs if not os.path.ismount(os.path.join(dir, d))
]
for file in files:
- if fnmatch.fnmatch(file, "*.opt.yaml*"):
+ if fnmatch.fnmatch(file, "*.opt.yaml*") or fnmatch.fnmatch(
+ file, "*.opt.ld.yaml*"
+ ):
all.append(os.path.join(dir, file))
return all
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index a383415..eaa1d8f 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -18,8 +18,10 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/CodeGen/LibcallLoweringInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/LLVMContext.h"
@@ -409,14 +411,25 @@ bool llvm::runPassPipeline(
P->CSAction = PGOOptions::CSIRUse;
}
}
- if (TM)
- TM->setPGOOption(P);
LoopAnalysisManager LAM;
FunctionAnalysisManager FAM;
CGSCCAnalysisManager CGAM;
ModuleAnalysisManager MAM;
+ if (TM) {
+ TM->setPGOOption(P);
+
+ MAM.registerPass([&] {
+ const TargetOptions &Options = TM->Options;
+ return RuntimeLibraryAnalysis(M.getTargetTriple(), Options.ExceptionModel,
+ Options.FloatABIType, Options.EABIVersion,
+ Options.MCOptions.ABIName, Options.VecLib);
+ });
+
+ MAM.registerPass([&] { return LibcallLoweringModuleAnalysis(); });
+ }
+
PassInstrumentationCallbacks PIC;
PrintPassOptions PrintPassOpts;
PrintPassOpts.Verbose = DebugPM == DebugLogging::Verbose;
@@ -507,7 +520,7 @@ bool llvm::runPassPipeline(
false, "", nullptr, DebugifyMode::OriginalDebugInfo,
&DebugInfoBeforePass, VerifyDIPreserveExport));
if (EnableProfcheck)
- MPM.addPass(createModuleToFunctionPassAdaptor(ProfileVerifierPass()));
+ MPM.addPass(ProfileVerifierPass());
// Add any relevant output pass at the end of the pipeline.
switch (OK) {
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index f70db31..ac318e6 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -17,6 +17,7 @@
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/RegionPass.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/AsmParser/Parser.h"
@@ -36,6 +37,7 @@
#include "llvm/InitializePasses.h"
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Remarks/HotnessThresholdParser.h"
@@ -64,6 +66,7 @@ using namespace llvm;
using namespace opt_tool;
static codegen::RegisterCodeGenFlags CFG;
+static codegen::RegisterSaveStatsFlag SSF;
// The OptimizationList is automatically populated with registered Passes by the
// PassNameParser.
@@ -512,6 +515,10 @@ optMain(int argc, char **argv,
}
LLVMRemarkFileHandle RemarksFile = std::move(*RemarksFileOrErr);
+ codegen::MaybeEnableStatistics();
+
+ StringRef ABIName = mc::getABIName(); // FIXME: Handle module flag.
+
// Load the input module...
auto SetDataLayout = [&](StringRef IRTriple,
StringRef IRLayout) -> std::optional<std::string> {
@@ -534,15 +541,16 @@ optMain(int argc, char **argv,
// the IR, we should default to an empty (default) DataLayout.
if (TripleStr.empty())
return std::nullopt;
- // Otherwise we infer the DataLayout from the target machine.
- Expected<std::unique_ptr<TargetMachine>> ExpectedTM =
- codegen::createTargetMachineForTriple(TripleStr, GetCodeGenOptLevel());
- if (!ExpectedTM) {
- errs() << argv[0] << ": warning: failed to infer data layout: "
- << toString(ExpectedTM.takeError()) << "\n";
+
+ Triple TT(TripleStr);
+
+ std::string Str = TT.computeDataLayout(ABIName);
+ if (Str.empty()) {
+ errs() << argv[0]
+ << ": warning: failed to infer data layout from target triple\n";
return std::nullopt;
}
- return (*ExpectedTM)->createDataLayout().getStringRepresentation();
+ return Str;
};
std::unique_ptr<Module> M;
if (NoUpgradeDebugInfo)
@@ -649,6 +657,13 @@ optMain(int argc, char **argv,
return 1;
}
+ TargetOptions CodeGenFlagsOptions;
+ const TargetOptions *Options = TM ? &TM->Options : &CodeGenFlagsOptions;
+ if (!TM) {
+ CodeGenFlagsOptions =
+ codegen::InitTargetOptionsFromCodeGenFlags(ModuleTriple);
+ }
+
// Override function attributes based on CPUStr, FeaturesStr, and command line
// flags.
codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M);
@@ -667,7 +682,7 @@ optMain(int argc, char **argv,
}
// Add an appropriate TargetLibraryInfo pass for the module's triple.
- TargetLibraryInfoImpl TLII(ModuleTriple);
+ TargetLibraryInfoImpl TLII(ModuleTriple, Options->VecLib);
// The -disable-simplify-libcalls flag actually disables all builtin optzns.
if (DisableSimplifyLibCalls)
@@ -742,15 +757,15 @@ optMain(int argc, char **argv,
// The user has asked to use the new pass manager and provided a pipeline
// string. Hand off the rest of the functionality to the new code for that
// layer.
- return runPassPipeline(
- argv[0], *M, TM.get(), &TLII, Out.get(), ThinLinkOut.get(),
- RemarksFile.get(), Pipeline, PluginList, PassBuilderCallbacks,
- OK, VK, /* ShouldPreserveAssemblyUseListOrder */ false,
- /* ShouldPreserveBitcodeUseListOrder */ true, EmitSummaryIndex,
- EmitModuleHash, EnableDebugify, VerifyDebugInfoPreserve,
- EnableProfileVerification, UnifiedLTO)
- ? 0
- : 1;
+ if (!runPassPipeline(
+ argv[0], *M, TM.get(), &TLII, Out.get(), ThinLinkOut.get(),
+ RemarksFile.get(), Pipeline, PluginList, PassBuilderCallbacks, OK,
+ VK, /* ShouldPreserveAssemblyUseListOrder */ false,
+ /* ShouldPreserveBitcodeUseListOrder */ true, EmitSummaryIndex,
+ EmitModuleHash, EnableDebugify, VerifyDebugInfoPreserve,
+ EnableProfileVerification, UnifiedLTO))
+ return 1;
+ return codegen::MaybeSaveStatistics(OutputFilename, "opt");
}
if (OptLevelO0 || OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz ||
@@ -791,6 +806,9 @@ optMain(int argc, char **argv,
(VerifyDebugInfoPreserve && !VerifyEachDebugInfoPreserve);
Passes.add(new TargetLibraryInfoWrapperPass(TLII));
+ Passes.add(new RuntimeLibraryInfoWrapper(
+ ModuleTriple, Options->ExceptionModel, Options->FloatABIType,
+ Options->EABIVersion, Options->MCOptions.ABIName, Options->VecLib));
// Add internal analysis passes from the target machine.
Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()
@@ -928,5 +946,5 @@ optMain(int argc, char **argv,
if (ThinLinkOut)
ThinLinkOut->keep();
- return 0;
+ return codegen::MaybeSaveStatistics(OutputFilename, "opt");
}