diff options
| author | Cameron Hart <cameron.hart@gmail.com> | 2016-08-06 15:50:48 +1000 |
|---|---|---|
| committer | Cameron Hart <cameron.hart@gmail.com> | 2016-08-06 15:50:48 +1000 |
| commit | cbb88faad77d2c9d3de07a1e4b676f95c6780727 (patch) | |
| tree | 8f6d010cb4334d31514a08392d784aaecdeae42d /src/rustllvm | |
| parent | fc210a8994174d48965453fa6cbeafc8902bd399 (diff) | |
| parent | b30eff7ba72a78e31acd61a2b6931919a0ad62e8 (diff) | |
| download | rust-cbb88faad77d2c9d3de07a1e4b676f95c6780727.tar.gz rust-cbb88faad77d2c9d3de07a1e4b676f95c6780727.zip | |
Merge branch 'master' into issue-30961
Diffstat (limited to 'src/rustllvm')
| -rw-r--r-- | src/rustllvm/ArchiveWrapper.cpp | 138 | ||||
| -rw-r--r-- | src/rustllvm/ExecutionEngineWrapper.cpp | 111 | ||||
| -rw-r--r-- | src/rustllvm/PassWrapper.cpp | 204 | ||||
| -rw-r--r-- | src/rustllvm/README | 14 | ||||
| -rw-r--r-- | src/rustllvm/RustWrapper.cpp | 562 | ||||
| -rw-r--r-- | src/rustllvm/llvm-auto-clean-trigger | 2 | ||||
| -rw-r--r-- | src/rustllvm/rustllvm.h | 5 |
7 files changed, 661 insertions, 375 deletions
diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 1e7b04c814c..1e873b5345c 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -16,24 +16,62 @@ using namespace llvm; using namespace llvm::object; -struct LLVMRustArchiveMember { +struct RustArchiveMember { const char *filename; const char *name; Archive::Child child; - LLVMRustArchiveMember(): filename(NULL), name(NULL), + RustArchiveMember(): filename(NULL), name(NULL), #if LLVM_VERSION_MINOR >= 8 child(NULL, NULL, NULL) #else child(NULL, NULL) #endif {} - ~LLVMRustArchiveMember() {} + ~RustArchiveMember() {} }; -typedef OwningBinary<Archive> RustArchive; -extern "C" void* +struct RustArchiveIterator { + Archive::child_iterator cur; + Archive::child_iterator end; +#if LLVM_VERSION_MINOR >= 9 + Error err; +#endif +}; + +enum class LLVMRustArchiveKind { + Other, + GNU, + MIPS64, + BSD, + COFF, +}; + +static Archive::Kind +from_rust(LLVMRustArchiveKind kind) +{ + switch (kind) { + case LLVMRustArchiveKind::GNU: + return Archive::K_GNU; + case LLVMRustArchiveKind::MIPS64: + return Archive::K_MIPS64; + case LLVMRustArchiveKind::BSD: + return Archive::K_BSD; + case LLVMRustArchiveKind::COFF: + return Archive::K_COFF; + default: + llvm_unreachable("Bad ArchiveKind."); + } +} + +typedef OwningBinary<Archive> *LLVMRustArchiveRef; +typedef RustArchiveMember *LLVMRustArchiveMemberRef; +typedef Archive::Child *LLVMRustArchiveChildRef; +typedef Archive::Child const *LLVMRustArchiveChildConstRef; +typedef RustArchiveIterator *LLVMRustArchiveIteratorRef; + +extern "C" LLVMRustArchiveRef LLVMRustOpenArchive(char *path) { ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path, -1, @@ -43,11 +81,19 @@ LLVMRustOpenArchive(char *path) { return nullptr; } +#if LLVM_VERSION_MINOR <= 8 ErrorOr<std::unique_ptr<Archive>> archive_or = +#else + Expected<std::unique_ptr<Archive>> archive_or = +#endif Archive::create(buf_or.get()->getMemBufferRef()); if (!archive_or) { +#if LLVM_VERSION_MINOR <= 8 LLVMRustSetLastError(archive_or.getError().message().c_str()); +#else + LLVMRustSetLastError(toString(archive_or.takeError()).c_str()); +#endif return nullptr; } @@ -58,29 +104,38 @@ LLVMRustOpenArchive(char *path) { } extern "C" void -LLVMRustDestroyArchive(RustArchive *ar) { +LLVMRustDestroyArchive(LLVMRustArchiveRef ar) { delete ar; } -struct RustArchiveIterator { - Archive::child_iterator cur; - Archive::child_iterator end; -}; - -extern "C" RustArchiveIterator* -LLVMRustArchiveIteratorNew(RustArchive *ra) { +extern "C" LLVMRustArchiveIteratorRef +LLVMRustArchiveIteratorNew(LLVMRustArchiveRef ra) { Archive *ar = ra->getBinary(); RustArchiveIterator *rai = new RustArchiveIterator(); +#if LLVM_VERSION_MINOR <= 8 rai->cur = ar->child_begin(); +#else + rai->cur = ar->child_begin(rai->err); + if (rai->err) { + LLVMRustSetLastError(toString(std::move(rai->err)).c_str()); + return NULL; + } +#endif rai->end = ar->child_end(); return rai; } -extern "C" const Archive::Child* -LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) { +extern "C" LLVMRustArchiveChildConstRef +LLVMRustArchiveIteratorNext(LLVMRustArchiveIteratorRef rai) { +#if LLVM_VERSION_MINOR >= 9 + if (rai->err) { + LLVMRustSetLastError(toString(std::move(rai->err)).c_str()); + return NULL; + } +#endif if (rai->cur == rai->end) return NULL; -#if LLVM_VERSION_MINOR >= 8 +#if LLVM_VERSION_MINOR == 8 const ErrorOr<Archive::Child>* cur = rai->cur.operator->(); if (!*cur) { LLVMRustSetLastError(cur->getError().message().c_str()); @@ -97,17 +152,17 @@ LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) { } extern "C" void -LLVMRustArchiveChildFree(Archive::Child *child) { +LLVMRustArchiveChildFree(LLVMRustArchiveChildRef child) { delete child; } extern "C" void -LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) { +LLVMRustArchiveIteratorFree(LLVMRustArchiveIteratorRef rai) { delete rai; } extern "C" const char* -LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) { +LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef child, size_t *size) { ErrorOr<StringRef> name_or_err = child->getName(); if (name_or_err.getError()) return NULL; @@ -117,7 +172,7 @@ LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) { } extern "C" const char* -LLVMRustArchiveChildData(Archive::Child *child, size_t *size) { +LLVMRustArchiveChildData(LLVMRustArchiveChildRef child, size_t *size) { StringRef buf; ErrorOr<StringRef> buf_or_err = child->getBuffer(); if (buf_or_err.getError()) { @@ -129,9 +184,10 @@ LLVMRustArchiveChildData(Archive::Child *child, size_t *size) { return buf.data(); } -extern "C" LLVMRustArchiveMember* -LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) { - LLVMRustArchiveMember *Member = new LLVMRustArchiveMember; +extern "C" LLVMRustArchiveMemberRef +LLVMRustArchiveMemberNew(char *Filename, char *Name, + LLVMRustArchiveChildRef child) { + RustArchiveMember *Member = new RustArchiveMember; Member->filename = Filename; Member->name = Name; if (child) @@ -140,29 +196,51 @@ LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) { } extern "C" void -LLVMRustArchiveMemberFree(LLVMRustArchiveMember *Member) { +LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) { delete Member; } -extern "C" int +extern "C" LLVMRustResult LLVMRustWriteArchive(char *Dst, size_t NumMembers, - const LLVMRustArchiveMember **NewMembers, + const LLVMRustArchiveMemberRef *NewMembers, bool WriteSymbtab, - Archive::Kind Kind) { + LLVMRustArchiveKind rust_kind) { + +#if LLVM_VERSION_MINOR <= 8 std::vector<NewArchiveIterator> Members; +#else + std::vector<NewArchiveMember> Members; +#endif + auto Kind = from_rust(rust_kind); for (size_t i = 0; i < NumMembers; i++) { auto Member = NewMembers[i]; assert(Member->name); if (Member->filename) { -#if LLVM_VERSION_MINOR >= 8 +#if LLVM_VERSION_MINOR >= 9 + Expected<NewArchiveMember> MOrErr = NewArchiveMember::getFile(Member->filename, true); + if (!MOrErr) { + LLVMRustSetLastError(toString(MOrErr.takeError()).c_str()); + return LLVMRustResult::Failure; + } + Members.push_back(std::move(*MOrErr)); +#elif LLVM_VERSION_MINOR == 8 Members.push_back(NewArchiveIterator(Member->filename)); #else Members.push_back(NewArchiveIterator(Member->filename, Member->name)); #endif } else { +#if LLVM_VERSION_MINOR <= 8 Members.push_back(NewArchiveIterator(Member->child, Member->name)); +#else + Expected<NewArchiveMember> MOrErr = NewArchiveMember::getOldMember(Member->child, true); + if (!MOrErr) { + LLVMRustSetLastError(toString(MOrErr.takeError()).c_str()); + return LLVMRustResult::Failure; + } + Members.push_back(std::move(*MOrErr)); +#endif } } #if LLVM_VERSION_MINOR >= 8 @@ -171,7 +249,7 @@ LLVMRustWriteArchive(char *Dst, auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true); #endif if (!pair.second) - return 0; + return LLVMRustResult::Success; LLVMRustSetLastError(pair.second.message().c_str()); - return -1; + return LLVMRustResult::Failure; } diff --git a/src/rustllvm/ExecutionEngineWrapper.cpp b/src/rustllvm/ExecutionEngineWrapper.cpp deleted file mode 100644 index b26ab446019..00000000000 --- a/src/rustllvm/ExecutionEngineWrapper.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#include "rustllvm.h" - -#include "llvm/ExecutionEngine/SectionMemoryManager.h" - -using namespace llvm; -using namespace llvm::sys; -using namespace llvm::object; - -class RustJITMemoryManager : public SectionMemoryManager -{ - typedef SectionMemoryManager Base; - - public: - - RustJITMemoryManager() {} - - uint64_t getSymbolAddress(const std::string &Name) override - { - return Base::getSymbolAddress(Name); - } -}; - -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef) - -extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path) -{ - std::string err; - DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(path, &err); - - if (!lib.isValid()) - LLVMRustSetLastError(err.c_str()); - - return lib.isValid(); -} - -// Calls LLVMAddModule; -// exists for consistency with LLVMExecutionEngineRemoveModule -extern "C" void LLVMExecutionEngineAddModule( - LLVMExecutionEngineRef eeref, LLVMModuleRef mref) -{ -#ifdef _WIN32 - // On Windows, MCJIT must generate ELF objects - std::string target = getProcessTriple(); - target += "-elf"; - target = Triple::normalize(target); - unwrap(mref)->setTargetTriple(target); -#endif - LLVMAddModule(eeref, mref); -} - -// LLVMRemoveModule exists in LLVM's C bindings, -// but it requires pointless parameters -extern "C" LLVMBool LLVMExecutionEngineRemoveModule( - LLVMExecutionEngineRef eeref, LLVMModuleRef mref) -{ - ExecutionEngine *ee = unwrap(eeref); - Module *m = unwrap(mref); - - return ee->removeModule(m); -} - -extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod) -{ - // These are necessary for code generation to work properly. - InitializeNativeTarget(); - InitializeNativeTargetAsmPrinter(); - InitializeNativeTargetAsmParser(); - -#ifdef _WIN32 - // On Windows, MCJIT must generate ELF objects - std::string target = getProcessTriple(); - target += "-elf"; - target = Triple::normalize(target); - unwrap(mod)->setTargetTriple(target); -#endif - - std::string error_str; - TargetOptions options; - - RustJITMemoryManager *mm = new RustJITMemoryManager; - - ExecutionEngine *ee = - EngineBuilder(std::unique_ptr<Module>(unwrap(mod))) - .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(mm)) - .setEngineKind(EngineKind::JIT) - .setErrorStr(&error_str) - .setTargetOptions(options) - .create(); - - if (!ee) - LLVMRustSetLastError(error_str.c_str()); - - return wrap(ee); -} - -extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref) -{ - ExecutionEngine *ee = unwrap(eeref); - - ee->finalizeObject(); -} diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index b94e667701c..0555a96ff24 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -17,6 +17,7 @@ #include "llvm/Support/Host.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/IR/AutoUpgrade.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" @@ -54,41 +55,48 @@ LLVMInitializePasses() { initializeTarget(Registry); } - -enum class SupportedPassKind { +enum class LLVMRustPassKind { + Other, Function, Module, - Unsupported }; -extern "C" Pass* +static LLVMRustPassKind +to_rust(PassKind kind) +{ + switch (kind) { + case PT_Function: + return LLVMRustPassKind::Function; + case PT_Module: + return LLVMRustPassKind::Module; + default: + return LLVMRustPassKind::Other; + } +} + +extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) { StringRef SR(PassName); PassRegistry *PR = PassRegistry::getPassRegistry(); const PassInfo *PI = PR->getPassInfo(SR); if (PI) { - return PI->createPass(); + return wrap(PI->createPass()); } return NULL; } -extern "C" SupportedPassKind -LLVMRustPassKind(Pass *pass) { - assert(pass); - PassKind passKind = pass->getPassKind(); - if (passKind == PT_Module) { - return SupportedPassKind::Module; - } else if (passKind == PT_Function) { - return SupportedPassKind::Function; - } else { - return SupportedPassKind::Unsupported; - } +extern "C" LLVMRustPassKind +LLVMRustPassKind(LLVMPassRef rust_pass) { + assert(rust_pass); + Pass *pass = unwrap(rust_pass); + return to_rust(pass->getPassKind()); } extern "C" void -LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) { - assert(pass); +LLVMRustAddPass(LLVMPassManagerRef PM, LLVMPassRef rust_pass) { + assert(rust_pass); + Pass *pass = unwrap(rust_pass); PassManagerBase *pm = unwrap(PM); pm->add(pass); } @@ -162,6 +170,62 @@ LLVMRustHasFeature(LLVMTargetMachineRef TM, return (Bits & FeatureEntry->Value) == FeatureEntry->Value; } +enum class LLVMRustCodeModel { + Other, + Default, + JITDefault, + Small, + Kernel, + Medium, + Large, +}; + +static CodeModel::Model +from_rust(LLVMRustCodeModel model) +{ + switch (model) { + case LLVMRustCodeModel::Default: + return CodeModel::Default; + case LLVMRustCodeModel::JITDefault: + return CodeModel::JITDefault; + case LLVMRustCodeModel::Small: + return CodeModel::Small; + case LLVMRustCodeModel::Kernel: + return CodeModel::Kernel; + case LLVMRustCodeModel::Medium: + return CodeModel::Medium; + case LLVMRustCodeModel::Large: + return CodeModel::Large; + default: + llvm_unreachable("Bad CodeModel."); + } +} + +enum class LLVMRustCodeGenOptLevel { + Other, + None, + Less, + Default, + Aggressive, +}; + +static CodeGenOpt::Level +from_rust(LLVMRustCodeGenOptLevel level) +{ + switch (level) { + case LLVMRustCodeGenOptLevel::None: + return CodeGenOpt::None; + case LLVMRustCodeGenOptLevel::Less: + return CodeGenOpt::Less; + case LLVMRustCodeGenOptLevel::Default: + return CodeGenOpt::Default; + case LLVMRustCodeGenOptLevel::Aggressive: + return CodeGenOpt::Aggressive; + default: + llvm_unreachable("Bad CodeGenOptLevel."); + } +} + #if LLVM_RUSTLLVM /// getLongestEntryLength - Return the length of the longest entry in the table. /// @@ -218,13 +282,39 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(const char *triple, const char *cpu, const char *feature, - CodeModel::Model CM, - Reloc::Model RM, - CodeGenOpt::Level OptLevel, + LLVMRustCodeModel rust_CM, + LLVMRelocMode Reloc, + LLVMRustCodeGenOptLevel rust_OptLevel, bool UseSoftFloat, bool PositionIndependentExecutable, bool FunctionSections, bool DataSections) { + +#if LLVM_VERSION_MINOR <= 8 + Reloc::Model RM; +#else + Optional<Reloc::Model> RM; +#endif + auto CM = from_rust(rust_CM); + auto OptLevel = from_rust(rust_OptLevel); + + switch (Reloc){ + case LLVMRelocStatic: + RM = Reloc::Static; + break; + case LLVMRelocPIC: + RM = Reloc::PIC_; + break; + case LLVMRelocDynamicNoPic: + RM = Reloc::DynamicNoPIC; + break; + default: +#if LLVM_VERSION_MINOR <= 8 + RM = Reloc::Default; +#endif + break; + } + std::string Error; Triple Trip(Triple::normalize(triple)); const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(), @@ -240,7 +330,10 @@ LLVMRustCreateTargetMachine(const char *triple, } TargetOptions Options; +#if LLVM_VERSION_MINOR <= 8 Options.PositionIndependentExecutable = PositionIndependentExecutable; +#endif + Options.FloatABIType = FloatABI::Default; if (UseSoftFloat) { Options.FloatABIType = FloatABI::Soft; @@ -277,14 +370,14 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM, extern "C" void LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB, - CodeGenOpt::Level OptLevel, + LLVMRustCodeGenOptLevel OptLevel, bool MergeFunctions, bool SLPVectorize, bool LoopVectorize) { // Ignore mergefunc for now as enabling it causes crashes. //unwrap(PMB)->MergeFunctions = MergeFunctions; unwrap(PMB)->SLPVectorize = SLPVectorize; - unwrap(PMB)->OptLevel = OptLevel; + unwrap(PMB)->OptLevel = from_rust(OptLevel); unwrap(PMB)->LoopVectorize = LoopVectorize; } @@ -319,12 +412,19 @@ LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB, // similar code in clang's BackendUtil.cpp file. extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) { - FunctionPassManager *P = unwrap<FunctionPassManager>(PM); + llvm::legacy::FunctionPassManager *P = unwrap<llvm::legacy::FunctionPassManager>(PM); P->doInitialization(); + + // Upgrade all calls to old intrinsics first. + for (Module::iterator I = unwrap(M)->begin(), + E = unwrap(M)->end(); I != E;) + UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove + for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E; ++I) if (!I->isDeclaration()) P->run(*I); + P->doFinalization(); } @@ -340,13 +440,33 @@ LLVMRustSetLLVMOptions(int Argc, char **Argv) { cl::ParseCommandLineOptions(Argc, Argv); } -extern "C" bool +enum class LLVMRustFileType { + Other, + AssemblyFile, + ObjectFile, +}; + +static TargetMachine::CodeGenFileType +from_rust(LLVMRustFileType type) +{ + switch (type) { + case LLVMRustFileType::AssemblyFile: + return TargetMachine::CGFT_AssemblyFile; + case LLVMRustFileType::ObjectFile: + return TargetMachine::CGFT_ObjectFile; + default: + llvm_unreachable("Bad FileType."); + } +} + +extern "C" LLVMRustResult LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR, LLVMModuleRef M, const char *path, - TargetMachine::CodeGenFileType FileType) { - PassManager *PM = unwrap<PassManager>(PMR); + LLVMRustFileType rust_FileType) { + llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR); + auto FileType = from_rust(rust_FileType); std::string ErrorInfo; std::error_code EC; @@ -355,7 +475,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, ErrorInfo = EC.message(); if (ErrorInfo != "") { LLVMRustSetLastError(ErrorInfo.c_str()); - return false; + return LLVMRustResult::Failure; } unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false); @@ -365,14 +485,14 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, // stream (OS), so the only real safe place to delete this is here? Don't we // wish this was written in Rust? delete PM; - return true; + return LLVMRustResult::Success; } extern "C" void LLVMRustPrintModule(LLVMPassManagerRef PMR, LLVMModuleRef M, const char* path) { - PassManager *PM = unwrap<PassManager>(PMR); + llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR); std::string ErrorInfo; std::error_code EC; @@ -410,9 +530,24 @@ LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMB, bool AddLifetimes) { extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **symbols, size_t len) { - PassManager passes; + llvm::legacy::PassManager passes; + +#if LLVM_VERSION_MINOR <= 8 ArrayRef<const char*> ref(symbols, len); passes.add(llvm::createInternalizePass(ref)); +#else + auto PreserveFunctions = [=](const GlobalValue &GV) { + for (size_t i=0; i<len; i++) { + if (GV.getName() == symbols[i]) { + return true; + } + } + return false; + }; + + passes.add(llvm::createInternalizePass(PreserveFunctions)); +#endif + passes.run(*unwrap(M)); } @@ -448,3 +583,10 @@ extern "C" LLVMTargetDataRef LLVMRustGetModuleDataLayout(LLVMModuleRef M) { return wrap(&unwrap(M)->getDataLayout()); } + +extern "C" void +LLVMRustSetModulePIELevel(LLVMModuleRef M) { +#if LLVM_VERSION_MINOR >= 9 + unwrap(M)->setPIELevel(PIELevel::Level::Large); +#endif +} diff --git a/src/rustllvm/README b/src/rustllvm/README index c0db3f68a76..e1c6dd07d2b 100644 --- a/src/rustllvm/README +++ b/src/rustllvm/README @@ -1,2 +1,16 @@ This directory currently contains some LLVM support code. This will generally be sent upstream to LLVM in time; for now it lives here. + +NOTE: the LLVM C++ ABI is subject to between-version breakage and must *never* +be exposed to Rust. To allow for easy auditing of that, all Rust-exposed types +must be typedef-ed as "LLVMXyz", or "LLVMRustXyz" if they were defined here. + +Functions that return a failure status and leave the error in +the LLVM last error should return an LLVMRustResult rather than an +int or anything to avoid confusion. + +When translating enums, add a single `Other` variant as the first +one to allow for new variants to be added. It should abort when used +as an input. + +All other types must not be typedef-ed as such. diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index fadd95c9a72..0da25e7ac57 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -13,6 +13,7 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/CallSite.h" @@ -27,6 +28,30 @@ using namespace llvm; using namespace llvm::sys; using namespace llvm::object; +// LLVMAtomicOrdering is already an enum - don't create another +// one. +static AtomicOrdering from_rust(LLVMAtomicOrdering Ordering) { + switch (Ordering) { + case LLVMAtomicOrderingNotAtomic: + return AtomicOrdering::NotAtomic; + case LLVMAtomicOrderingUnordered: + return AtomicOrdering::Unordered; + case LLVMAtomicOrderingMonotonic: + return AtomicOrdering::Monotonic; + case LLVMAtomicOrderingAcquire: + return AtomicOrdering::Acquire; + case LLVMAtomicOrderingRelease: + return AtomicOrdering::Release; + case LLVMAtomicOrderingAcquireRelease: + return AtomicOrdering::AcquireRelease; + case LLVMAtomicOrderingSequentiallyConsistent: + return AtomicOrdering::SequentiallyConsistent; + } + + llvm_unreachable("Invalid LLVMAtomicOrdering value!"); +} + + static char *LastError; extern "C" LLVMMemoryBufferRef @@ -57,49 +82,34 @@ LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) { unwrap(M)->setTargetTriple(Triple::normalize(triple)); } -extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N, - LLVMBool SignExtend) { - return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend); -} - -extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy, - unsigned N_hi, - unsigned N_lo, - LLVMBool SignExtend) { - unsigned long long N = N_hi; - N <<= 32; - N |= N_lo; - return LLVMConstInt(IntTy, N, SignExtend); -} - extern "C" void LLVMRustPrintPassTimings() { raw_fd_ostream OS (2, false); // stderr. TimerGroup::printAll(OS); } -extern "C" LLVMValueRef LLVMGetNamedValue(LLVMModuleRef M, - const char* Name) { +extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, + const char* Name) { return wrap(unwrap(M)->getNamedValue(Name)); } -extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M, - const char* Name, - LLVMTypeRef FunctionTy) { +extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M, + const char* Name, + LLVMTypeRef FunctionTy) { return wrap(unwrap(M)->getOrInsertFunction(Name, unwrap<FunctionType>(FunctionTy))); } -extern "C" LLVMValueRef LLVMGetOrInsertGlobal(LLVMModuleRef M, - const char* Name, - LLVMTypeRef Ty) { +extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M, + const char* Name, + LLVMTypeRef Ty) { return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty))); } -extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) { +extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) { return wrap(Type::getMetadataTy(*unwrap(C))); } -extern "C" void LLVMAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) { +extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) { CallSite Call = CallSite(unwrap<Instruction>(Instr)); AttrBuilder B; B.addRawValue(Val); @@ -110,7 +120,10 @@ extern "C" void LLVMAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uin } -extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned idx, uint64_t b) { +extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr, + unsigned idx, + uint64_t b) +{ CallSite Call = CallSite(unwrap<Instruction>(Instr)); AttrBuilder B; B.addDereferenceableAttr(b); @@ -120,38 +133,50 @@ extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned idx, B))); } -extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index, - uint64_t Val) { +extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, + unsigned index, + uint64_t Val) +{ Function *A = unwrap<Function>(Fn); AttrBuilder B; B.addRawValue(Val); A->addAttributes(index, AttributeSet::get(A->getContext(), index, B)); } -extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef Fn, unsigned index, uint64_t bytes) { +extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, + unsigned index, + uint64_t bytes) +{ Function *A = unwrap<Function>(Fn); AttrBuilder B; B.addDereferenceableAttr(bytes); A->addAttributes(index, AttributeSet::get(A->getContext(), index, B)); } -extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn, unsigned index, const char *Name) { +extern "C" void LLVMRustAddFunctionAttrString(LLVMValueRef Fn, + unsigned index, + const char *Name) +{ Function *F = unwrap<Function>(Fn); AttrBuilder B; B.addAttribute(Name); F->addAttributes(index, AttributeSet::get(F->getContext(), index, B)); } -extern "C" void LLVMAddFunctionAttrStringValue(LLVMValueRef Fn, unsigned index, - const char *Name, - const char *Value) { +extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn, + unsigned index, + const char *Name, + const char *Value) { Function *F = unwrap<Function>(Fn); AttrBuilder B; B.addAttribute(Name, Value); F->addAttributes(index, AttributeSet::get(F->getContext(), index, B)); } -extern "C" void LLVMRemoveFunctionAttributes(LLVMValueRef Fn, unsigned index, uint64_t Val) { +extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn, + unsigned index, + uint64_t Val) +{ Function *A = unwrap<Function>(Fn); const AttributeSet PAL = A->getAttributes(); AttrBuilder B(Val); @@ -161,7 +186,10 @@ extern "C" void LLVMRemoveFunctionAttributes(LLVMValueRef Fn, unsigned index, ui A->setAttributes(PALnew); } -extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, unsigned index, const char *Name) { +extern "C" void LLVMRustRemoveFunctionAttrString(LLVMValueRef fn, + unsigned index, + const char *Name) +{ Function *f = unwrap<Function>(fn); LLVMContext &C = f->getContext(); AttrBuilder B; @@ -181,80 +209,122 @@ extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) { } } -extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B, - LLVMValueRef source, - const char* Name, - AtomicOrdering order, - unsigned alignment) { +extern "C" LLVMValueRef LLVMRustBuildAtomicLoad(LLVMBuilderRef B, + LLVMValueRef source, + const char* Name, + LLVMAtomicOrdering order, + unsigned alignment) { LoadInst* li = new LoadInst(unwrap(source),0); - li->setAtomic(order); + li->setAtomic(from_rust(order)); li->setAlignment(alignment); return wrap(unwrap(B)->Insert(li, Name)); } -extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B, - LLVMValueRef val, - LLVMValueRef target, - AtomicOrdering order, - unsigned alignment) { +extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B, + LLVMValueRef val, + LLVMValueRef target, + LLVMAtomicOrdering order, + unsigned alignment) { StoreInst* si = new StoreInst(unwrap(val),unwrap(target)); - si->setAtomic(order); + si->setAtomic(from_rust(order)); si->setAlignment(alignment); return wrap(unwrap(B)->Insert(si)); } -extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, +extern "C" LLVMValueRef LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef target, LLVMValueRef old, LLVMValueRef source, - AtomicOrdering order, - AtomicOrdering failure_order, + LLVMAtomicOrdering order, + LLVMAtomicOrdering failure_order, LLVMBool weak) { - AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg(unwrap(target), - unwrap(old), - unwrap(source), - order, - failure_order); + AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg( + unwrap(target), + unwrap(old), + unwrap(source), + from_rust(order), + from_rust(failure_order)); acxi->setWeak(weak); return wrap(acxi); } -extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, - AtomicOrdering order, - SynchronizationScope scope) { - return wrap(unwrap(B)->CreateFence(order, scope)); + +enum class LLVMRustSynchronizationScope { + Other, + SingleThread, + CrossThread, +}; + +static SynchronizationScope +from_rust(LLVMRustSynchronizationScope scope) +{ + switch (scope) { + case LLVMRustSynchronizationScope::SingleThread: + return SingleThread; + case LLVMRustSynchronizationScope::CrossThread: + return CrossThread; + default: + llvm_unreachable("bad SynchronizationScope."); + } } -extern "C" void LLVMSetDebug(int Enabled) { +extern "C" LLVMValueRef LLVMRustBuildAtomicFence( + LLVMBuilderRef B, + LLVMAtomicOrdering order, + LLVMRustSynchronizationScope scope) +{ + return wrap(unwrap(B)->CreateFence(from_rust(order), from_rust(scope))); +} + +extern "C" void LLVMRustSetDebug(int Enabled) { #ifndef NDEBUG DebugFlag = Enabled; #endif } -extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty, - char *AsmString, - char *Constraints, - LLVMBool HasSideEffects, - LLVMBool IsAlignStack, - unsigned Dialect) { +enum class LLVMRustAsmDialect { + Other, + Att, + Intel, +}; + +static InlineAsm::AsmDialect +from_rust(LLVMRustAsmDialect dialect) +{ + switch (dialect) { + case LLVMRustAsmDialect::Att: + return InlineAsm::AD_ATT; + case LLVMRustAsmDialect::Intel: + return InlineAsm::AD_Intel; + default: + llvm_unreachable("bad AsmDialect."); + } +} + +extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty, + char *AsmString, + char *Constraints, + LLVMBool HasSideEffects, + LLVMBool IsAlignStack, + LLVMRustAsmDialect Dialect) { return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString, Constraints, HasSideEffects, - IsAlignStack, (InlineAsm::AsmDialect) Dialect)); + IsAlignStack, from_rust(Dialect))); } -typedef DIBuilder* DIBuilderRef; +typedef DIBuilder* LLVMRustDIBuilderRef; -typedef struct LLVMOpaqueMetadata *LLVMMetadataRef; +typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef; namespace llvm { -DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef) +DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef) -inline Metadata **unwrap(LLVMMetadataRef *Vals) { +inline Metadata **unwrap(LLVMRustMetadataRef *Vals) { return reinterpret_cast<Metadata**>(Vals); } } template<typename DIT> -DIT* unwrapDIptr(LLVMMetadataRef ref) { +DIT* unwrapDIptr(LLVMRustMetadataRef ref) { return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL); } @@ -266,11 +336,11 @@ extern "C" uint32_t LLVMRustDebugMetadataVersion() { return DEBUG_METADATA_VERSION; } -extern "C" uint32_t LLVMVersionMinor() { +extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; } -extern "C" uint32_t LLVMVersionMajor() { +extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; } @@ -280,20 +350,20 @@ extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, unwrap(M)->addModuleFlag(Module::Warning, name, value); } -extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) { +extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) { return new DIBuilder(*unwrap(M)); } -extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) { +extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) { delete Builder; } -extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) { +extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) { Builder->finalize(); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit( - DIBuilderRef Builder, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit( + LLVMRustDIBuilderRef Builder, unsigned Lang, const char* File, const char* Dir, @@ -312,17 +382,17 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit( SplitName)); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateFile( - DIBuilderRef Builder, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFile( + LLVMRustDIBuilderRef Builder, const char* Filename, const char* Directory) { return wrap(Builder->createFile(Filename, Directory)); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType( - DIBuilderRef Builder, - LLVMMetadataRef File, - LLVMMetadataRef ParameterTypes) { +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateSubroutineType( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef File, + LLVMRustMetadataRef ParameterTypes) { return wrap(Builder->createSubroutineType( #if LLVM_VERSION_MINOR == 7 unwrapDI<DIFile>(File), @@ -330,22 +400,22 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType( DITypeRefArray(unwrap<MDTuple>(ParameterTypes)))); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction( - DIBuilderRef Builder, - LLVMMetadataRef Scope, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef Scope, const char* Name, const char* LinkageName, - LLVMMetadataRef File, + LLVMRustMetadataRef File, unsigned LineNo, - LLVMMetadataRef Ty, + LLVMRustMetadataRef Ty, bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized, LLVMValueRef Fn, - LLVMMetadataRef TParam, - LLVMMetadataRef Decl) { + LLVMRustMetadataRef TParam, + LLVMRustMetadataRef Decl) { #if LLVM_VERSION_MINOR >= 8 DITemplateParameterArray TParams = DITemplateParameterArray(unwrap<MDTuple>(TParam)); @@ -370,8 +440,8 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction( #endif } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType( - DIBuilderRef Builder, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateBasicType( + LLVMRustDIBuilderRef Builder, const char* Name, uint64_t SizeInBits, uint64_t AlignInBits, @@ -381,9 +451,9 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType( AlignInBits, Encoding)); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType( - DIBuilderRef Builder, - LLVMMetadataRef PointeeTy, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef PointeeTy, uint64_t SizeInBits, uint64_t AlignInBits, const char* Name) { @@ -391,19 +461,19 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType( unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name)); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType( - DIBuilderRef Builder, - LLVMMetadataRef Scope, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef Scope, const char* Name, - LLVMMetadataRef File, + LLVMRustMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, - LLVMMetadataRef DerivedFrom, - LLVMMetadataRef Elements, + LLVMRustMetadataRef DerivedFrom, + LLVMRustMetadataRef Elements, unsigned RunTimeLang, - LLVMMetadataRef VTableHolder, + LLVMRustMetadataRef VTableHolder, const char *UniqueId) { return wrap(Builder->createStructType( unwrapDI<DIDescriptor>(Scope), @@ -421,17 +491,17 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType( )); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType( - DIBuilderRef Builder, - LLVMMetadataRef Scope, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef Scope, const char* Name, - LLVMMetadataRef File, + LLVMRustMetadataRef File, unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, - LLVMMetadataRef Ty) { + LLVMRustMetadataRef Ty) { return wrap(Builder->createMemberType( unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNo, @@ -439,10 +509,10 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType( unwrapDI<DIType>(Ty))); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock( - DIBuilderRef Builder, - LLVMMetadataRef Scope, - LLVMMetadataRef File, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef Scope, + LLVMRustMetadataRef File, unsigned Line, unsigned Col) { return wrap(Builder->createLexicalBlock( @@ -451,17 +521,17 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock( )); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable( - DIBuilderRef Builder, - LLVMMetadataRef Context, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef Context, const char* Name, const char* LinkageName, - LLVMMetadataRef File, + LLVMRustMetadataRef File, unsigned LineNo, - LLVMMetadataRef Ty, + LLVMRustMetadataRef Ty, bool isLocalToUnit, LLVMValueRef Val, - LLVMMetadataRef Decl = NULL) { + LLVMRustMetadataRef Decl = NULL) { return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context), Name, LinkageName, @@ -473,14 +543,14 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable( unwrapDIptr<MDNode>(Decl))); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable( - DIBuilderRef Builder, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable( + LLVMRustDIBuilderRef Builder, unsigned Tag, - LLVMMetadataRef Scope, + LLVMRustMetadataRef Scope, const char* Name, - LLVMMetadataRef File, + LLVMRustMetadataRef File, unsigned LineNo, - LLVMMetadataRef Ty, + LLVMRustMetadataRef Ty, bool AlwaysPreserve, unsigned Flags, int64_t* AddrOps, @@ -509,50 +579,50 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable( #endif } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateArrayType( - DIBuilderRef Builder, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateArrayType( + LLVMRustDIBuilderRef Builder, uint64_t Size, uint64_t AlignInBits, - LLVMMetadataRef Ty, - LLVMMetadataRef Subscripts) { + LLVMRustMetadataRef Ty, + LLVMRustMetadataRef Subscripts) { return wrap(Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty), DINodeArray(unwrapDI<MDTuple>(Subscripts)) )); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType( - DIBuilderRef Builder, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVectorType( + LLVMRustDIBuilderRef Builder, uint64_t Size, uint64_t AlignInBits, - LLVMMetadataRef Ty, - LLVMMetadataRef Subscripts) { + LLVMRustMetadataRef Ty, + LLVMRustMetadataRef Subscripts) { return wrap(Builder->createVectorType(Size, AlignInBits, unwrapDI<DIType>(Ty), DINodeArray(unwrapDI<MDTuple>(Subscripts)) )); } -extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange( - DIBuilderRef Builder, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateSubrange( + LLVMRustDIBuilderRef Builder, int64_t Lo, int64_t Count) { return wrap(Builder->getOrCreateSubrange(Lo, Count)); } -extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray( - DIBuilderRef Builder, - LLVMMetadataRef* Ptr, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateArray( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef* Ptr, unsigned Count) { Metadata **DataValue = unwrap(Ptr); return wrap(Builder->getOrCreateArray( ArrayRef<Metadata*>(DataValue, Count)).get()); } -extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd( - DIBuilderRef Builder, +extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd( + LLVMRustDIBuilderRef Builder, LLVMValueRef Val, - LLVMMetadataRef VarInfo, + LLVMRustMetadataRef VarInfo, int64_t* AddrOps, unsigned AddrOpsCount, LLVMValueRef DL, @@ -566,10 +636,10 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd( unwrap(InsertAtEnd))); } -extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore( - DIBuilderRef Builder, +extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareBefore( + LLVMRustDIBuilderRef Builder, LLVMValueRef Val, - LLVMMetadataRef VarInfo, + LLVMRustMetadataRef VarInfo, int64_t* AddrOps, unsigned AddrOpsCount, LLVMValueRef DL, @@ -583,24 +653,24 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore( unwrap<Instruction>(InsertBefore))); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerator( - DIBuilderRef Builder, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerator( + LLVMRustDIBuilderRef Builder, const char* Name, uint64_t Val) { return wrap(Builder->createEnumerator(Name, Val)); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType( - DIBuilderRef Builder, - LLVMMetadataRef Scope, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef Scope, const char* Name, - LLVMMetadataRef File, + LLVMRustMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, - LLVMMetadataRef Elements, - LLVMMetadataRef ClassType) + LLVMRustMetadataRef Elements, + LLVMRustMetadataRef ClassType) { return wrap(Builder->createEnumerationType( unwrapDI<DIDescriptor>(Scope), @@ -613,16 +683,16 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType( unwrapDI<DIType>(ClassType))); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType( - DIBuilderRef Builder, - LLVMMetadataRef Scope, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef Scope, const char* Name, - LLVMMetadataRef File, + LLVMRustMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, - LLVMMetadataRef Elements, + LLVMRustMetadataRef Elements, unsigned RunTimeLang, const char* UniqueId) { @@ -640,12 +710,12 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType( )); } -extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter( - DIBuilderRef Builder, - LLVMMetadataRef Scope, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef Scope, const char* Name, - LLVMMetadataRef Ty, - LLVMMetadataRef File, + LLVMRustMetadataRef Ty, + LLVMRustMetadataRef File, unsigned LineNo, unsigned ColumnNo) { @@ -656,21 +726,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter( )); } -extern "C" int64_t LLVMDIBuilderCreateOpDeref() -{ - return dwarf::DW_OP_deref; -} - -extern "C" int64_t LLVMDIBuilderCreateOpPlus() -{ - return dwarf::DW_OP_plus; -} - -extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace( - DIBuilderRef Builder, - LLVMMetadataRef Scope, +extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef Scope, const char* Name, - LLVMMetadataRef File, + LLVMRustMetadataRef File, unsigned LineNo) { return wrap(Builder->createNameSpace( @@ -680,22 +740,22 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace( LineNo)); } -extern "C" void LLVMDICompositeTypeSetTypeArray( - DIBuilderRef Builder, - LLVMMetadataRef CompositeType, - LLVMMetadataRef TypeArray) +extern "C" void LLVMRustDICompositeTypeSetTypeArray( + LLVMRustDIBuilderRef Builder, + LLVMRustMetadataRef CompositeType, + LLVMRustMetadataRef TypeArray) { DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType); Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray))); } -extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation( +extern "C" LLVMValueRef LLVMRustDIBuilderCreateDebugLocation( LLVMContextRef Context, unsigned Line, unsigned Column, - LLVMMetadataRef Scope, - LLVMMetadataRef InlinedAt) { - + LLVMRustMetadataRef Scope, + LLVMRustMetadataRef InlinedAt) +{ LLVMContext& context = *unwrap(Context); DebugLoc debug_loc = DebugLoc::get(Line, @@ -706,12 +766,22 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation( return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode())); } -extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) { +extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() +{ + return dwarf::DW_OP_deref; +} + +extern "C" int64_t LLVMRustDIBuilderCreateOpPlus() +{ + return dwarf::DW_OP_plus; +} + +extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type, RustStringRef str) { raw_rust_string_ostream os(str); unwrap<llvm::Type>(Type)->print(os); } -extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) { +extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str) { raw_rust_string_ostream os(str); os << "("; unwrap<llvm::Value>(Value)->getType()->print(os); @@ -746,13 +816,6 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) { return true; } -extern "C" void -LLVMRustSetDLLStorageClass(LLVMValueRef Value, - GlobalValue::DLLStorageClassTypes Class) { - GlobalValue *V = unwrap<GlobalValue>(Value); - V->setDLLStorageClass(Class); -} - // Note that the two following functions look quite similar to the // LLVMGetSectionName function. Sadly, it appears that this function only // returns a char* pointer, which isn't guaranteed to be null-terminated. The @@ -768,7 +831,7 @@ inline section_iterator *unwrap(LLVMSectionIteratorRef SI) { return reinterpret_cast<section_iterator*>(SI); } -extern "C" int +extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) { StringRef ret; if (std::error_code ec = (*unwrap(SI))->getName(ret)) @@ -787,13 +850,13 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef) extern "C" void -LLVMWriteTwineToString(LLVMTwineRef T, RustStringRef str) { +LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) { raw_rust_string_ostream os(str); unwrap(T)->print(os); } extern "C" void -LLVMUnpackOptimizationDiagnostic( +LLVMRustUnpackOptimizationDiagnostic( LLVMDiagnosticInfoRef di, const char **pass_name_out, LLVMValueRef *function_out, @@ -811,7 +874,7 @@ LLVMUnpackOptimizationDiagnostic( } extern "C" void -LLVMUnpackInlineAsmDiagnostic( +LLVMRustUnpackInlineAsmDiagnostic( LLVMDiagnosticInfoRef di, unsigned *cookie_out, LLVMTwineRef *message_out, @@ -826,17 +889,111 @@ LLVMUnpackInlineAsmDiagnostic( *instruction_out = wrap(ia->getInstruction()); } -extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) { +extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) { raw_rust_string_ostream os(str); DiagnosticPrinterRawOStream dp(os); unwrap(di)->print(dp); } -extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di) { - return unwrap(di)->getKind(); +enum class LLVMRustDiagnosticKind { + Other, + InlineAsm, + StackSize, + DebugMetadataVersion, + SampleProfile, + OptimizationRemark, + OptimizationRemarkMissed, + OptimizationRemarkAnalysis, + OptimizationRemarkAnalysisFPCommute, + OptimizationRemarkAnalysisAliasing, + OptimizationRemarkOther, + OptimizationFailure, +}; + +static LLVMRustDiagnosticKind +to_rust(DiagnosticKind kind) +{ + switch (kind) { + case DK_InlineAsm: + return LLVMRustDiagnosticKind::InlineAsm; + case DK_StackSize: + return LLVMRustDiagnosticKind::StackSize; + case DK_DebugMetadataVersion: + return LLVMRustDiagnosticKind::DebugMetadataVersion; + case DK_SampleProfile: + return LLVMRustDiagnosticKind::SampleProfile; + case DK_OptimizationRemark: + return LLVMRustDiagnosticKind::OptimizationRemark; + case DK_OptimizationRemarkMissed: + return LLVMRustDiagnosticKind::OptimizationRemarkMissed; + case DK_OptimizationRemarkAnalysis: + return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis; +#if LLVM_VERSION_MINOR >= 8 + case DK_OptimizationRemarkAnalysisFPCommute: + return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute; + case DK_OptimizationRemarkAnalysisAliasing: + return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing; +#endif + default: +#if LLVM_VERSION_MINOR >= 9 + return (kind >= DK_FirstRemark && kind <= DK_LastRemark) ? + LLVMRustDiagnosticKind::OptimizationRemarkOther : + LLVMRustDiagnosticKind::Other; +#else + return LLVMRustDiagnosticKind::Other; +#endif + } +} + +extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) { + return to_rust((DiagnosticKind) unwrap(di)->getKind()); +} +// This is kept distinct from LLVMGetTypeKind, because when +// a new type kind is added, the Rust-side enum must be +// updated or UB will result. +extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) { + switch (unwrap(Ty)->getTypeID()) { + case Type::VoidTyID: + return LLVMVoidTypeKind; + case Type::HalfTyID: + return LLVMHalfTypeKind; + case Type::FloatTyID: + return LLVMFloatTypeKind; + case Type::DoubleTyID: + return LLVMDoubleTypeKind; + case Type::X86_FP80TyID: + return LLVMX86_FP80TypeKind; + case Type::FP128TyID: + return LLVMFP128TypeKind; + case Type::PPC_FP128TyID: + return LLVMPPC_FP128TypeKind; + case Type::LabelTyID: + return LLVMLabelTypeKind; + case Type::MetadataTyID: + return LLVMMetadataTypeKind; + case Type::IntegerTyID: + return LLVMIntegerTypeKind; + case Type::FunctionTyID: + return LLVMFunctionTypeKind; + case Type::StructTyID: + return LLVMStructTypeKind; + case Type::ArrayTyID: + return LLVMArrayTypeKind; + case Type::PointerTyID: + return LLVMPointerTypeKind; + case Type::VectorTyID: + return LLVMVectorTypeKind; + case Type::X86_MMXTyID: + return LLVMX86_MMXTypeKind; +#if LLVM_VERSION_MINOR >= 8 + case Type::TokenTyID: + return LLVMTokenTypeKind; +#endif + } + llvm_unreachable("Unhandled TypeID."); } -extern "C" void LLVMWriteDebugLocToString( +extern "C" void LLVMRustWriteDebugLocToString( LLVMContextRef C, LLVMDebugLocRef dl, RustStringRef str) @@ -847,7 +1004,7 @@ extern "C" void LLVMWriteDebugLocToString( DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef) -extern "C" void LLVMSetInlineAsmDiagnosticHandler( +extern "C" void LLVMRustSetInlineAsmDiagnosticHandler( LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) @@ -855,7 +1012,8 @@ extern "C" void LLVMSetInlineAsmDiagnosticHandler( unwrap(C)->setInlineAsmDiagnosticHandler(H, CX); } -extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) { +extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, + RustStringRef str) { raw_rust_string_ostream os(str); unwrap(d)->print("", os); } diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 1953fc5a6b4..e871763a48d 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2016-06-23 +2016-07-25b diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 2a47e8b0895..5aae11fb456 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -58,6 +58,11 @@ void LLVMRustSetLastError(const char*); +enum class LLVMRustResult { + Success, + Failure +}; + typedef struct OpaqueRustString *RustStringRef; typedef struct LLVMOpaqueTwine *LLVMTwineRef; typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef; |
