Skip to content

Commit 7ae1903

Browse files
TBD: initial impl, need to split out langref
1 parent b53e0d1 commit 7ae1903

File tree

19 files changed

+248
-18
lines changed

19 files changed

+248
-18
lines changed

llvm/docs/LangRef.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,23 @@ Currently, only the following parameter attributes are defined:
11731173
site. If the alignment is not specified, then the code generator
11741174
makes a target-specific assumption.
11751175

1176+
.. _attr_range:
1177+
1178+
``range(<meta>)``
1179+
This indicates the possible ranges the parameter can take.
1180+
If the parameter is not in the specified range,
1181+
:ref:`poison value <poisonvalues>` is passed instead.
1182+
This attribute must reference a single metadata node, with the same format
1183+
and behavior as used for :ref:`range metadata <range-metadata>`.
1184+
1185+
.. code-block:: llvm
1186+
1187+
define void @f(i8 range(!0) %a) {
1188+
; %a can only be 0, 1, 3, 4 or 5
1189+
}
1190+
1191+
!0 = !{ i8 0, i8 2, i8 3, i8 6 }
1192+
11761193
.. _attr_inalloca:
11771194

11781195
``inalloca(<ty>)``

llvm/include/llvm-c/Core.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,17 @@ LLVMAttributeRef LLVMCreateTypeAttribute(LLVMContextRef C, unsigned KindID,
642642
*/
643643
LLVMTypeRef LLVMGetTypeAttributeValue(LLVMAttributeRef A);
644644

645+
/**
646+
* Create a metadata attribute
647+
*/
648+
LLVMAttributeRef LLVMCreateMetadataAttribute(LLVMContextRef C, unsigned KindID,
649+
LLVMMetadataRef type_ref);
650+
651+
/**
652+
* Get the metadata attribute's value.
653+
*/
654+
LLVMMetadataRef LLVMGetMetadataAttributeValue(LLVMAttributeRef A);
655+
645656
/**
646657
* Create a string attribute.
647658
*/
@@ -665,6 +676,7 @@ const char *LLVMGetStringAttributeValue(LLVMAttributeRef A, unsigned *Length);
665676
LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A);
666677
LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A);
667678
LLVMBool LLVMIsTypeAttribute(LLVMAttributeRef A);
679+
LLVMBool LLVMIsMetadataAttribute(LLVMAttributeRef A);
668680

669681
/**
670682
* Obtain a Type from a context by its registered name.

llvm/include/llvm/AsmParser/LLParser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,8 @@ namespace llvm {
352352
bool inAttrGrp, LocTy &BuiltinLoc);
353353
bool parseRequiredTypeAttr(AttrBuilder &B, lltok::Kind AttrToken,
354354
Attribute::AttrKind AttrKind);
355+
bool parseRequiredMetadataAttr(AttrBuilder &B, lltok::Kind AttrToken,
356+
Attribute::AttrKind AttrKind);
355357

356358
// Module Summary Index Parsing.
357359
bool skipModuleSummaryEntry();

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ enum AttributeKindCodes {
710710
ATTR_KIND_FNRETTHUNK_EXTERN = 84,
711711
ATTR_KIND_SKIP_PROFILE = 85,
712712
ATTR_KIND_MEMORY = 86,
713+
ATTR_KIND_RANGE = 87,
713714
};
714715

715716
enum ComdatSelectionKindCodes {

llvm/include/llvm/IR/Attributes.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/ADT/SmallString.h"
2222
#include "llvm/ADT/StringRef.h"
2323
#include "llvm/Config/llvm-config.h"
24+
#include "llvm/IR/Metadata.h"
2425
#include "llvm/Support/Alignment.h"
2526
#include "llvm/Support/CodeGen.h"
2627
#include "llvm/Support/PointerLikeTypeTraits.h"
@@ -105,6 +106,9 @@ class Attribute {
105106
static bool isTypeAttrKind(AttrKind Kind) {
106107
return Kind >= FirstTypeAttr && Kind <= LastTypeAttr;
107108
}
109+
static bool isMetadataAttrKind(AttrKind Kind) {
110+
return Kind >= FirstMetadataAttr && Kind <= LastMetadataAttr;
111+
}
108112

109113
static bool canUseAsFnAttr(AttrKind Kind);
110114
static bool canUseAsParamAttr(AttrKind Kind);
@@ -127,6 +131,7 @@ class Attribute {
127131
static Attribute get(LLVMContext &Context, StringRef Kind,
128132
StringRef Val = StringRef());
129133
static Attribute get(LLVMContext &Context, AttrKind Kind, Type *Ty);
134+
static Attribute get(LLVMContext &Context, AttrKind Kind, Metadata *Meta);
130135

131136
/// Return a uniquified Attribute object that has the specific
132137
/// alignment set.
@@ -181,6 +186,9 @@ class Attribute {
181186
/// Return true if the attribute is a type attribute.
182187
bool isTypeAttribute() const;
183188

189+
/// Return true if the attribute is a metadata attribute.
190+
bool isMetadataAttribute() const;
191+
184192
/// Return true if the attribute is any kind of attribute.
185193
bool isValid() const { return pImpl; }
186194

@@ -214,6 +222,10 @@ class Attribute {
214222
/// a type attribute.
215223
Type *getValueAsType() const;
216224

225+
/// Return the attribute's value as Metadata. This requires the attribute to be
226+
/// a metadata attribute.
227+
Metadata *getValueAsMetadata() const;
228+
217229
/// Returns the alignment field of an attribute as a byte alignment
218230
/// value.
219231
MaybeAlign getAlignment() const;
@@ -376,6 +388,7 @@ class AttributeSet {
376388
Type *getPreallocatedType() const;
377389
Type *getInAllocaType() const;
378390
Type *getElementType() const;
391+
MDNode *getRangeMetadata() const;
379392
std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()
380393
const;
381394
unsigned getVScaleRangeMin() const;
@@ -856,6 +869,9 @@ class AttributeList {
856869
/// Return the elementtype type for the specified function parameter.
857870
Type *getParamElementType(unsigned ArgNo) const;
858871

872+
/// Return the range metadata for the specified function parameter.
873+
MDNode *getParamRangeMetadata(unsigned ArgNo) const;
874+
859875
/// Get the stack alignment of the function.
860876
MaybeAlign getFnStackAlignment() const;
861877

@@ -1157,6 +1173,11 @@ class AttrBuilder {
11571173
std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()
11581174
const;
11591175

1176+
/// Retrieve metadata for the given metadata attribute.
1177+
Metadata *getMetadataAttr(Attribute::AttrKind Kind) const;
1178+
1179+
MDNode *getRangeMetadata() const { return cast<MDNode>(getMetadataAttr(Attribute::Range)); }
1180+
11601181
/// Add integer attribute with raw value (packed/encoded if necessary).
11611182
AttrBuilder &addRawIntAttr(Attribute::AttrKind Kind, uint64_t Value);
11621183

@@ -1236,6 +1257,12 @@ class AttrBuilder {
12361257
/// Add memory effect attribute.
12371258
AttrBuilder &addMemoryAttr(MemoryEffects ME);
12381259

1260+
/// Add a metadata attribute with the given metadata.
1261+
AttrBuilder &addMetadataAttr(Attribute::AttrKind Kind, Metadata *Meta);
1262+
1263+
/// Add a range attribute with the given range metadata.
1264+
AttrBuilder &addRangeAttr(MDNode *Meta);
1265+
12391266
ArrayRef<Attribute> attrs() const { return Attrs; }
12401267

12411268
bool operator==(const AttrBuilder &B) const;

llvm/include/llvm/IR/Attributes.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class IntAttr<string S, list<AttrProperty> P> : Attr<S, P>;
3838
/// Type attribute.
3939
class TypeAttr<string S, list<AttrProperty> P> : Attr<S, P>;
4040

41+
/// Type attribute.
42+
class MetadataAttr<string S, list<AttrProperty> P> : Attr<S, P>;
43+
4144
/// StringBool attribute.
4245
class StrBoolAttr<string S> : Attr<S, []>;
4346

@@ -206,6 +209,9 @@ def OptimizeNone : EnumAttr<"optnone", [FnAttr]>;
206209
/// Similar to byval but without a copy.
207210
def Preallocated : TypeAttr<"preallocated", [FnAttr, ParamAttr]>;
208211

212+
/// Valid range for parameter.
213+
def Range : MetadataAttr<"range", [ParamAttr]>;
214+
209215
/// Function does not access memory.
210216
def ReadNone : EnumAttr<"readnone", [ParamAttr]>;
211217

llvm/include/llvm/IR/InstrTypes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,6 +1800,10 @@ class CallBase : public Instruction {
18001800
return Attrs.getParamElementType(ArgNo);
18011801
}
18021802

1803+
Metadata *getParamRangeMetadata(unsigned ArgNo) const {
1804+
return Attrs.getParamRangeMetadata(ArgNo);
1805+
}
1806+
18031807
/// Extract the number of dereferenceable bytes for a call or
18041808
/// parameter (0=unknown).
18051809
uint64_t getRetDereferenceableBytes() const {

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,9 @@ bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B,
14091409
if (Attribute::isTypeAttrKind(Attr))
14101410
return parseRequiredTypeAttr(B, Lex.getKind(), Attr);
14111411

1412+
if (Attribute::isMetadataAttrKind(Attr))
1413+
return parseRequiredMetadataAttr(B, Lex.getKind(), Attr);
1414+
14121415
switch (Attr) {
14131416
case Attribute::Alignment: {
14141417
MaybeAlign Alignment;
@@ -2792,6 +2795,24 @@ bool LLParser::parseRequiredTypeAttr(AttrBuilder &B, lltok::Kind AttrToken,
27922795
return false;
27932796
}
27942797

2798+
/// parseRequiredMetadataAttr
2799+
/// ::= attrname(<meta>)
2800+
bool LLParser::parseRequiredMetadataAttr(AttrBuilder &B, lltok::Kind AttrToken,
2801+
Attribute::AttrKind AttrKind) {
2802+
Metadata *Meta = nullptr;
2803+
if (!EatIfPresent(AttrToken))
2804+
return true;
2805+
if (!EatIfPresent(lltok::lparen))
2806+
return error(Lex.getLoc(), "expected '('");
2807+
if (parseMetadata(Meta, nullptr))
2808+
return true;
2809+
if (!EatIfPresent(lltok::rparen))
2810+
return error(Lex.getLoc(), "expected ')'");
2811+
2812+
B.addMetadataAttr(AttrKind, Meta);
2813+
return false;
2814+
}
2815+
27952816
/// parseOptionalOperandBundles
27962817
/// ::= /*empty*/
27972818
/// ::= '[' OperandBundle [, OperandBundle ]* ']'

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
19951995
return Attribute::OptimizeNone;
19961996
case bitc::ATTR_KIND_READ_NONE:
19971997
return Attribute::ReadNone;
1998+
case bitc::ATTR_KIND_RANGE:
1999+
return Attribute::Range;
19982000
case bitc::ATTR_KIND_READ_ONLY:
19992001
return Attribute::ReadOnly;
20002002
case bitc::ATTR_KIND_RETURNED:
@@ -2229,6 +2231,15 @@ Error BitcodeReader::parseAttributeGroupBlock() {
22292231
return error("Not a type attribute");
22302232

22312233
B.addTypeAttr(Kind, HasType ? getTypeByID(Record[++i]) : nullptr);
2234+
} else if (Record[i] == 7 || Record[i] == 8) {
2235+
bool HasMetadata = Record[i] == 8;
2236+
Attribute::AttrKind Kind;
2237+
if (Error Err = parseAttrKind(Record[++i], &Kind))
2238+
return Err;
2239+
if (!Attribute::isMetadataAttrKind(Kind))
2240+
return error("Not a metadata attribute");
2241+
2242+
B.addMetadataAttr(Kind, HasMetadata ? MDLoader->getMetadataFwdRefOrLoad(Record[++i]) : nullptr);
22322243
} else {
22332244
return error("Invalid attribute group entry");
22342245
}

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
735735
return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE;
736736
case Attribute::OptimizeNone:
737737
return bitc::ATTR_KIND_OPTIMIZE_NONE;
738+
case Attribute::Range:
739+
return bitc::ATTR_KIND_RANGE;
738740
case Attribute::ReadNone:
739741
return bitc::ATTR_KIND_READ_NONE;
740742
case Attribute::ReadOnly:
@@ -848,13 +850,20 @@ void ModuleBitcodeWriter::writeAttributeGroupTable() {
848850
Record.append(Val.begin(), Val.end());
849851
Record.push_back(0);
850852
}
851-
} else {
852-
assert(Attr.isTypeAttribute());
853+
} else if (Attr.isTypeAttribute()) {
853854
Type *Ty = Attr.getValueAsType();
854855
Record.push_back(Ty ? 6 : 5);
855856
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
856857
if (Ty)
857858
Record.push_back(VE.getTypeID(Attr.getValueAsType()));
859+
} else if (Attr.isMetadataAttribute()) {
860+
Metadata *Meta = Attr.getValueAsMetadata();
861+
Record.push_back(Meta ? 8 : 7);
862+
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
863+
if (Meta)
864+
Record.push_back(VE.getMetadataID(Meta));
865+
} else {
866+
llvm_unreachable("Trying to encode unknown attribute kind");
858867
}
859868
}
860869

llvm/lib/Bitcode/Writer/ValueEnumerator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,8 @@ void ValueEnumerator::EnumerateAttributes(AttributeList PAL) {
10141014
for (Attribute Attr : AS) {
10151015
if (Attr.isTypeAttribute())
10161016
EnumerateType(Attr.getValueAsType());
1017+
else if (Attr.isMetadataAttribute())
1018+
EnumerateMetadata(nullptr, Attr.getValueAsMetadata());
10171019
}
10181020
}
10191021
}

llvm/lib/IR/AttributeImpl.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class AttributeImpl : public FoldingSetNode {
4646
IntAttrEntry,
4747
StringAttrEntry,
4848
TypeAttrEntry,
49+
MetadataAttrEntry
4950
};
5051

5152
AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {}
@@ -59,6 +60,7 @@ class AttributeImpl : public FoldingSetNode {
5960
bool isIntAttribute() const { return KindID == IntAttrEntry; }
6061
bool isStringAttribute() const { return KindID == StringAttrEntry; }
6162
bool isTypeAttribute() const { return KindID == TypeAttrEntry; }
63+
bool isMetadataAttribute() const { return KindID == MetadataAttrEntry; }
6264

6365
bool hasAttribute(Attribute::AttrKind A) const;
6466
bool hasAttribute(StringRef Kind) const;
@@ -72,6 +74,8 @@ class AttributeImpl : public FoldingSetNode {
7274

7375
Type *getValueAsType() const;
7476

77+
Metadata *getValueAsMetadata() const;
78+
7579
/// Used when sorting the attributes.
7680
bool operator<(const AttributeImpl &AI) const;
7781

@@ -82,8 +86,12 @@ class AttributeImpl : public FoldingSetNode {
8286
Profile(ID, getKindAsEnum(), getValueAsInt());
8387
else if (isStringAttribute())
8488
Profile(ID, getKindAsString(), getValueAsString());
85-
else
89+
else if (isTypeAttribute())
8690
Profile(ID, getKindAsEnum(), getValueAsType());
91+
else if (isMetadataAttribute())
92+
Profile(ID, getKindAsEnum(), getValueAsMetadata());
93+
else
94+
llvm_unreachable("invalid attribute kind");
8795
}
8896

8997
static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind) {
@@ -108,6 +116,12 @@ class AttributeImpl : public FoldingSetNode {
108116
ID.AddInteger(Kind);
109117
ID.AddPointer(Ty);
110118
}
119+
120+
static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,
121+
Metadata *Meta) {
122+
ID.AddInteger(Kind);
123+
ID.AddPointer(Meta);
124+
}
111125
};
112126

113127
static_assert(std::is_trivially_destructible<AttributeImpl>::value,
@@ -196,6 +210,16 @@ class TypeAttributeImpl : public EnumAttributeImpl {
196210
Type *getTypeValue() const { return Ty; }
197211
};
198212

213+
class MetadataAttributeImpl : public EnumAttributeImpl {
214+
Metadata *Meta;
215+
216+
public:
217+
MetadataAttributeImpl(Attribute::AttrKind Kind, Metadata *Meta)
218+
: EnumAttributeImpl(MetadataAttrEntry, Kind), Meta(Meta) {}
219+
220+
Metadata *getMetadataValue() const { return Meta; }
221+
};
222+
199223
class AttributeBitSet {
200224
/// Bitset with a bit for each available attribute Attribute::AttrKind.
201225
uint8_t AvailableAttrs[12] = {};
@@ -268,6 +292,7 @@ class AttributeSetNode final
268292
MemoryEffects getMemoryEffects() const;
269293
std::string getAsString(bool InAttrGrp) const;
270294
Type *getAttributeType(Attribute::AttrKind Kind) const;
295+
Metadata *getAttributeMetadata(Attribute::AttrKind Kind) const;
271296

272297
using iterator = const Attribute *;
273298

0 commit comments

Comments
 (0)