Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp

Issue 940243003: PNaCl localmod mods in LLVM to 223109 (local files only) (Closed)
Patch Set: xx Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698