Format C++ files in llvm-wrapper
This commit is contained in:
parent
de0ece2f29
commit
e17c16d55b
@ -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() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,11 +24,8 @@ struct RustArchiveIterator {
|
|||||||
std::unique_ptr<Error> Err;
|
std::unique_ptr<Error> Err;
|
||||||
|
|
||||||
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,10 +166,9 @@ 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;
|
||||||
auto Kind = fromRust(RustKind);
|
auto Kind = fromRust(RustKind);
|
||||||
@ -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;
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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);
|
||||||
@ -444,18 +439,20 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
|||||||
Options.MCOptions.PreserveAsmComments = AsmComments;
|
Options.MCOptions.PreserveAsmComments = AsmComments;
|
||||||
Options.MCOptions.ABIName = ABIStr;
|
Options.MCOptions.ABIName = ABIStr;
|
||||||
if (SplitDwarfFile) {
|
if (SplitDwarfFile) {
|
||||||
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
|
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
|
||||||
}
|
}
|
||||||
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);
|
||||||
@ -527,7 +521,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
|||||||
|
|
||||||
Options.MCOptions.Argv0 = arg0;
|
Options.MCOptions.Argv0 = arg0;
|
||||||
Options.MCOptions.CommandLineArgs =
|
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(
|
TargetMachine *TM = TheTarget->createTargetMachine(
|
||||||
@ -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();
|
||||||
|
|
||||||
@ -613,7 +607,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
|
|||||||
auto DOS = raw_fd_ostream(DwoPath, EC, sys::fs::OF_None);
|
auto DOS = raw_fd_ostream(DwoPath, EC, sys::fs::OF_None);
|
||||||
EC.clear();
|
EC.clear();
|
||||||
if (EC)
|
if (EC)
|
||||||
ErrorInfo = EC.message();
|
ErrorInfo = EC.message();
|
||||||
if (ErrorInfo != "") {
|
if (ErrorInfo != "") {
|
||||||
LLVMRustSetLastError(ErrorInfo.c_str());
|
LLVMRustSetLastError(ErrorInfo.c_str());
|
||||||
return LLVMRustResult::Failure;
|
return LLVMRustResult::Failure;
|
||||||
@ -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,35 +646,35 @@ 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());
|
||||||
});
|
});
|
||||||
|
|
||||||
PIC.registerAfterAnalysisCallback(
|
PIC.registerAfterAnalysisCallback(
|
||||||
[LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
|
[LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
|
||||||
@ -704,7 +700,7 @@ struct LLVMRustSanitizerOptions {
|
|||||||
bool SanitizeKCFI;
|
bool SanitizeKCFI;
|
||||||
bool SanitizeMemory;
|
bool SanitizeMemory;
|
||||||
bool SanitizeMemoryRecover;
|
bool SanitizeMemoryRecover;
|
||||||
int SanitizeMemoryTrackOrigins;
|
int SanitizeMemoryTrackOrigins;
|
||||||
bool SanitizeThread;
|
bool SanitizeThread;
|
||||||
bool SanitizeHWAddress;
|
bool SanitizeHWAddress;
|
||||||
bool SanitizeHWAddressRecover;
|
bool SanitizeHWAddressRecover;
|
||||||
@ -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,58 +817,53 @@ 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) {
|
||||||
PipelineStartEPCallbacks.push_back(
|
PipelineStartEPCallbacks.push_back(
|
||||||
[InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
|
[InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
|
||||||
InstrProfOptions Options;
|
InstrProfOptions Options;
|
||||||
if (InstrProfileOutput) {
|
if (InstrProfileOutput) {
|
||||||
Options.InstrProfileOutput = InstrProfileOutput;
|
Options.InstrProfileOutput = InstrProfileOutput;
|
||||||
}
|
}
|
||||||
// cargo run tests in multhreading mode by default
|
// cargo run tests in multhreading mode by default
|
||||||
// so use atomics for coverage counters
|
// so use atomics for coverage counters
|
||||||
Options.Atomic = true;
|
Options.Atomic = true;
|
||||||
#if LLVM_VERSION_GE(18, 0)
|
#if LLVM_VERSION_GE(18, 0)
|
||||||
MPM.addPass(InstrProfilingLoweringPass(Options, false));
|
MPM.addPass(InstrProfilingLoweringPass(Options, false));
|
||||||
#else
|
#else
|
||||||
MPM.addPass(InstrProfiling(Options, false));
|
MPM.addPass(InstrProfiling(Options, false));
|
||||||
#endif
|
#endif
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SanitizerOptions) {
|
if (SanitizerOptions) {
|
||||||
@ -886,10 +873,9 @@ LLVMRustOptimize(
|
|||||||
SanitizerOptions->SanitizeDataFlowABIList +
|
SanitizerOptions->SanitizeDataFlowABIList +
|
||||||
SanitizerOptions->SanitizeDataFlowABIListLen);
|
SanitizerOptions->SanitizeDataFlowABIListLen);
|
||||||
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) {
|
||||||
@ -899,54 +885,54 @@ LLVMRustOptimize(
|
|||||||
/*CompileKernel=*/false,
|
/*CompileKernel=*/false,
|
||||||
/*EagerChecks=*/true);
|
/*EagerChecks=*/true);
|
||||||
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,
|
||||||
/*DisableOptimization=*/false);
|
SanitizerOptions->SanitizeHWAddressRecover,
|
||||||
MPM.addPass(HWAddressSanitizerPass(opts));
|
/*DisableOptimization=*/false);
|
||||||
}
|
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 {
|
||||||
|
|
||||||
@ -1064,7 +1050,7 @@ public:
|
|||||||
formatted_raw_ostream &OS) override {
|
formatted_raw_ostream &OS) override {
|
||||||
StringRef Demangled = CallDemangle(F->getName());
|
StringRef Demangled = CallDemangle(F->getName());
|
||||||
if (Demangled.empty()) {
|
if (Demangled.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << "; " << Demangled << "\n";
|
OS << "; " << Demangled << "\n";
|
||||||
@ -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();
|
||||||
@ -1366,16 +1348,15 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
|
|||||||
auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
|
auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
|
||||||
const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
|
const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
|
||||||
return (ExportList != Ret->ExportLists.end() &&
|
return (ExportList != Ret->ExportLists.end() &&
|
||||||
ExportList->second.count(VI)) ||
|
ExportList->second.count(VI)) ||
|
||||||
ExportedGUIDs.count(VI.getGUID());
|
ExportedGUIDs.count(VI.getGUID());
|
||||||
};
|
};
|
||||||
thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
|
thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
|
||||||
|
|
||||||
return Ret.release();
|
return Ret.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
|
||||||
LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
|
|
||||||
delete Data;
|
delete Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1387,20 +1368,18 @@ 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,24 +1394,28 @@ 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,11 +1542,10 @@ 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) {
|
|
||||||
auto Data = StringRef(data, len);
|
auto Data = StringRef(data, len);
|
||||||
auto Buffer = MemoryBufferRef(Data, identifier);
|
auto Buffer = MemoryBufferRef(Data, identifier);
|
||||||
unwrap(Context)->enableDebugTypeODRUniquing();
|
unwrap(Context)->enableDebugTypeODRUniquing();
|
||||||
@ -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
@ -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
|
||||||
|
@ -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 *
|
||||||
LLVMRustGetSymbolsErrorCallback ErrorCallback) {
|
LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State,
|
||||||
std::unique_ptr<MemoryBuffer> Buf =
|
LLVMRustGetSymbolsCallback Callback,
|
||||||
MemoryBuffer::getMemBuffer(StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"),
|
LLVMRustGetSymbolsErrorCallback ErrorCallback) {
|
||||||
false);
|
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(
|
||||||
|
StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false);
|
||||||
SmallString<0> SymNameBuf;
|
SmallString<0> SymNameBuf;
|
||||||
auto SymName = raw_svector_ostream(SymNameBuf);
|
auto SymName = raw_svector_ostream(SymNameBuf);
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ extern "C" void *LLVMRustGetSymbols(
|
|||||||
|
|
||||||
if (Type == file_magic::bitcode) {
|
if (Type == file_magic::bitcode) {
|
||||||
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
|
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
|
||||||
Buf->getMemBufferRef(), file_magic::bitcode, &Context);
|
Buf->getMemBufferRef(), file_magic::bitcode, &Context);
|
||||||
if (!ObjOrErr) {
|
if (!ObjOrErr) {
|
||||||
Error E = ObjOrErr.takeError();
|
Error E = ObjOrErr.takeError();
|
||||||
SmallString<0> ErrorBuf;
|
SmallString<0> ErrorBuf;
|
||||||
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user