summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_llvm
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_llvm
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_llvm')
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp118
2 files changed, 112 insertions, 7 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index 058906283..af6f4d5ea 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -96,6 +96,7 @@ enum LLVMRustAttribute {
AllocatedPointer = 38,
AllocAlign = 39,
#endif
+ SanitizeSafeStack = 40,
};
typedef struct OpaqueRustString *RustStringRef;
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 49acd71b3..bb7510b3a 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -7,7 +7,12 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsARM.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
#include "llvm/IR/Mangler.h"
+#include "llvm/Remarks/RemarkStreamer.h"
+#include "llvm/Remarks/RemarkSerializer.h"
+#include "llvm/Remarks/RemarkFormat.h"
+#include "llvm/Support/ToolOutputFile.h"
#if LLVM_VERSION_GE(16, 0)
#include "llvm/Support/ModRef.h"
#endif
@@ -116,6 +121,32 @@ extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
}
+enum class LLVMRustTailCallKind {
+ None,
+ Tail,
+ MustTail,
+ NoTail,
+};
+
+static CallInst::TailCallKind fromRust(LLVMRustTailCallKind Kind) {
+ switch (Kind) {
+ case LLVMRustTailCallKind::None:
+ return CallInst::TailCallKind::TCK_None;
+ case LLVMRustTailCallKind::Tail:
+ return CallInst::TailCallKind::TCK_Tail;
+ case LLVMRustTailCallKind::MustTail:
+ return CallInst::TailCallKind::TCK_MustTail;
+ case LLVMRustTailCallKind::NoTail:
+ return CallInst::TailCallKind::TCK_NoTail;
+ default:
+ report_fatal_error("bad CallInst::TailCallKind.");
+ }
+}
+
+extern "C" void LLVMRustSetTailCallKind(LLVMValueRef Call, LLVMRustTailCallKind TCK) {
+ unwrap<CallInst>(Call)->setTailCallKind(fromRust(TCK));
+}
+
extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
const char *Name,
size_t NameLen,
@@ -234,6 +265,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
case AllocAlign:
return Attribute::AllocAlign;
#endif
+ case SanitizeSafeStack:
+ return Attribute::SafeStack;
}
report_fatal_error("bad AttributeKind");
}
@@ -1853,23 +1886,44 @@ using LLVMDiagnosticHandlerTy = DiagnosticHandler::DiagnosticHandlerTy;
// When RemarkAllPasses is true, remarks are enabled for all passes. Otherwise
// the RemarkPasses array specifies individual passes for which remarks will be
// enabled.
+//
+// If RemarkFilePath is not NULL, optimization remarks will be streamed directly into this file,
+// bypassing the diagnostics handler.
extern "C" void LLVMRustContextConfigureDiagnosticHandler(
LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
void *DiagnosticHandlerContext, bool RemarkAllPasses,
- const char * const * RemarkPasses, size_t RemarkPassesLen) {
+ const char * const * RemarkPasses, size_t RemarkPassesLen,
+ const char * RemarkFilePath
+) {
class RustDiagnosticHandler final : public DiagnosticHandler {
public:
- RustDiagnosticHandler(LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
- void *DiagnosticHandlerContext,
- bool RemarkAllPasses,
- std::vector<std::string> RemarkPasses)
+ RustDiagnosticHandler(
+ LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
+ void *DiagnosticHandlerContext,
+ bool RemarkAllPasses,
+ std::vector<std::string> RemarkPasses,
+ std::unique_ptr<ToolOutputFile> RemarksFile,
+ std::unique_ptr<llvm::remarks::RemarkStreamer> RemarkStreamer,
+ std::unique_ptr<LLVMRemarkStreamer> LlvmRemarkStreamer
+ )
: DiagnosticHandlerCallback(DiagnosticHandlerCallback),
DiagnosticHandlerContext(DiagnosticHandlerContext),
RemarkAllPasses(RemarkAllPasses),
- RemarkPasses(RemarkPasses) {}
+ RemarkPasses(std::move(RemarkPasses)),
+ RemarksFile(std::move(RemarksFile)),
+ RemarkStreamer(std::move(RemarkStreamer)),
+ LlvmRemarkStreamer(std::move(LlvmRemarkStreamer)) {}
virtual bool handleDiagnostics(const DiagnosticInfo &DI) override {
+ if (this->LlvmRemarkStreamer) {
+ if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) {
+ if (OptDiagBase->isEnabled()) {
+ this->LlvmRemarkStreamer->emit(*OptDiagBase);
+ return true;
+ }
+ }
+ }
if (DiagnosticHandlerCallback) {
DiagnosticHandlerCallback(DI, DiagnosticHandlerContext);
return true;
@@ -1910,14 +1964,64 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler(
bool RemarkAllPasses = false;
std::vector<std::string> RemarkPasses;
+
+ // Since LlvmRemarkStreamer contains a pointer to RemarkStreamer, the ordering of the three
+ // members below is important.
+ std::unique_ptr<ToolOutputFile> RemarksFile;
+ std::unique_ptr<llvm::remarks::RemarkStreamer> RemarkStreamer;
+ std::unique_ptr<LLVMRemarkStreamer> LlvmRemarkStreamer;
};
std::vector<std::string> Passes;
for (size_t I = 0; I != RemarkPassesLen; ++I)
+ {
Passes.push_back(RemarkPasses[I]);
+ }
+
+ // We need to hold onto both the streamers and the opened file
+ std::unique_ptr<ToolOutputFile> RemarkFile;
+ std::unique_ptr<llvm::remarks::RemarkStreamer> RemarkStreamer;
+ std::unique_ptr<LLVMRemarkStreamer> LlvmRemarkStreamer;
+
+ if (RemarkFilePath != nullptr) {
+ std::error_code EC;
+ RemarkFile = std::make_unique<ToolOutputFile>(
+ RemarkFilePath,
+ EC,
+ llvm::sys::fs::OF_TextWithCRLF
+ );
+ if (EC) {
+ std::string Error = std::string("Cannot create remark file: ") +
+ toString(errorCodeToError(EC));
+ report_fatal_error(Twine(Error));
+ }
+
+ // Do not delete the file after we gather remarks
+ RemarkFile->keep();
+
+ auto RemarkSerializer = remarks::createRemarkSerializer(
+ llvm::remarks::Format::YAML,
+ remarks::SerializerMode::Separate,
+ RemarkFile->os()
+ );
+ if (Error E = RemarkSerializer.takeError())
+ {
+ std::string Error = std::string("Cannot create remark serializer: ") + toString(std::move(E));
+ report_fatal_error(Twine(Error));
+ }
+ RemarkStreamer = std::make_unique<llvm::remarks::RemarkStreamer>(std::move(*RemarkSerializer));
+ LlvmRemarkStreamer = std::make_unique<LLVMRemarkStreamer>(*RemarkStreamer);
+ }
unwrap(C)->setDiagnosticHandler(std::make_unique<RustDiagnosticHandler>(
- DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, Passes));
+ DiagnosticHandlerCallback,
+ DiagnosticHandlerContext,
+ RemarkAllPasses,
+ Passes,
+ std::move(RemarkFile),
+ std::move(RemarkStreamer),
+ std::move(LlvmRemarkStreamer)
+ ));
}
extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) {