llvm.org GIT mirror llvm / 48f8487
implement scafolding for lazy deserialization of function bodies git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36614 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 13 years ago
2 changed file(s) with 85 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
1212
1313 #include "llvm/Bitcode/ReaderWriter.h"
1414 #include "BitcodeReader.h"
15 #include "llvm/Bitcode/BitstreamReader.h"
1615 #include "llvm/Constants.h"
1716 #include "llvm/DerivedTypes.h"
1817 #include "llvm/Module.h"
659658 }
660659 }
661660
661 /// ParseFunction - When we see the block for a function body, remember where it
662 /// is and then skip it. This lets us lazily deserialize the functions.
663 bool BitcodeReader::ParseFunction(BitstreamReader &Stream) {
664 // Get the function we are talking about.
665 if (FunctionsWithBodies.empty())
666 return Error("Insufficient function protos");
667
668 Function *Fn = FunctionsWithBodies.back();
669 FunctionsWithBodies.pop_back();
670
671 // Save the current stream state.
672 uint64_t CurBit = Stream.GetCurrentBitNo();
673 DeferredFunctionInfo[Fn] = std::make_pair(CurBit, Fn->getLinkage());
674
675 // Set the functions linkage to GhostLinkage so we know it is lazily
676 // deserialized.
677 Fn->setLinkage(GlobalValue::GhostLinkage);
678
679 // Skip over the function block for now.
680 if (Stream.SkipBlock())
681 return Error("Malformed block record");
682 return false;
683 }
684
662685 bool BitcodeReader::ParseModule(BitstreamReader &Stream,
663686 const std::string &ModuleID) {
664687 // Reject multiple MODULE_BLOCK's in a single bitstream.
681704 ResolveGlobalAndAliasInits();
682705 if (!GlobalInits.empty() || !AliasInits.empty())
683706 return Error("Malformed global initializer set");
707 if (!FunctionsWithBodies.empty())
708 return Error("Too few function bodies found");
684709 if (Stream.ReadBlockEnd())
685710 return Error("Error at end of module block");
686711 return false;
708733 if (ParseConstants(Stream) || ResolveGlobalAndAliasInits())
709734 return true;
710735 break;
736 case bitc::FUNCTION_BLOCK_ID:
737 // If this is the first function body we've seen, reverse the
738 // FunctionsWithBodies list.
739 if (!HasReversedFunctionsWithBodies) {
740 std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
741 HasReversedFunctionsWithBodies = true;
742 }
743
744 if (ParseFunction(Stream))
745 return true;
746 break;
711747 }
712748 continue;
713749 }
818854 "", TheModule);
819855
820856 Func->setCallingConv(Record[1]);
857 bool isProto = Record[2];
821858 Func->setLinkage(GetDecodedLinkage(Record[3]));
822859 Func->setAlignment((1 << Record[4]) >> 1);
823860 if (Record[5]) {
828865 Func->setVisibility(GetDecodedVisibility(Record[6]));
829866
830867 ValueList.push_back(Func);
868
869 // If this is a function with a body, remember the prototype we are
870 // creating now, so that we can match up the body with them later.
871 if (!isProto)
872 FunctionsWithBodies.push_back(Func);
831873 break;
832874 }
833875 // ALIAS: [alias type, aliasee val#, linkage]
866908 return Error("Bitcode stream should be a multiple of 4 bytes in length");
867909
868910 unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
869 BitstreamReader Stream(BufPtr, BufPtr+Buffer->getBufferSize());
911 Stream.init(BufPtr, BufPtr+Buffer->getBufferSize());
870912
871913 // Sniff for the signature.
872914 if (Stream.Read(8) != 'B' ||
899941 return false;
900942 }
901943
944
945 bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) {
946 // If it already is material, ignore the request.
947 if (!F->hasNotBeenReadFromBytecode()) return false;
948
949 DenseMap >::iterator DFII =
950 DeferredFunctionInfo.find(F);
951 assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
952
953 // Move the bit stream to the saved position of the deferred function body and
954 // restore the real linkage type for the function.
955 Stream.JumpToBit(DFII->second.first);
956 F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second);
957 DeferredFunctionInfo.erase(DFII);
958
959 return false;
960 }
961
962
902963 //===----------------------------------------------------------------------===//
903964 // External interface
904965 //===----------------------------------------------------------------------===//
1616 #include "llvm/ModuleProvider.h"
1717 #include "llvm/Type.h"
1818 #include "llvm/User.h"
19 #include "llvm/Bitcode/BitstreamReader.h"
1920 #include "llvm/Bitcode/LLVMBitCodes.h"
21 #include "llvm/ADT/DenseMap.h"
2022 #include
2123
2224 namespace llvm {
5860
5961 class BitcodeReader : public ModuleProvider {
6062 MemoryBuffer *Buffer;
63 BitstreamReader Stream;
64
6165 const char *ErrorString;
6266
6367 std::vector TypeList;
6468 BitcodeReaderValueList ValueList;
6569 std::vector > GlobalInits;
6670 std::vector > AliasInits;
71
72 // When reading the module header, this list is populated with functions that
73 // have bodies later in the file.
74 std::vector FunctionsWithBodies;
75
76 // After the module header has been read, the FunctionsWithBodies list is
77 // reversed. This keeps track of whether we've done this yet.
78 bool HasReversedFunctionsWithBodies;
79
80 /// DeferredFunctionInfo - When function bodies are initially scanned, this
81 /// map contains info about where to find deferred function body (in the
82 /// stream) and what linkage the original function had.
83 DenseMap > DeferredFunctionInfo;
6784 public:
68 BitcodeReader(MemoryBuffer *buffer) : Buffer(buffer), ErrorString(0) {}
85 BitcodeReader(MemoryBuffer *buffer) : Buffer(buffer), ErrorString(0) {
86 HasReversedFunctionsWithBodies = false;
87 }
6988 ~BitcodeReader();
7089
7190
7695 Buffer = 0;
7796 }
7897
79 virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0) {
80 // FIXME: TODO
81 return false;
82 }
98 virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0);
8399
84100 virtual Module *materializeModule(std::string *ErrInfo = 0) {
85101 // FIXME: TODO
105121 bool ParseTypeSymbolTable(BitstreamReader &Stream);
106122 bool ParseValueSymbolTable(BitstreamReader &Stream);
107123 bool ParseConstants(BitstreamReader &Stream);
124 bool ParseFunction(BitstreamReader &Stream);
108125 bool ResolveGlobalAndAliasInits();
109126 };
110127