#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/Operator.h"
#include "llvm/AutoUpgrade.h"
using namespace llvm;
void BitcodeReader::FreeState() {
- delete Buffer;
+ if (BufferOwned)
+ delete Buffer;
Buffer = 0;
std::vector<PATypeHolder>().swap(TypeList);
ValueList.clear();
switch (Val) {
default: return -1;
case bitc::BINOP_ADD:
- return Ty->isFPOrFPVector() ? Instruction::FAdd : Instruction::Add;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add;
case bitc::BINOP_SUB:
- return Ty->isFPOrFPVector() ? Instruction::FSub : Instruction::Sub;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub;
case bitc::BINOP_MUL:
- return Ty->isFPOrFPVector() ? Instruction::FMul : Instruction::Mul;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul;
case bitc::BINOP_UDIV: return Instruction::UDiv;
case bitc::BINOP_SDIV:
- return Ty->isFPOrFPVector() ? Instruction::FDiv : Instruction::SDiv;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv;
case bitc::BINOP_UREM: return Instruction::URem;
case bitc::BINOP_SREM:
- return Ty->isFPOrFPVector() ? Instruction::FRem : Instruction::SRem;
+ return Ty->isFPOrFPVectorTy() ? Instruction::FRem : Instruction::SRem;
case bitc::BINOP_SHL: return Instruction::Shl;
case bitc::BINOP_LSHR: return Instruction::LShr;
case bitc::BINOP_ASHR: return Instruction::AShr;
} else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) {
NewC = ConstantStruct::get(Context, &NewOps[0], NewOps.size(),
UserCS->getType()->isPacked());
+ } else if (ConstantUnion *UserCU = dyn_cast<ConstantUnion>(UserC)) {
+ NewC = ConstantUnion::get(UserCU->getType(), NewOps[0]);
} else if (isa<ConstantVector>(UserC)) {
NewC = ConstantVector::get(&NewOps[0], NewOps.size());
} else {
resize(Idx + 1);
if (Value *V = MDValuePtrs[Idx]) {
- assert(V->getType() == Type::getMetadataTy(Context) && "Type mismatch in value table!");
+ assert(V->getType()->isMetadataTy() && "Type mismatch in value table!");
return V;
}
ResultTy = StructType::get(Context, EltTys, Record[0]);
break;
}
+ case bitc::TYPE_CODE_UNION: { // UNION: [eltty x N]
+ SmallVector<const Type*, 8> EltTys;
+ for (unsigned i = 0, e = Record.size(); i != e; ++i)
+ EltTys.push_back(getTypeByID(Record[i], true));
+ ResultTy = UnionType::get(&EltTys[0], EltTys.size());
+ break;
+ }
case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
if (Record.size() < 2)
return Error("Invalid ARRAY type record");
}
bool BitcodeReader::ParseMetadata() {
- unsigned NextValueNo = MDValueList.size();
+ unsigned NextMDValueNo = MDValueList.size();
if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
return Error("Malformed block record");
continue;
}
+ bool IsFunctionLocal = false;
// Read a record.
Record.clear();
switch (Stream.ReadRecord(Code, Record)) {
// Read named metadata elements.
unsigned Size = Record.size();
- SmallVector<MetadataBase*, 8> Elts;
+ SmallVector<MDNode *, 8> Elts;
for (unsigned i = 0; i != Size; ++i) {
- Value *MD = MDValueList.getValueFwdRef(Record[i]);
- if (MetadataBase *B = dyn_cast<MetadataBase>(MD))
- Elts.push_back(B);
+ if (Record[i] == ~0U) {
+ Elts.push_back(NULL);
+ continue;
+ }
+ MDNode *MD = dyn_cast<MDNode>(MDValueList.getValueFwdRef(Record[i]));
+ if (MD == 0)
+ return Error("Malformed metadata record");
+ Elts.push_back(MD);
}
Value *V = NamedMDNode::Create(Context, Name.str(), Elts.data(),
Elts.size(), TheModule);
- MDValueList.AssignValue(V, NextValueNo++);
+ MDValueList.AssignValue(V, NextMDValueNo++);
break;
}
+ case bitc::METADATA_FN_NODE:
+ IsFunctionLocal = true;
+ // fall-through
case bitc::METADATA_NODE: {
if (Record.empty() || Record.size() % 2 == 1)
return Error("Invalid METADATA_NODE record");
SmallVector<Value*, 8> Elts;
for (unsigned i = 0; i != Size; i += 2) {
const Type *Ty = getTypeByID(Record[i], false);
- if (Ty == Type::getMetadataTy(Context))
+ if (Ty->isMetadataTy())
Elts.push_back(MDValueList.getValueFwdRef(Record[i+1]));
- else if (Ty != Type::getVoidTy(Context))
+ else if (!Ty->isVoidTy())
Elts.push_back(ValueList.getValueFwdRef(Record[i+1], Ty));
else
Elts.push_back(NULL);
}
- Value *V = MDNode::get(Context, &Elts[0], Elts.size());
- MDValueList.AssignValue(V, NextValueNo++);
+ Value *V = MDNode::getWhenValsUnresolved(Context, &Elts[0], Elts.size(),
+ IsFunctionLocal);
+ IsFunctionLocal = false;
+ MDValueList.AssignValue(V, NextMDValueNo++);
break;
}
case bitc::METADATA_STRING: {
String[i] = Record[i];
Value *V = MDString::get(Context,
StringRef(String.data(), String.size()));
- MDValueList.AssignValue(V, NextValueNo++);
+ MDValueList.AssignValue(V, NextMDValueNo++);
break;
}
case bitc::METADATA_KIND: {
return Error("Invalid METADATA_KIND record");
SmallString<8> Name;
Name.resize(RecordLength-1);
- MDKindID Kind = Record[0];
+ unsigned Kind = Record[0];
+ (void) Kind;
for (unsigned i = 1; i != RecordLength; ++i)
Name[i-1] = Record[i];
- Metadata &TheMetadata = Context.getMetadata();
- assert(TheMetadata.MDHandlerNames.find(Name.str())
- == TheMetadata.MDHandlerNames.end() &&
- "Already registered MDKind!");
- TheMetadata.MDHandlerNames[Name.str()] = Kind;
+
+ unsigned NewKind = TheModule->getMDKindID(Name.str());
+ assert(Kind == NewKind &&
+ "FIXME: Unable to handle custom metadata mismatch!");(void)NewKind;
break;
}
}
V = Constant::getNullValue(CurTy);
break;
case bitc::CST_CODE_INTEGER: // INTEGER: [intval]
- if (!isa<IntegerType>(CurTy) || Record.empty())
+ if (!CurTy->isIntegerTy() || Record.empty())
return Error("Invalid CST_INTEGER record");
V = ConstantInt::get(CurTy, DecodeSignRotatedValue(Record[0]));
break;
case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval]
- if (!isa<IntegerType>(CurTy) || Record.empty())
+ if (!CurTy->isIntegerTy() || Record.empty())
return Error("Invalid WIDE_INTEGER record");
unsigned NumWords = Record.size();
case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
if (Record.empty())
return Error("Invalid FLOAT record");
- if (CurTy == Type::getFloatTy(Context))
+ if (CurTy->isFloatTy())
V = ConstantFP::get(Context, APFloat(APInt(32, (uint32_t)Record[0])));
- else if (CurTy == Type::getDoubleTy(Context))
+ else if (CurTy->isDoubleTy())
V = ConstantFP::get(Context, APFloat(APInt(64, Record[0])));
- else if (CurTy == Type::getX86_FP80Ty(Context)) {
+ else if (CurTy->isX86_FP80Ty()) {
// Bits are not stored the same way as a normal i80 APInt, compensate.
uint64_t Rearrange[2];
Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16);
Rearrange[1] = Record[0] >> 48;
V = ConstantFP::get(Context, APFloat(APInt(80, 2, Rearrange)));
- } else if (CurTy == Type::getFP128Ty(Context))
+ } else if (CurTy->isFP128Ty())
V = ConstantFP::get(Context, APFloat(APInt(128, 2, &Record[0]), true));
- else if (CurTy == Type::getPPC_FP128Ty(Context))
+ else if (CurTy->isPPC_FP128Ty())
V = ConstantFP::get(Context, APFloat(APInt(128, 2, &Record[0])));
else
V = UndefValue::get(CurTy);
Elts.push_back(ValueList.getConstantFwdRef(Record[i],
STy->getElementType(i)));
V = ConstantStruct::get(STy, Elts);
+ } else if (const UnionType *UnTy = dyn_cast<UnionType>(CurTy)) {
+ uint64_t Index = Record[0];
+ Constant *Val = ValueList.getConstantFwdRef(Record[1],
+ UnTy->getElementType(Index));
+ V = ConstantUnion::get(UnTy, Val);
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) {
const Type *EltTy = ATy->getElementType();
for (unsigned i = 0; i != Size; ++i)
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
- if (OpTy->isFloatingPoint())
+ if (OpTy->isFPOrFPVectorTy())
V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
else
V = ConstantExpr::getICmp(Record[3], Op0, Op1);
case bitc::CST_CODE_INLINEASM: {
if (Record.size() < 2) return Error("Invalid INLINEASM record");
std::string AsmStr, ConstrStr;
- bool HasSideEffects = Record[0];
+ bool HasSideEffects = Record[0] & 1;
+ bool IsAlignStack = Record[0] >> 1;
unsigned AsmStrSize = Record[1];
if (2+AsmStrSize >= Record.size())
return Error("Invalid INLINEASM record");
ConstrStr += (char)Record[3+AsmStrSize+i];
const PointerType *PTy = cast<PointerType>(CurTy);
V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
- AsmStr, ConstrStr, HasSideEffects);
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
break;
}
+ case bitc::CST_CODE_BLOCKADDRESS:{
+ if (Record.size() < 3) return Error("Invalid CE_BLOCKADDRESS record");
+ const Type *FnTy = getTypeByID(Record[0]);
+ if (FnTy == 0) return Error("Invalid CE_BLOCKADDRESS record");
+ Function *Fn =
+ dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
+ if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record");
+
+ GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(),
+ Type::getInt8Ty(Context),
+ false, GlobalValue::InternalLinkage,
+ 0, "");
+ BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
+ V = FwdRef;
+ break;
+ }
}
ValueList.AssignValue(V, NextCstNo);
// Save the current stream state.
uint64_t CurBit = Stream.GetCurrentBitNo();
- DeferredFunctionInfo[Fn] = std::make_pair(CurBit, Fn->getLinkage());
-
- // Set the functions linkage to GhostLinkage so we know it is lazily
- // deserialized.
- Fn->setLinkage(GlobalValue::GhostLinkage);
+ DeferredFunctionInfo[Fn] = CurBit;
// Skip over the function block for now.
if (Stream.SkipBlock())
return false;
}
-bool BitcodeReader::ParseModule(const std::string &ModuleID) {
- // Reject multiple MODULE_BLOCK's in a single bitstream.
- if (TheModule)
- return Error("Multiple MODULE_BLOCKs in same stream");
-
+bool BitcodeReader::ParseModule() {
if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
return Error("Malformed block record");
- // Otherwise, create the module.
- TheModule = new Module(ModuleID, Context);
-
SmallVector<uint64_t, 64> Record;
std::vector<std::string> SectionTable;
std::vector<std::string> GCTable;
if (Record.size() < 6)
return Error("Invalid MODULE_CODE_GLOBALVAR record");
const Type *Ty = getTypeByID(Record[0]);
- if (!isa<PointerType>(Ty))
+ if (!Ty->isPointerTy())
return Error("Global not a pointer type!");
unsigned AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
Ty = cast<PointerType>(Ty)->getElementType();
if (Record.size() < 8)
return Error("Invalid MODULE_CODE_FUNCTION record");
const Type *Ty = getTypeByID(Record[0]);
- if (!isa<PointerType>(Ty))
+ if (!Ty->isPointerTy())
return Error("Function not a pointer type!");
const FunctionType *FTy =
dyn_cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
if (Record.size() < 3)
return Error("Invalid MODULE_ALIAS record");
const Type *Ty = getTypeByID(Record[0]);
- if (!isa<PointerType>(Ty))
+ if (!Ty->isPointerTy())
return Error("Function not a pointer type!");
GlobalAlias *NewGA = new GlobalAlias(Ty, GetDecodedLinkage(Record[2]),
return Error("Premature end of bitstream");
}
-bool BitcodeReader::ParseBitcode() {
+bool BitcodeReader::ParseBitcodeInto(Module *M) {
TheModule = 0;
- if (Buffer->getBufferSize() & 3)
- return Error("Bitcode stream should be a multiple of 4 bytes in length");
-
unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
+ if (Buffer->getBufferSize() & 3) {
+ if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
+ return Error("Invalid bitcode signature");
+ else
+ return Error("Bitcode stream should be a multiple of 4 bytes in length");
+ }
+
// If we have a wrapper header, parse it and ignore the non-bc file contents.
// The magic number is 0x0B17C0DE stored in little endian.
if (isBitcodeWrapper(BufPtr, BufEnd))
return Error("Malformed BlockInfoBlock");
break;
case bitc::MODULE_BLOCK_ID:
- if (ParseModule(Buffer->getBufferIdentifier()))
+ // Reject multiple MODULE_BLOCK's in a single bitstream.
+ if (TheModule)
+ return Error("Multiple MODULE_BLOCKs in same stream");
+ TheModule = M;
+ if (ParseModule())
return true;
break;
default:
if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
return Error("Malformed block record");
- Metadata &TheMetadata = Context.getMetadata();
SmallVector<uint64_t, 64> Record;
while(1) {
unsigned Code = Stream.ReadCode();
return Error ("Invalid METADATA_ATTACHMENT reader!");
Instruction *Inst = InstructionList[Record[0]];
for (unsigned i = 1; i != RecordLength; i = i+2) {
- MDKindID Kind = Record[i];
+ unsigned Kind = Record[i];
Value *Node = MDValueList.getValueFwdRef(Record[i+1]);
- TheMetadata.setMD(Kind, cast<MDNode>(Node), Inst);
+ Inst->setMetadata(Kind, cast<MDNode>(Node));
}
break;
}
if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
return Error("Malformed block record");
+ InstructionList.clear();
unsigned ModuleValueListSize = ValueList.size();
// Add all the function arguments to the value table.
BasicBlock *CurBB = 0;
unsigned CurBBNo = 0;
+ DebugLoc LastLoc;
+
// Read all the records.
SmallVector<uint64_t, 64> Record;
while (1) {
case bitc::METADATA_ATTACHMENT_ID:
if (ParseMetadataAttachment()) return true;
break;
+ case bitc::METADATA_BLOCK_ID:
+ if (ParseMetadata()) return true;
+ break;
}
continue;
}
CurBB = FunctionBBs[0];
continue;
+
+ case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: // DEBUG_LOC_AGAIN
+ // This record indicates that the last instruction is at the same
+ // location as the previous instruction with a location.
+ I = 0;
+
+ // Get the last instruction emitted.
+ if (CurBB && !CurBB->empty())
+ I = &CurBB->back();
+ else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
+ !FunctionBBs[CurBBNo-1]->empty())
+ I = &FunctionBBs[CurBBNo-1]->back();
+
+ if (I == 0) return Error("Invalid DEBUG_LOC_AGAIN record");
+ I->setDebugLoc(LastLoc);
+ I = 0;
+ continue;
+
+ case bitc::FUNC_CODE_DEBUG_LOC: { // DEBUG_LOC: [line, col, scope, ia]
+ I = 0; // Get the last instruction emitted.
+ if (CurBB && !CurBB->empty())
+ I = &CurBB->back();
+ else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
+ !FunctionBBs[CurBBNo-1]->empty())
+ I = &FunctionBBs[CurBBNo-1]->back();
+ if (I == 0 || Record.size() < 4)
+ return Error("Invalid FUNC_CODE_DEBUG_LOC record");
+
+ unsigned Line = Record[0], Col = Record[1];
+ unsigned ScopeID = Record[2], IAID = Record[3];
+
+ MDNode *Scope = 0, *IA = 0;
+ if (ScopeID) Scope = cast<MDNode>(MDValueList.getValueFwdRef(ScopeID-1));
+ if (IAID) IA = cast<MDNode>(MDValueList.getValueFwdRef(IAID-1));
+ LastLoc = DebugLoc::get(Line, Col, Scope, IA);
+ I->setDebugLoc(LastLoc);
+ I = 0;
+ continue;
+ }
+
case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode]
unsigned OpNum = 0;
Value *LHS, *RHS;
if (Opc == Instruction::Add ||
Opc == Instruction::Sub ||
Opc == Instruction::Mul) {
- if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+ if (Record[OpNum] & (1 << bitc::OBO_NO_SIGNED_WRAP))
cast<BinaryOperator>(I)->setHasNoSignedWrap(true);
- if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+ if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true);
} else if (Opc == Instruction::SDiv) {
- if (Record[3] & (1 << bitc::SDIV_EXACT))
+ if (Record[OpNum] & (1 << bitc::SDIV_EXACT))
cast<BinaryOperator>(I)->setIsExact(true);
}
}
OpNum+1 != Record.size())
return Error("Invalid CMP record");
- if (LHS->getType()->isFPOrFPVector())
+ if (LHS->getType()->isFPOrFPVectorTy())
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
else
I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
const Type *ReturnType = F->getReturnType();
if (Vs.size() > 1 ||
- (isa<StructType>(ReturnType) &&
+ (ReturnType->isStructTy() &&
(Vs.empty() || Vs[0]->getType() != ReturnType))) {
Value *RV = UndefValue::get(ReturnType);
for (unsigned i = 0, e = Vs.size(); i != e; ++i) {
}
break;
}
- case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, opval, n, n x ops]
+ case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
if (Record.size() < 3 || (Record.size() & 1) == 0)
return Error("Invalid SWITCH record");
const Type *OpTy = getTypeByID(Record[0]);
I = SI;
break;
}
-
+ case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...]
+ if (Record.size() < 2)
+ return Error("Invalid INDIRECTBR record");
+ const Type *OpTy = getTypeByID(Record[0]);
+ Value *Address = getFnValueByID(Record[1], OpTy);
+ if (OpTy == 0 || Address == 0)
+ return Error("Invalid INDIRECTBR record");
+ unsigned NumDests = Record.size()-2;
+ IndirectBrInst *IBI = IndirectBrInst::Create(Address, NumDests);
+ InstructionList.push_back(IBI);
+ for (unsigned i = 0, e = NumDests; i != e; ++i) {
+ if (BasicBlock *DestBB = getBasicBlock(Record[2+i])) {
+ IBI->addDestination(DestBB);
+ } else {
+ delete IBI;
+ return Error("Invalid INDIRECTBR record!");
+ }
+ }
+ I = IBI;
+ break;
+ }
+
case bitc::FUNC_CODE_INST_INVOKE: {
// INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...]
if (Record.size() < 4) return Error("Invalid INVOKE record");
case bitc::FUNC_CODE_INST_MALLOC: { // MALLOC: [instty, op, align]
// Autoupgrade malloc instruction to malloc call.
+ // FIXME: Remove in LLVM 3.0.
if (Record.size() < 3)
return Error("Invalid MALLOC record");
const PointerType *Ty =
Value *Size = getFnValueByID(Record[1], Type::getInt32Ty(Context));
if (!Ty || !Size) return Error("Invalid MALLOC record");
if (!CurBB) return Error("Invalid malloc instruction with no BB");
- const Type* Int32Ty = IntegerType::getInt32Ty(CurBB->getContext());
- if (Size->getType() != Int32Ty)
- Size = CastInst::CreateIntegerCast(Size, Int32Ty, false /*ZExt*/,
- "", CurBB);
- Value* Malloc = CallInst::CreateMalloc(CurBB, Int32Ty,
- Ty->getElementType(), Size, NULL);
- I = cast<Instruction>(Malloc);
+ const Type *Int32Ty = IntegerType::getInt32Ty(CurBB->getContext());
+ Constant *AllocSize = ConstantExpr::getSizeOf(Ty->getElementType());
+ AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, Int32Ty);
+ I = CallInst::CreateMalloc(CurBB, Int32Ty, Ty->getElementType(),
+ AllocSize, Size, NULL);
InstructionList.push_back(I);
break;
}
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
OpNum != Record.size())
return Error("Invalid FREE record");
- I = new FreeInst(Op);
+ if (!CurBB) return Error("Invalid free instruction with no BB");
+ I = CallInst::CreateFree(Op, CurBB);
InstructionList.push_back(I);
break;
}
}
// Non-void values get registered in the value table for future use.
- if (I && I->getType() != Type::getVoidTy(Context))
+ if (I && !I->getType()->isVoidTy())
ValueList.AssignValue(I, NextValueNo++);
}
}
}
+ // See if anything took the address of blocks in this function. If so,
+ // resolve them now.
+ DenseMap<Function*, std::vector<BlockAddrRefTy> >::iterator BAFRI =
+ BlockAddrFwdRefs.find(F);
+ if (BAFRI != BlockAddrFwdRefs.end()) {
+ std::vector<BlockAddrRefTy> &RefList = BAFRI->second;
+ for (unsigned i = 0, e = RefList.size(); i != e; ++i) {
+ unsigned BlockIdx = RefList[i].first;
+ if (BlockIdx >= FunctionBBs.size())
+ return Error("Invalid blockaddress block #");
+
+ GlobalVariable *FwdRef = RefList[i].second;
+ FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx]));
+ FwdRef->eraseFromParent();
+ }
+
+ BlockAddrFwdRefs.erase(BAFRI);
+ }
+
// Trim the value list down to the size it was before we parsed this function.
ValueList.shrinkTo(ModuleValueListSize);
std::vector<BasicBlock*>().swap(FunctionBBs);
}
//===----------------------------------------------------------------------===//
-// ModuleProvider implementation
+// GVMaterializer implementation
//===----------------------------------------------------------------------===//
-bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) {
- // If it already is material, ignore the request.
- if (!F->hasNotBeenReadFromBitcode()) return false;
+bool BitcodeReader::isMaterializable(const GlobalValue *GV) const {
+ if (const Function *F = dyn_cast<Function>(GV)) {
+ return F->isDeclaration() &&
+ DeferredFunctionInfo.count(const_cast<Function*>(F));
+ }
+ return false;
+}
- DenseMap<Function*, std::pair<uint64_t, unsigned> >::iterator DFII =
- DeferredFunctionInfo.find(F);
+bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) {
+ Function *F = dyn_cast<Function>(GV);
+ // If it's not a function or is already material, ignore the request.
+ if (!F || !F->isMaterializable()) return false;
+
+ DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F);
assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
- // Move the bit stream to the saved position of the deferred function body and
- // restore the real linkage type for the function.
- Stream.JumpToBit(DFII->second.first);
- F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second);
+ // Move the bit stream to the saved position of the deferred function body.
+ Stream.JumpToBit(DFII->second);
if (ParseFunctionBody(F)) {
if (ErrInfo) *ErrInfo = ErrorString;
return false;
}
-void BitcodeReader::dematerializeFunction(Function *F) {
- // If this function isn't materialized, or if it is a proto, this is a noop.
- if (F->hasNotBeenReadFromBitcode() || F->isDeclaration())
+bool BitcodeReader::isDematerializable(const GlobalValue *GV) const {
+ const Function *F = dyn_cast<Function>(GV);
+ if (!F || F->isDeclaration())
+ return false;
+ return DeferredFunctionInfo.count(const_cast<Function*>(F));
+}
+
+void BitcodeReader::Dematerialize(GlobalValue *GV) {
+ Function *F = dyn_cast<Function>(GV);
+ // If this function isn't dematerializable, this is a noop.
+ if (!F || !isDematerializable(F))
return;
assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
// Just forget the function body, we can remat it later.
F->deleteBody();
- F->setLinkage(GlobalValue::GhostLinkage);
}
-Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
+bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
+ assert(M == TheModule &&
+ "Can only Materialize the Module this BitcodeReader is attached to.");
// Iterate over the module, deserializing any functions that are still on
// disk.
for (Module::iterator F = TheModule->begin(), E = TheModule->end();
F != E; ++F)
- if (F->hasNotBeenReadFromBitcode() &&
- materializeFunction(F, ErrInfo))
- return 0;
+ if (F->isMaterializable() &&
+ Materialize(F, ErrInfo))
+ return true;
// Upgrade any intrinsic calls that slipped through (should not happen!) and
// delete the old functions to clean up. We can't do this unless the entire
// Check debug info intrinsics.
CheckDebugInfoIntrinsics(TheModule);
- return TheModule;
-}
-
-
-/// This method is provided by the parent ModuleProvde class and overriden
-/// here. It simply releases the module from its provided and frees up our
-/// state.
-/// @brief Release our hold on the generated module
-Module *BitcodeReader::releaseModule(std::string *ErrInfo) {
- // Since we're losing control of this Module, we must hand it back complete
- Module *M = ModuleProvider::releaseModule(ErrInfo);
- FreeState();
- return M;
+ return false;
}
// External interface
//===----------------------------------------------------------------------===//
-/// getBitcodeModuleProvider - lazy function-at-a-time loading from a file.
+/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
///
-ModuleProvider *llvm::getBitcodeModuleProvider(MemoryBuffer *Buffer,
- LLVMContext& Context,
- std::string *ErrMsg) {
+Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
+ LLVMContext& Context,
+ std::string *ErrMsg) {
+ Module *M = new Module(Buffer->getBufferIdentifier(), Context);
BitcodeReader *R = new BitcodeReader(Buffer, Context);
- if (R->ParseBitcode()) {
+ M->setMaterializer(R);
+ if (R->ParseBitcodeInto(M)) {
if (ErrMsg)
*ErrMsg = R->getErrorString();
- // Don't let the BitcodeReader dtor delete 'Buffer'.
- R->releaseMemoryBuffer();
- delete R;
+ delete M; // Also deletes R.
return 0;
}
- return R;
+ // Have the BitcodeReader dtor delete 'Buffer'.
+ R->setBufferOwned(true);
+ return M;
}
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
/// If an error occurs, return null and fill in *ErrMsg if non-null.
Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
std::string *ErrMsg){
- BitcodeReader *R;
- R = static_cast<BitcodeReader*>(getBitcodeModuleProvider(Buffer, Context,
- ErrMsg));
- if (!R) return 0;
-
- // Read in the entire module.
- Module *M = R->materializeModule(ErrMsg);
+ Module *M = getLazyBitcodeModule(Buffer, Context, ErrMsg);
+ if (!M) return 0;
// Don't let the BitcodeReader dtor delete 'Buffer', regardless of whether
// there was an error.
- R->releaseMemoryBuffer();
+ static_cast<BitcodeReader*>(M->getMaterializer())->setBufferOwned(false);
- // If there was no error, tell ModuleProvider not to delete it when its dtor
- // is run.
- if (M)
- M = R->releaseModule(ErrMsg);
-
- delete R;
+ // Read in the entire module, and destroy the BitcodeReader.
+ if (M->MaterializeAllPermanently(ErrMsg)) {
+ delete M;
+ return NULL;
+ }
return M;
}