}
const Type *BytecodeParser::getType(unsigned ID) {
- if (ID < Type::NumPrimitiveIDs) {
- const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID);
- if (T) return T;
- }
+ if (ID < Type::NumPrimitiveIDs)
+ if (const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID))
+ return T;
//cerr << "Looking up Type ID: " << ID << "\n";
- if (ID < Type::NumPrimitiveIDs) {
- const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID);
- if (T) return T; // Asked for a primitive type...
- }
+ if (ID < Type::NumPrimitiveIDs)
+ if (const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID))
+ return T; // Asked for a primitive type...
// Otherwise, derived types need offset...
ID -= FirstDerivedTyID;
if (ID < FunctionTypeValues.size())
return FunctionTypeValues[ID].get();
- return 0;
+ throw std::string("Illegal type reference!");
}
-int BytecodeParser::insertValue(Value *Val, ValueTable &ValueTab) {
+unsigned BytecodeParser::insertValue(Value *Val, ValueTable &ValueTab) {
assert((!HasImplicitZeroInitializer || !isa<Constant>(Val) ||
Val->getType()->isPrimitiveType() ||
!cast<Constant>(Val)->isNullValue()) &&
}
-void BytecodeParser::setValueTo(ValueTable &ValueTab, unsigned Slot,
- Value *Val) {
- assert(&ValueTab == &ModuleValues && "Can only setValueTo on Module values!");
- assert((!HasImplicitZeroInitializer || Slot != 0) &&
- "Cannot change zero init");
- unsigned type = getTypeSlot(Val->getType());
- assert(type < ValueTab.size() && Slot <= ValueTab[type]->size());
- ValueTab[type]->setOperand(Slot-HasImplicitZeroInitializer, Val);
-}
-
-
Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) {
return getValue(getTypeSlot(Ty), oNum, Create);
}
Value *BytecodeParser::getValue(unsigned type, unsigned oNum, bool Create) {
assert(type != Type::TypeTyID && "getValue() cannot get types!");
+ assert(type != Type::LabelTyID && "getValue() cannot get blocks!");
unsigned Num = oNum;
if (HasImplicitZeroInitializer && type >= FirstDerivedTyID) {
if (!Create) return 0; // Do not create a placeholder?
- const Type *Ty = getType(type);
- Value *Val = type == Type::LabelTyID ? (Value*)new BBPHolder(Ty, oNum) :
- (Value*)new ValPHolder(Ty, oNum);
+ std::pair<unsigned,unsigned> KeyValue(type, oNum);
+ std::map<std::pair<unsigned,unsigned>, Value*>::iterator I =
+ ForwardReferences.lower_bound(KeyValue);
+ if (I != ForwardReferences.end() && I->first == KeyValue)
+ return I->second; // We have already created this placeholder
- assert(Val != 0 && "How did we not make something?");
- if (insertValue(Val, LateResolveValues) == -1) return 0;
+ Value *Val = new Argument(getType(type));
+ ForwardReferences.insert(I, std::make_pair(KeyValue, Val));
return Val;
}
+/// getBasicBlock - Get a particular numbered basic block, which might be a
+/// forward reference. This works together with ParseBasicBlock to handle these
+/// forward references in a clean manner.
+///
+BasicBlock *BytecodeParser::getBasicBlock(unsigned ID) {
+ // Make sure there is room in the table...
+ if (ParsedBasicBlocks.size() <= ID) ParsedBasicBlocks.resize(ID+1);
+
+ // First check to see if this is a backwards reference, i.e., ParseBasicBlock
+ // has already created this block, or if the forward reference has already
+ // been created.
+ if (ParsedBasicBlocks[ID])
+ return ParsedBasicBlocks[ID];
+
+ // Otherwise, the basic block has not yet been created. Do so and add it to
+ // the ParsedBasicBlocks list.
+ return ParsedBasicBlocks[ID] = new BasicBlock();
+}
+
/// getConstantValue - Just like getValue, except that it returns a null pointer
/// only on error. It always returns a constant (meaning that if the value is
/// defined, but is not a constant, that is an error). If the specified
}
-std::auto_ptr<BasicBlock>
-BytecodeParser::ParseBasicBlock(const unsigned char *&Buf,
- const unsigned char *EndBuf) {
- std::auto_ptr<BasicBlock> BB(new BasicBlock());
+BasicBlock *BytecodeParser::ParseBasicBlock(const unsigned char *&Buf,
+ const unsigned char *EndBuf,
+ unsigned BlockNo) {
+ BasicBlock *BB;
+ if (ParsedBasicBlocks.size() == BlockNo)
+ ParsedBasicBlocks.push_back(BB = new BasicBlock());
+ else if (ParsedBasicBlocks[BlockNo] == 0)
+ BB = ParsedBasicBlocks[BlockNo] = new BasicBlock();
+ else
+ BB = ParsedBasicBlocks[BlockNo];
while (Buf < EndBuf) {
- Instruction *Inst;
- ParseInstruction(Buf, EndBuf, Inst);
-
- if (Inst == 0) { throw std::string("Could not parse Instruction."); }
- if (insertValue(Inst, Values) == -1) {
- throw std::string("Could not insert value.");
- }
-
+ Instruction *Inst = ParseInstruction(Buf, EndBuf);
+ insertValue(Inst, Values);
BB->getInstList().push_back(Inst);
BCR_TRACE(4, Inst);
}
void BytecodeParser::ParseSymbolTable(const unsigned char *&Buf,
const unsigned char *EndBuf,
- SymbolTable *ST) {
+ SymbolTable *ST,
+ Function *CurrentFunction) {
while (Buf < EndBuf) {
// Symtab block header: [num entries][type id number]
unsigned NumEntries, Typ;
if (read_vbr(Buf, EndBuf, NumEntries) ||
read_vbr(Buf, EndBuf, Typ)) throw Error_readvbr;
const Type *Ty = getType(Typ);
- if (Ty == 0) throw std::string("Invalid type read in symbol table.");
-
- BCR_TRACE(3, "Plane Type: '" << Ty << "' with " << NumEntries <<
+ BCR_TRACE(3, "Plane Type: '" << *Ty << "' with " << NumEntries <<
" entries\n");
for (unsigned i = 0; i < NumEntries; ++i) {
if (read(Buf, EndBuf, Name, false)) // Not aligned...
throw std::string("Buffer not aligned.");
- Value *V;
+ Value *V = 0;
if (Typ == Type::TypeTyID)
V = (Value*)getType(slot);
- else
+ else if (Typ == Type::LabelTyID) {
+ if (CurrentFunction) {
+ // FIXME: THIS IS N^2!!!
+ Function::iterator BlockIterator = CurrentFunction->begin();
+ std::advance(BlockIterator, slot);
+ V = BlockIterator;
+ }
+ } else
V = getValue(Typ, slot, false); // Find mapping...
if (V == 0) throw std::string("Failed value look-up.");
BCR_TRACE(4, "Map: '" << Name << "' to #" << slot << ":" << *V;
GlobalRefs.erase(I); // Remove the map entry for it
}
-void
-BytecodeParser::ParseFunction(const unsigned char *&Buf,
- const unsigned char *EndBuf) {
+void BytecodeParser::ParseFunction(const unsigned char *&Buf,
+ const unsigned char *EndBuf) {
if (FunctionSignatureList.empty())
throw std::string("FunctionSignatureList empty!");
const FunctionType::ParamTypes &Params =F->getFunctionType()->getParamTypes();
Function::aiterator AI = F->abegin();
for (FunctionType::ParamTypes::const_iterator It = Params.begin();
- It != Params.end(); ++It, ++AI) {
- if (insertValue(AI, Values) == -1)
- throw std::string("Error reading function arguments!");
- }
+ It != Params.end(); ++It, ++AI)
+ insertValue(AI, Values);
+
+ // Keep track of how many basic blocks we have read in...
+ unsigned BlockNum = 0;
while (Buf < EndBuf) {
unsigned Type, Size;
case BytecodeFormat::BasicBlock: {
BCR_TRACE(2, "BLOCK BytecodeFormat::BasicBlock: {\n");
- std::auto_ptr<BasicBlock> BB = ParseBasicBlock(Buf, Buf+Size);
- if (!BB.get() || insertValue(BB.get(), Values) == -1)
- throw std::string("Parse error: BasicBlock");
-
- F->getBasicBlockList().push_back(BB.release());
+ BasicBlock *BB = ParseBasicBlock(Buf, Buf+Size, BlockNum++);
+ F->getBasicBlockList().push_back(BB);
break;
}
case BytecodeFormat::SymbolTable: {
BCR_TRACE(2, "BLOCK BytecodeFormat::SymbolTable: {\n");
- ParseSymbolTable(Buf, Buf+Size, &F->getSymbolTable());
+ ParseSymbolTable(Buf, Buf+Size, &F->getSymbolTable(), F);
break;
}
ALIGN32(Buf, EndBuf);
}
- // Check for unresolvable references
- while (!LateResolveValues.empty()) {
- ValueList &VL = *LateResolveValues.back();
- LateResolveValues.pop_back();
+ // Make sure there were no references to non-existant basic blocks.
+ if (BlockNum != ParsedBasicBlocks.size())
+ throw std::string("Illegal basic block operand reference");
+ ParsedBasicBlocks.clear();
+
- while (!VL.empty()) {
- Value *V = VL.back();
- unsigned IDNumber = getValueIDNumberFromPlaceHolder(V);
- VL.pop_back();
+ // Resolve forward references
+ while (!ForwardReferences.empty()) {
+ std::map<std::pair<unsigned,unsigned>, Value*>::iterator I = ForwardReferences.begin();
+ unsigned type = I->first.first;
+ unsigned Slot = I->first.second;
+ Value *PlaceHolder = I->second;
+ ForwardReferences.erase(I);
- Value *NewVal = getValue(V->getType(), IDNumber, false);
- if (NewVal == 0)
- throw std::string("Unresolvable reference found: <" +
- V->getType()->getDescription() + ">:" +
- utostr(IDNumber) + ".");
+ Value *NewVal = getValue(type, Slot, false);
+ if (NewVal == 0)
+ throw std::string("Unresolvable reference found: <" +
+ PlaceHolder->getType()->getDescription() + ">:" +
+ utostr(Slot) + ".");
- // Fixup all of the uses of this placeholder def...
- V->replaceAllUsesWith(NewVal);
+ // Fixup all of the uses of this placeholder def...
+ PlaceHolder->replaceAllUsesWith(NewVal);
- // Now that all the uses are gone, delete the placeholder...
- // If we couldn't find a def (error case), then leak a little
- // memory, because otherwise we can't remove all uses!
- delete V;
- }
- delete &VL;
+ // Now that all the uses are gone, delete the placeholder...
+ // If we couldn't find a def (error case), then leak a little
+ // memory, because otherwise we can't remove all uses!
+ delete PlaceHolder;
}
// Clear out function-level types...
}
const Type *Ty = getType(SlotNo);
- if (!Ty || !isa<PointerType>(Ty))
+ if (!isa<PointerType>(Ty))
throw std::string("Global not pointer type! Ty = " +
Ty->getDescription());
// Create the global variable...
GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, Linkage,
0, "", TheModule);
- int DestSlot = insertValue(GV, ModuleValues);
- if (DestSlot == -1) throw Error_DestSlot;
BCR_TRACE(2, "Global Variable of type: " << *Ty << "\n");
- ResolveReferencesToValue(GV, (unsigned)DestSlot);
+ ResolveReferencesToValue(GV, insertValue(GV, ModuleValues));
if (VarType & 2) { // Does it have an initializer?
unsigned InitSlot;
if (read_vbr(Buf, End, FnSignature)) throw Error_readvbr;
while (FnSignature != Type::VoidTyID) { // List is terminated by Void
const Type *Ty = getType(FnSignature);
- if (!Ty || !isa<PointerType>(Ty) ||
- !isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
+ if (!isa<PointerType>(Ty) ||
+ !isa<FunctionType>(cast<PointerType>(Ty)->getElementType()))
throw std::string("Function not ptr to func type! Ty = " +
Ty->getDescription());
- }
// We create functions by passing the underlying FunctionType to create...
Ty = cast<PointerType>(Ty)->getElementType();
// Insert the placeholder...
Function *Func = new Function(cast<FunctionType>(Ty),
GlobalValue::InternalLinkage, "", TheModule);
- int DestSlot = insertValue(Func, ModuleValues);
- if (DestSlot == -1) throw Error_DestSlot;
- ResolveReferencesToValue(Func, (unsigned)DestSlot);
+ unsigned DestSlot = insertValue(Func, ModuleValues);
+ ResolveReferencesToValue(Func, DestSlot);
// Keep track of this information in a list that is emptied as functions are
// loaded...
case BytecodeFormat::SymbolTable:
BCR_TRACE(1, "BLOCK BytecodeFormat::SymbolTable: {\n");
- ParseSymbolTable(Buf, Buf+Size, &TheModule->getSymbolTable());
+ ParseSymbolTable(Buf, Buf+Size, &TheModule->getSymbolTable(), 0);
break;
default: