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 |