diff --git a/deps/Makefile b/deps/Makefile index 4de02e420d9e8..813689c21129f 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -671,6 +671,11 @@ $(eval $(call LLVM_PATCH,win64-int128.llvm-3.3)) else ifeq ($(LLVM_VER),3.6.0) $(eval $(call LLVM_PATCH,zerosign-llvm-3.6.0)) $(eval $(call LLVM_PATCH,win64-allocas-llvm-3.6.0)) +else ifeq ($(LLVM_VER),3.7.0) +$(eval $(call LLVM_PATCH,llvm-3.7.0)) +$(eval $(call LLVM_PATCH,llvm-3.7.1)) +else ifeq ($(LLVM_VER),3.7.1) +$(eval $(call LLVM_PATCH,llvm-3.7.1)) endif # LLVM_VER LLVM_BUILDDIR_withtype := $(LLVM_BUILD_DIR)/build_$(LLVM_BUILDTYPE) diff --git a/deps/checksums/cfe-3.7.0.src.tar.xz/md5 b/deps/checksums/cfe-3.7.0.src.tar.xz/md5 new file mode 100644 index 0000000000000..05e1a3361ab84 --- /dev/null +++ b/deps/checksums/cfe-3.7.0.src.tar.xz/md5 @@ -0,0 +1 @@ +8f9d27335e7331cf0a4711e952f21f01 diff --git a/deps/checksums/cfe-3.7.0.src.tar.xz/sha512 b/deps/checksums/cfe-3.7.0.src.tar.xz/sha512 new file mode 100644 index 0000000000000..3f84b7f3fa035 --- /dev/null +++ b/deps/checksums/cfe-3.7.0.src.tar.xz/sha512 @@ -0,0 +1 @@ +099d34cb019ea548c6ee85efd22b150beba0aa92061394fa3e423b1ebfe4a5c98c0586e5d56fc5c39e2b1606d36db59f442c056cc59473e32df76c8790c9d0ae diff --git a/deps/checksums/compiler-rt-3.7.0.src.tar.xz/md5 b/deps/checksums/compiler-rt-3.7.0.src.tar.xz/md5 new file mode 100644 index 0000000000000..72f9deb233c60 --- /dev/null +++ b/deps/checksums/compiler-rt-3.7.0.src.tar.xz/md5 @@ -0,0 +1 @@ +383c10affd513026f08936b5525523f5 diff --git a/deps/checksums/compiler-rt-3.7.0.src.tar.xz/sha512 b/deps/checksums/compiler-rt-3.7.0.src.tar.xz/sha512 new file mode 100644 index 0000000000000..bc0b953409998 --- /dev/null +++ b/deps/checksums/compiler-rt-3.7.0.src.tar.xz/sha512 @@ -0,0 +1 @@ +2ba6abb3d6ec7f1469cfe1d48fde2069e9a767d19144f80f05516ac63f353ace90a9df3e9d1c1f708f3c397aba0ec61b12e4f105b25a2e1cd26b25b0dd252bc9 diff --git a/deps/checksums/lldb-3.7.0.src.tar.xz/md5 b/deps/checksums/lldb-3.7.0.src.tar.xz/md5 new file mode 100644 index 0000000000000..169bc27601afb --- /dev/null +++ b/deps/checksums/lldb-3.7.0.src.tar.xz/md5 @@ -0,0 +1 @@ +e5931740400d1dc3e7db4c7ba2ceff68 diff --git a/deps/checksums/lldb-3.7.0.src.tar.xz/sha512 b/deps/checksums/lldb-3.7.0.src.tar.xz/sha512 new file mode 100644 index 0000000000000..74bb25ddf19ef --- /dev/null +++ b/deps/checksums/lldb-3.7.0.src.tar.xz/sha512 @@ -0,0 +1 @@ +52157782ef13e2c8b7b35ff3ccc05887195fe46ddb6bafcf0707a3c46c1e034734b55342b8dbfc46cae7a8c3cb1012345284e4bedb2344c5016b8d19a12e90df diff --git a/deps/llvm-3.7.0.patch b/deps/llvm-3.7.0.patch new file mode 100644 index 0000000000000..6ae438393a22a --- /dev/null +++ b/deps/llvm-3.7.0.patch @@ -0,0 +1,29 @@ +commit 06e88db43d1ff367d03b731c9c1f4f69da78149b +Author: Keno Fischer +Date: Fri Oct 9 17:24:54 2015 +0000 + + Clear SectionSymbols in MCContext::Reset + + This was just forgotten when SectionSymbols was introduced and could cause + corruption if the MCContext was reused after Reset. + + Reviewers: rafael + + Subscribers: llvm-commits + + Differential Revision: http://reviews.llvm.org/D13547 + + git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249854 91177308-0d34-0410-b5e6-96231b3b80d8 + +diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp +index ff195d0..2160b4e 100644 +--- a/lib/MC/MCContext.cpp ++++ b/lib/MC/MCContext.cpp +@@ -80,6 +80,7 @@ void MCContext::reset() { + + UsedNames.clear(); + Symbols.clear(); ++ SectionSymbols.clear(); + Allocator.Reset(); + Instances.clear(); + CompilationDir.clear(); diff --git a/deps/llvm-3.7.1.patch b/deps/llvm-3.7.1.patch new file mode 100644 index 0000000000000..2291b72a5a71e --- /dev/null +++ b/deps/llvm-3.7.1.patch @@ -0,0 +1,550 @@ +diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h +index 0b0dcb0..7bb96eb 100644 +--- a/include/llvm/ExecutionEngine/SectionMemoryManager.h ++++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h +@@ -83,10 +83,28 @@ public: + virtual void invalidateInstructionCache(); + + private: ++ struct FreeMemBlock { ++ // The actual block of free memory ++ sys::MemoryBlock Free; ++ // If there is a pending allocation from the same reservation right before ++ // this block, store it's index in PendingMem, to be able to update the ++ // pending region if part of this block is allocated, rather than having to ++ // create a new one ++ unsigned PendingPrefixIndex; ++ }; ++ + struct MemoryGroup { +- SmallVector AllocatedMem; +- SmallVector FreeMem; +- sys::MemoryBlock Near; ++ // PendingMem contains all blocks of memory (subblocks of AllocatedMem) ++ // which have not yet had their permissions applied, but have been given ++ // out to the user. FreeMem contains all block of memory, which have ++ // neither had their permissions applied, nor been given out to the user. ++ SmallVector PendingMem; ++ SmallVector FreeMem; ++ ++ // All memory blocks that have been requested from the system ++ SmallVector AllocatedMem; ++ ++ sys::MemoryBlock Near; + }; + + uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size, +@@ -103,4 +121,3 @@ private: + } + + #endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H +- +diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h +index 28e512c..686e8c8 100644 +--- a/include/llvm/Support/raw_ostream.h ++++ b/include/llvm/Support/raw_ostream.h +@@ -485,6 +485,9 @@ public: + + /// A raw_ostream that writes to an SmallVector or SmallString. This is a + /// simple adaptor class. This class does not encounter output errors. ++/// raw_svector_ostream operates without a buffer, delegating all memory ++/// management to the SmallString. Thus the SmallString is always up-to-date, ++/// may be used directly and there is no need to call flush(). + class raw_svector_ostream : public raw_pwrite_stream { + SmallVectorImpl &OS; + +@@ -493,32 +496,24 @@ class raw_svector_ostream : public raw_pwrite_stream { + + void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override; + +- /// Return the current position within the stream, not counting the bytes +- /// currently in the buffer. ++ /// Return the current position within the stream. + uint64_t current_pos() const override; + +-protected: +- // Like the regular constructor, but doesn't call init. +- explicit raw_svector_ostream(SmallVectorImpl &O, unsigned); +- void init(); +- + public: + /// Construct a new raw_svector_ostream. + /// + /// \param O The vector to write to; this should generally have at least 128 + /// bytes free to avoid any extraneous memory overhead. +- explicit raw_svector_ostream(SmallVectorImpl &O); +- ~raw_svector_ostream() override; +- ++ explicit raw_svector_ostream(SmallVectorImpl &O) : OS(O) { ++ SetUnbuffered(); ++ } ++ ~raw_svector_ostream() override {} + +- /// This is called when the SmallVector we're appending to is changed outside +- /// of the raw_svector_ostream's control. It is only safe to do this if the +- /// raw_svector_ostream has previously been flushed. +- void resync(); ++ // FIXME: resync is no-op. Remove it and its users. ++ void resync() {} + +- /// Flushes the stream contents to the target vector and return a StringRef +- /// for the vector contents. +- StringRef str(); ++ /// Return a StringRef for the vector contents. ++ StringRef str() { return StringRef(OS.data(), OS.size()); } + }; + + /// A raw_ostream that discards all output. +@@ -541,9 +536,7 @@ class buffer_ostream : public raw_svector_ostream { + SmallVector Buffer; + + public: +- buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer, 0), OS(OS) { +- init(); +- } ++ buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer), OS(OS) {} + ~buffer_ostream() { OS << str(); } + }; + +diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp +index 6a20624..53a9ea7 100644 +--- a/lib/CodeGen/MachineModuleInfo.cpp ++++ b/lib/CodeGen/MachineModuleInfo.cpp +@@ -227,6 +227,7 @@ bool MachineModuleInfo::doFinalization(Module &M) { + AddrLabelSymbols = nullptr; + + Context.reset(); ++ FuncInfoMap.clear(); + + delete ObjFileMMI; + ObjFileMMI = nullptr; +diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +index 93287a3..93bbd6f 100644 +--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp ++++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +@@ -85,20 +85,25 @@ void RuntimeDyldImpl::resolveRelocations() { + // First, resolve relocations associated with external symbols. + resolveExternalSymbols(); + +- // Just iterate over the sections we have and resolve all the relocations +- // in them. Gross overkill, but it gets the job done. +- for (int i = 0, e = Sections.size(); i != e; ++i) { ++ // Iterate over all outstanding relocations ++ for (auto it = Relocations.begin(), e = Relocations.end(); it != e; ++it) { + // The Section here (Sections[i]) refers to the section in which the + // symbol for the relocation is located. The SectionID in the relocation + // entry provides the section to which the relocation will be applied. +- uint64_t Addr = Sections[i].LoadAddress; +- DEBUG(dbgs() << "Resolving relocations Section #" << i << "\t" ++ int Idx = it->first; ++ uint64_t Addr = Sections[Idx].LoadAddress; ++ DEBUG(dbgs() << "Resolving relocations Section #" << Idx << "\t" + << format("%p", (uintptr_t)Addr) << "\n"); +- DEBUG(dumpSectionMemory(Sections[i], "before relocations")); +- resolveRelocationList(Relocations[i], Addr); +- DEBUG(dumpSectionMemory(Sections[i], "after relocations")); +- Relocations.erase(i); ++ resolveRelocationList(it->second, Addr); + } ++ Relocations.clear(); ++ ++ // Print out sections after relocation. ++ DEBUG( ++ for (int i = 0, e = Sections.size(); i != e; ++i) ++ dumpSectionMemory(Sections[i], "after relocations"); ++ ); ++ + } + + void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress, +diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +index e085a92..cc12093 100644 +--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h ++++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +@@ -30,6 +30,7 @@ + #include "llvm/Support/SwapByteOrder.h" + #include "llvm/Support/raw_ostream.h" + #include ++#include + #include + + using namespace llvm; +@@ -224,7 +225,7 @@ protected: + // Relocations to sections already loaded. Indexed by SectionID which is the + // source of the address. The target where the address will be written is + // SectionID/Offset in the relocation itself. +- DenseMap Relocations; ++ std::unordered_map Relocations; + + // Relocations to external symbols that are not yet resolved. Symbols are + // external when they aren't found in the global symbol table of all loaded +diff --git a/lib/ExecutionEngine/SectionMemoryManager.cpp b/lib/ExecutionEngine/SectionMemoryManager.cpp +index 5986084..e2f2208 100644 +--- a/lib/ExecutionEngine/SectionMemoryManager.cpp ++++ b/lib/ExecutionEngine/SectionMemoryManager.cpp +@@ -15,6 +15,7 @@ + #include "llvm/Config/config.h" + #include "llvm/ExecutionEngine/SectionMemoryManager.h" + #include "llvm/Support/MathExtras.h" ++#include "llvm/Support/Process.h" + + namespace llvm { + +@@ -48,16 +49,27 @@ uint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup, + + // Look in the list of free memory regions and use a block there if one + // is available. +- for (int i = 0, e = MemGroup.FreeMem.size(); i != e; ++i) { +- sys::MemoryBlock &MB = MemGroup.FreeMem[i]; +- if (MB.size() >= RequiredSize) { +- Addr = (uintptr_t)MB.base(); +- uintptr_t EndOfBlock = Addr + MB.size(); ++ for (FreeMemBlock &FreeMB : MemGroup.FreeMem) { ++ if (FreeMB.Free.size() >= RequiredSize) { ++ Addr = (uintptr_t)FreeMB.Free.base(); ++ uintptr_t EndOfBlock = Addr + FreeMB.Free.size(); + // Align the address. + Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); +- // Store cutted free memory block. +- MemGroup.FreeMem[i] = sys::MemoryBlock((void*)(Addr + Size), +- EndOfBlock - Addr - Size); ++ ++ if (FreeMB.PendingPrefixIndex == (unsigned)-1) { ++ // The part of the block we're giving out to the user is now pending ++ MemGroup.PendingMem.push_back(sys::MemoryBlock((void *)Addr, Size)); ++ ++ // Remember this pending block, such that future allocations can just ++ // modify it rather than creating a new one ++ FreeMB.PendingPrefixIndex = MemGroup.PendingMem.size() - 1; ++ } else { ++ sys::MemoryBlock &PendingMB = MemGroup.PendingMem[FreeMB.PendingPrefixIndex]; ++ PendingMB = sys::MemoryBlock(PendingMB.base(), Addr + Size - (uintptr_t)PendingMB.base()); ++ } ++ ++ // Remember how much free space is now left in this block ++ FreeMB.Free = sys::MemoryBlock((void *)(Addr + Size), EndOfBlock - Addr - Size); + return (uint8_t*)Addr; + } + } +@@ -85,6 +97,7 @@ uint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup, + // Save this address as the basis for our next request + MemGroup.Near = MB; + ++ // Remember that we allocated this memory + MemGroup.AllocatedMem.push_back(MB); + Addr = (uintptr_t)MB.base(); + uintptr_t EndOfBlock = Addr + MB.size(); +@@ -92,11 +105,18 @@ uint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup, + // Align the address. + Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); + ++ // The part of the block we're giving out to the user is now pending ++ MemGroup.PendingMem.push_back(sys::MemoryBlock((void *)Addr, Size)); ++ + // The allocateMappedMemory may allocate much more memory than we need. In + // this case, we store the unused memory as a free memory block. + unsigned FreeSize = EndOfBlock-Addr-Size; +- if (FreeSize > 16) +- MemGroup.FreeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize)); ++ if (FreeSize > 16) { ++ FreeMemBlock FreeMB; ++ FreeMB.Free = sys::MemoryBlock((void*)(Addr + Size), FreeSize); ++ FreeMB.PendingPrefixIndex = (unsigned)-1; ++ MemGroup.FreeMem.push_back(FreeMB); ++ } + + // Return aligned address + return (uint8_t*)Addr; +@@ -107,9 +127,6 @@ bool SectionMemoryManager::finalizeMemory(std::string *ErrMsg) + // FIXME: Should in-progress permissions be reverted if an error occurs? + std::error_code ec; + +- // Don't allow free memory blocks to be used after setting protection flags. +- CodeMem.FreeMem.clear(); +- + // Make code memory executable. + ec = applyMemoryGroupPermissions(CodeMem, + sys::Memory::MF_READ | sys::Memory::MF_EXEC); +@@ -143,36 +160,62 @@ bool SectionMemoryManager::finalizeMemory(std::string *ErrMsg) + return false; + } + ++static sys::MemoryBlock trimBlockToPageSize(sys::MemoryBlock M) { ++ static const size_t PageSize = sys::Process::getPageSize(); ++ ++ size_t StartOverlap = ++ (PageSize - ((uintptr_t)M.base() % PageSize)) % PageSize; ++ ++ size_t TrimmedSize = M.size(); ++ TrimmedSize -= StartOverlap; ++ TrimmedSize -= TrimmedSize % PageSize; ++ ++ sys::MemoryBlock Trimmed((void *)((uintptr_t)M.base() + StartOverlap), TrimmedSize); ++ ++ assert(((uintptr_t)Trimmed.base() % PageSize) == 0); ++ assert((Trimmed.size() % PageSize) == 0); ++ assert(M.base() <= Trimmed.base() && Trimmed.size() <= M.size()); ++ ++ return Trimmed; ++} ++ ++ + std::error_code + SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup, + unsigned Permissions) { +- +- for (int i = 0, e = MemGroup.AllocatedMem.size(); i != e; ++i) { +- std::error_code ec; +- ec = +- sys::Memory::protectMappedMemory(MemGroup.AllocatedMem[i], Permissions); +- if (ec) { +- return ec; +- } ++ for (sys::MemoryBlock &MB : MemGroup.PendingMem) ++ if (std::error_code EC = sys::Memory::protectMappedMemory(MB, Permissions)) ++ return EC; ++ ++ MemGroup.PendingMem.clear(); ++ ++ // Now go through free blocks and trim any of them that don't span the entire ++ // page because one of the pending blocks may have overlapped it. ++ for (FreeMemBlock &FreeMB : MemGroup.FreeMem) { ++ FreeMB.Free = trimBlockToPageSize(FreeMB.Free); ++ // We cleared the PendingMem list, so all these pointers are now invalid ++ FreeMB.PendingPrefixIndex = (unsigned)-1; + } + ++ // Remove all blocks which are now empty ++ MemGroup.FreeMem.erase( ++ std::remove_if(MemGroup.FreeMem.begin(), MemGroup.FreeMem.end(), ++ [](FreeMemBlock &FreeMB) { return FreeMB.Free.size() == 0; }), ++ MemGroup.FreeMem.end()); ++ + return std::error_code(); + } + + void SectionMemoryManager::invalidateInstructionCache() { +- for (int i = 0, e = CodeMem.AllocatedMem.size(); i != e; ++i) +- sys::Memory::InvalidateInstructionCache(CodeMem.AllocatedMem[i].base(), +- CodeMem.AllocatedMem[i].size()); ++ for (sys::MemoryBlock &Block : CodeMem.PendingMem) ++ sys::Memory::InvalidateInstructionCache(Block.base(), Block.size()); + } + + SectionMemoryManager::~SectionMemoryManager() { +- for (unsigned i = 0, e = CodeMem.AllocatedMem.size(); i != e; ++i) +- sys::Memory::releaseMappedMemory(CodeMem.AllocatedMem[i]); +- for (unsigned i = 0, e = RWDataMem.AllocatedMem.size(); i != e; ++i) +- sys::Memory::releaseMappedMemory(RWDataMem.AllocatedMem[i]); +- for (unsigned i = 0, e = RODataMem.AllocatedMem.size(); i != e; ++i) +- sys::Memory::releaseMappedMemory(RODataMem.AllocatedMem[i]); ++ for (MemoryGroup *Group : {&CodeMem, &RWDataMem, &RODataMem}) { ++ for (sys::MemoryBlock &Block : Group->AllocatedMem) ++ sys::Memory::releaseMappedMemory(Block); ++ } + } + + } // namespace llvm +- +diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp +index 2a0a4ff..228c09f 100644 +--- a/lib/IR/Verifier.cpp ++++ b/lib/IR/Verifier.cpp +@@ -1754,6 +1754,14 @@ void Verifier::visitFunction(const Function &F) { + assert(F.hasMetadata() != MDs.empty() && "Bit out-of-sync"); + VerifyFunctionMetadata(MDs); + ++ // Check validity of the personality function ++ if (F.hasPersonalityFn()) { ++ auto *Per = dyn_cast(F.getPersonalityFn()->stripPointerCasts()); ++ if (Per) ++ Assert(Per->getParent() == F.getParent(), ++ "Referencing personality function in another module!", &F, Per); ++ } ++ + if (F.isMaterializable()) { + // Function has a body somewhere we can't see. + Assert(MDs.empty(), "unmaterialized function cannot have metadata", &F, +diff --git a/lib/Support/Unix/Memory.inc b/lib/Support/Unix/Memory.inc +index c421ee8..33beff5 100644 +--- a/lib/Support/Unix/Memory.inc ++++ b/lib/Support/Unix/Memory.inc +@@ -153,6 +153,7 @@ Memory::releaseMappedMemory(MemoryBlock &M) { + + std::error_code + Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { ++ static const size_t PageSize = Process::getPageSize(); + if (M.Address == nullptr || M.Size == 0) + return std::error_code(); + +@@ -161,7 +162,7 @@ Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { + + int Protect = getPosixProtectionFlags(Flags); + +- int Result = ::mprotect(M.Address, M.Size, Protect); ++ int Result = ::mprotect((void*)((uintptr_t)M.Address & ~(PageSize-1)), PageSize*((M.Size+PageSize-1)/PageSize), Protect); + if (Result != 0) + return std::error_code(errno, std::generic_category()); + +@@ -181,7 +182,7 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock, + std::string *ErrMsg) { + if (NumBytes == 0) return MemoryBlock(); + +- size_t PageSize = Process::getPageSize(); ++ static const size_t PageSize = Process::getPageSize(); + size_t NumPages = (NumBytes+PageSize-1)/PageSize; + + int fd = -1; +diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp +index 42f830b..3a37987 100644 +--- a/lib/Support/raw_ostream.cpp ++++ b/lib/Support/raw_ostream.cpp +@@ -755,72 +755,15 @@ void raw_string_ostream::write_impl(const char *Ptr, size_t Size) { + // raw_svector_ostream + //===----------------------------------------------------------------------===// + +-// The raw_svector_ostream implementation uses the SmallVector itself as the +-// buffer for the raw_ostream. We guarantee that the raw_ostream buffer is +-// always pointing past the end of the vector, but within the vector +-// capacity. This allows raw_ostream to write directly into the correct place, +-// and we only need to set the vector size when the data is flushed. ++uint64_t raw_svector_ostream::current_pos() const { return OS.size(); } + +-raw_svector_ostream::raw_svector_ostream(SmallVectorImpl &O, unsigned) +- : OS(O) {} +- +-raw_svector_ostream::raw_svector_ostream(SmallVectorImpl &O) : OS(O) { +- init(); +-} +- +-void raw_svector_ostream::init() { +- // Set up the initial external buffer. We make sure that the buffer has at +- // least 128 bytes free; raw_ostream itself only requires 64, but we want to +- // make sure that we don't grow the buffer unnecessarily on destruction (when +- // the data is flushed). See the FIXME below. +- OS.reserve(OS.size() + 128); +- SetBuffer(OS.end(), OS.capacity() - OS.size()); +-} +- +-raw_svector_ostream::~raw_svector_ostream() { +- // FIXME: Prevent resizing during this flush(). +- flush(); +-} ++void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { ++ OS.append(Ptr, Ptr + Size); ++}; + + void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size, + uint64_t Offset) { +- flush(); +- memcpy(OS.begin() + Offset, Ptr, Size); +-} +- +-/// resync - This is called when the SmallVector we're appending to is changed +-/// outside of the raw_svector_ostream's control. It is only safe to do this +-/// if the raw_svector_ostream has previously been flushed. +-void raw_svector_ostream::resync() { +- assert(GetNumBytesInBuffer() == 0 && "Didn't flush before mutating vector"); +- +- if (OS.capacity() - OS.size() < 64) +- OS.reserve(OS.capacity() * 2); +- SetBuffer(OS.end(), OS.capacity() - OS.size()); +-} +- +-void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { +- if (Ptr == OS.end()) { +- // Grow the buffer to include the scratch area without copying. +- size_t NewSize = OS.size() + Size; +- assert(NewSize <= OS.capacity() && "Invalid write_impl() call!"); +- OS.set_size(NewSize); +- } else { +- assert(!GetNumBytesInBuffer()); +- OS.append(Ptr, Ptr + Size); +- } +- +- OS.reserve(OS.size() + 64); +- SetBuffer(OS.end(), OS.capacity() - OS.size()); +-} +- +-uint64_t raw_svector_ostream::current_pos() const { +- return OS.size(); +-} +- +-StringRef raw_svector_ostream::str() { +- flush(); +- return StringRef(OS.begin(), OS.size()); ++ memcpy(OS.data() + Offset, Ptr, Size); + } + + //===----------------------------------------------------------------------===// +diff --git a/lib/Transforms/Scalar/Sink.cpp b/lib/Transforms/Scalar/Sink.cpp +index f49f4ea..1bdbf11 100644 +--- a/lib/Transforms/Scalar/Sink.cpp ++++ b/lib/Transforms/Scalar/Sink.cpp +@@ -169,7 +169,8 @@ static bool isSafeToMove(Instruction *Inst, AliasAnalysis *AA, + return false; + } + +- if (isa(Inst) || isa(Inst)) ++ if (isa(Inst) || isa(Inst) || ++ isa(Inst)) + return false; + + // Convergent operations can only be moved to control equivalent blocks. +diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp +index cc4d6c6..404b007 100644 +--- a/lib/Transforms/Utils/CloneFunction.cpp ++++ b/lib/Transforms/Utils/CloneFunction.cpp +@@ -96,6 +96,13 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, + NewFunc->copyAttributesFrom(OldFunc); + NewFunc->setAttributes(NewAttrs); + ++ // Fix up the personality function that got copied over. ++ if (OldFunc->hasPersonalityFn()) ++ NewFunc->setPersonalityFn( ++ MapValue(OldFunc->getPersonalityFn(), VMap, ++ ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges, ++ TypeMapper, Materializer)); ++ + AttributeSet OldAttrs = OldFunc->getAttributes(); + // Clone any argument attributes that are present in the VMap. + for (const Argument &OldArg : OldFunc->args()) +diff --git a/test/Transforms/Sink/landingpad.ll b/test/Transforms/Sink/landingpad.ll +new file mode 100644 +index 0000000..10548fd +--- /dev/null ++++ b/test/Transforms/Sink/landingpad.ll +@@ -0,0 +1,33 @@ ++; Test that we don't sink landingpads ++; RUN: opt -sink -S < %s | FileCheck %s ++ ++declare hidden void @g() ++declare void @h() ++declare i32 @__gxx_personality_v0(...) ++ ++define void @f() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { ++entry: ++ invoke void @g() ++ to label %invoke.cont.15 unwind label %lpad ++ ++invoke.cont.15: ++ unreachable ++ ++; CHECK: lpad: ++; CHECK: %0 = landingpad { i8*, i32 } ++lpad: ++ %0 = landingpad { i8*, i32 } ++ catch i8* null ++ invoke void @h() ++ to label %invoke.cont unwind label %lpad.1 ++ ++; CHECK: invoke.cont ++; CHECK-NOT: %0 = landingpad { i8*, i32 } ++invoke.cont: ++ ret void ++ ++lpad.1: ++ %1 = landingpad { i8*, i32 } ++ cleanup ++ resume { i8*, i32 } %1 ++} diff --git a/src/llvm-version.h b/src/llvm-version.h index e9c058993acc7..f03e5215d49d3 100644 --- a/src/llvm-version.h +++ b/src/llvm-version.h @@ -4,13 +4,17 @@ #if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 8 #define LLVM38 1 +#define USE_ORCJIT #endif #if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7 #define LLVM37 1 -// Experimental: -//#define USE_ORCMCJIT -//#define USE_ORCJIT + +// We enable ORCJIT only if we have our custom patches +#ifndef SYSTEM_LLVM +#define USE_ORCJIT +#endif + #endif #if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6