Format C++ files in llvm-wrapper

This commit is contained in:
DianQK 2024-06-04 22:46:20 +08:00
parent de0ece2f29
commit e17c16d55b
No known key found for this signature in database
6 changed files with 754 additions and 811 deletions

View File

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

View File

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

View File

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