mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 20:59:51 +00:00
Write and read metadata attachments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82259 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
88d9839d07
commit
e8e0213cc3
@ -34,7 +34,8 @@ namespace bitc {
|
||||
FUNCTION_BLOCK_ID,
|
||||
TYPE_SYMTAB_BLOCK_ID,
|
||||
VALUE_SYMTAB_BLOCK_ID,
|
||||
METADATA_BLOCK_ID
|
||||
METADATA_BLOCK_ID,
|
||||
METADATA_ATTACHMENT_ID
|
||||
};
|
||||
|
||||
|
||||
@ -111,7 +112,9 @@ namespace bitc {
|
||||
METADATA_STRING = 1, // MDSTRING: [values]
|
||||
METADATA_NODE = 2, // MDNODE: [n x (type num, value num)]
|
||||
METADATA_NAME = 3, // STRING: [values]
|
||||
METADATA_NAMED_NODE = 4 // NAMEDMDNODE: [n x mdnodes]
|
||||
METADATA_NAMED_NODE = 4, // NAMEDMDNODE: [n x mdnodes]
|
||||
METADATA_KIND = 5, // [n x [id, name]]
|
||||
METADATA_ATTACHMENT = 6 // [m x [value, [n x [id, mdnode]]]
|
||||
};
|
||||
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
|
||||
// constant and maintains an implicit current type value.
|
||||
|
@ -311,13 +311,14 @@ public:
|
||||
/// MDKindID - This id identifies metadata kind the metadata store. Valid
|
||||
/// ID values are 1 or higher. This ID is set by RegisterMDKind.
|
||||
typedef unsigned MDKindID;
|
||||
|
||||
class Metadata {
|
||||
public:
|
||||
typedef std::pair<MDKindID, WeakVH> MDPairTy;
|
||||
typedef SmallVector<MDPairTy, 2> MDMapTy;
|
||||
|
||||
private:
|
||||
typedef DenseMap<const Instruction *, MDMapTy> MDStoreTy;
|
||||
friend class BitcodeReader;
|
||||
private:
|
||||
|
||||
/// MetadataStore - Collection of metadata used in this context.
|
||||
MDStoreTy MetadataStore;
|
||||
@ -344,6 +345,10 @@ public:
|
||||
/// setMD - Attach the metadata of given kind with an Instruction.
|
||||
void setMD(MDKindID Kind, MDNode *Node, Instruction *Inst);
|
||||
|
||||
/// getHandlerNames - Get handler names. This is used by bitcode
|
||||
/// writer.
|
||||
const StringMap<unsigned> *getHandlerNames();
|
||||
|
||||
/// ValueIsDeleted - This handler is used to update metadata store
|
||||
/// when a value is deleted.
|
||||
void ValueIsDeleted(Value *V) {}
|
||||
|
@ -830,6 +830,22 @@ bool BitcodeReader::ParseMetadata() {
|
||||
MDValueList.AssignValue(V, NextValueNo++);
|
||||
break;
|
||||
}
|
||||
case bitc::METADATA_KIND: {
|
||||
unsigned RecordLength = Record.size();
|
||||
if (Record.empty() || RecordLength < 2)
|
||||
return Error("Invalid METADATA_KIND record");
|
||||
SmallString<8> Name;
|
||||
Name.resize(RecordLength-1);
|
||||
MDKindID Kind = Record[0];
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1535,6 +1551,45 @@ bool BitcodeReader::ParseBitcode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseMetadataAttachment - Parse metadata attachments.
|
||||
bool BitcodeReader::ParseMetadataAttachment() {
|
||||
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();
|
||||
if (Code == bitc::END_BLOCK) {
|
||||
if (Stream.ReadBlockEnd())
|
||||
return Error("Error at end of PARAMATTR block");
|
||||
break;
|
||||
}
|
||||
if (Code == bitc::DEFINE_ABBREV) {
|
||||
Stream.ReadAbbrevRecord();
|
||||
continue;
|
||||
}
|
||||
// Read a metadata attachment record.
|
||||
Record.clear();
|
||||
switch (Stream.ReadRecord(Code, Record)) {
|
||||
default: // Default behavior: ignore.
|
||||
break;
|
||||
case bitc::METADATA_ATTACHMENT: {
|
||||
unsigned RecordLength = Record.size();
|
||||
if (Record.empty() || (RecordLength - 1) % 2 == 1)
|
||||
return Error ("Invalid METADATA_ATTACHMENT reader!");
|
||||
Instruction *Inst = InstructionList[Record[0]];
|
||||
for (unsigned i = 1; i != RecordLength; i = i+2) {
|
||||
MDKindID Kind = Record[i];
|
||||
Value *Node = MDValueList.getValueFwdRef(Record[i+1]);
|
||||
TheMetadata.setMD(Kind, cast<MDNode>(Node), Inst);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseFunctionBody - Lazily parse the specified function body block.
|
||||
bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
@ -1574,6 +1629,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
case bitc::VALUE_SYMTAB_BLOCK_ID:
|
||||
if (ParseValueSymbolTable()) return true;
|
||||
break;
|
||||
case bitc::METADATA_ATTACHMENT_ID:
|
||||
if (ParseMetadataAttachment()) return true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -1611,6 +1669,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
|
||||
if (Opc == -1) return Error("Invalid BINOP record");
|
||||
I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
|
||||
InstructionList.push_back(I);
|
||||
if (OpNum < Record.size()) {
|
||||
if (Opc == Instruction::Add ||
|
||||
Opc == Instruction::Sub ||
|
||||
@ -1638,6 +1697,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
if (Opc == -1 || ResTy == 0)
|
||||
return Error("Invalid CAST record");
|
||||
I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_INBOUNDS_GEP:
|
||||
@ -1656,6 +1716,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
}
|
||||
|
||||
I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end());
|
||||
InstructionList.push_back(I);
|
||||
if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
|
||||
cast<GetElementPtrInst>(I)->setIsInBounds(true);
|
||||
break;
|
||||
@ -1679,6 +1740,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
|
||||
I = ExtractValueInst::Create(Agg,
|
||||
EXTRACTVALIdx.begin(), EXTRACTVALIdx.end());
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1703,6 +1765,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
|
||||
I = InsertValueInst::Create(Agg, Val,
|
||||
INSERTVALIdx.begin(), INSERTVALIdx.end());
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1717,6 +1780,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
return Error("Invalid SELECT record");
|
||||
|
||||
I = SelectInst::Create(Cond, TrueVal, FalseVal);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1743,6 +1807,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
}
|
||||
|
||||
I = SelectInst::Create(Cond, TrueVal, FalseVal);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1753,6 +1818,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
|
||||
return Error("Invalid EXTRACTELT record");
|
||||
I = ExtractElementInst::Create(Vec, Idx);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1765,6 +1831,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
|
||||
return Error("Invalid INSERTELT record");
|
||||
I = InsertElementInst::Create(Vec, Elt, Idx);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1778,6 +1845,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
if (getValueTypePair(Record, OpNum, NextValueNo, Mask))
|
||||
return Error("Invalid SHUFFLEVEC record");
|
||||
I = new ShuffleVectorInst(Vec1, Vec2, Mask);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1799,6 +1867,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
|
||||
else
|
||||
I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1810,6 +1879,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
getValueTypePair(Record, OpNum, NextValueNo, Op);
|
||||
unsigned Index = Record[1];
|
||||
I = ExtractValueInst::Create(Op, Index);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1818,6 +1888,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
unsigned Size = Record.size();
|
||||
if (Size == 0) {
|
||||
I = ReturnInst::Create(Context);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1837,15 +1908,18 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
Value *RV = UndefValue::get(ReturnType);
|
||||
for (unsigned i = 0, e = Vs.size(); i != e; ++i) {
|
||||
I = InsertValueInst::Create(RV, Vs[i], i, "mrv");
|
||||
InstructionList.push_back(I);
|
||||
CurBB->getInstList().push_back(I);
|
||||
ValueList.AssignValue(I, NextValueNo++);
|
||||
RV = I;
|
||||
}
|
||||
I = ReturnInst::Create(Context, RV);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
||||
I = ReturnInst::Create(Context, Vs[0]);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
|
||||
@ -1855,14 +1929,17 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
if (TrueDest == 0)
|
||||
return Error("Invalid BR record");
|
||||
|
||||
if (Record.size() == 1)
|
||||
if (Record.size() == 1) {
|
||||
I = BranchInst::Create(TrueDest);
|
||||
InstructionList.push_back(I);
|
||||
}
|
||||
else {
|
||||
BasicBlock *FalseDest = getBasicBlock(Record[1]);
|
||||
Value *Cond = getFnValueByID(Record[2], Type::getInt1Ty(Context));
|
||||
if (FalseDest == 0 || Cond == 0)
|
||||
return Error("Invalid BR record");
|
||||
I = BranchInst::Create(TrueDest, FalseDest, Cond);
|
||||
InstructionList.push_back(I);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1876,6 +1953,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
return Error("Invalid SWITCH record");
|
||||
unsigned NumCases = (Record.size()-3)/2;
|
||||
SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
|
||||
InstructionList.push_back(SI);
|
||||
for (unsigned i = 0, e = NumCases; i != e; ++i) {
|
||||
ConstantInt *CaseVal =
|
||||
dyn_cast_or_null<ConstantInt>(getFnValueByID(Record[3+i*2], OpTy));
|
||||
@ -1933,6 +2011,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
|
||||
I = InvokeInst::Create(Callee, NormalBB, UnwindBB,
|
||||
Ops.begin(), Ops.end());
|
||||
InstructionList.push_back(I);
|
||||
cast<InvokeInst>(I)->setCallingConv(
|
||||
static_cast<CallingConv::ID>(CCInfo));
|
||||
cast<InvokeInst>(I)->setAttributes(PAL);
|
||||
@ -1940,9 +2019,11 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_UNWIND: // UNWIND
|
||||
I = new UnwindInst(Context);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
|
||||
I = new UnreachableInst(Context);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
|
||||
if (Record.size() < 1 || ((Record.size()-1)&1))
|
||||
@ -1951,6 +2032,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
if (!Ty) return Error("Invalid PHI record");
|
||||
|
||||
PHINode *PN = PHINode::Create(Ty);
|
||||
InstructionList.push_back(PN);
|
||||
PN->reserveOperandSpace((Record.size()-1)/2);
|
||||
|
||||
for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
|
||||
@ -1972,6 +2054,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
unsigned Align = Record[2];
|
||||
if (!Ty || !Size) return Error("Invalid MALLOC record");
|
||||
I = new MallocInst(Ty->getElementType(), Size, (1 << Align) >> 1);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_FREE: { // FREE: [op, opty]
|
||||
@ -1981,6 +2064,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
OpNum != Record.size())
|
||||
return Error("Invalid FREE record");
|
||||
I = new FreeInst(Op);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, op, align]
|
||||
@ -1992,6 +2076,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
unsigned Align = Record[2];
|
||||
if (!Ty || !Size) return Error("Invalid ALLOCA record");
|
||||
I = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol]
|
||||
@ -2002,6 +2087,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
return Error("Invalid LOAD record");
|
||||
|
||||
I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_STORE2: { // STORE2:[ptrty, ptr, val, align, vol]
|
||||
@ -2014,6 +2100,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
return Error("Invalid STORE record");
|
||||
|
||||
I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_STORE: { // STORE:[val, valty, ptr, align, vol]
|
||||
@ -2027,6 +2114,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
return Error("Invalid STORE record");
|
||||
|
||||
I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_CALL: {
|
||||
@ -2072,6 +2160,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
}
|
||||
|
||||
I = CallInst::Create(Callee, Args.begin(), Args.end());
|
||||
InstructionList.push_back(I);
|
||||
cast<CallInst>(I)->setCallingConv(
|
||||
static_cast<CallingConv::ID>(CCInfo>>1));
|
||||
cast<CallInst>(I)->setTailCall(CCInfo & 1);
|
||||
@ -2087,6 +2176,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
if (!OpTy || !Op || !ResTy)
|
||||
return Error("Invalid VAARG record");
|
||||
I = new VAArgInst(Op, ResTy);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +132,8 @@ class BitcodeReader : public ModuleProvider {
|
||||
std::vector<PATypeHolder> TypeList;
|
||||
BitcodeReaderValueList ValueList;
|
||||
BitcodeReaderMDValueList MDValueList;
|
||||
SmallVector<Instruction *, 64> InstructionList;
|
||||
|
||||
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
|
||||
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
|
||||
|
||||
@ -250,6 +252,7 @@ private:
|
||||
bool ParseFunctionBody(Function *F);
|
||||
bool ResolveGlobalAndAliasInits();
|
||||
bool ParseMetadata();
|
||||
bool ParseMetadataAttachment();
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -551,7 +551,74 @@ static void WriteModuleMetadata(const ValueEnumerator &VE,
|
||||
}
|
||||
|
||||
if (StartedMetadataBlock)
|
||||
Stream.ExitBlock();
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
static void WriteMetadataAttachment(const Function &F,
|
||||
const ValueEnumerator &VE,
|
||||
BitstreamWriter &Stream) {
|
||||
bool StartedMetadataBlock = false;
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
|
||||
// Write metadata attachments
|
||||
// METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
|
||||
Metadata &TheMetadata = F.getContext().getMetadata();
|
||||
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
||||
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
|
||||
I != E; ++I) {
|
||||
const Metadata::MDMapTy *P = TheMetadata.getMDs(I);
|
||||
if (!P) continue;
|
||||
bool RecordedInstruction = false;
|
||||
for (Metadata::MDMapTy::const_iterator PI = P->begin(), PE = P->end();
|
||||
PI != PE; ++PI) {
|
||||
if (MDNode *ND = dyn_cast_or_null<MDNode>(PI->second)) {
|
||||
if (RecordedInstruction == false) {
|
||||
Record.push_back(VE.getInstructionID(I));
|
||||
RecordedInstruction = true;
|
||||
}
|
||||
Record.push_back(PI->first);
|
||||
Record.push_back(VE.getValueID(ND));
|
||||
}
|
||||
}
|
||||
if (!StartedMetadataBlock) {
|
||||
Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
|
||||
StartedMetadataBlock = true;
|
||||
}
|
||||
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
|
||||
Record.clear();
|
||||
}
|
||||
|
||||
if (StartedMetadataBlock)
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
static void WriteModuleMetadataStore(const Module *M,
|
||||
const ValueEnumerator &VE,
|
||||
BitstreamWriter &Stream) {
|
||||
|
||||
bool StartedMetadataBlock = false;
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
|
||||
// Write metadata kinds
|
||||
// METADATA_KIND - [n x [id, name]]
|
||||
Metadata &TheMetadata = M->getContext().getMetadata();
|
||||
const StringMap<unsigned> *Kinds = TheMetadata.getHandlerNames();
|
||||
for (StringMap<unsigned>::const_iterator
|
||||
I = Kinds->begin(), E = Kinds->end(); I != E; ++I) {
|
||||
Record.push_back(I->second);
|
||||
StringRef KName = I->first();
|
||||
for (unsigned i = 0, e = KName.size(); i != e; ++i)
|
||||
Record.push_back(KName[i]);
|
||||
if (!StartedMetadataBlock) {
|
||||
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
|
||||
StartedMetadataBlock = true;
|
||||
}
|
||||
Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
|
||||
Record.clear();
|
||||
}
|
||||
|
||||
if (StartedMetadataBlock)
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
static void WriteConstants(unsigned FirstVal, unsigned LastVal,
|
||||
@ -833,6 +900,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||
SmallVector<unsigned, 64> &Vals) {
|
||||
unsigned Code = 0;
|
||||
unsigned AbbrevToUse = 0;
|
||||
VE.setInstructionID(&I);
|
||||
switch (I.getOpcode()) {
|
||||
default:
|
||||
if (Instruction::isCast(I.getOpcode())) {
|
||||
@ -1146,7 +1214,8 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
|
||||
|
||||
// Emit names for all the instructions etc.
|
||||
WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
|
||||
|
||||
|
||||
WriteMetadataAttachment(F, VE, Stream);
|
||||
VE.purgeFunction();
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
@ -1390,6 +1459,9 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
|
||||
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||
if (!I->isDeclaration())
|
||||
WriteFunction(*I, VE, Stream);
|
||||
|
||||
// Emit metadata.
|
||||
WriteModuleMetadataStore(M, VE, Stream);
|
||||
|
||||
// Emit the type symbol table information.
|
||||
WriteTypeSymbolTable(M->getTypeSymbolTable(), VE, Stream);
|
||||
|
@ -40,6 +40,8 @@ static bool CompareByFrequency(const std::pair<const llvm::Type*,
|
||||
|
||||
/// ValueEnumerator - Enumerate module-level information.
|
||||
ValueEnumerator::ValueEnumerator(const Module *M) {
|
||||
InstructionCount = 0;
|
||||
|
||||
// Enumerate the global variables.
|
||||
for (Module::const_global_iterator I = M->global_begin(),
|
||||
E = M->global_end(); I != E; ++I)
|
||||
@ -83,7 +85,8 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
|
||||
for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
|
||||
I != E; ++I)
|
||||
EnumerateType(I->getType());
|
||||
|
||||
|
||||
Metadata &TheMetadata = F->getContext().getMetadata();
|
||||
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
|
||||
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I){
|
||||
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
|
||||
@ -94,6 +97,14 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
|
||||
EnumerateAttributes(CI->getAttributes());
|
||||
else if (const InvokeInst *II = dyn_cast<InvokeInst>(I))
|
||||
EnumerateAttributes(II->getAttributes());
|
||||
|
||||
// Enumerate metadata attached with this instruction.
|
||||
const Metadata::MDMapTy *MDs = TheMetadata.getMDs(I);
|
||||
if (MDs)
|
||||
for (Metadata::MDMapTy::const_iterator MI = MDs->begin(),
|
||||
ME = MDs->end(); MI != ME; ++MI)
|
||||
if (MDNode *MDN = dyn_cast_or_null<MDNode>(MI->second))
|
||||
EnumerateMetadata(MDN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,6 +125,16 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
|
||||
TypeMap[Types[i].first] = i+1;
|
||||
}
|
||||
|
||||
unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
|
||||
InstructionMapType::const_iterator I = InstructionMap.find(Inst);
|
||||
assert (I != InstructionMap.end() && "Instruction is not mapped!");
|
||||
return I->second;
|
||||
}
|
||||
|
||||
void ValueEnumerator::setInstructionID(const Instruction *I) {
|
||||
InstructionMap[I] = InstructionCount++;
|
||||
}
|
||||
|
||||
unsigned ValueEnumerator::getValueID(const Value *V) const {
|
||||
if (isa<MetadataBase>(V)) {
|
||||
ValueMapType::const_iterator I = MDValueMap.find(V);
|
||||
|
@ -22,6 +22,7 @@ namespace llvm {
|
||||
|
||||
class Type;
|
||||
class Value;
|
||||
class Instruction;
|
||||
class BasicBlock;
|
||||
class Function;
|
||||
class Module;
|
||||
@ -47,11 +48,15 @@ private:
|
||||
ValueList Values;
|
||||
ValueList MDValues;
|
||||
ValueMapType MDValueMap;
|
||||
|
||||
|
||||
typedef DenseMap<void*, unsigned> AttributeMapType;
|
||||
AttributeMapType AttributeMap;
|
||||
std::vector<AttrListPtr> Attributes;
|
||||
|
||||
typedef DenseMap<const Instruction*, unsigned> InstructionMapType;
|
||||
InstructionMapType InstructionMap;
|
||||
unsigned InstructionCount;
|
||||
|
||||
/// BasicBlocks - This contains all the basic blocks for the currently
|
||||
/// incorporated function. Their reverse mapping is stored in ValueMap.
|
||||
std::vector<const BasicBlock*> BasicBlocks;
|
||||
@ -74,7 +79,10 @@ public:
|
||||
assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
|
||||
return I->second-1;
|
||||
}
|
||||
|
||||
|
||||
unsigned getInstructionID(const Instruction *I) const;
|
||||
void setInstructionID(const Instruction *I);
|
||||
|
||||
unsigned getAttributeID(const AttrListPtr &PAL) const {
|
||||
if (PAL.isEmpty()) return 0; // Null maps to zero.
|
||||
AttributeMapType::const_iterator I = AttributeMap.find(PAL.getRawPointer());
|
||||
|
@ -317,6 +317,12 @@ const Metadata::MDMapTy *Metadata::getMDs(const Instruction *Inst) {
|
||||
return &(I->second);
|
||||
}
|
||||
|
||||
/// getHandlerNames - Get handler names. This is used by bitcode
|
||||
/// writer.
|
||||
const StringMap<unsigned> *Metadata::getHandlerNames() {
|
||||
return &MDHandlerNames;
|
||||
}
|
||||
|
||||
/// ValueIsDeleted - This handler is used to update metadata store
|
||||
/// when a value is deleted.
|
||||
void Metadata::ValueIsDeleted(const Instruction *Inst) {
|
||||
|
22
test/Feature/md_on_instruction2.ll
Normal file
22
test/Feature/md_on_instruction2.ll
Normal file
@ -0,0 +1,22 @@
|
||||
; RUN: llvm-as < %s | llvm-dis | grep " dbg " | count 4
|
||||
define i32 @foo() nounwind ssp {
|
||||
entry:
|
||||
%retval = alloca i32 ; <i32*> [#uses=2]
|
||||
call void @llvm.dbg.func.start(metadata !0)
|
||||
store i32 42, i32* %retval, dbg !3
|
||||
br label %0, dbg !3
|
||||
|
||||
; <label>:0 ; preds = %entry
|
||||
call void @llvm.dbg.region.end(metadata !0)
|
||||
%1 = load i32* %retval, dbg !3 ; <i32> [#uses=1]
|
||||
ret i32 %1, dbg !3
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.func.start(metadata) nounwind readnone
|
||||
|
||||
declare void @llvm.dbg.region.end(metadata) nounwind readnone
|
||||
|
||||
!0 = metadata !{i32 458798, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 1, metadata !2, i1 false, i1 true}
|
||||
!1 = metadata !{i32 458769, i32 0, i32 12, metadata !"foo.c", metadata !"/tmp", metadata !"clang 1.0", i1 true, i1 false, metadata !"", i32 0}
|
||||
!2 = metadata !{i32 458788, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}
|
||||
!3 = metadata !{i32 1, i32 13, metadata !1, metadata !1}
|
@ -92,15 +92,16 @@ static const char *GetBlockName(unsigned BlockID,
|
||||
if (CurStreamType != LLVMIRBitstream) return 0;
|
||||
|
||||
switch (BlockID) {
|
||||
default: return 0;
|
||||
case bitc::MODULE_BLOCK_ID: return "MODULE_BLOCK";
|
||||
case bitc::PARAMATTR_BLOCK_ID: return "PARAMATTR_BLOCK";
|
||||
case bitc::TYPE_BLOCK_ID: return "TYPE_BLOCK";
|
||||
case bitc::CONSTANTS_BLOCK_ID: return "CONSTANTS_BLOCK";
|
||||
case bitc::FUNCTION_BLOCK_ID: return "FUNCTION_BLOCK";
|
||||
case bitc::TYPE_SYMTAB_BLOCK_ID: return "TYPE_SYMTAB";
|
||||
case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB";
|
||||
case bitc::METADATA_BLOCK_ID: return "METADATA_BLOCK";
|
||||
default: return 0;
|
||||
case bitc::MODULE_BLOCK_ID: return "MODULE_BLOCK";
|
||||
case bitc::PARAMATTR_BLOCK_ID: return "PARAMATTR_BLOCK";
|
||||
case bitc::TYPE_BLOCK_ID: return "TYPE_BLOCK";
|
||||
case bitc::CONSTANTS_BLOCK_ID: return "CONSTANTS_BLOCK";
|
||||
case bitc::FUNCTION_BLOCK_ID: return "FUNCTION_BLOCK";
|
||||
case bitc::TYPE_SYMTAB_BLOCK_ID: return "TYPE_SYMTAB";
|
||||
case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB";
|
||||
case bitc::METADATA_BLOCK_ID: return "METADATA_BLOCK";
|
||||
case bitc::METADATA_ATTACHMENT_ID: return "METADATA_ATTACHMENT_BLOCK";
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,6 +246,11 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
|
||||
case bitc::VST_CODE_ENTRY: return "ENTRY";
|
||||
case bitc::VST_CODE_BBENTRY: return "BBENTRY";
|
||||
}
|
||||
case bitc::METADATA_ATTACHMENT_ID:
|
||||
switch(CodeID) {
|
||||
default:return 0;
|
||||
case bitc::METADATA_ATTACHMENT: return "METADATA_ATTACHMENT";
|
||||
}
|
||||
case bitc::METADATA_BLOCK_ID:
|
||||
switch(CodeID) {
|
||||
default:return 0;
|
||||
@ -252,6 +258,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
|
||||
case bitc::METADATA_NODE: return "MDNODE";
|
||||
case bitc::METADATA_NAME: return "METADATA_NAME";
|
||||
case bitc::METADATA_NAMED_NODE: return "NAMEDMDNODE";
|
||||
case bitc::METADATA_KIND: return "METADATA_KIND";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user