AsmWriter/Bitcode: MDSubrange

llvm-svn: 229003
This commit is contained in:
Duncan P. N. Exon Smith 2015-02-13 01:10:38 +00:00
parent 193a4fdafd
commit c7363f1147
11 changed files with 119 additions and 9 deletions

View File

@ -147,7 +147,8 @@ namespace bitc {
METADATA_OLD_FN_NODE = 9, // OLD_FN_NODE: [n x (type num, value num)]
METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes]
METADATA_ATTACHMENT = 11, // [m x [value, [n x [id, mdnode]]]
METADATA_GENERIC_DEBUG = 12 // [distinct, tag, vers, header, n x md num]
METADATA_GENERIC_DEBUG = 12, // [distinct, tag, vers, header, n x md num]
METADATA_SUBRANGE = 13 // [distinct, count, lo]
};
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each

View File

@ -2930,6 +2930,7 @@ template <class FieldTy> struct MDFieldImpl {
explicit MDFieldImpl(FieldTy Default)
: Val(std::move(Default)), Seen(false) {}
};
struct MDUnsignedField : public MDFieldImpl<uint64_t> {
uint64_t Max;
@ -2945,6 +2946,17 @@ struct ColumnField : public MDUnsignedField {
struct DwarfTagField : public MDUnsignedField {
DwarfTagField() : MDUnsignedField(0, dwarf::DW_TAG_hi_user) {}
};
struct MDSignedField : public MDFieldImpl<int64_t> {
int64_t Min;
int64_t Max;
MDSignedField(int64_t Default = 0)
: ImplTy(Default), Min(INT64_MIN), Max(INT64_MAX) {}
MDSignedField(int64_t Default, int64_t Min, int64_t Max)
: ImplTy(Default), Min(Min), Max(Max) {}
};
struct MDField : public MDFieldImpl<Metadata *> {
MDField() : ImplTy(nullptr) {}
};
@ -3002,6 +3014,26 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) {
return false;
}
template <>
bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
MDSignedField &Result) {
if (Lex.getKind() != lltok::APSInt)
return TokError("expected signed integer");
auto &S = Lex.getAPSIntVal();
if (S < Result.Min)
return TokError("value for '" + Name + "' too small, limit is " +
Twine(Result.Min));
if (S > Result.Max)
return TokError("value for '" + Name + "' too large, limit is " +
Twine(Result.Max));
Result.assign(S.getExtValue());
assert(Result.Val >= Result.Min && "Expected value in range");
assert(Result.Val <= Result.Max && "Expected value in range");
Lex.Lex();
return false;
}
template <>
bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
Metadata *MD;
@ -3136,9 +3168,19 @@ bool LLParser::ParseGenericDebugNode(MDNode *&Result, bool IsDistinct) {
return false;
}
/// ParseMDSubrange:
/// ::= !MDSubrange(count: 30, lowerBound: 2)
bool LLParser::ParseMDSubrange(MDNode *&Result, bool IsDistinct) {
return TokError("unimplemented parser");
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(count, MDUnsignedField, (0, UINT64_MAX >> 1)); \
OPTIONAL(lowerBound, MDSignedField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
Result = GET_OR_DISTINCT(MDSubrange, (Context, count.Val, lowerBound.Val));
return false;
}
bool LLParser::ParseMDEnumerator(MDNode *&Result, bool IsDistinct) {
return TokError("unimplemented parser");
}

View File

@ -1173,6 +1173,8 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
}
}
static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; }
std::error_code BitcodeReader::ParseMetadata() {
unsigned NextMDValueNo = MDValueList.size();
@ -1349,6 +1351,16 @@ std::error_code BitcodeReader::ParseMetadata() {
NextMDValueNo++);
break;
}
case bitc::METADATA_SUBRANGE: {
if (Record.size() != 3)
return Error("Invalid record");
MDValueList.AssignValue(
GET_OR_DISTINCT(MDSubrange, Record[0],
(Context, Record[1], unrotateSign(Record[2]))),
NextMDValueNo++);
break;
}
case bitc::METADATA_STRING: {
std::string String(Record.begin(), Record.end());
llvm::UpgradeMDStringConstant(String);

View File

@ -809,11 +809,23 @@ static void WriteGenericDebugNode(const GenericDebugNode *N,
Record.clear();
}
static void WriteMDSubrange(const MDSubrange *, const ValueEnumerator &,
BitstreamWriter &, SmallVectorImpl<uint64_t> &,
unsigned) {
llvm_unreachable("write not implemented");
static uint64_t rotateSign(int64_t I) {
uint64_t U = I;
return I < 0 ? ~(U << 1) : U << 1;
}
static void WriteMDSubrange(const MDSubrange *N, const ValueEnumerator &,
BitstreamWriter &Stream,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
Record.push_back(N->isDistinct());
Record.push_back(N->getCount());
Record.push_back(rotateSign(N->getLo()));
Stream.EmitRecord(bitc::METADATA_SUBRANGE, Record, Abbrev);
Record.clear();
}
static void WriteMDEnumerator(const MDEnumerator *, const ValueEnumerator &,
BitstreamWriter &, SmallVectorImpl<uint64_t> &,
unsigned) {

View File

@ -1347,10 +1347,16 @@ static void writeMDLocation(raw_ostream &Out, const MDLocation *DL,
Out << ")";
}
static void writeMDSubrange(raw_ostream &, const MDSubrange *, TypePrinting *,
SlotTracker *, const Module *) {
llvm_unreachable("write not implemented");
static void writeMDSubrange(raw_ostream &Out, const MDSubrange *N,
TypePrinting *, SlotTracker *, const Module *) {
Out << "!MDSubrange(";
FieldSeparator FS;
Out << FS << "count: " << N->getCount();
if (N->getLo())
Out << FS << "lowerBound: " << N->getLo();
Out << ")";
}
static void writeMDEnumerator(raw_ostream &, const MDEnumerator *,
TypePrinting *, SlotTracker *, const Module *) {
llvm_unreachable("write not implemented");

View File

@ -0,0 +1,14 @@
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
; RUN: verify-uselistorder %s
; CHECK: !named = !{!0, !0, !1, !2}
!named = !{!0, !1, !2, !3}
; CHECK: !0 = !MDSubrange(count: 3)
; CHECK-NEXT: !1 = !MDSubrange(count: 3, lowerBound: 4)
; CHECK-NEXT: !2 = !MDSubrange(count: 3, lowerBound: -5)
!0 = !MDSubrange(count: 3)
!1 = !MDSubrange(count: 3, lowerBound: 0)
!2 = !MDSubrange(count: 3, lowerBound: 4)
!3 = !MDSubrange(count: 3, lowerBound: -5)

View File

@ -0,0 +1,7 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK-NOT: error
!0 = !MDSubrange(count: 9223372036854775807)
; CHECK: <stdin>:[[@LINE+1]]:25: error: value for 'count' too large, limit is 9223372036854775807
!1 = !MDSubrange(count: 9223372036854775808)

View File

@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: [[@LINE+1]]:32: error: missing required field 'count'
!0 = !MDSubrange(lowerBound: -3)

View File

@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: [[@LINE+1]]:25: error: expected unsigned integer
!0 = !MDSubrange(count: -3)

View File

@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: [[@LINE+1]]:41: error: value for 'lowerBound' too large, limit is 9223372036854775807
!0 = !MDSubrange(count: 30, lowerBound: 9223372036854775808)

View File

@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: [[@LINE+1]]:41: error: value for 'lowerBound' too small, limit is -9223372036854775808
!0 = !MDSubrange(count: 30, lowerBound: -9223372036854775809)