diff options
Diffstat (limited to 'lib/Bytecode/Reader')
-rw-r--r-- | lib/Bytecode/Reader/Analyzer.cpp | 87 | ||||
-rw-r--r-- | lib/Bytecode/Reader/AnalyzerWrappers.cpp | 137 | ||||
-rw-r--r-- | lib/Bytecode/Reader/Dumper.cpp | 3 | ||||
-rw-r--r-- | lib/Bytecode/Reader/Parser.cpp | 510 | ||||
-rw-r--r-- | lib/Bytecode/Reader/Parser.h | 92 |
5 files changed, 590 insertions, 239 deletions
diff --git a/lib/Bytecode/Reader/Analyzer.cpp b/lib/Bytecode/Reader/Analyzer.cpp index eb710711d9..133c1fbaa6 100644 --- a/lib/Bytecode/Reader/Analyzer.cpp +++ b/lib/Bytecode/Reader/Analyzer.cpp @@ -30,13 +30,13 @@ public: bool handleError(const std::string& str ) { - std::cerr << "Analysis Error: " << str; return false; } void handleStart() { bca.ModuleId.clear(); + bca.numBlocks = 0; bca.numTypes = 0; bca.numValues = 0; bca.numFunctions = 0; @@ -49,16 +49,38 @@ public: bca.numSymTab = 0; bca.maxTypeSlot = 0; bca.maxValueSlot = 0; - bca.density = 0.0; + bca.numAlignment = 0; + bca.fileDensity = 0.0; + bca.globalsDensity = 0.0; + bca.functionDensity = 0.0; + bca.vbrCount32 = 0; + bca.vbrCount64 = 0; + bca.vbrCompBytes = 0; + bca.vbrExpdBytes = 0; bca.FunctionInfo.clear(); bca.BytecodeDump.clear(); + bca.BlockSizes[BytecodeFormat::Module] = 0; + bca.BlockSizes[BytecodeFormat::Function] = 0; + bca.BlockSizes[BytecodeFormat::ConstantPool] = 0; + bca.BlockSizes[BytecodeFormat::SymbolTable] = 0; + bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo] = 0; + bca.BlockSizes[BytecodeFormat::GlobalTypePlane] = 0; + bca.BlockSizes[BytecodeFormat::BasicBlock] = 0; + bca.BlockSizes[BytecodeFormat::InstructionList] = 0; + bca.BlockSizes[BytecodeFormat::CompactionTable] = 0; } void handleFinish() { - bca.density = bca.numTypes + bca.numFunctions + bca.numConstants + - bca.numGlobalVars + bca.numInstructions; - bca.density /= bca.byteSize; + bca.fileDensity = double(bca.byteSize) / double( bca.numTypes + bca.numValues ); + double globalSize = 0.0; + globalSize += double(bca.BlockSizes[BytecodeFormat::ConstantPool]); + globalSize += double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo]); + globalSize += double(bca.BlockSizes[BytecodeFormat::GlobalTypePlane]); + bca.globalsDensity = globalSize / double( bca.numTypes + bca.numConstants + + bca.numGlobalVars ); + bca.functionDensity = double(bca.BlockSizes[BytecodeFormat::Function]) / + double(bca.numFunctions); } void handleModuleBegin(const std::string& id) @@ -78,8 +100,9 @@ public: { } - void handleModuleGlobalsBegin() + void handleModuleGlobalsBegin(unsigned size) { + // bca.globalBytesize += size; } void handleGlobalVariable( @@ -89,6 +112,7 @@ public: ) { bca.numGlobalVars++; + bca.numValues++; } void handleInitializedGV( @@ -99,6 +123,7 @@ public: ) { bca.numGlobalVars++; + bca.numValues++; } virtual void handleType( const Type* Ty ) @@ -111,6 +136,7 @@ public: ) { bca.numFunctions++; + bca.numValues++; } void handleModuleGlobalsEnd() @@ -200,15 +226,19 @@ public: ) { bca.numBasicBlocks++; + bca.numValues++; } bool handleInstruction( unsigned Opcode, const Type* iType, - std::vector<unsigned>& Operands + std::vector<unsigned>& Operands, + unsigned Size ) { bca.numInstructions++; + bca.numValues++; + bca.numOperands += Operands.size(); return Instruction::isTerminator(Opcode); } @@ -227,43 +257,67 @@ public: ) { bca.numConstants++; + bca.numValues++; } void handleConstantValue( Constant * c ) { bca.numConstants++; + bca.numValues++; } void handleConstantArray( - const ArrayType* AT, - std::vector<unsigned>& Elements ) + const ArrayType* AT, + std::vector<unsigned>& Elements ) { bca.numConstants++; + bca.numValues++; } void handleConstantStruct( - const StructType* ST, - std::vector<unsigned>& ElementSlots) + const StructType* ST, + std::vector<unsigned>& ElementSlots) { bca.numConstants++; + bca.numValues++; } void handleConstantPointer( - const PointerType* PT, unsigned Slot) + const PointerType* PT, unsigned Slot) { bca.numConstants++; + bca.numValues++; } void handleConstantString( const ConstantArray* CA ) { bca.numConstants++; + bca.numValues++; } - void handleGlobalConstantsEnd() - { + void handleGlobalConstantsEnd() { } + + void handleAlignment(unsigned numBytes) { + bca.numAlignment += numBytes; + } + + void handleBlock( + unsigned BType, const unsigned char* StartPtr, unsigned Size) { + bca.numBlocks++; + bca.BlockSizes[llvm::BytecodeFormat::FileBlockIDs(BType)] += Size; } + virtual void handleVBR32(unsigned Size ) { + bca.vbrCount32++; + bca.vbrCompBytes += Size; + bca.vbrExpdBytes += sizeof(uint32_t); + } + virtual void handleVBR64(unsigned Size ) { + bca.vbrCount64++; + bca.vbrCompBytes += Size; + bca.vbrExpdBytes += sizeof(uint64_t); + } }; } @@ -277,10 +331,9 @@ void llvm::BytecodeAnalyzer::AnalyzeBytecode( { bca.byteSize = Length; AnalyzerHandler TheHandler(bca); - AbstractBytecodeParser TheParser(&TheHandler); + AbstractBytecodeParser TheParser(&TheHandler, true, true, true); TheParser.ParseBytecode( Buf, Length, ModuleID ); - if ( bca.detailedResults ) - TheParser.ParseAllFunctionBodies(); + TheParser.ParseAllFunctionBodies(); } // vim: sw=2 diff --git a/lib/Bytecode/Reader/AnalyzerWrappers.cpp b/lib/Bytecode/Reader/AnalyzerWrappers.cpp index 2caf069eb4..fd23dc8086 100644 --- a/lib/Bytecode/Reader/AnalyzerWrappers.cpp +++ b/lib/Bytecode/Reader/AnalyzerWrappers.cpp @@ -18,6 +18,7 @@ #include "Support/StringExtras.h" #include "Config/unistd.h" #include <cerrno> +#include <iomanip> using namespace llvm; @@ -46,7 +47,7 @@ static std::string ErrnoMessage (int savedErrNum, std::string descr) { } BytecodeFileAnalyzer::BytecodeFileAnalyzer(const std::string &Filename, - BytecodeAnalysis& bca) { + BytecodeAnalysis& bca) { Buffer = (unsigned char*)ReadFileIntoAddressSpace(Filename, Length); if (Buffer == 0) throw "Error reading file '" + Filename + "'."; @@ -84,16 +85,16 @@ namespace { public: BytecodeBufferAnalyzer(const unsigned char *Buf, unsigned Length, - BytecodeAnalysis& bca, const std::string &ModuleID); + BytecodeAnalysis& bca, const std::string &ModuleID); ~BytecodeBufferAnalyzer(); }; } BytecodeBufferAnalyzer::BytecodeBufferAnalyzer(const unsigned char *Buf, - unsigned Length, - BytecodeAnalysis& bca, - const std::string &ModuleID) { + unsigned Length, + BytecodeAnalysis& bca, + const std::string &ModuleID) { // If not aligned, allocate a new buffer to hold the bytecode... const unsigned char *ParseBegin = 0; if ((intptr_t)Buf & 3) { @@ -200,28 +201,118 @@ void llvm::AnalyzeBytecodeBuffer( /// This function prints the contents of rhe BytecodeAnalysis structure in /// a human legible form. /// @brief Print BytecodeAnalysis structure to an ostream +namespace { +inline static void print(std::ostream& Out, const char*title, + unsigned val, bool nl = true ) { + Out << std::setw(30) << std::right << title + << std::setw(0) << ": " + << std::setw(9) << val << "\n"; +} + +inline static void print(std::ostream&Out, const char*title, + double val ) { + Out << std::setw(30) << std::right << title + << std::setw(0) << ": " + << std::setw(9) << std::setprecision(6) << val << "\n" ; +} + +inline static void print(std::ostream&Out, const char*title, + double top, double bot ) { + Out << std::setw(30) << std::right << title + << std::setw(0) << ": " + << std::setw(9) << std::setprecision(6) << top + << " (" << std::left << std::setw(0) << std::setprecision(4) + << (top/bot)*100.0 << "%)\n"; +} +inline static void print(std::ostream&Out, const char*title, + std::string val, bool nl = true) { + Out << std::setw(30) << std::right << title + << std::setw(0) << ": " + << std::left << val << (nl ? "\n" : ""); +} + +} + void llvm::PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out ) { - Out << " Bytecode Analysis of: " << bca.ModuleId << "\n"; - Out << " File Size: " << bca.byteSize << "\n"; - Out << " Number Of Types: " << bca.numTypes << "\n"; - Out << " Number Of Constants: " << bca.numConstants << "\n"; - Out << " Number Of Global Variables: " << bca.numGlobalVars << "\n"; - Out << " Number Of Functions: " << bca.numFunctions << "\n"; - Out << " Number Of Basic Blocks: " << bca.numBasicBlocks << "\n"; - Out << " Number Of Instructions: " << bca.numInstructions << "\n"; - Out << " Number Of Operands: " << bca.numOperands << "\n"; - Out << "Number Of Compaction Tables: " << bca.numCmpctnTables << "\n"; - Out << " Number Of Symbol Tables: " << bca.numSymTab << "\n"; - Out << " Maximum Type Slot Number: " << bca.maxTypeSlot << "\n"; - Out << " Maximum Value Slot Number: " << bca.maxValueSlot << "\n"; - Out << " Bytecode Density: " << bca.density << "\n"; - - if ( bca.detailedResults ) - Out << "Detailed Results Not Implemented Yet.\n"; + print(Out, "Bytecode Analysis Of Module", bca.ModuleId); + print(Out, "File Size", bca.byteSize); + print(Out, "Bytecode Compression Index",std::string("TBD")); + print(Out, "Number Of Bytecode Blocks", bca.numBlocks); + print(Out, "Number Of Types", bca.numTypes); + print(Out, "Number Of Values", bca.numValues); + print(Out, "Number Of Constants", bca.numConstants); + print(Out, "Number Of Global Variables", bca.numGlobalVars); + print(Out, "Number Of Functions", bca.numFunctions); + print(Out, "Number Of Basic Blocks", bca.numBasicBlocks); + print(Out, "Number Of Instructions", bca.numInstructions); + print(Out, "Number Of Operands", bca.numOperands); + print(Out, "Number Of Compaction Tables", bca.numCmpctnTables); + print(Out, "Number Of Symbol Tables", bca.numSymTab); + print(Out, "Maximum Type Slot Number", bca.maxTypeSlot); + print(Out, "Maximum Value Slot Number", bca.maxValueSlot); + print(Out, "Bytes Thrown To Alignment", double(bca.numAlignment), + double(bca.byteSize)); + print(Out, "File Density (bytes/def)", bca.fileDensity); + print(Out, "Globals Density (bytes/def)", bca.globalsDensity); + print(Out, "Function Density (bytes/func)", bca.functionDensity); + print(Out, "Number of VBR 32-bit Integers", bca.vbrCount32); + print(Out, "Number of VBR 64-bit Integers", bca.vbrCount64); + print(Out, "Number of VBR Compressed Bytes", bca.vbrCompBytes); + print(Out, "Number of VBR Expanded Bytes", bca.vbrExpdBytes); + print(Out, "VBR Savings", + double(bca.vbrExpdBytes)-double(bca.vbrCompBytes), + double(bca.byteSize)); + + if ( bca.detailedResults ) { + print(Out, "Module Bytes", + double(bca.BlockSizes[BytecodeFormat::Module]), + double(bca.byteSize)); + print(Out, "Function Bytes", + double(bca.BlockSizes[BytecodeFormat::Function]), + double(bca.byteSize)); + print(Out, "Constant Pool Bytes", + double(bca.BlockSizes[BytecodeFormat::ConstantPool]), + double(bca.byteSize)); + print(Out, "Symbol Table Bytes", + double(bca.BlockSizes[BytecodeFormat::SymbolTable]), + double(bca.byteSize)); + print(Out, "Module Global Info Bytes", + double(bca.BlockSizes[BytecodeFormat::ModuleGlobalInfo]), + double(bca.byteSize)); + print(Out, "Global Type Plane Bytes", + double(bca.BlockSizes[BytecodeFormat::GlobalTypePlane]), + double(bca.byteSize)); + print(Out, "Basic Block Bytes", + double(bca.BlockSizes[BytecodeFormat::BasicBlock]), + double(bca.byteSize)); + print(Out, "Instruction List Bytes", + double(bca.BlockSizes[BytecodeFormat::InstructionList]), + double(bca.byteSize)); + print(Out, "Compaction Table Bytes", + double(bca.BlockSizes[BytecodeFormat::CompactionTable]), + double(bca.byteSize)); + + std::map<unsigned,BytecodeAnalysis::BytecodeFunctionInfo>::iterator I = + bca.FunctionInfo.begin(); + std::map<unsigned,BytecodeAnalysis::BytecodeFunctionInfo>::iterator E = + bca.FunctionInfo.end(); + + while ( I != E ) { + Out << std::left << std::setw(0); + Out << "Function: " << I->second.name << " Slot=" << I->first << "\n"; + print(Out,"Type:", I->second.description); + print(Out,"Byte Size", I->second.byteSize); + print(Out,"Instructions", I->second.numInstructions); + print(Out,"Basic Blocks", I->second.numBasicBlocks); + print(Out,"Operand", I->second.numOperands); + print(Out,"Function Density", I->second.density); + print(Out,"VBR Effectiveness", I->second.vbrEffectiveness); + ++I; + } + } if ( bca.dumpBytecode ) Out << bca.BytecodeDump; } - // vim: sw=2 diff --git a/lib/Bytecode/Reader/Dumper.cpp b/lib/Bytecode/Reader/Dumper.cpp index 12752ff883..d61afe4255 100644 --- a/lib/Bytecode/Reader/Dumper.cpp +++ b/lib/Bytecode/Reader/Dumper.cpp @@ -212,7 +212,8 @@ public: virtual bool handleInstruction( unsigned Opcode, const Type* iType, - std::vector<unsigned>& Operands + std::vector<unsigned>& Operands, + unsigned Size ) { std::cout << " INST: OpCode=" diff --git a/lib/Bytecode/Reader/Parser.cpp b/lib/Bytecode/Reader/Parser.cpp index 743db6c315..80800e75a6 100644 --- a/lib/Bytecode/Reader/Parser.cpp +++ b/lib/Bytecode/Reader/Parser.cpp @@ -1,4 +1,4 @@ -//===- Reader.cpp - Code to read bytecode files ---------------------------===// +//===- Parser.cpp - Code to parse bytecode files --------------------------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This library implements the functionality defined in llvm/Bytecode/Reader.h +// This library implements the functionality defined in llvm/Bytecode/Parser.h // // Note that this library should be as fast as possible, reentrant, and // threadsafe!! @@ -17,7 +17,6 @@ //===----------------------------------------------------------------------===// #include "AnalyzerInternals.h" -#include "ReaderPrimitives.h" #include "llvm/Module.h" #include "llvm/Bytecode/Format.h" #include "Support/StringExtras.h" @@ -37,40 +36,128 @@ using namespace llvm; #define BCR_TRACE(n, X) #endif -#define PARSE_ERROR(inserters) \ - { \ +#define PARSE_ERROR(inserters) { \ std::ostringstream errormsg; \ errormsg << inserters; \ if ( ! handler->handleError( errormsg.str() ) ) \ throw std::string(errormsg.str()); \ } +inline bool AbstractBytecodeParser::moreInBlock() { + return At < BlockEnd; +} -inline void AbstractBytecodeParser::readBlock(const unsigned char *&Buf, - const unsigned char *EndBuf, - unsigned &Type, unsigned &Size) -{ - Type = read(Buf, EndBuf); - Size = read(Buf, EndBuf); +inline void AbstractBytecodeParser::checkPastBlockEnd(const char * block_name) { + if ( At > BlockEnd ) + PARSE_ERROR("Attempt to read past the end of " << block_name << " block."); } -const Type *AbstractBytecodeParser::getType(unsigned ID) { - //cerr << "Looking up Type ID: " << ID << "\n"; +inline void AbstractBytecodeParser::align32() { + BufPtr Save = At; + At = (const unsigned char *)((unsigned long)(At+3) & (~3UL)); + if ( reportAlignment && At > Save ) handler->handleAlignment( At - Save ); + if (At > BlockEnd) + throw std::string("Ran out of data while aligning!"); +} + +inline unsigned AbstractBytecodeParser::read_uint() { + if (At+4 > BlockEnd) + throw std::string("Ran out of data reading uint!"); + At += 4; + return At[-4] | (At[-3] << 8) | (At[-2] << 16) | (At[-1] << 24); +} + +inline unsigned AbstractBytecodeParser::read_vbr_uint() { + unsigned Shift = 0; + unsigned Result = 0; + BufPtr Save = At; + + do { + if (At == BlockEnd) + throw std::string("Ran out of data reading vbr_uint!"); + Result |= (unsigned)((*At++) & 0x7F) << Shift; + Shift += 7; + } while (At[-1] & 0x80); + if (reportVBR) + handler->handleVBR32(At-Save); + return Result; +} + +inline uint64_t AbstractBytecodeParser::read_vbr_uint64() { + unsigned Shift = 0; + uint64_t Result = 0; + BufPtr Save = At; + + do { + if (At == BlockEnd) + throw std::string("Ran out of data reading vbr_uint64!"); + Result |= (uint64_t)((*At++) & 0x7F) << Shift; + Shift += 7; + } while (At[-1] & 0x80); + if (reportVBR) + handler->handleVBR64(At-Save); + return Result; +} - if (ID < Type::FirstDerivedTyID) - if (const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID)) - return T; // Asked for a primitive type... +inline int64_t AbstractBytecodeParser::read_vbr_int64() { + uint64_t R = read_vbr_uint64(); + if (R & 1) { + if (R != 1) + return -(int64_t)(R >> 1); + else // There is no such thing as -0 with integers. "-0" really means + // 0x8000000000000000. + return 1LL << 63; + } else + return (int64_t)(R >> 1); +} - // Otherwise, derived types need offset... - ID -= Type::FirstDerivedTyID; +inline std::string AbstractBytecodeParser::read_str() { + unsigned Size = read_vbr_uint(); + const unsigned char *OldAt = At; + At += Size; + if (At > BlockEnd) // Size invalid? + throw std::string("Ran out of data reading a string!"); + return std::string((char*)OldAt, Size); +} + +inline void AbstractBytecodeParser::read_data(void *Ptr, void *End) { + unsigned char *Start = (unsigned char *)Ptr; + unsigned Amount = (unsigned char *)End - Start; + if (At+Amount > BlockEnd) + throw std::string("Ran out of data!"); + std::copy(At, At+Amount, Start); + At += Amount; +} - if (!CompactionTypeTable.empty()) { - if (ID >= CompactionTypeTable.size()) - PARSE_ERROR("Type ID out of range for compaction table!"); - return CompactionTypeTable[ID]; +inline void AbstractBytecodeParser::readBlock(unsigned &Type, unsigned &Size) { + Type = read_uint(); + Size = read_uint(); + BlockStart = At; + if ( At + Size > BlockEnd ) + throw std::string("Attempt to size a block past end of memory"); + BlockEnd = At + Size; + if ( reportBlocks ) { + handler->handleBlock( Type, BlockStart, Size ); } +} + +const Type *AbstractBytecodeParser::getType(unsigned ID) { +//cerr << "Looking up Type ID: " << ID << "\n"; + +if (ID < Type::FirstDerivedTyID) + if (const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID)) + return T; // Asked for a primitive type... + +// Otherwise, derived types need offset... +ID -= Type::FirstDerivedTyID; - // Is it a module-level type? +if (!CompactionTypeTable.empty()) { + if (ID >= CompactionTypeTable.size()) + PARSE_ERROR("Type ID out of range for compaction table!"); + return CompactionTypeTable[ID]; +} + +// Is it a module-level type? if (ID < ModuleTypes.size()) return ModuleTypes[ID].get(); @@ -83,12 +170,12 @@ const Type *AbstractBytecodeParser::getType(unsigned ID) { return Type::VoidTy; } -bool AbstractBytecodeParser::ParseInstruction(BufPtr& Buf, BufPtr EndBuf, - std::vector<unsigned> &Operands) { +bool AbstractBytecodeParser::ParseInstruction(std::vector<unsigned> &Operands) { + BufPtr SaveAt = At; Operands.clear(); unsigned iType = 0; unsigned Opcode = 0; - unsigned Op = read(Buf, EndBuf); + unsigned Op = read_uint(); // bits Instruction format: Common to all formats // -------------------------- @@ -134,61 +221,56 @@ bool AbstractBytecodeParser::ParseInstruction(BufPtr& Buf, BufPtr EndBuf, Operands[2] = (Op >> 26) & 63; break; case 0: - Buf -= 4; // Hrm, try this again... - Opcode = read_vbr_uint(Buf, EndBuf); + At -= 4; // Hrm, try this again... + Opcode = read_vbr_uint(); Opcode >>= 2; - iType = read_vbr_uint(Buf, EndBuf); + iType = read_vbr_uint(); - unsigned NumOperands = read_vbr_uint(Buf, EndBuf); + unsigned NumOperands = read_vbr_uint(); Operands.resize(NumOperands); if (NumOperands == 0) PARSE_ERROR("Zero-argument instruction found; this is invalid."); for (unsigned i = 0; i != NumOperands; ++i) - Operands[i] = read_vbr_uint(Buf, EndBuf); - align32(Buf, EndBuf); + Operands[i] = read_vbr_uint(); + align32(); break; } - return handler->handleInstruction(Opcode, getType(iType), Operands); + return handler->handleInstruction(Opcode, getType(iType), Operands, At-SaveAt); } /// ParseBasicBlock - In LLVM 1.0 bytecode files, we used to output one /// basicblock at a time. This method reads in one of the basicblock packets. -void AbstractBytecodeParser::ParseBasicBlock(BufPtr &Buf, - BufPtr EndBuf, - unsigned BlockNo) { +void AbstractBytecodeParser::ParseBasicBlock( unsigned BlockNo) { handler->handleBasicBlockBegin( BlockNo ); std::vector<unsigned> Args; bool is_terminating = false; - while (Buf < EndBuf) - is_terminating = ParseInstruction(Buf, EndBuf, Args); + while ( moreInBlock() ) + is_terminating = ParseInstruction(Args); if ( ! is_terminating ) - PARSE_ERROR( - "Failed to recognize instruction as terminating at end of block"); + PARSE_ERROR("Non-terminated basic block found!"); handler->handleBasicBlockEnd( BlockNo ); } - /// ParseInstructionList - Parse all of the BasicBlock's & Instruction's in the /// body of a function. In post 1.0 bytecode files, we no longer emit basic /// block individually, in order to avoid per-basic-block overhead. -unsigned AbstractBytecodeParser::ParseInstructionList( BufPtr &Buf, - BufPtr EndBuf) { +unsigned AbstractBytecodeParser::ParseInstructionList() { unsigned BlockNo = 0; std::vector<unsigned> Args; - while (Buf < EndBuf) { + while ( moreInBlock() ) { handler->handleBasicBlockBegin( BlockNo ); // Read instructions into this basic block until we get to a terminator bool is_terminating = false; - while (Buf < EndBuf && !is_terminating ) - is_terminating = ParseInstruction(Buf, EndBuf, Args ) ; + while (moreInBlock() && !is_terminating ) + is_terminating = ParseInstruction(Args ) ; if (!is_terminating) PARSE_ERROR( "Non-terminated basic block found!"); @@ -199,36 +281,34 @@ unsigned AbstractBytecodeParser::ParseInstructionList( BufPtr &Buf, return BlockNo; } -void AbstractBytecodeParser::ParseSymbolTable(BufPtr &Buf, BufPtr EndBuf) { +void AbstractBytecodeParser::ParseSymbolTable() { handler->handleSymbolTableBegin(); - while (Buf < EndBuf) { + while ( moreInBlock() ) { // Symtab block header: [num entries][type id number] - unsigned NumEntries = read_vbr_uint(Buf, EndBuf); - unsigned Typ = read_vbr_uint(Buf, EndBuf); + unsigned NumEntries = read_vbr_uint(); + unsigned Typ = read_vbr_uint(); const Type *Ty = getType(Typ); handler->handleSymbolTablePlane( Typ, NumEntries, Ty ); for (unsigned i = 0; i != NumEntries; ++i) { // Symtab entry: [def slot #][name] - unsigned slot = read_vbr_uint(Buf, EndBuf); - std::string Name = read_str(Buf, EndBuf); + unsigned slot = read_vbr_uint(); + std::string Name = read_str(); if (Typ == Type::TypeTyID) handler->handleSymbolTableType( i, slot, Name ); else - handler->handleSymbolTableValue( i, slot, Name ); + handler->handleSymbolTableValue( i, slot, Name ); } } - - if (Buf > EndBuf) - PARSE_ERROR("Tried to read past end of buffer while reading symbol table."); + checkPastBlockEnd("Symbol Table"); handler->handleSymbolTableEnd(); } -void AbstractBytecodeParser::ParseFunctionLazily(BufPtr &Buf, BufPtr EndBuf) { +void AbstractBytecodeParser::ParseFunctionLazily() { if (FunctionSignatureList.empty()) throw std::string("FunctionSignatureList empty!"); @@ -236,9 +316,10 @@ void AbstractBytecodeParser::ParseFunctionLazily(BufPtr &Buf, BufPtr EndBuf) { FunctionSignatureList.pop_back(); // Save the information for future reading of the function - LazyFunctionLoadMap[FType] = LazyFunctionInfo(Buf, EndBuf); + LazyFunctionLoadMap[FType] = LazyFunctionInfo(BlockStart, BlockEnd); + // Pretend we've `parsed' this function - Buf = EndBuf; + At = BlockEnd; } void AbstractBytecodeParser::ParseNextFunction(Type* FType) { @@ -251,21 +332,20 @@ void AbstractBytecodeParser::ParseNextFunction(Type* FType) { return; } - BufPtr Buf = Fi->second.Buf; - BufPtr EndBuf = Fi->second.EndBuf; + BlockStart = At = Fi->second.Buf; + BlockEnd = Fi->second.Buf; assert(Fi->first == FType); LazyFunctionLoadMap.erase(Fi); - this->ParseFunctionBody( FType, Buf, EndBuf ); + this->ParseFunctionBody( FType ); } -void AbstractBytecodeParser::ParseFunctionBody(const Type* FType, - BufPtr &Buf, BufPtr EndBuf ) { +void AbstractBytecodeParser::ParseFunctionBody(const Type* FType ) { GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage; - unsigned LinkageType = read_vbr_uint(Buf, EndBuf); + unsigned LinkageType = read_vbr_uint(); switch (LinkageType) { case 0: Linkage = GlobalValue::ExternalLinkage; break; case 1: Linkage = GlobalValue::WeakLinkage; break; @@ -284,43 +364,45 @@ void AbstractBytecodeParser::ParseFunctionBody(const Type* FType, unsigned BlockNum = 0; bool InsertedArguments = false; - while (Buf < EndBuf) { + BufPtr MyEnd = BlockEnd; + while ( At < MyEnd ) { unsigned Type, Size; - BufPtr OldBuf = Buf; - readBlock(Buf, EndBuf, Type, Size); + BufPtr OldAt = At; + readBlock(Type, Size); switch (Type) { case BytecodeFormat::ConstantPool: - ParseConstantPool(Buf, Buf+Size, FunctionTypes ); + ParseConstantPool(FunctionTypes ); break; case BytecodeFormat::CompactionTable: - ParseCompactionTable(Buf, Buf+Size); + ParseCompactionTable(); break; case BytecodeFormat::BasicBlock: - ParseBasicBlock(Buf, Buf+Size, BlockNum++); + ParseBasicBlock(BlockNum++); break; case BytecodeFormat::InstructionList: if (BlockNum) - PARSE_ERROR("InstructionList must come before basic blocks!"); - BlockNum = ParseInstructionList(Buf, Buf+Size); + PARSE_ERROR("InstructionList must come before basic blocks!"); + BlockNum = ParseInstructionList(); break; case BytecodeFormat::SymbolTable: - ParseSymbolTable(Buf, Buf+Size ); + ParseSymbolTable(); break; default: - Buf += Size; - if (OldBuf > Buf) - PARSE_ERROR("Wrapped around reading bytecode"); + At += Size; + if (OldAt > At) + PARSE_ERROR("Wrapped around reading bytecode"); break; } + BlockEnd = MyEnd; // Malformed bc file if read past end of block. - align32(Buf, EndBuf); + align32(); } handler->handleFunctionEnd(FType); @@ -336,21 +418,24 @@ void AbstractBytecodeParser::ParseAllFunctionBodies() { while ( Fi != Fe ) { const Type* FType = Fi->first; - this->ParseFunctionBody(FType, Fi->second.Buf, Fi->second.EndBuf); + BlockStart = At = Fi->second.Buf; + BlockEnd = Fi->second.EndBuf; + this->ParseFunctionBody(FType); + ++Fi; } } -void AbstractBytecodeParser::ParseCompactionTable(BufPtr &Buf, BufPtr End) { +void AbstractBytecodeParser::ParseCompactionTable() { handler->handleCompactionTableBegin(); - while (Buf != End) { - unsigned NumEntries = read_vbr_uint(Buf, End); + while ( moreInBlock() ) { + unsigned NumEntries = read_vbr_uint(); unsigned Ty; if ((NumEntries & 3) == 3) { NumEntries >>= 2; - Ty = read_vbr_uint(Buf, End); + Ty = read_vbr_uint(); } else { Ty = NumEntries >> 2; NumEntries &= 3; @@ -360,25 +445,24 @@ void AbstractBytecodeParser::ParseCompactionTable(BufPtr &Buf, BufPtr End) { if (Ty == Type::TypeTyID) { for (unsigned i = 0; i != NumEntries; ++i) { - unsigned TypeSlot = read_vbr_uint(Buf,End); + unsigned TypeSlot = read_vbr_uint(); const Type *Typ = getGlobalTableType(TypeSlot); - handler->handleCompactionTableType( i, TypeSlot, Typ ); + handler->handleCompactionTableType( i, TypeSlot, Typ ); } } else { const Type *Typ = getType(Ty); // Push the implicit zero for (unsigned i = 0; i != NumEntries; ++i) { - unsigned ValSlot = read_vbr_uint(Buf, End); - handler->handleCompactionTableValue( i, ValSlot, Typ ); + unsigned ValSlot = read_vbr_uint(); + handler->handleCompactionTableValue( i, ValSlot, Typ ); } } } handler->handleCompactionTableEnd(); } -const Type *AbstractBytecodeParser::ParseTypeConstant(const unsigned char *&Buf, - const unsigned char *EndBuf) { - unsigned PrimType = read_vbr_uint(Buf, EndBuf); +const Type *AbstractBytecodeParser::ParseTypeConstant() { + unsigned PrimType = read_vbr_uint(); const Type *Val = 0; if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType))) @@ -386,13 +470,13 @@ const Type *AbstractBytecodeParser::ParseTypeConstant(const unsigned char *&Buf, switch (PrimType) { case Type::FunctionTyID: { - const Type *RetType = getType(read_vbr_uint(Buf, EndBuf)); + const Type *RetType = getType(read_vbr_uint()); - unsigned NumParams = read_vbr_uint(Buf, EndBuf); + unsigned NumParams = read_vbr_uint(); std::vector<const Type*> Params; while (NumParams--) - Params.push_back(getType(read_vbr_uint(Buf, EndBuf))); + Params.push_back(getType(read_vbr_uint())); bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); @@ -402,10 +486,10 @@ const Type *AbstractBytecodeParser::ParseTypeConstant(const unsigned char *&Buf, return result; } case Type::ArrayTyID: { - unsigned ElTyp = read_vbr_uint(Buf, EndBuf); + unsigned ElTyp = read_vbr_uint(); const Type *ElementType = getType(ElTyp); - unsigned NumElements = read_vbr_uint(Buf, EndBuf); + unsigned NumElements = read_vbr_uint(); BCR_TRACE(5, "Array Type Constant #" << ElTyp << " size=" << NumElements << "\n"); @@ -415,10 +499,10 @@ const Type *AbstractBytecodeParser::ParseTypeConstant(const unsigned char *&Buf, } case Type::StructTyID: { std::vector<const Type*> Elements; - unsigned Typ = read_vbr_uint(Buf, EndBuf); + unsigned Typ = read_vbr_uint(); while (Typ) { // List is terminated by void/0 typeid Elements.push_back(getType(Typ)); - Typ = read_vbr_uint(Buf, EndBuf); + Typ = read_vbr_uint(); } Type* result = StructType::get(Elements); @@ -426,7 +510,7 @@ const Type *AbstractBytecodeParser::ParseTypeConstant(const unsigned char *&Buf, return result; } case Type::PointerTyID: { - unsigned ElTyp = read_vbr_uint(Buf, EndBuf); + unsigned ElTyp = read_vbr_uint(); BCR_TRACE(5, "Pointer Type Constant #" << ElTyp << "\n"); Type* result = PointerType::get(getType(ElTyp)); handler->handleType( result ); @@ -455,10 +539,9 @@ const Type *AbstractBytecodeParser::ParseTypeConstant(const unsigned char *&Buf, // something and when we reread the type later, we can replace the opaque type // with a new resolved concrete type. // -void AbstractBytecodeParser::ParseTypeConstants(const unsigned char *&Buf, - const unsigned char *EndBuf, - TypeListTy &Tab, - unsigned NumEntries) { +void AbstractBytecodeParser::ParseTypeConstants( + TypeListTy &Tab, unsigned NumEntries +) { assert(Tab.size() == 0 && "should not have read type constants in before!"); // Insert a bunch of opaque types to be resolved later... @@ -470,7 +553,7 @@ void AbstractBytecodeParser::ParseTypeConstants(const unsigned char *&Buf, // opaque types just inserted. // for (unsigned i = 0; i != NumEntries; ++i) { - const Type *NewTy = ParseTypeConstant(Buf, EndBuf), *OldTy = Tab[i].get(); + const Type *NewTy = ParseTypeConstant(), *OldTy = Tab[i].get(); if (NewTy == 0) throw std::string("Couldn't parse type!"); BCR_TRACE(4, "#" << i << ": Read Type Constant: '" << NewTy << "' Replacing: " << OldTy << "\n"); @@ -497,18 +580,16 @@ void AbstractBytecodeParser::ParseTypeConstants(const unsigned char *&Buf, } -void AbstractBytecodeParser::ParseConstantValue(const unsigned char *&Buf, - const unsigned char *EndBuf, - unsigned TypeID) { +void AbstractBytecodeParser::ParseConstantValue(unsigned TypeID) { // We must check for a ConstantExpr before switching by type because // a ConstantExpr can be of any type, and has no explicit value. // // 0 if not expr; numArgs if is expr - unsigned isExprNumArgs = read_vbr_uint(Buf, EndBuf); + unsigned isExprNumArgs = read_vbr_uint(); if (isExprNumArgs) { - unsigned Opcode = read_vbr_uint(Buf, EndBuf); + unsigned Opcode = read_vbr_uint(); const Type* Typ = getType(TypeID); // FIXME: Encoding of constant exprs could be much more compact! @@ -517,8 +598,8 @@ void AbstractBytecodeParser::ParseConstantValue(const unsigned char *&Buf, |