Auto merge of #123918 - DianQK:clang-format, r=Kobzol

Use `clang-format` in `tidy` to check the C++ code style under `llvm-wrapper`

Fixes #123510.

Based on the discussion at https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Enable.20.60clang-format.60.20for.20.60rustc.60.20compiler-team.23756/near/443562800, we can use clang-format from pip to achieve the code formatting.

r? `@Kobzol`
This commit is contained in:
bors 2024-06-27 01:18:56 +00:00
commit 7033f9b14a
14 changed files with 899 additions and 824 deletions

1
.clang-format Normal file
View file

@ -0,0 +1 @@
BasedOnStyle: LLVM

View file

@ -29,6 +29,7 @@ Files: compiler/*
x
x.ps1
x.py
.clang-format
.editorconfig
.git-blame-ignore-revs
.gitattributes

View file

@ -5627,6 +5627,7 @@ dependencies = [
"regex",
"rustc-hash",
"semver",
"similar",
"termcolor",
"walkdir",
]

View file

@ -13,10 +13,7 @@ struct RustArchiveMember {
Archive::Child Child;
RustArchiveMember()
: Filename(nullptr), Name(nullptr),
Child(nullptr, nullptr, nullptr)
{
}
: Filename(nullptr), Name(nullptr), Child(nullptr, nullptr, nullptr) {}
~RustArchiveMember() {}
};
@ -27,11 +24,8 @@ struct RustArchiveIterator {
std::unique_ptr<Error> Err;
RustArchiveIterator(Archive::child_iterator Cur, Archive::child_iterator End,
std::unique_ptr<Error> Err)
: First(true),
Cur(Cur),
End(End),
Err(std::move(Err)) {}
std::unique_ptr<Error> Err)
: First(true), Cur(Cur), End(End), Err(std::move(Err)) {}
};
enum class LLVMRustArchiveKind {
@ -66,8 +60,8 @@ typedef Archive::Child const *LLVMRustArchiveChildConstRef;
typedef RustArchiveIterator *LLVMRustArchiveIteratorRef;
extern "C" LLVMRustArchiveRef LLVMRustOpenArchive(char *Path) {
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
MemoryBuffer::getFile(Path, /*IsText*/false, /*RequiresNullTerminator=*/false);
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr = MemoryBuffer::getFile(
Path, /*IsText*/ false, /*RequiresNullTerminator=*/false);
if (!BufOr) {
LLVMRustSetLastError(BufOr.getError().message().c_str());
return nullptr;
@ -146,8 +140,8 @@ extern "C" const char *
LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) {
Expected<StringRef> NameOrErr = Child->getName();
if (!NameOrErr) {
// rustc_codegen_llvm currently doesn't use this error string, but it might be
// useful in the future, and in the meantime this tells LLVM that the
// rustc_codegen_llvm currently doesn't use this error string, but it might
// be useful in the future, and in the meantime this tells LLVM that the
// error was not ignored and that it shouldn't abort the process.
LLVMRustSetLastError(toString(NameOrErr.takeError()).c_str());
return nullptr;
@ -172,10 +166,9 @@ extern "C" void LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) {
delete Member;
}
extern "C" LLVMRustResult
LLVMRustWriteArchive(char *Dst, size_t NumMembers,
const LLVMRustArchiveMemberRef *NewMembers,
bool WriteSymbtab, LLVMRustArchiveKind RustKind, bool isEC) {
extern "C" LLVMRustResult LLVMRustWriteArchive(
char *Dst, size_t NumMembers, const LLVMRustArchiveMemberRef *NewMembers,
bool WriteSymbtab, LLVMRustArchiveKind RustKind, bool isEC) {
std::vector<NewArchiveMember> Members;
auto Kind = fromRust(RustKind);
@ -206,8 +199,10 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers,
#if LLVM_VERSION_LT(18, 0)
auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
#else
auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab : SymtabWritingMode::NoSymtab;
auto Result = writeArchive(Dst, Members, SymtabMode, Kind, true, false, nullptr, isEC);
auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab
: SymtabWritingMode::NoSymtab;
auto Result =
writeArchive(Dst, Members, SymtabMode, Kind, true, false, nullptr, isEC);
#endif
if (!Result)
return LLVMRustResult::Success;

View file

@ -1,5 +1,5 @@
#include "SuppressLLVMWarnings.h"
#include "llvm/Linker/Linker.h"
#include "SuppressLLVMWarnings.h"
#include "LLVMWrapper.h"
@ -9,26 +9,18 @@ struct RustLinker {
Linker L;
LLVMContext &Ctx;
RustLinker(Module &M) :
L(M),
Ctx(M.getContext())
{}
RustLinker(Module &M) : L(M), Ctx(M.getContext()) {}
};
extern "C" RustLinker*
LLVMRustLinkerNew(LLVMModuleRef DstRef) {
extern "C" RustLinker *LLVMRustLinkerNew(LLVMModuleRef DstRef) {
Module *Dst = unwrap(DstRef);
return new RustLinker(*Dst);
}
extern "C" void
LLVMRustLinkerFree(RustLinker *L) {
delete L;
}
extern "C" void LLVMRustLinkerFree(RustLinker *L) { delete L; }
extern "C" bool
LLVMRustLinkerAdd(RustLinker *L, char *BC, size_t Len) {
extern "C" bool LLVMRustLinkerAdd(RustLinker *L, char *BC, size_t Len) {
std::unique_ptr<MemoryBuffer> Buf =
MemoryBuffer::getMemBufferCopy(StringRef(BC, Len));

View file

@ -2,23 +2,25 @@
#include <cstddef>
#include <iomanip>
#include <vector>
#include <set>
#include <vector>
#include "LLVMWrapper.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Verifier.h"
#include "llvm/LTO/LTO.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/StandardInstrumentations.h"
@ -33,26 +35,24 @@
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#include "llvm/Transforms/Utils/AddDiscriminators.h"
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#if LLVM_VERSION_GE(18, 0)
#include "llvm/TargetParser/Host.h"
#endif
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
#include "llvm/Support/TimeProfiler.h"
#if LLVM_VERSION_GE(19, 0)
#include "llvm/Support/PGOOptions.h"
#endif
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
#include "llvm/Transforms/Utils/NameAnonGlobals.h"
#include "llvm/Transforms/Utils.h"
using namespace llvm;
@ -74,7 +74,7 @@ extern "C" void LLVMRustTimeTraceProfilerFinishThread() {
timeTraceProfilerFinishThread();
}
extern "C" void LLVMRustTimeTraceProfilerFinish(const char* FileName) {
extern "C" void LLVMRustTimeTraceProfilerFinish(const char *FileName) {
auto FN = StringRef(FileName);
std::error_code EC;
auto OS = raw_fd_ostream(FN, EC, sys::fs::CD_CreateAlways);
@ -188,7 +188,7 @@ extern "C" void LLVMRustTimeTraceProfilerFinish(const char* FileName) {
SUBTARGET_HEXAGON \
SUBTARGET_XTENSA \
SUBTARGET_RISCV \
SUBTARGET_LOONGARCH \
SUBTARGET_LOONGARCH
#define SUBTARGET(x) \
namespace llvm { \
@ -215,8 +215,7 @@ enum class LLVMRustCodeModel {
None,
};
static std::optional<CodeModel::Model>
fromRust(LLVMRustCodeModel Model) {
static std::optional<CodeModel::Model> fromRust(LLVMRustCodeModel Model) {
switch (Model) {
case LLVMRustCodeModel::Tiny:
return CodeModel::Tiny;
@ -243,9 +242,9 @@ enum class LLVMRustCodeGenOptLevel {
};
#if LLVM_VERSION_GE(18, 0)
using CodeGenOptLevelEnum = llvm::CodeGenOptLevel;
using CodeGenOptLevelEnum = llvm::CodeGenOptLevel;
#else
using CodeGenOptLevelEnum = llvm::CodeGenOpt::Level;
using CodeGenOptLevelEnum = llvm::CodeGenOpt::Level;
#endif
static CodeGenOptLevelEnum fromRust(LLVMRustCodeGenOptLevel Level) {
@ -319,48 +318,49 @@ static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
}
/// getLongestEntryLength - Return the length of the longest entry in the table.
template<typename KV>
static size_t getLongestEntryLength(ArrayRef<KV> Table) {
template <typename KV> static size_t getLongestEntryLength(ArrayRef<KV> Table) {
size_t MaxLen = 0;
for (auto &I : Table)
MaxLen = std::max(MaxLen, std::strlen(I.Key));
return MaxLen;
}
using PrintBackendInfo = void(void*, const char* Data, size_t Len);
using PrintBackendInfo = void(void *, const char *Data, size_t Len);
extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM,
const char* TargetCPU,
PrintBackendInfo Print,
void* Out) {
const char *TargetCPU,
PrintBackendInfo Print, void *Out) {
const TargetMachine *Target = unwrap(TM);
const Triple::ArchType HostArch = Triple(sys::getDefaultTargetTriple()).getArch();
const Triple::ArchType HostArch =
Triple(sys::getDefaultTargetTriple()).getArch();
const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
std::ostringstream Buf;
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getAllProcessorDescriptions();
const ArrayRef<SubtargetSubTypeKV> CPUTable =
MCInfo->getAllProcessorDescriptions();
unsigned MaxCPULen = getLongestEntryLength(CPUTable);
Buf << "Available CPUs for this target:\n";
// Don't print the "native" entry when the user specifies --target with a
// different arch since that could be wrong or misleading.
if (HostArch == TargetArch) {
MaxCPULen = std::max(MaxCPULen, (unsigned) std::strlen("native"));
MaxCPULen = std::max(MaxCPULen, (unsigned)std::strlen("native"));
const StringRef HostCPU = sys::getHostCPUName();
Buf << " " << std::left << std::setw(MaxCPULen) << "native"
<< " - Select the CPU of the current host "
"(currently " << HostCPU.str() << ").\n";
"(currently "
<< HostCPU.str() << ").\n";
}
for (auto &CPU : CPUTable) {
// Compare cpu against current target to label the default
if (strcmp(CPU.Key, TargetCPU) == 0) {
Buf << " " << std::left << std::setw(MaxCPULen) << CPU.Key
<< " - This is the default target CPU for the current build target "
"(currently " << Target->getTargetTriple().str() << ").";
}
else {
"(currently "
<< Target->getTargetTriple().str() << ").";
} else {
Buf << " " << CPU.Key;
}
Buf << "\n";
@ -374,7 +374,8 @@ extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) {
#if LLVM_VERSION_GE(18, 0)
const TargetMachine *Target = unwrap(TM);
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getAllProcessorFeatures();
const ArrayRef<SubtargetFeatureKV> FeatTable =
MCInfo->getAllProcessorFeatures();
return FeatTable.size();
#else
return 0;
@ -382,18 +383,20 @@ extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) {
}
extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index,
const char** Feature, const char** Desc) {
const char **Feature,
const char **Desc) {
#if LLVM_VERSION_GE(18, 0)
const TargetMachine *Target = unwrap(TM);
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getAllProcessorFeatures();
const ArrayRef<SubtargetFeatureKV> FeatTable =
MCInfo->getAllProcessorFeatures();
const SubtargetFeatureKV Feat = FeatTable[Index];
*Feature = Feat.Key;
*Desc = Feat.Desc;
#endif
}
extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
extern "C" const char *LLVMRustGetHostCPUName(size_t *len) {
StringRef Name = sys::getHostCPUName();
*len = Name.size();
return Name.data();
@ -403,19 +406,11 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
const char *TripleStr, const char *CPU, const char *Feature,
const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
bool FunctionSections,
bool DataSections,
bool UniqueSectionNames,
bool TrapUnreachable,
bool Singlethread,
bool AsmComments,
bool EmitStackSizeSection,
bool RelaxELFRelocations,
bool UseInitArray,
const char *SplitDwarfFile,
const char *OutputObjFile,
const char *DebugInfoCompression,
bool UseEmulatedTls,
bool FunctionSections, bool DataSections, bool UniqueSectionNames,
bool TrapUnreachable, bool Singlethread, bool AsmComments,
bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray,
const char *SplitDwarfFile, const char *OutputObjFile,
const char *DebugInfoCompression, bool UseEmulatedTls,
const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) {
auto OptLevel = fromRust(RustOptLevel);
@ -444,18 +439,20 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
Options.MCOptions.PreserveAsmComments = AsmComments;
Options.MCOptions.ABIName = ABIStr;
if (SplitDwarfFile) {
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
}
if (OutputObjFile) {
Options.ObjectFilenameForDebug = OutputObjFile;
Options.ObjectFilenameForDebug = OutputObjFile;
}
if (!strcmp("zlib", DebugInfoCompression) && llvm::compression::zlib::isAvailable()) {
if (!strcmp("zlib", DebugInfoCompression) &&
llvm::compression::zlib::isAvailable()) {
#if LLVM_VERSION_GE(19, 0)
Options.MCOptions.CompressDebugSections = DebugCompressionType::Zlib;
#else
Options.CompressDebugSections = DebugCompressionType::Zlib;
#endif
} else if (!strcmp("zstd", DebugInfoCompression) && llvm::compression::zstd::isAvailable()) {
} else if (!strcmp("zstd", DebugInfoCompression) &&
llvm::compression::zstd::isAvailable()) {
#if LLVM_VERSION_GE(19, 0)
Options.MCOptions.CompressDebugSections = DebugCompressionType::Zstd;
#else
@ -499,24 +496,21 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
Options.EmitStackSizeSection = EmitStackSizeSection;
if (ArgsCstrBuff != nullptr)
{
if (ArgsCstrBuff != nullptr) {
int buffer_offset = 0;
assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0');
const size_t arg0_len = std::strlen(ArgsCstrBuff);
char* arg0 = new char[arg0_len + 1];
char *arg0 = new char[arg0_len + 1];
memcpy(arg0, ArgsCstrBuff, arg0_len);
arg0[arg0_len] = '\0';
buffer_offset += arg0_len + 1;
const int num_cmd_arg_strings =
std::count(&ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0');
const int num_cmd_arg_strings = std::count(
&ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0');
std::string* cmd_arg_strings = new std::string[num_cmd_arg_strings];
for (int i = 0; i < num_cmd_arg_strings; ++i)
{
std::string *cmd_arg_strings = new std::string[num_cmd_arg_strings];
for (int i = 0; i < num_cmd_arg_strings; ++i) {
assert(buffer_offset < ArgsCstrBuffLen);
const int len = std::strlen(ArgsCstrBuff + buffer_offset);
cmd_arg_strings[i] = std::string(&ArgsCstrBuff[buffer_offset], len);
@ -527,7 +521,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
Options.MCOptions.Argv0 = arg0;
Options.MCOptions.CommandLineArgs =
llvm::ArrayRef<std::string>(cmd_arg_strings, num_cmd_arg_strings);
llvm::ArrayRef<std::string>(cmd_arg_strings, num_cmd_arg_strings);
}
TargetMachine *TM = TheTarget->createTargetMachine(
@ -537,7 +531,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
MCTargetOptions& MCOptions = unwrap(TM)->Options.MCOptions;
MCTargetOptions &MCOptions = unwrap(TM)->Options.MCOptions;
delete[] MCOptions.Argv0;
delete[] MCOptions.CommandLineArgs.data();
@ -613,7 +607,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
auto DOS = raw_fd_ostream(DwoPath, EC, sys::fs::OF_None);
EC.clear();
if (EC)
ErrorInfo = EC.message();
ErrorInfo = EC.message();
if (ErrorInfo != "") {
LLVMRustSetLastError(ErrorInfo.c_str());
return LLVMRustResult::Failure;
@ -633,10 +627,12 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
return LLVMRustResult::Success;
}
extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmSelfProfiler
const char*, // pass name
const char*); // IR name
extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler
extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(
void *, // LlvmSelfProfiler
const char *, // pass name
const char *); // IR name
extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(
void *); // LlvmSelfProfiler
std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) {
if (const auto *Cast = any_cast<const Module *>(&WrappedIr))
@ -650,35 +646,35 @@ std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) {
return "<UNKNOWN>";
}
void LLVMSelfProfileInitializeCallbacks(
PassInstrumentationCallbacks& PIC, void* LlvmSelfProfiler,
PassInstrumentationCallbacks &PIC, void *LlvmSelfProfiler,
LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
PIC.registerBeforeNonSkippedPassCallback([LlvmSelfProfiler, BeforePassCallback](
StringRef Pass, llvm::Any Ir) {
std::string PassName = Pass.str();
std::string IrName = LLVMRustwrappedIrGetName(Ir);
BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
});
PIC.registerBeforeNonSkippedPassCallback(
[LlvmSelfProfiler, BeforePassCallback](StringRef Pass, llvm::Any Ir) {
std::string PassName = Pass.str();
std::string IrName = LLVMRustwrappedIrGetName(Ir);
BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
});
PIC.registerAfterPassCallback(
[LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any IR,
const PreservedAnalyses &Preserved) {
[LlvmSelfProfiler, AfterPassCallback](
StringRef Pass, llvm::Any IR, const PreservedAnalyses &Preserved) {
AfterPassCallback(LlvmSelfProfiler);
});
PIC.registerAfterPassInvalidatedCallback(
[LlvmSelfProfiler, AfterPassCallback](StringRef Pass, const PreservedAnalyses &Preserved) {
[LlvmSelfProfiler,
AfterPassCallback](StringRef Pass, const PreservedAnalyses &Preserved) {
AfterPassCallback(LlvmSelfProfiler);
});
PIC.registerBeforeAnalysisCallback([LlvmSelfProfiler, BeforePassCallback](
StringRef Pass, llvm::Any Ir) {
std::string PassName = Pass.str();
std::string IrName = LLVMRustwrappedIrGetName(Ir);
BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
});
PIC.registerBeforeAnalysisCallback(
[LlvmSelfProfiler, BeforePassCallback](StringRef Pass, llvm::Any Ir) {
std::string PassName = Pass.str();
std::string IrName = LLVMRustwrappedIrGetName(Ir);
BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
});
PIC.registerAfterAnalysisCallback(
[LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
@ -704,7 +700,7 @@ struct LLVMRustSanitizerOptions {
bool SanitizeKCFI;
bool SanitizeMemory;
bool SanitizeMemoryRecover;
int SanitizeMemoryTrackOrigins;
int SanitizeMemoryTrackOrigins;
bool SanitizeThread;
bool SanitizeHWAddress;
bool SanitizeHWAddressRecover;
@ -712,31 +708,25 @@ struct LLVMRustSanitizerOptions {
bool SanitizeKernelAddressRecover;
};
extern "C" LLVMRustResult
LLVMRustOptimize(
LLVMModuleRef ModuleRef,
LLVMTargetMachineRef TMRef,
LLVMRustPassBuilderOptLevel OptLevelRust,
LLVMRustOptStage OptStage,
bool IsLinkerPluginLTO,
bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
LLVMRustSanitizerOptions *SanitizerOptions,
const char *PGOGenPath, const char *PGOUsePath,
bool InstrumentCoverage, const char *InstrProfileOutput,
bool InstrumentGCOV,
extern "C" LLVMRustResult LLVMRustOptimize(
LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef,
LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage,
bool IsLinkerPluginLTO, bool NoPrepopulatePasses, bool VerifyIR,
bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops,
bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls,
bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions,
const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage,
const char *InstrProfileOutput, bool InstrumentGCOV,
const char *PGOSampleUsePath, bool DebugInfoForProfiling,
void* LlvmSelfProfiler,
void *LlvmSelfProfiler,
LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
LLVMRustSelfProfileAfterPassCallback AfterPassCallback,
const char *ExtraPasses, size_t ExtraPassesLen,
const char *LLVMPlugins, size_t LLVMPluginsLen) {
const char *ExtraPasses, size_t ExtraPassesLen, const char *LLVMPlugins,
size_t LLVMPluginsLen) {
Module *TheModule = unwrap(ModuleRef);
TargetMachine *TM = unwrap(TMRef);
OptimizationLevel OptLevel = fromRust(OptLevelRust);
PipelineTuningOptions PTO;
PTO.LoopUnrolling = UnrollLoops;
PTO.LoopInterleaving = UnrollLoops;
@ -751,38 +741,39 @@ LLVMRustOptimize(
StandardInstrumentations SI(TheModule->getContext(), DebugPassManager);
SI.registerCallbacks(PIC);
if (LlvmSelfProfiler){
LLVMSelfProfileInitializeCallbacks(PIC,LlvmSelfProfiler,BeforePassCallback,AfterPassCallback);
if (LlvmSelfProfiler) {
LLVMSelfProfileInitializeCallbacks(PIC, LlvmSelfProfiler,
BeforePassCallback, AfterPassCallback);
}
std::optional<PGOOptions> PGOOpt;
auto FS = vfs::getRealFileSystem();
if (PGOGenPath) {
assert(!PGOUsePath && !PGOSampleUsePath);
PGOOpt = PGOOptions(PGOGenPath, "", "", "", FS,
PGOOptions::IRInstr, PGOOptions::NoCSAction,
PGOOpt = PGOOptions(PGOGenPath, "", "", "", FS, PGOOptions::IRInstr,
PGOOptions::NoCSAction,
#if LLVM_VERSION_GE(19, 0)
PGOOptions::ColdFuncOpt::Default,
#endif
DebugInfoForProfiling);
} else if (PGOUsePath) {
assert(!PGOSampleUsePath);
PGOOpt = PGOOptions(PGOUsePath, "", "", "", FS,
PGOOptions::IRUse, PGOOptions::NoCSAction,
PGOOpt = PGOOptions(PGOUsePath, "", "", "", FS, PGOOptions::IRUse,
PGOOptions::NoCSAction,
#if LLVM_VERSION_GE(19, 0)
PGOOptions::ColdFuncOpt::Default,
#endif
DebugInfoForProfiling);
} else if (PGOSampleUsePath) {
PGOOpt = PGOOptions(PGOSampleUsePath, "", "", "", FS,
PGOOptions::SampleUse, PGOOptions::NoCSAction,
PGOOpt = PGOOptions(PGOSampleUsePath, "", "", "", FS, PGOOptions::SampleUse,
PGOOptions::NoCSAction,
#if LLVM_VERSION_GE(19, 0)
PGOOptions::ColdFuncOpt::Default,
#endif
DebugInfoForProfiling);
} else if (DebugInfoForProfiling) {
PGOOpt = PGOOptions("", "", "", "", FS,
PGOOptions::NoAction, PGOOptions::NoCSAction,
PGOOpt = PGOOptions("", "", "", "", FS, PGOOptions::NoAction,
PGOOptions::NoCSAction,
#if LLVM_VERSION_GE(19, 0)
PGOOptions::ColdFuncOpt::Default,
#endif
@ -799,7 +790,7 @@ LLVMRustOptimize(
auto PluginsStr = StringRef(LLVMPlugins, LLVMPluginsLen);
SmallVector<StringRef> Plugins;
PluginsStr.split(Plugins, ',', -1, false);
for (auto PluginPath: Plugins) {
for (auto PluginPath : Plugins) {
auto Plugin = PassPlugin::Load(PluginPath.str());
if (!Plugin) {
auto Err = Plugin.takeError();
@ -814,7 +805,8 @@ LLVMRustOptimize(
FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
Triple TargetTriple(TheModule->getTargetTriple());
std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple));
std::unique_ptr<TargetLibraryInfoImpl> TLII(
new TargetLibraryInfoImpl(TargetTriple));
if (DisableSimplifyLibCalls)
TLII->disableAllFunctions();
FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
@ -825,58 +817,53 @@ LLVMRustOptimize(
PB.registerLoopAnalyses(LAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
// We manually collect pipeline callbacks so we can apply them at O0, where the
// PassBuilder does not create a pipeline.
// We manually collect pipeline callbacks so we can apply them at O0, where
// the PassBuilder does not create a pipeline.
std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
PipelineStartEPCallbacks;
std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
OptimizerLastEPCallbacks;
if (!IsLinkerPluginLTO
&& SanitizerOptions && SanitizerOptions->SanitizeCFI
&& !NoPrepopulatePasses) {
if (!IsLinkerPluginLTO && SanitizerOptions && SanitizerOptions->SanitizeCFI &&
!NoPrepopulatePasses) {
PipelineStartEPCallbacks.push_back(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
/*ImportSummary=*/nullptr,
/*DropTypeTests=*/false));
}
);
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
/*ImportSummary=*/nullptr,
/*DropTypeTests=*/false));
});
}
if (VerifyIR) {
PipelineStartEPCallbacks.push_back(
[VerifyIR](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(VerifierPass());
}
);
[VerifyIR](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(VerifierPass());
});
}
if (InstrumentGCOV) {
PipelineStartEPCallbacks.push_back(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault()));
}
);
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault()));
});
}
if (InstrumentCoverage) {
PipelineStartEPCallbacks.push_back(
[InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
InstrProfOptions Options;
if (InstrProfileOutput) {
Options.InstrProfileOutput = InstrProfileOutput;
}
// cargo run tests in multhreading mode by default
// so use atomics for coverage counters
Options.Atomic = true;
[InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
InstrProfOptions Options;
if (InstrProfileOutput) {
Options.InstrProfileOutput = InstrProfileOutput;
}
// cargo run tests in multhreading mode by default
// so use atomics for coverage counters
Options.Atomic = true;
#if LLVM_VERSION_GE(18, 0)
MPM.addPass(InstrProfilingLoweringPass(Options, false));
MPM.addPass(InstrProfilingLoweringPass(Options, false));
#else
MPM.addPass(InstrProfiling(Options, false));
MPM.addPass(InstrProfiling(Options, false));
#endif
}
);
});
}
if (SanitizerOptions) {
@ -886,10 +873,9 @@ LLVMRustOptimize(
SanitizerOptions->SanitizeDataFlowABIList +
SanitizerOptions->SanitizeDataFlowABIListLen);
OptimizerLastEPCallbacks.push_back(
[ABIListFiles](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(DataFlowSanitizerPass(ABIListFiles));
}
);
[ABIListFiles](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(DataFlowSanitizerPass(ABIListFiles));
});
}
if (SanitizerOptions->SanitizeMemory) {
@ -899,54 +885,54 @@ LLVMRustOptimize(
/*CompileKernel=*/false,
/*EagerChecks=*/true);
OptimizerLastEPCallbacks.push_back(
[Options](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(MemorySanitizerPass(Options));
}
);
[Options](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(MemorySanitizerPass(Options));
});
}
if (SanitizerOptions->SanitizeThread) {
OptimizerLastEPCallbacks.push_back(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(ModuleThreadSanitizerPass());
MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
}
);
OptimizerLastEPCallbacks.push_back([](ModulePassManager &MPM,
OptimizationLevel Level) {
MPM.addPass(ModuleThreadSanitizerPass());
MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
});
}
if (SanitizerOptions->SanitizeAddress || SanitizerOptions->SanitizeKernelAddress) {
if (SanitizerOptions->SanitizeAddress ||
SanitizerOptions->SanitizeKernelAddress) {
OptimizerLastEPCallbacks.push_back(
[SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
auto CompileKernel = SanitizerOptions->SanitizeKernelAddress;
AddressSanitizerOptions opts = AddressSanitizerOptions{
CompileKernel,
SanitizerOptions->SanitizeAddressRecover
|| SanitizerOptions->SanitizeKernelAddressRecover,
/*UseAfterScope=*/true,
AsanDetectStackUseAfterReturnMode::Runtime,
};
MPM.addPass(AddressSanitizerPass(opts));
}
);
[SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
auto CompileKernel = SanitizerOptions->SanitizeKernelAddress;
AddressSanitizerOptions opts = AddressSanitizerOptions{
CompileKernel,
SanitizerOptions->SanitizeAddressRecover ||
SanitizerOptions->SanitizeKernelAddressRecover,
/*UseAfterScope=*/true,
AsanDetectStackUseAfterReturnMode::Runtime,
};
MPM.addPass(AddressSanitizerPass(opts));
});
}
if (SanitizerOptions->SanitizeHWAddress) {
OptimizerLastEPCallbacks.push_back(
[SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
HWAddressSanitizerOptions opts(
/*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover,
/*DisableOptimization=*/false);
MPM.addPass(HWAddressSanitizerPass(opts));
}
);
[SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
HWAddressSanitizerOptions opts(
/*CompileKernel=*/false,
SanitizerOptions->SanitizeHWAddressRecover,
/*DisableOptimization=*/false);
MPM.addPass(HWAddressSanitizerPass(opts));
});
}
}
ModulePassManager MPM;
bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
if (!NoPrepopulatePasses) {
// The pre-link pipelines don't support O0 and require using buildO0DefaultPipeline() instead.
// At the same time, the LTO pipelines do support O0 and using them is required.
bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO || OptStage == LLVMRustOptStage::FatLTO;
// The pre-link pipelines don't support O0 and require using
// buildO0DefaultPipeline() instead. At the same time, the LTO pipelines do
// support O0 and using them is required.
bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO ||
OptStage == LLVMRustOptStage::FatLTO;
if (OptLevel == OptimizationLevel::O0 && !IsLTO) {
for (const auto &C : PipelineStartEPCallbacks)
PB.registerPipelineStartEPCallback(C);
@ -993,7 +979,8 @@ LLVMRustOptimize(
}
if (ExtraPassesLen) {
if (auto Err = PB.parsePassPipeline(MPM, StringRef(ExtraPasses, ExtraPassesLen))) {
if (auto Err =
PB.parsePassPipeline(MPM, StringRef(ExtraPasses, ExtraPassesLen))) {
std::string ErrMsg = toString(std::move(Err));
LLVMRustSetLastError(ErrMsg.c_str());
return LLVMRustResult::Failure;
@ -1020,8 +1007,7 @@ LLVMRustOptimize(
// * output buffer
// * output buffer len
// Returns len of demangled string, or 0 if demangle failed.
typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
typedef size_t (*DemangleFn)(const char *, size_t, char *, size_t);
namespace {
@ -1064,7 +1050,7 @@ public:
formatted_raw_ostream &OS) override {
StringRef Demangled = CallDemangle(F->getName());
if (Demangled.empty()) {
return;
return;
}
OS << "; " << Demangled << "\n";
@ -1077,7 +1063,7 @@ public:
if (const CallInst *CI = dyn_cast<CallInst>(I)) {
Name = "call";
Value = CI->getCalledOperand();
} else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) {
Name = "invoke";
Value = II->getCalledOperand();
} else {
@ -1101,8 +1087,8 @@ public:
} // namespace
extern "C" LLVMRustResult
LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
extern "C" LLVMRustResult LLVMRustPrintModule(LLVMModuleRef M, const char *Path,
DemangleFn Demangle) {
std::string ErrorInfo;
std::error_code EC;
auto OS = raw_fd_ostream(Path, EC, sys::fs::OF_None);
@ -1264,11 +1250,9 @@ getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
// The main entry point for creating the global ThinLTO analysis. The structure
// here is basically the same as before threads are spawned in the `run`
// function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
extern "C" LLVMRustThinLTOData*
LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
int num_modules,
const char **preserved_symbols,
int num_symbols) {
extern "C" LLVMRustThinLTOData *
LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, int num_modules,
const char **preserved_symbols, int num_symbols) {
auto Ret = std::make_unique<LLVMRustThinLTOData>();
// Load each module's summary and merge it into one combined index
@ -1290,7 +1274,8 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
}
// Collect for each module the list of function it defines (GUID -> Summary)
Ret->Index.collectDefinedGVSummariesPerModule(Ret->ModuleToDefinedGVSummaries);
Ret->Index.collectDefinedGVSummariesPerModule(
Ret->ModuleToDefinedGVSummaries);
// Convert the preserved symbols set from string to GUID, this is then needed
// for internalization.
@ -1310,7 +1295,8 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
// crate, so we need `ImportEnabled = false` to limit internalization.
// Otherwise, we sometimes lose `static` values -- see #60184.
computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols,
deadIsPrevailing, /* ImportEnabled = */ false);
deadIsPrevailing,
/* ImportEnabled = */ false);
// Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
// impacts the caching.
//
@ -1319,7 +1305,8 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
for (auto &I : Ret->Index) {
if (I.second.SummaryList.size() > 1)
PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second.SummaryList);
PrevailingCopy[I.first] =
getFirstDefinitionForLinker(I.second.SummaryList);
}
auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
const auto &Prevailing = PrevailingCopy.find(GUID);
@ -1327,13 +1314,8 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
return true;
return Prevailing->second == S;
};
ComputeCrossModuleImport(
Ret->Index,
Ret->ModuleToDefinedGVSummaries,
isPrevailing,
Ret->ImportLists,
Ret->ExportLists
);
ComputeCrossModuleImport(Ret->Index, Ret->ModuleToDefinedGVSummaries,
isPrevailing, Ret->ImportLists, Ret->ExportLists);
auto recordNewLinkage = [&](StringRef ModuleIdentifier,
GlobalValue::GUID GUID,
@ -1345,8 +1327,8 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
// formats. We probably could and should use ELF visibility scheme for many of
// our targets, however.
lto::Config conf;
thinLTOResolvePrevailingInIndex(conf, Ret->Index, isPrevailing, recordNewLinkage,
Ret->GUIDPreservedSymbols);
thinLTOResolvePrevailingInIndex(conf, Ret->Index, isPrevailing,
recordNewLinkage, Ret->GUIDPreservedSymbols);
// Here we calculate an `ExportedGUIDs` set for use in the `isExported`
// callback below. This callback below will dictate the linkage for all
@ -1355,7 +1337,7 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
// linkage will stay as external, and internal will stay as internal.
std::set<GlobalValue::GUID> ExportedGUIDs;
for (auto &List : Ret->Index) {
for (auto &GVS: List.second.SummaryList) {
for (auto &GVS : List.second.SummaryList) {
if (GlobalValue::isLocalLinkage(GVS->linkage()))
continue;
auto GUID = GVS->getOriginalName();
@ -1366,16 +1348,15 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
return (ExportList != Ret->ExportLists.end() &&
ExportList->second.count(VI)) ||
ExportedGUIDs.count(VI.getGUID());
ExportList->second.count(VI)) ||
ExportedGUIDs.count(VI.getGUID());
};
thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
return Ret.release();
}
extern "C" void
LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
extern "C" void LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
delete Data;
}
@ -1387,20 +1368,18 @@ LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
// `ProcessThinLTOModule` function. Here they're split up into separate steps
// so rustc can save off the intermediate bytecode between each step.
static bool
clearDSOLocalOnDeclarations(Module &Mod, TargetMachine &TM) {
static bool clearDSOLocalOnDeclarations(Module &Mod, TargetMachine &TM) {
// When linking an ELF shared object, dso_local should be dropped. We
// conservatively do this for -fpic.
bool ClearDSOLocalOnDeclarations =
TM.getTargetTriple().isOSBinFormatELF() &&
TM.getRelocationModel() != Reloc::Static &&
Mod.getPIELevel() == PIELevel::Default;
bool ClearDSOLocalOnDeclarations = TM.getTargetTriple().isOSBinFormatELF() &&
TM.getRelocationModel() != Reloc::Static &&
Mod.getPIELevel() == PIELevel::Default;
return ClearDSOLocalOnDeclarations;
}
extern "C" bool
LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
LLVMTargetMachineRef TM) {
extern "C" bool LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data,
LLVMModuleRef M,
LLVMTargetMachineRef TM) {
Module &Mod = *unwrap(M);
TargetMachine &Target = *unwrap(TM);
@ -1415,24 +1394,28 @@ LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
}
extern "C" bool
LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data,
LLVMModuleRef M) {
Module &Mod = *unwrap(M);
const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
const auto &DefinedGlobals =
Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
thinLTOFinalizeInModule(Mod, DefinedGlobals, /*PropagateAttrs=*/true);
return true;
}
extern "C" bool
LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data,
LLVMModuleRef M) {
Module &Mod = *unwrap(M);
const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
const auto &DefinedGlobals =
Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
thinLTOInternalizeModule(Mod, DefinedGlobals);
return true;
}
extern "C" bool
LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
LLVMTargetMachineRef TM) {
extern "C" bool LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data,
LLVMModuleRef M,
LLVMTargetMachineRef TM) {
Module &Mod = *unwrap(M);
TargetMachine &Target = *unwrap(TM);
@ -1464,7 +1447,8 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
return Ret;
}
auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
auto *WasmCustomSections =
(*MOrErr)->getNamedMetadata("wasm.custom_sections");
if (WasmCustomSections)
WasmCustomSections->eraseFromParent();
@ -1498,7 +1482,7 @@ struct LLVMRustThinLTOBuffer {
std::string thin_link_data;
};
extern "C" LLVMRustThinLTOBuffer*
extern "C" LLVMRustThinLTOBuffer *
LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin, bool emit_summary) {
auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
{
@ -1520,7 +1504,8 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin, bool emit_summary) {
// We only pass ThinLinkOS to be filled in if we want the summary,
// because otherwise LLVM does extra work and may double-emit some
// errors or warnings.
MPM.addPass(ThinLTOBitcodeWriterPass(OS, emit_summary ? &ThinLinkOS : nullptr));
MPM.addPass(
ThinLTOBitcodeWriterPass(OS, emit_summary ? &ThinLinkOS : nullptr));
MPM.run(*unwrap(M), MAM);
} else {
WriteBitcodeToFile(*unwrap(M), OS);
@ -1530,12 +1515,11 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin, bool emit_summary) {
return Ret.release();
}
extern "C" void
LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
extern "C" void LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
delete Buffer;
}
extern "C" const void*
extern "C" const void *
LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
return Buffer->data.data();
}
@ -1545,7 +1529,7 @@ LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
return Buffer->data.length();
}
extern "C" const void*
extern "C" const void *
LLVMRustThinLTOBufferThinLinkDataPtr(const LLVMRustThinLTOBuffer *Buffer) {
return Buffer->thin_link_data.data();
}
@ -1558,11 +1542,10 @@ LLVMRustThinLTOBufferThinLinkDataLen(const LLVMRustThinLTOBuffer *Buffer) {
// This is what we used to parse upstream bitcode for actual ThinLTO
// processing. We'll call this once per module optimized through ThinLTO, and
// it'll be called concurrently on many threads.
extern "C" LLVMModuleRef
LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
const char *data,
size_t len,
const char *identifier) {
extern "C" LLVMModuleRef LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
const char *data,
size_t len,
const char *identifier) {
auto Data = StringRef(data, len);
auto Buffer = MemoryBufferRef(Data, identifier);
unwrap(Context)->enableDebugTypeODRUniquing();
@ -1614,8 +1597,9 @@ extern "C" const char *LLVMRustGetSliceFromObjectDataByName(const char *data,
// of access globals, etc).
// The precise details are determined by LLVM in `computeLTOCacheKey`, which is
// used during the normal linker-plugin incremental thin-LTO process.
extern "C" void
LLVMRustComputeLTOCacheKey(RustStringRef KeyOut, const char *ModId, LLVMRustThinLTOData *Data) {
extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
const char *ModId,
LLVMRustThinLTOData *Data) {
SmallString<40> Key;
llvm::lto::Config conf;
const auto &ImportList = Data->ImportLists.lookup(ModId);
@ -1633,9 +1617,9 @@ LLVMRustComputeLTOCacheKey(RustStringRef KeyOut, const char *ModId, LLVMRustThin
CfiFunctionDecls.insert(
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
llvm::computeLTOCacheKey(Key, conf, Data->Index, ModId,
ImportList, ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls
);
llvm::computeLTOCacheKey(Key, conf, Data->Index, ModId, ImportList,
ExportList, ResolvedODR, DefinedGlobals,
CfiFunctionDefs, CfiFunctionDecls);
LLVMRustStringWriteImpl(KeyOut, Key.c_str(), Key.size());
}

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,17 @@
#ifndef _rustc_llvm_SuppressLLVMWarnings_h
#define _rustc_llvm_SuppressLLVMWarnings_h
// LLVM currently generates many warnings when compiled using MSVC. These warnings make it difficult
// to diagnose real problems when working on C++ code, so we suppress them.
// LLVM currently generates many warnings when compiled using MSVC. These
// warnings make it difficult to diagnose real problems when working on C++
// code, so we suppress them.
#ifdef _MSC_VER
#pragma warning(disable:4530) // C++ exception handler used, but unwind semantics are not enabled.
#pragma warning(disable:4624) // 'xxx': destructor was implicitly defined as deleted
#pragma warning(disable:4244) // conversion from 'xxx' to 'yyy', possible loss of data
#pragma warning(disable : 4530) // C++ exception handler used, but unwind
// semantics are not enabled.
#pragma warning( \
disable : 4624) // 'xxx': destructor was implicitly defined as deleted
#pragma warning( \
disable : 4244) // conversion from 'xxx' to 'yyy', possible loss of data
#endif
#endif // _rustc_llvm_SuppressLLVMWarnings_h

View file

@ -34,14 +34,15 @@ static bool isArchiveSymbol(const object::BasicSymbolRef &S) {
typedef void *(*LLVMRustGetSymbolsCallback)(void *, const char *);
typedef void *(*LLVMRustGetSymbolsErrorCallback)(const char *);
// Note: This is implemented in C++ instead of using the C api from Rust as IRObjectFile doesn't
// implement getSymbolName, only printSymbolName, which is inaccessible from the C api.
extern "C" void *LLVMRustGetSymbols(
char *BufPtr, size_t BufLen, void *State, LLVMRustGetSymbolsCallback Callback,
LLVMRustGetSymbolsErrorCallback ErrorCallback) {
std::unique_ptr<MemoryBuffer> Buf =
MemoryBuffer::getMemBuffer(StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"),
false);
// Note: This is implemented in C++ instead of using the C api from Rust as
// IRObjectFile doesn't implement getSymbolName, only printSymbolName, which is
// inaccessible from the C api.
extern "C" void *
LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State,
LLVMRustGetSymbolsCallback Callback,
LLVMRustGetSymbolsErrorCallback ErrorCallback) {
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(
StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false);
SmallString<0> SymNameBuf;
auto SymName = raw_svector_ostream(SymNameBuf);
@ -57,7 +58,7 @@ extern "C" void *LLVMRustGetSymbols(
if (Type == file_magic::bitcode) {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
Buf->getMemBufferRef(), file_magic::bitcode, &Context);
Buf->getMemBufferRef(), file_magic::bitcode, &Context);
if (!ObjOrErr) {
Error E = ObjOrErr.takeError();
SmallString<0> ErrorBuf;
@ -67,7 +68,8 @@ extern "C" void *LLVMRustGetSymbols(
}
Obj = std::move(*ObjOrErr);
} else {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(Buf->getMemBufferRef());
auto ObjOrErr =
object::SymbolicFile::createSymbolicFile(Buf->getMemBufferRef());
if (!ObjOrErr) {
Error E = ObjOrErr.takeError();
SmallString<0> ErrorBuf;
@ -78,7 +80,6 @@ extern "C" void *LLVMRustGetSymbols(
Obj = std::move(*ObjOrErr);
}
for (const object::BasicSymbolRef &S : Obj->symbols()) {
if (!isArchiveSymbol(S))
continue;

View file

@ -35,4 +35,4 @@ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
# NOTE: intentionally uses python2 for x.py so we can test it still works.
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \
--stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint
--stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint,cpp:fmt

View file

@ -15,6 +15,7 @@ semver = "1.0"
termcolor = "1.1.3"
rustc-hash = "1.1.0"
fluent-syntax = "0.11.1"
similar = "2.5.0"
[[bin]]
name = "rust-tidy"

View file

@ -8,3 +8,4 @@
black==24.4.2
ruff==0.4.9
clang-format==18.1.7

View file

@ -28,6 +28,23 @@ black==24.4.2 \
--hash=sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063 \
--hash=sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e
# via -r src/tools/tidy/config/requirements.in
clang-format==18.1.7 \
--hash=sha256:035204410f65d03f98cb81c9c39d6d193f9987917cc88de9d0dbd01f2aa9c302 \
--hash=sha256:05c482a854287a5d21f7567186c0bd4b8dbd4a871751e655a45849185f30b931 \
--hash=sha256:0b352ec51b291fe04c25a0f0ed15ba1a55b9c9c8eaa7fdf14de3d3585aef4f72 \
--hash=sha256:217526c8189c18fd175e19bb3e4da2d1bdf14a2bf79d97108c9b6a98d9938351 \
--hash=sha256:42d0b580ab7a45348155944adebe0bef53d1de9357b925830a59bbc351a25560 \
--hash=sha256:57090c40a8f0a898e0db8be150a19be2551302d5f5620d2a01de07e7c9220a53 \
--hash=sha256:607772cf474c1ebe0de44f44c1324e57a2d5b45a1d96d4aff166645532d99b43 \
--hash=sha256:a49c44d7cc00431be8285aa120a7a21fa0475786c03c53b04a26882c4e626a43 \
--hash=sha256:a62fca204293893badde0ab004df8b6df1d13eac4d452051554d9684d0a8254e \
--hash=sha256:a914592a51f77c3563563c7a8970f19bc1ed59174ab992f095a78f4e142382ac \
--hash=sha256:b3a0a09428cdd656ed87074543222a80660bc506407ed21b8e4bcb3d6d3a5a3c \
--hash=sha256:c151d42e6ac7c3cc03d7fec61bed3211ce8f75528e1efd8fc64bdb33840987b2 \
--hash=sha256:d6a2f051124d6ae506ba2a68accfe4ea4c8cb90d13b422c3131bb124413bac32 \
--hash=sha256:f4f77ac0f4f9a659213fedda0f2d216886c410132e6e7dd4b13f92b34e925554 \
--hash=sha256:f935d34152a2e11e55120eb9182862f432bc9789ab819f680c9f6db4edebf9e3
# via -r src/tools/tidy/config/requirements.in
click==8.1.3 \
--hash=sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e \
--hash=sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48

View file

@ -73,6 +73,8 @@ fn check_impl(
let python_fmt = lint_args.contains(&"py:fmt") || python_all;
let shell_all = lint_args.contains(&"shell");
let shell_lint = lint_args.contains(&"shell:lint") || shell_all;
let cpp_all = lint_args.contains(&"cpp");
let cpp_fmt = lint_args.contains(&"cpp:fmt") || cpp_all;
let mut py_path = None;
@ -81,7 +83,7 @@ fn check_impl(
.map(OsStr::new)
.partition(|arg| arg.to_str().is_some_and(|s| s.starts_with('-')));
if python_lint || python_fmt {
if python_lint || python_fmt || cpp_fmt {
let venv_path = outdir.join("venv");
let mut reqs_path = root_path.to_owned();
reqs_path.extend(PIP_REQ_PATH);
@ -111,13 +113,13 @@ fn check_impl(
let mut args = merge_args(&cfg_args_ruff, &file_args_ruff);
args.insert(0, "check".as_ref());
let res = py_runner(py_path.as_ref().unwrap(), "ruff", &args);
let res = py_runner(py_path.as_ref().unwrap(), true, None, "ruff", &args);
if res.is_err() && show_diff {
eprintln!("\npython linting failed! Printing diff suggestions:");
args.insert(1, "--diff".as_ref());
let _ = py_runner(py_path.as_ref().unwrap(), "ruff", &args);
let _ = py_runner(py_path.as_ref().unwrap(), true, None, "ruff", &args);
}
// Rethrow error
let _ = res?;
@ -144,13 +146,84 @@ fn check_impl(
}
let mut args = merge_args(&cfg_args_black, &file_args_black);
let res = py_runner(py_path.as_ref().unwrap(), "black", &args);
let res = py_runner(py_path.as_ref().unwrap(), true, None, "black", &args);
if res.is_err() && show_diff {
eprintln!("\npython formatting does not match! Printing diff:");
args.insert(0, "--diff".as_ref());
let _ = py_runner(py_path.as_ref().unwrap(), "black", &args);
let _ = py_runner(py_path.as_ref().unwrap(), true, None, "black", &args);
}
// Rethrow error
let _ = res?;
}
if cpp_fmt {
let mut cfg_args_clang_format = cfg_args.clone();
let mut file_args_clang_format = file_args.clone();
let config_path = root_path.join(".clang-format");
let config_file_arg = format!("file:{}", config_path.display());
cfg_args_clang_format.extend(&["--style".as_ref(), config_file_arg.as_ref()]);
if bless {
eprintln!("formatting C++ files");
cfg_args_clang_format.push("-i".as_ref());
} else {
eprintln!("checking C++ file formatting");
cfg_args_clang_format.extend(&["--dry-run".as_ref(), "--Werror".as_ref()]);
}
let files;
if file_args_clang_format.is_empty() {
let llvm_wrapper = root_path.join("compiler/rustc_llvm/llvm-wrapper");
files = find_with_extension(
root_path,
Some(llvm_wrapper.as_path()),
&[OsStr::new("h"), OsStr::new("cpp")],
)?;
file_args_clang_format.extend(files.iter().map(|p| p.as_os_str()));
}
let args = merge_args(&cfg_args_clang_format, &file_args_clang_format);
let res = py_runner(py_path.as_ref().unwrap(), false, None, "clang-format", &args);
if res.is_err() && show_diff {
eprintln!("\nclang-format linting failed! Printing diff suggestions:");
let mut cfg_args_clang_format_diff = cfg_args.clone();
cfg_args_clang_format_diff.extend(&["--style".as_ref(), config_file_arg.as_ref()]);
for file in file_args_clang_format {
let mut formatted = String::new();
let mut diff_args = cfg_args_clang_format_diff.clone();
diff_args.push(file);
let _ = py_runner(
py_path.as_ref().unwrap(),
false,
Some(&mut formatted),
"clang-format",
&diff_args,
);
if formatted.is_empty() {
eprintln!(
"failed to obtain the formatted content for '{}'",
file.to_string_lossy()
);
continue;
}
let actual = std::fs::read_to_string(file).unwrap_or_else(|e| {
panic!(
"failed to read the C++ file at '{}' due to '{e}'",
file.to_string_lossy()
)
});
if formatted != actual {
let diff = similar::TextDiff::from_lines(&actual, &formatted);
eprintln!(
"{}",
diff.unified_diff().context_radius(4).header(
&format!("{} (actual)", file.to_string_lossy()),
&format!("{} (formatted)", file.to_string_lossy())
)
);
}
}
}
// Rethrow error
let _ = res?;
@ -162,7 +235,7 @@ fn check_impl(
let mut file_args_shc = file_args.clone();
let files;
if file_args_shc.is_empty() {
files = find_with_extension(root_path, "sh")?;
files = find_with_extension(root_path, None, &[OsStr::new("sh")])?;
file_args_shc.extend(files.iter().map(|p| p.as_os_str()));
}
@ -181,8 +254,31 @@ fn merge_args<'a>(cfg_args: &[&'a OsStr], file_args: &[&'a OsStr]) -> Vec<&'a Os
}
/// Run a python command with given arguments. `py_path` should be a virtualenv.
fn py_runner(py_path: &Path, bin: &'static str, args: &[&OsStr]) -> Result<(), Error> {
let status = Command::new(py_path).arg("-m").arg(bin).args(args).status()?;
///
/// Captures `stdout` to a string if provided, otherwise prints the output.
fn py_runner(
py_path: &Path,
as_module: bool,
stdout: Option<&mut String>,
bin: &'static str,
args: &[&OsStr],
) -> Result<(), Error> {
let mut cmd = Command::new(py_path);
if as_module {
cmd.arg("-m").arg(bin).args(args);
} else {
let bin_path = py_path.with_file_name(bin);
cmd.arg(bin_path).args(args);
}
let status = if let Some(stdout) = stdout {
let output = cmd.output()?;
if let Ok(s) = std::str::from_utf8(&output.stdout) {
stdout.push_str(s);
}
output.status
} else {
cmd.status()?
};
if status.success() { Ok(()) } else { Err(Error::FailedCheck(bin)) }
}
@ -357,7 +453,11 @@ fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> {
}
/// Check git for tracked files matching an extension
fn find_with_extension(root_path: &Path, extension: &str) -> Result<Vec<PathBuf>, Error> {
fn find_with_extension(
root_path: &Path,
find_dir: Option<&Path>,
extensions: &[&OsStr],
) -> Result<Vec<PathBuf>, Error> {
// Untracked files show up for short status and are indicated with a leading `?`
// -C changes git to be as if run from that directory
let stat_output =
@ -368,15 +468,25 @@ fn find_with_extension(root_path: &Path, extension: &str) -> Result<Vec<PathBuf>
}
let mut output = Vec::new();
let binding = Command::new("git").arg("-C").arg(root_path).args(["ls-files"]).output()?;
let binding = {
let mut command = Command::new("git");
command.arg("-C").arg(root_path).args(["ls-files"]);
if let Some(find_dir) = find_dir {
command.arg(find_dir);
}
command.output()?
};
let tracked = String::from_utf8_lossy(&binding.stdout);
for line in tracked.lines() {
let line = line.trim();
let path = Path::new(line);
if path.extension() == Some(OsStr::new(extension)) {
output.push(path.to_owned());
let Some(ref extension) = path.extension() else {
continue;
};
if extensions.contains(extension) {
output.push(root_path.join(path));
}
}