| OLD | NEW |
| 1 //===- NaClBitcodeReader.cpp ----------------------------------------------===// | 1 //===- NaClBitcodeReader.cpp ----------------------------------------------===// |
| 2 // Internal NaClBitcodeReader implementation | 2 // Internal NaClBitcodeReader implementation |
| 3 // | 3 // |
| 4 // The LLVM Compiler Infrastructure | 4 // The LLVM Compiler Infrastructure |
| 5 // | 5 // |
| 6 // This file is distributed under the University of Illinois Open Source | 6 // This file is distributed under the University of Illinois Open Source |
| 7 // License. See LICENSE.TXT for details. | 7 // License. See LICENSE.TXT for details. |
| 8 // | 8 // |
| 9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
| 10 | 10 |
| (...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 bool isProto = Record[2]; | 1019 bool isProto = Record[2]; |
| 1020 GlobalValue::LinkageTypes Linkage; | 1020 GlobalValue::LinkageTypes Linkage; |
| 1021 if (!naclbitc::DecodeLinkage(Record[3], Linkage)) | 1021 if (!naclbitc::DecodeLinkage(Record[3], Linkage)) |
| 1022 return Error(InvalidValue, "Unknown linkage type"); | 1022 return Error(InvalidValue, "Unknown linkage type"); |
| 1023 Func->setLinkage(Linkage); | 1023 Func->setLinkage(Linkage); |
| 1024 ValueList.push_back(Func); | 1024 ValueList.push_back(Func); |
| 1025 | 1025 |
| 1026 // If this is a function with a body, remember the prototype we are | 1026 // If this is a function with a body, remember the prototype we are |
| 1027 // creating now, so that we can match up the body with them later. | 1027 // creating now, so that we can match up the body with them later. |
| 1028 if (!isProto) { | 1028 if (!isProto) { |
| 1029 Func->setIsMaterializable(true); |
| 1029 FunctionsWithBodies.push_back(Func); | 1030 FunctionsWithBodies.push_back(Func); |
| 1030 if (LazyStreamer) DeferredFunctionInfo[Func] = 0; | 1031 if (LazyStreamer) DeferredFunctionInfo[Func] = 0; |
| 1031 } | 1032 } |
| 1032 break; | 1033 break; |
| 1033 } | 1034 } |
| 1034 } | 1035 } |
| 1035 Record.clear(); | 1036 Record.clear(); |
| 1036 } | 1037 } |
| 1037 return std::error_code(); | 1038 return std::error_code(); |
| 1038 } | 1039 } |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1724 } | 1725 } |
| 1725 return std::error_code(); | 1726 return std::error_code(); |
| 1726 } | 1727 } |
| 1727 | 1728 |
| 1728 //===----------------------------------------------------------------------===// | 1729 //===----------------------------------------------------------------------===// |
| 1729 // GVMaterializer implementation | 1730 // GVMaterializer implementation |
| 1730 //===----------------------------------------------------------------------===// | 1731 //===----------------------------------------------------------------------===// |
| 1731 | 1732 |
| 1732 void NaClBitcodeReader::releaseBuffer() { Buffer.release(); } | 1733 void NaClBitcodeReader::releaseBuffer() { Buffer.release(); } |
| 1733 | 1734 |
| 1734 bool NaClBitcodeReader::isMaterializable(const GlobalValue *GV) const { | 1735 std::error_code NaClBitcodeReader::materialize(GlobalValue *GV) { |
| 1735 if (const Function *F = dyn_cast<Function>(GV)) { | |
| 1736 return F->isDeclaration() && | |
| 1737 DeferredFunctionInfo.count(const_cast<Function*>(F)); | |
| 1738 } | |
| 1739 return false; | |
| 1740 } | |
| 1741 | |
| 1742 std::error_code NaClBitcodeReader::Materialize(GlobalValue *GV) { | |
| 1743 Function *F = dyn_cast<Function>(GV); | 1736 Function *F = dyn_cast<Function>(GV); |
| 1744 // If it's not a function or is already material, ignore the request. | 1737 // If it's not a function or is already material, ignore the request. |
| 1745 if (!F || !F->isMaterializable()) | 1738 if (!F || !F->isMaterializable()) |
| 1746 return std::error_code(); | 1739 return std::error_code(); |
| 1747 | 1740 |
| 1748 DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F); | 1741 DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F); |
| 1749 assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); | 1742 assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); |
| 1750 // If its position is recorded as 0, its body is somewhere in the stream | 1743 // If its position is recorded as 0, its body is somewhere in the stream |
| 1751 // but we haven't seen it yet. | 1744 // but we haven't seen it yet. |
| 1752 if (DFII->second == 0) { | 1745 if (DFII->second == 0) { |
| 1753 if (std::error_code EC = FindFunctionInStream(F, DFII)) { | 1746 if (std::error_code EC = FindFunctionInStream(F, DFII)) { |
| 1754 return EC; | 1747 return EC; |
| 1755 } | 1748 } |
| 1756 } | 1749 } |
| 1757 | 1750 |
| 1758 // Move the bit stream to the saved position of the deferred function body. | 1751 // Move the bit stream to the saved position of the deferred function body. |
| 1759 Stream.JumpToBit(DFII->second); | 1752 Stream.JumpToBit(DFII->second); |
| 1760 | 1753 |
| 1761 if (std::error_code EC = ParseFunctionBody(F)) | 1754 if (std::error_code EC = ParseFunctionBody(F)) |
| 1762 return EC; | 1755 return EC; |
| 1756 F->setIsMaterializable(false); |
| 1763 | 1757 |
| 1764 // Upgrade any old intrinsic calls in the function. | 1758 // Upgrade any old intrinsic calls in the function. |
| 1765 for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(), | 1759 for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(), |
| 1766 E = UpgradedIntrinsics.end(); I != E; ++I) { | 1760 E = UpgradedIntrinsics.end(); I != E; ++I) { |
| 1767 if (I->first != I->second) { | 1761 if (I->first != I->second) { |
| 1768 for (Value::use_iterator UI = I->first->use_begin(), | 1762 for (Value::use_iterator UI = I->first->use_begin(), |
| 1769 UE = I->first->use_end(); UI != UE; ) { | 1763 UE = I->first->use_end(); UI != UE; ) { |
| 1770 if (CallInst* CI = dyn_cast<CallInst>(*UI++)) | 1764 if (CallInst* CI = dyn_cast<CallInst>(*UI++)) |
| 1771 UpgradeIntrinsicCall(CI, I->second); | 1765 UpgradeIntrinsicCall(CI, I->second); |
| 1772 } | 1766 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1786 void NaClBitcodeReader::Dematerialize(GlobalValue *GV) { | 1780 void NaClBitcodeReader::Dematerialize(GlobalValue *GV) { |
| 1787 Function *F = dyn_cast<Function>(GV); | 1781 Function *F = dyn_cast<Function>(GV); |
| 1788 // If this function isn't dematerializable, this is a noop. | 1782 // If this function isn't dematerializable, this is a noop. |
| 1789 if (!F || !isDematerializable(F)) | 1783 if (!F || !isDematerializable(F)) |
| 1790 return; | 1784 return; |
| 1791 | 1785 |
| 1792 assert(DeferredFunctionInfo.count(F) && "No info to read function later?"); | 1786 assert(DeferredFunctionInfo.count(F) && "No info to read function later?"); |
| 1793 | 1787 |
| 1794 // Just forget the function body, we can remat it later. | 1788 // Just forget the function body, we can remat it later. |
| 1795 F->dropAllReferences(); | 1789 F->dropAllReferences(); |
| 1790 F->setIsMaterializable(true); |
| 1796 } | 1791 } |
| 1797 | 1792 |
| 1798 | 1793 |
| 1799 std::error_code NaClBitcodeReader::MaterializeModule(Module *M) { | 1794 std::error_code NaClBitcodeReader::MaterializeModule(Module *M) { |
| 1800 assert(M == TheModule && | 1795 assert(M == TheModule && |
| 1801 "Can only Materialize the Module this NaClBitcodeReader is attached to.
"); | 1796 "Can only Materialize the Module this NaClBitcodeReader is attached to.
"); |
| 1802 // Iterate over the module, deserializing any functions that are still on | 1797 // Iterate over the module, deserializing any functions that are still on |
| 1803 // disk. | 1798 // disk. |
| 1804 for (Module::iterator F = TheModule->begin(), E = TheModule->end(); | 1799 for (Module::iterator F = TheModule->begin(), E = TheModule->end(); |
| 1805 F != E; ++F) { | 1800 F != E; ++F) { |
| 1806 if (F->isMaterializable()) { | 1801 if (F->isMaterializable()) { |
| 1807 if (std::error_code EC = Materialize(F)) | 1802 if (std::error_code EC = materialize(F)) |
| 1808 return EC; | 1803 return EC; |
| 1809 } | 1804 } |
| 1810 } | 1805 } |
| 1811 | 1806 |
| 1812 // At this point, if there are any function bodies, the current bit is | 1807 // At this point, if there are any function bodies, the current bit is |
| 1813 // pointing to the END_BLOCK record after them. Now make sure the rest | 1808 // pointing to the END_BLOCK record after them. Now make sure the rest |
| 1814 // of the bits in the module have been read. | 1809 // of the bits in the module have been read. |
| 1815 if (NextUnreadBit) | 1810 if (NextUnreadBit) |
| 1816 ParseModule(true); | 1811 ParseModule(true); |
| 1817 | 1812 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1871 Stream.init(StreamFile.get()); | 1866 Stream.init(StreamFile.get()); |
| 1872 if (AcceptHeader()) | 1867 if (AcceptHeader()) |
| 1873 return Error(InvalidBitstream, Header.Unsupported()); | 1868 return Error(InvalidBitstream, Header.Unsupported()); |
| 1874 return std::error_code(); | 1869 return std::error_code(); |
| 1875 } | 1870 } |
| 1876 | 1871 |
| 1877 //===----------------------------------------------------------------------===// | 1872 //===----------------------------------------------------------------------===// |
| 1878 // External interface | 1873 // External interface |
| 1879 //===----------------------------------------------------------------------===// | 1874 //===----------------------------------------------------------------------===// |
| 1880 | 1875 |
| 1881 /// getNaClLazyBitcodeModule - lazy function-at-a-time loading from a file. | 1876 /// \brief Get a lazy one-at-time loading module from bitcode. |
| 1882 /// | 1877 /// |
| 1878 /// This isn't always used in a lazy context. In particular, it's also used by |
| 1879 /// \a NaClParseBitcodeFile(). Compared to the upstream LLVM bitcode reader, |
| 1880 /// NaCl does not support BlockAddresses, so it does not need to materialize |
| 1881 /// forward-referenced functions from block address references. |
| 1883 ErrorOr<Module *> llvm::getNaClLazyBitcodeModule( | 1882 ErrorOr<Module *> llvm::getNaClLazyBitcodeModule( |
| 1884 MemoryBuffer *Buffer, LLVMContext& Context, raw_ostream *Verbose, | 1883 std::unique_ptr<MemoryBuffer> &&Buffer, LLVMContext& Context, |
| 1885 bool AcceptSupportedOnly) { | 1884 raw_ostream *Verbose, bool AcceptSupportedOnly) { |
| 1886 Module *M = new Module(Buffer->getBufferIdentifier(), Context); | 1885 Module *M = new Module(Buffer->getBufferIdentifier(), Context); |
| 1887 NaClBitcodeReader *R = | 1886 NaClBitcodeReader *R = |
| 1888 new NaClBitcodeReader(Buffer, Context, Verbose, AcceptSupportedOnly); | 1887 new NaClBitcodeReader(Buffer.get(), Context, Verbose, AcceptSupportedOnly)
; |
| 1889 M->setMaterializer(R); | 1888 M->setMaterializer(R); |
| 1890 if (std::error_code EC = R->ParseBitcodeInto(M)) { | 1889 |
| 1890 auto cleanupOnError = [&](std::error_code EC) { |
| 1891 R->releaseBuffer(); // Never take ownership on error. | 1891 R->releaseBuffer(); // Never take ownership on error. |
| 1892 delete M; // Also deletes R. | 1892 delete M; // Also deletes R. |
| 1893 return EC; | 1893 return EC; |
| 1894 } | 1894 }; |
| 1895 | 1895 |
| 1896 if (std::error_code EC = R->ParseBitcodeInto(M)) |
| 1897 return cleanupOnError(EC); |
| 1898 |
| 1899 Buffer.release(); // The BitcodeReader owns it now. |
| 1896 return M; | 1900 return M; |
| 1897 } | 1901 } |
| 1898 | 1902 |
| 1899 | 1903 |
| 1900 Module *llvm::getNaClStreamedBitcodeModule(const std::string &name, | 1904 Module *llvm::getNaClStreamedBitcodeModule(const std::string &name, |
| 1901 StreamingMemoryObject *Streamer, | 1905 StreamingMemoryObject *Streamer, |
| 1902 LLVMContext &Context, | 1906 LLVMContext &Context, |
| 1903 raw_ostream *Verbose, | 1907 raw_ostream *Verbose, |
| 1904 std::string *ErrMsg, | 1908 std::string *ErrMsg, |
| 1905 bool AcceptSupportedOnly) { | 1909 bool AcceptSupportedOnly) { |
| 1906 Module *M = new Module(name, Context); | 1910 Module *M = new Module(name, Context); |
| 1907 NaClBitcodeReader *R = | 1911 NaClBitcodeReader *R = |
| 1908 new NaClBitcodeReader(Streamer, Context, Verbose, | 1912 new NaClBitcodeReader(Streamer, Context, Verbose, |
| 1909 AcceptSupportedOnly); | 1913 AcceptSupportedOnly); |
| 1910 M->setMaterializer(R); | 1914 M->setMaterializer(R); |
| 1911 if (std::error_code EC = R->ParseBitcodeInto(M)) { | 1915 if (std::error_code EC = R->ParseBitcodeInto(M)) { |
| 1912 if (ErrMsg) | 1916 if (ErrMsg) |
| 1913 *ErrMsg = EC.message(); | 1917 *ErrMsg = EC.message(); |
| 1914 delete M; // Also deletes R. | 1918 delete M; // Also deletes R. |
| 1915 return nullptr; | 1919 return nullptr; |
| 1916 } | 1920 } |
| 1917 | 1921 |
| 1918 return M; | 1922 return M; |
| 1919 } | 1923 } |
| 1920 | 1924 |
| 1921 /// NaClParseBitcodeFile - Read the specified bitcode file, returning the module
. | |
| 1922 /// If an error occurs, return null and fill in *ErrMsg if non-null. | |
| 1923 ErrorOr<Module *> llvm::NaClParseBitcodeFile( | 1925 ErrorOr<Module *> llvm::NaClParseBitcodeFile( |
| 1924 MemoryBuffer *Buffer, LLVMContext& Context, raw_ostream *Verbose, | 1926 MemoryBufferRef Buffer, LLVMContext& Context, raw_ostream *Verbose, |
| 1925 bool AcceptSupportedOnly){ | 1927 bool AcceptSupportedOnly){ |
| 1928 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false); |
| 1926 ErrorOr<Module *> ModuleOrErr = | 1929 ErrorOr<Module *> ModuleOrErr = |
| 1927 getNaClLazyBitcodeModule(Buffer, Context, Verbose, AcceptSupportedOnly); | 1930 getNaClLazyBitcodeModule(std::move(Buf), Context, Verbose, AcceptSupported
Only); |
| 1928 if (!ModuleOrErr) | 1931 if (!ModuleOrErr) |
| 1929 return ModuleOrErr; | 1932 return ModuleOrErr; |
| 1930 Module *M = ModuleOrErr.get(); | 1933 Module *M = ModuleOrErr.get(); |
| 1931 // Read in the entire module, and destroy the NaClBitcodeReader. | 1934 // Read in the entire module, and destroy the NaClBitcodeReader. |
| 1932 if (std::error_code EC = M->materializeAllPermanently(true)) { | 1935 if (std::error_code EC = M->materializeAllPermanently()) { |
| 1933 // Be sure the input buffer is released on error | |
| 1934 // (materalializeAllPermanently doesn't release the buffer on error). | |
| 1935 // TODO(kschimpf) Revisit this when we merge to tip of LLVM. | |
| 1936 if (GVMaterializer *Materializer = M->getMaterializer()) | |
| 1937 Materializer->releaseBuffer(); | |
| 1938 delete M; | 1936 delete M; |
| 1939 return EC; | 1937 return EC; |
| 1940 } | 1938 } |
| 1941 | 1939 |
| 1942 // TODO: Restore the use-lists to the in-memory state when the bitcode was | 1940 // TODO: Restore the use-lists to the in-memory state when the bitcode was |
| 1943 // written. We must defer until the Module has been fully materialized. | 1941 // written. We must defer until the Module has been fully materialized. |
| 1944 | 1942 |
| 1945 return M; | 1943 return M; |
| 1946 } | 1944 } |
| OLD | NEW |