llvm.org GIT mirror llvm / 3d26f10
Revert "IR: add optional type to 'byval' function parameters" The IRLinker doesn't delve into the new byval attribute when mapping types, and this breaks LTO. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362029 91177308-0d34-0410-b5e6-96231b3b80d8 Tim Northover 4 months ago
40 changed file(s) with 44 addition(s) and 428 deletion(s). Raw diff Collapse all Expand all
10161016 opposed to memory, though some targets use it to distinguish between
10171017 two different kinds of registers). Use of this attribute is
10181018 target-specific.
1019 ``byval`` or ``byval()``
1019 ``byval``
10201020 This indicates that the pointer parameter should really be passed by
10211021 value to the function. The attribute implies that a hidden copy of
10221022 the pointee is made between the caller and the callee, so the callee
10271027 callee (for example, ``readonly`` functions should not write to
10281028 ``byval`` parameters). This is not a valid attribute for return
10291029 values.
1030
1031 The byval attribute also supports an optional type argument, which must be
1032 the same as the pointee type of the argument.
10331030
10341031 The byval attribute also supports specifying an alignment with the
10351032 align attribute. It indicates the alignment of the stack slot to
187187 bool IsSwiftSelf : 1;
188188 bool IsSwiftError : 1;
189189 uint16_t Alignment = 0;
190 Type *ByValType = nullptr;
191190
192191 ArgListEntry()
193192 : IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
7777 /// If this is a byval or inalloca argument, return its alignment.
7878 unsigned getParamAlignment() const;
7979
80 /// If this is a byval argument, return its type.
81 Type *getParamByValType() const;
82
8380 /// Return true if this argument has the nest attribute.
8481 bool hasNestAttr() const;
8582
8989 static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0);
9090 static Attribute get(LLVMContext &Context, StringRef Kind,
9191 StringRef Val = StringRef());
92 static Attribute get(LLVMContext &Context, AttrKind Kind, Type *Ty);
9392
9493 /// Return a uniquified Attribute object that has the specific
9594 /// alignment set.
102101 static Attribute getWithAllocSizeArgs(LLVMContext &Context,
103102 unsigned ElemSizeArg,
104103 const Optional &NumElemsArg);
105 static Attribute getWithByValType(LLVMContext &Context, Type *Ty);
106104
107105 //===--------------------------------------------------------------------===//
108106 // Attribute Accessors
118116 /// attribute.
119117 bool isStringAttribute() const;
120118
121 /// Return true if the attribute is a type attribute.
122 bool isTypeAttribute() const;
123
124119 /// Return true if the attribute is present.
125120 bool hasAttribute(AttrKind Val) const;
126121
142137 /// Return the attribute's value as a string. This requires the
143138 /// attribute to be a string attribute.
144139 StringRef getValueAsString() const;
145
146 /// Return the attribute's value as a Type. This requires the attribute to be
147 /// a type attribute.
148 Type *getValueAsType() const;
149140
150141 /// Returns the alignment field of an attribute as a byte alignment
151142 /// value.
287278 unsigned getStackAlignment() const;
288279 uint64_t getDereferenceableBytes() const;
289280 uint64_t getDereferenceableOrNullBytes() const;
290 Type *getByValType() const;
291281 std::pair> getAllocSizeArgs() const;
292282 std::string getAsString(bool InAttrGrp = false) const;
293283
607597 /// Return the alignment for the specified function parameter.
608598 unsigned getParamAlignment(unsigned ArgNo) const;
609599
610 /// Return the byval type for the specified function parameter.
611 Type *getParamByValType(unsigned ArgNo) const;
612
613600 /// Get the stack alignment.
614601 unsigned getStackAlignment(unsigned Index) const;
615602
709696 uint64_t DerefBytes = 0;
710697 uint64_t DerefOrNullBytes = 0;
711698 uint64_t AllocSizeArgs = 0;
712 Type *ByValType = nullptr;
713699
714700 public:
715701 AttrBuilder() = default;
785771 /// dereferenceable_or_null attribute exists (zero is returned otherwise).
786772 uint64_t getDereferenceableOrNullBytes() const { return DerefOrNullBytes; }
787773
788 /// Retrieve the byval type.
789 Type *getByValType() const { return ByValType; }
790
791774 /// Retrieve the allocsize args, if the allocsize attribute exists. If it
792775 /// doesn't exist, pair(0, 0) is returned.
793776 std::pair> getAllocSizeArgs() const;
811794 /// This turns one (or two) ints into the form used internally in Attribute.
812795 AttrBuilder &addAllocSizeAttr(unsigned ElemSizeArg,
813796 const Optional &NumElemsArg);
814
815 /// This turns a byval type into the form used internally in Attribute.
816 AttrBuilder &addByValAttr(Type *Ty);
817797
818798 /// Add an allocsize attribute, using the representation returned by
819799 /// Attribute.getIntValue().
412412 /// Extract the alignment for a call or parameter (0=unknown).
413413 unsigned getParamAlignment(unsigned ArgNo) const {
414414 CALLSITE_DELEGATE_GETTER(getParamAlignment(ArgNo));
415 }
416
417 /// Extract the byval type for a call or parameter (nullptr=unknown).
418 Type *getParamByValType(unsigned ArgNo) const {
419 CALLSITE_DELEGATE_GETTER(getParamByValType(ArgNo));
420415 }
421416
422417 /// Extract the number of dereferenceable bytes for a call or parameter
430430 return AttributeSets.getParamAlignment(ArgNo);
431431 }
432432
433 /// Extract the byval type for a parameter (nullptr=unknown).
434 Type *getParamByValType(unsigned ArgNo) const {
435 return AttributeSets.getParamByValType(ArgNo);
436 }
437
438433 /// Extract the number of dereferenceable bytes for a call or
439434 /// parameter (0=unknown).
440435 /// @param i AttributeList index, referring to a return value or argument.
15591559 return Attrs.getParamAlignment(ArgNo);
15601560 }
15611561
1562 /// Extract the byval type for a call or parameter (nullptr=unknown).
1563 Type *getParamByValType(unsigned ArgNo) const {
1564 return Attrs.getParamByValType(ArgNo);
1565 }
1566
15671562 /// Extract the number of dereferenceable bytes for a call or
15681563 /// parameter (0=unknown).
15691564 uint64_t getDereferenceableBytes(unsigned i) const {
16001600 B.addAlignmentAttr(Alignment);
16011601 continue;
16021602 }
1603 case lltok::kw_byval: {
1604 Type *Ty;
1605 if (ParseByValWithOptionalType(Ty))
1606 return true;
1607 B.addByValAttr(Ty);
1608 continue;
1609 }
1603 case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break;
16101604 case lltok::kw_dereferenceable: {
16111605 uint64_t Bytes;
16121606 if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
24592453 return false;
24602454 }
24612455
2462 /// ParseByValWithOptionalType
2463 /// ::= byval
2464 /// ::= byval()
2465 bool LLParser::ParseByValWithOptionalType(Type *&Result) {
2466 Result = nullptr;
2467 if (!EatIfPresent(lltok::kw_byval))
2468 return true;
2469 if (!EatIfPresent(lltok::lparen))
2470 return false;
2471 if (ParseType(Result))
2472 return true;
2473 if (!EatIfPresent(lltok::rparen))
2474 return Error(Lex.getLoc(), "expected ')'");
2475 return false;
2476 }
2477
24782456 /// ParseOptionalOperandBundles
24792457 /// ::= /*empty*/
24802458 /// ::= '[' OperandBundle [, OperandBundle ]* ']'
338338 bool ParseFnAttributeValuePairs(AttrBuilder &B,
339339 std::vector &FwdRefAttrGrps,
340340 bool inAttrGrp, LocTy &BuiltinLoc);
341 bool ParseByValWithOptionalType(Type *&Result);
342341
343342 // Module Summary Index Parsing.
344343 bool SkipModuleSummaryEntry();
636636 ValNo = InstNum - ValNo;
637637 return getFnValueByID(ValNo, Ty);
638638 }
639
640 /// Upgrades old-style typeless byval attributes by adding the corresponding
641 /// argument's pointee type.
642 void propagateByValTypes(CallBase *CB);
643639
644640 /// Converts alignment exponent (i.e. power of two (or zero)) to the
645641 /// corresponding alignment to use. If alignment is too large, returns
14951491 if (Error Err = parseAttrKind(Record[++i], &Kind))
14961492 return Err;
14971493
1498 // Upgrade old-style byval attribute to one with a type, even if it's
1499 // nullptr. We will have to insert the real type when we associate
1500 // this AttributeList with a function.
1501 if (Kind == Attribute::ByVal)
1502 B.addByValAttr(nullptr);
1503
15041494 B.addAttribute(Kind);
15051495 } else if (Record[i] == 1) { // Integer attribute
15061496 Attribute::AttrKind Kind;
15161506 B.addDereferenceableOrNullAttr(Record[++i]);
15171507 else if (Kind == Attribute::AllocSize)
15181508 B.addAllocSizeAttrFromRawRepr(Record[++i]);
1519 } else if (Record[i] == 3 || Record[i] == 4) { // String attribute
1509 } else { // String attribute
1510 assert((Record[i] == 3 || Record[i] == 4) &&
1511 "Invalid attribute group entry");
15201512 bool HasValue = (Record[i++] == 4);
15211513 SmallString<64> KindStr;
15221514 SmallString<64> ValStr;
15341526 }
15351527
15361528 B.addAttribute(KindStr.str(), ValStr.str());
1537 } else {
1538 assert((Record[i] == 5 || Record[i] == 6) &&
1539 "Invalid attribute group entry");
1540 bool HasType = Record[i] == 6;
1541 Attribute::AttrKind Kind;
1542 if (Error Err = parseAttrKind(Record[++i], &Kind))
1543 return Err;
1544 if (Kind == Attribute::ByVal)
1545 B.addByValAttr(HasType ? getTypeByID(Record[++i]) : nullptr);
15461529 }
15471530 }
15481531
30433026 uint64_t RawLinkage = Record[3];
30443027 Func->setLinkage(getDecodedLinkage(RawLinkage));
30453028 Func->setAttributes(getAttributes(Record[4]));
3046
3047 // Upgrade any old-style byval without a type by propagating the argument's
3048 // pointee type. There should be no opaque pointers where the byval type is
3049 // implicit.
3050 for (auto &Arg : Func->args()) {
3051 if (Arg.hasByValAttr() && !Arg.getParamByValType()) {
3052 Arg.removeAttr(Attribute::ByVal);
3053 Arg.addAttr(Attribute::getWithByValType(
3054 Context, Arg.getType()->getPointerElementType()));
3055 }
3056 }
30573029
30583030 unsigned Alignment;
30593031 if (Error Err = parseAlignmentValue(Record[5], Alignment))
34683440 return Error::success();
34693441 }
34703442
3471 void BitcodeReader::propagateByValTypes(CallBase *CB) {
3472 for (unsigned i = 0; i < CB->getNumArgOperands(); ++i) {
3473 if (CB->paramHasAttr(i, Attribute::ByVal) &&
3474 !CB->getAttribute(i, Attribute::ByVal).getValueAsType()) {
3475 CB->removeParamAttr(i, Attribute::ByVal);
3476 CB->addParamAttr(
3477 i, Attribute::getWithByValType(
3478 Context,
3479 CB->getArgOperand(i)->getType()->getPointerElementType()));
3480 }
3481 }
3482 }
3483
34843443 /// Lazily parse the specified function body block.
34853444 Error BitcodeReader::parseFunctionBody(Function *F) {
34863445 if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
42964255 cast(I)->setCallingConv(
42974256 static_cast(CallingConv::MaxID & CCInfo));
42984257 cast(I)->setAttributes(PAL);
4299 propagateByValTypes(cast(I));
4300
43014258 break;
43024259 }
43034260 case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval]
47734730 TCK = CallInst::TCK_NoTail;
47744731 cast(I)->setTailCallKind(TCK);
47754732 cast(I)->setAttributes(PAL);
4776 propagateByValTypes(cast(I));
47774733 if (FMF.any()) {
47784734 if (!isa(I))
47794735 return error("Fast-math-flags specified for call without "
746746 Record.push_back(1);
747747 Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
748748 Record.push_back(Attr.getValueAsInt());
749 } else if (Attr.isStringAttribute()) {
749 } else {
750750 StringRef Kind = Attr.getKindAsString();
751751 StringRef Val = Attr.getValueAsString();
752752
757757 Record.append(Val.begin(), Val.end());
758758 Record.push_back(0);
759759 }
760 } else {
761 assert(Attr.isTypeAttribute());
762 Type *Ty = Attr.getValueAsType();
763 Record.push_back(Ty ? 6 : 5);
764 Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
765 if (Ty)
766 Record.push_back(VE.getTypeID(Attr.getValueAsType()));
767760 }
768761 }
769762
41324125 // Emit blockinfo, which defines the standard abbreviations etc.
41334126 writeBlockInfo();
41344127
4128 // Emit information about attribute groups.
4129 writeAttributeGroupTable();
4130
4131 // Emit information about parameter attributes.
4132 writeAttributeTable();
4133
41354134 // Emit information describing all of the types in the module.
41364135 writeTypeTable();
4137
4138 // Emit information about attribute groups.
4139 writeAttributeGroupTable();
4140
4141 // Emit information about parameter attributes.
4142 writeAttributeTable();
41434136
41444137 writeComdats();
41454138
948948 incorporateFunctionMetadata(F);
949949
950950 // Adding function arguments to the value table.
951 for (const auto &I : F.args()) {
951 for (const auto &I : F.args())
952952 EnumerateValue(&I);
953 if (I.hasAttribute(Attribute::ByVal) && I.getParamByValType())
954 EnumerateType(I.getParamByValType());
955 }
953
956954 FirstFuncConstantID = Values.size();
957955
958956 // Add all function-level constants to the value table.
8686
8787 if (Arg.Flags.isByVal() || Arg.Flags.isInAlloca()) {
8888 Type *ElementTy = cast(Arg.Ty)->getElementType();
89
90 auto Ty = Attrs.getAttribute(OpIdx, Attribute::ByVal).getValueAsType();
91 Arg.Flags.setByValSize(DL.getTypeAllocSize(Ty ? Ty : ElementTy));
92
89 Arg.Flags.setByValSize(DL.getTypeAllocSize(ElementTy));
9390 // For ByVal, alignment should be passed from FE. BE will guess if
9491 // this info is not there but there are cases it cannot get right.
9592 unsigned FrameAlign;
12031203 if (Arg.IsByVal || Arg.IsInAlloca) {
12041204 PointerType *Ty = cast(Arg.Ty);
12051205 Type *ElementTy = Ty->getElementType();
1206 unsigned FrameSize =
1207 DL.getTypeAllocSize(Arg.ByValType ? Arg.ByValType : ElementTy);
1208
1209 // For ByVal, alignment should come from FE. BE will guess if this info
1210 // is not there, but there are cases it cannot get right.
1206 unsigned FrameSize = DL.getTypeAllocSize(ElementTy);
1207 // For ByVal, alignment should come from FE. BE will guess if this info is
1208 // not there, but there are cases it cannot get right.
12111209 unsigned FrameAlign = Arg.Alignment;
12121210 if (!FrameAlign)
12131211 FrameAlign = TLI.getByValTypeAlignment(ElementTy, DL);
90759075 if (Args[i].IsByVal || Args[i].IsInAlloca) {
90769076 PointerType *Ty = cast(Args[i].Ty);
90779077 Type *ElementTy = Ty->getElementType();
9078
9079 unsigned FrameSize = DL.getTypeAllocSize(
9080 Args[i].ByValType ? Args[i].ByValType : ElementTy);
9081 Flags.setByValSize(FrameSize);
9082
9078 Flags.setByValSize(DL.getTypeAllocSize(ElementTy));
9079 // For ByVal, alignment should come from FE. BE will guess if this
90839080 // info is not there but there are cases it cannot get right.
90849081 unsigned FrameAlign;
90859082 if (Args[i].Alignment)
95769573 if (Flags.isByVal() || Flags.isInAlloca()) {
95779574 PointerType *Ty = cast(Arg.getType());
95789575 Type *ElementTy = Ty->getElementType();
9579
9580 // For ByVal, size and alignment should be passed from FE. BE will
9581 // guess if this info is not there but there are cases it cannot get
9582 // right.
9583 unsigned FrameSize = DL.getTypeAllocSize(
9584 Arg.getParamByValType() ? Arg.getParamByValType() : ElementTy);
9585 Flags.setByValSize(FrameSize);
9586
9576 Flags.setByValSize(DL.getTypeAllocSize(ElementTy));
9577 // For ByVal, alignment should be passed from FE. BE will guess if
9578 // this info is not there but there are cases it cannot get right.
95879579 unsigned FrameAlign;
95889580 if (Arg.getParamAlignment())
95899581 FrameAlign = Arg.getParamAlignment();
111111 IsSwiftSelf = Call->paramHasAttr(ArgIdx, Attribute::SwiftSelf);
112112 IsSwiftError = Call->paramHasAttr(ArgIdx, Attribute::SwiftError);
113113 Alignment = Call->getParamAlignment(ArgIdx);
114 ByValType = Call->getParamByValType(ArgIdx);
115114 }
116115
117116 /// Generate a libcall taking the given operands as arguments and returning a
2828 namespace llvm {
2929
3030 class LLVMContext;
31 class Type;
3231
3332 //===----------------------------------------------------------------------===//
3433 /// \class
4140 enum AttrEntryKind {
4241 EnumAttrEntry,
4342 IntAttrEntry,
44 StringAttrEntry,
45 TypeAttrEntry,
43 StringAttrEntry
4644 };
4745
4846 AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {}
5755 bool isEnumAttribute() const { return KindID == EnumAttrEntry; }
5856 bool isIntAttribute() const { return KindID == IntAttrEntry; }
5957 bool isStringAttribute() const { return KindID == StringAttrEntry; }
60 bool isTypeAttribute() const { return KindID == TypeAttrEntry; }
6158
6259 bool hasAttribute(Attribute::AttrKind A) const;
6360 bool hasAttribute(StringRef Kind) const;
6865 StringRef getKindAsString() const;
6966 StringRef getValueAsString() const;
7067
71 Type *getValueAsType() const;
72
7368 /// Used when sorting the attributes.
7469 bool operator<(const AttributeImpl &AI) const;
7570
7671 void Profile(FoldingSetNodeID &ID) const {
7772 if (isEnumAttribute())
78 Profile(ID, getKindAsEnum(), static_cast(0));
73 Profile(ID, getKindAsEnum(), 0);
7974 else if (isIntAttribute())
8075 Profile(ID, getKindAsEnum(), getValueAsInt());
81 else if (isStringAttribute())
76 else
8277 Profile(ID, getKindAsString(), getValueAsString());
83 else
84 Profile(ID, getKindAsEnum(), getValueAsType());
8578 }
8679
8780 static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,
9386 static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) {
9487 ID.AddString(Kind);
9588 if (!Values.empty()) ID.AddString(Values);
96 }
97
98 static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,
99 Type *Ty) {
100 ID.AddInteger(Kind);
101 ID.AddPointer(Ty);
10289 }
10390 };
10491
157144 StringRef getStringValue() const { return Val; }
158145 };
159146
160 class TypeAttributeImpl : public EnumAttributeImpl {
161 virtual void anchor();
162
163 Type *Ty;
164
165 public:
166 TypeAttributeImpl(Attribute::AttrKind Kind, Type *Ty)
167 : EnumAttributeImpl(TypeAttrEntry, Kind), Ty(Ty) {}
168
169 Type *getTypeValue() const { return Ty; }
170 };
171
172147 //===----------------------------------------------------------------------===//
173148 /// \class
174149 /// This class represents a group of attributes that apply to one
213188 uint64_t getDereferenceableOrNullBytes() const;
214189 std::pair> getAllocSizeArgs() const;
215190 std::string getAsString(bool InAttrGrp) const;
216 Type *getByValType() const;
217191
218192 using iterator = const Attribute *;
219193
120120 return Attribute(PA);
121121 }
122122
123 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
124 Type *Ty) {
125 LLVMContextImpl *pImpl = Context.pImpl;
126 FoldingSetNodeID ID;
127 ID.AddInteger(Kind);
128 ID.AddPointer(Ty);
129
130 void *InsertPoint;
131 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
132
133 if (!PA) {
134 // If we didn't find any existing attributes of the same shape then create a
135 // new one and insert it.
136 PA = new TypeAttributeImpl(Kind, Ty);
137 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
138 }
139
140 // Return the Attribute that we found or created.
141 return Attribute(PA);
142 }
143
144123 Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
145124 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
146125 assert(Align <= 0x40000000 && "Alignment too large.");
164143 uint64_t Bytes) {
165144 assert(Bytes && "Bytes must be non-zero.");
166145 return get(Context, DereferenceableOrNull, Bytes);
167 }
168
169 Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
170 return get(Context, ByVal, Ty);
171146 }
172147
173148 Attribute
194169 return pImpl && pImpl->isStringAttribute();
195170 }
196171
197 bool Attribute::isTypeAttribute() const {
198 return pImpl && pImpl->isTypeAttribute();
199 }
200
201172 Attribute::AttrKind Attribute::getKindAsEnum() const {
202173 if (!pImpl) return None;
203 assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
174 assert((isEnumAttribute() || isIntAttribute()) &&
204175 "Invalid attribute type to get the kind as an enum!");
205176 return pImpl->getKindAsEnum();
206177 }
225196 "Invalid attribute type to get the value as a string!");
226197 return pImpl->getValueAsString();
227198 }
228
229 Type *Attribute::getValueAsType() const {
230 if (!pImpl) return {};
231 assert(isTypeAttribute() &&
232 "Invalid attribute type to get the value as a type!");
233 return pImpl->getValueAsType();
234 }
235
236199
237200 bool Attribute::hasAttribute(AttrKind Kind) const {
238201 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
288251 return "argmemonly";
289252 if (hasAttribute(Attribute::Builtin))
290253 return "builtin";
254 if (hasAttribute(Attribute::ByVal))
255 return "byval";
291256 if (hasAttribute(Attribute::Convergent))
292257 return "convergent";
293258 if (hasAttribute(Attribute::SwiftError))
387352 if (hasAttribute(Attribute::ImmArg))
388353 return "immarg";
389354
390 if (hasAttribute(Attribute::ByVal)) {
391 std::string Result;
392 Result += "byval";
393 if (Type *Ty = getValueAsType()) {
394 raw_string_ostream OS(Result);
395 Result += '(';
396 Ty->print(OS, false, true);
397 OS.flush();
398 Result += ')';
399 }
400 return Result;
401 }
402
403355 // FIXME: These should be output like this:
404356 //
405357 // align=4
498450
499451 void StringAttributeImpl::anchor() {}
500452
501 void TypeAttributeImpl::anchor() {}
502
503453 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
504454 if (isStringAttribute()) return false;
505455 return getKindAsEnum() == A;
511461 }
512462
513463 Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
514 assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
464 assert(isEnumAttribute() || isIntAttribute());
515465 return static_cast(this)->getEnumKind();
516466 }
517467
528478 StringRef AttributeImpl::getValueAsString() const {
529479 assert(isStringAttribute());
530480 return static_cast(this)->getStringValue();
531 }
532
533 Type *AttributeImpl::getValueAsType() const {
534 assert(isTypeAttribute());
535 return static_cast(this)->getTypeValue();
536481 }
537482
538483 bool AttributeImpl::operator<(const AttributeImpl &AI) const {
542487 if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
543488 if (AI.isIntAttribute()) return true;
544489 if (AI.isStringAttribute()) return true;
545 if (AI.isTypeAttribute()) return true;
546 }
547
548 if (isTypeAttribute()) {
549 if (AI.isEnumAttribute()) return false;
550 if (AI.isTypeAttribute()) {
551 assert(getKindAsEnum() != AI.getKindAsEnum() &&
552 "Comparison of types would be unstable");
553 return getKindAsEnum() < AI.getKindAsEnum();
554 }
555 if (AI.isIntAttribute()) return true;
556 if (AI.isStringAttribute()) return true;
557490 }
558491
559492 if (isIntAttribute()) {
560493 if (AI.isEnumAttribute()) return false;
561 if (AI.isTypeAttribute()) return false;
562494 if (AI.isIntAttribute()) {
563495 if (getKindAsEnum() == AI.getKindAsEnum())
564496 return getValueAsInt() < AI.getValueAsInt();
567499 if (AI.isStringAttribute()) return true;
568500 }
569501
570 assert(isStringAttribute());
571502 if (AI.isEnumAttribute()) return false;
572 if (AI.isTypeAttribute()) return false;
573503 if (AI.isIntAttribute()) return false;
574504 if (getKindAsString() == AI.getKindAsString())
575505 return getValueAsString() < AI.getValueAsString();
675605
676606 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
677607 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
678 }
679
680 Type *AttributeSet::getByValType() const {
681 return SetNode ? SetNode->getByValType() : nullptr;
682608 }
683609
684610 std::pair> AttributeSet::getAllocSizeArgs() const {
764690
765691 Attribute Attr;
766692 switch (Kind) {
767 case Attribute::ByVal:
768 Attr = Attribute::getWithByValType(C, B.getByValType());
769 break;
770693 case Attribute::Alignment:
771694 Attr = Attribute::getWithAlignment(C, B.getAlignment());
772695 break;
836759 return 0;
837760 }
838761
839 Type *AttributeSetNode::getByValType() const {
840 for (const auto I : *this)
841 if (I.hasAttribute(Attribute::ByVal))
842 return I.getValueAsType();
843 return 0;
844 }
845
846762 uint64_t AttributeSetNode::getDereferenceableBytes() const {
847763 for (const auto I : *this)
848764 if (I.hasAttribute(Attribute::Dereferenceable))
13411257 return getAttributes(ArgNo + FirstArgIndex).getAlignment();
13421258 }
13431259
1344 Type *AttributeList::getParamByValType(unsigned Index) const {
1345 return getAttributes(Index+FirstArgIndex).getByValType();
1346 }
1347
1348
13491260 unsigned AttributeList::getStackAlignment(unsigned Index) const {
13501261 return getAttributes(Index).getStackAlignment();
13511262 }
14241335 TargetDepAttrs.clear();
14251336 Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
14261337 AllocSizeArgs = 0;
1427 ByValType = nullptr;
14281338 }
14291339
14301340 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
14491359 Alignment = Attr.getAlignment();
14501360 else if (Kind == Attribute::StackAlignment)
14511361 StackAlignment = Attr.getStackAlignment();
1452 else if (Kind == Attribute::ByVal)
1453 ByValType = Attr.getValueAsType();
14541362 else if (Kind == Attribute::Dereferenceable)
14551363 DerefBytes = Attr.getDereferenceableBytes();
14561364 else if (Kind == Attribute::DereferenceableOrNull)
14731381 Alignment = 0;
14741382 else if (Val == Attribute::StackAlignment)
14751383 StackAlignment = 0;
1476 else if (Val == Attribute::ByVal)
1477 ByValType = nullptr;
14781384 else if (Val == Attribute::Dereferenceable)
14791385 DerefBytes = 0;
14801386 else if (Val == Attribute::DereferenceableOrNull)
15541460 // Reuse existing machinery to store this as a single 64-bit integer so we can
15551461 // save a few bytes over using a pair>.
15561462 AllocSizeArgs = RawArgs;
1557 return *this;
1558 }
1559
1560 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
1561 Attrs[Attribute::ByVal] = true;
1562 ByValType = Ty;
15631463 return *this;
15641464 }
15651465
110110 unsigned Argument::getParamAlignment() const {
111111 assert(getType()->isPointerTy() && "Only pointers have alignments");
112112 return getParent()->getParamAlignment(getArgNo());
113 }
114
115 Type *Argument::getParamByValType() const {
116 assert(getType()->isPointerTy() && "Only pointers have byval types");
117 return getParent()->getParamByValType(getArgNo());
118113 }
119114
120115 uint64_t Argument::getDereferenceableBytes() const {
16941694 "'noinline and alwaysinline' are incompatible!",
16951695 V);
16961696
1697 if (Attrs.hasAttribute(Attribute::ByVal) && Attrs.getByValType()) {
1698 Assert(Attrs.getByValType() == cast(Ty)->getElementType(),
1699 "Attribute 'byval' type does not match parameter!");
1700 }
1701
17021697 AttrBuilder IncompatibleAttrs = AttributeFuncs::typeIncompatible(Ty);
17031698 Assert(!AttrBuilder(Attrs).overlaps(IncompatibleAttrs),
17041699 "Wrong types for attribute: " +
+0
-31
test/Assembler/byval-type-attr.ll less more
None ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
1
2 ; CHECK: define void @foo(i32* byval(i32) align 4)
3 define void @foo(i32* byval(i32) align 4) {
4 ret void
5 }
6
7 ; CHECK: define void @bar({ i32*, i8 }* byval({ i32*, i8 }) align 4)
8 define void @bar({i32*, i8}* byval({i32*, i8}) align 4) {
9 ret void
10 }
11
12 define void @caller({ i32*, i8 }* %ptr) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
13 ; CHECK: call void @bar({ i32*, i8 }* byval({ i32*, i8 }) %ptr)
14 ; CHECK: invoke void @bar({ i32*, i8 }* byval({ i32*, i8 }) %ptr)
15 call void @bar({i32*, i8}* byval %ptr)
16 invoke void @bar({i32*, i8}* byval %ptr) to label %success unwind label %fail
17
18 success:
19 ret void
20
21 fail:
22 landingpad { i8*, i32 } cleanup
23 ret void
24 }
25
26 ; CHECK: declare void @baz([8 x i8]* byval([8 x i8]))
27 %named_type = type [8 x i8]
28 declare void @baz(%named_type* byval(%named_type))
29
30 declare i32 @__gxx_personality_v0(...)
+0
-4
test/Assembler/invalid-byval-type1.ll less more
None ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
1
2 ; CHECK: Attribute 'byval' type does not match parameter!
3 declare void @foo(i32* byval(i8))
+0
-4
test/Assembler/invalid-byval-type2.ll less more
None ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
1
2 ; CHECK: error: void type only allowed for function results
3 declare void @foo(i32* byval(void))
+0
-4
test/Assembler/invalid-byval-type3.ll less more
None ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
1
2 ; CHECK: Attributes 'byval' and 'inalloca' do not support unsized types!
3 declare void @foo(void()* byval(void()))
test/Bitcode/Inputs/byval-upgrade.bc less more
Binary diff not shown
4747 }
4848
4949 define void @f8(i8* byval)
50 ; CHECK: define void @f8(i8* byval(i8))
50 ; CHECK: define void @f8(i8* byval)
5151 {
5252 ret void;
5353 }
4444 }
4545
4646 define void @f8(i8* byval)
47 ; CHECK: define void @f8(i8* byval(i8))
47 ; CHECK: define void @f8(i8* byval)
4848 {
4949 ret void;
5050 }
+0
-7
test/Bitcode/byval-upgrade.test less more
None RUN: llvm-dis %p/Inputs/byval-upgrade.bc -o - | FileCheck %s
1
2 Make sure we upgrade old-stile IntAttribute byval records to a fully typed
3 version correctly.
4
5 CHECK: call void @bar({ i32*, i8 }* byval({ i32*, i8 }) %ptr)
6 CHECK: invoke void @bar({ i32*, i8 }* byval({ i32*, i8 }) %ptr)
403403 declare void @f.param.inreg(i8 inreg)
404404 ; CHECK: declare void @f.param.inreg(i8 inreg)
405405 declare void @f.param.byval({ i8, i8 }* byval)
406 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 }))
406 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval)
407407 declare void @f.param.inalloca(i8* inalloca)
408408 ; CHECK: declare void @f.param.inalloca(i8* inalloca)
409409 declare void @f.param.sret(i8* sret)
409409 declare void @f.param.inreg(i8 inreg)
410410 ; CHECK: declare void @f.param.inreg(i8 inreg)
411411 declare void @f.param.byval({ i8, i8 }* byval)
412 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 }))
412 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval)
413413 declare void @f.param.inalloca(i8* inalloca)
414414 ; CHECK: declare void @f.param.inalloca(i8* inalloca)
415415 declare void @f.param.sret(i8* sret)
434434 declare void @f.param.inreg(i8 inreg)
435435 ; CHECK: declare void @f.param.inreg(i8 inreg)
436436 declare void @f.param.byval({ i8, i8 }* byval)
437 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 }))
437 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval)
438438 declare void @f.param.inalloca(i8* inalloca)
439439 ; CHECK: declare void @f.param.inalloca(i8* inalloca)
440440 declare void @f.param.sret(i8* sret)
503503 declare void @f.param.inreg(i8 inreg)
504504 ; CHECK: declare void @f.param.inreg(i8 inreg)
505505 declare void @f.param.byval({ i8, i8 }* byval)
506 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 }))
506 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval)
507507 declare void @f.param.inalloca(i8* inalloca)
508508 ; CHECK: declare void @f.param.inalloca(i8* inalloca)
509509 declare void @f.param.sret(i8* sret)
503503 declare void @f.param.inreg(i8 inreg)
504504 ; CHECK: declare void @f.param.inreg(i8 inreg)
505505 declare void @f.param.byval({ i8, i8 }* byval)
506 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 }))
506 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval)
507507 declare void @f.param.inalloca(i8* inalloca)
508508 ; CHECK: declare void @f.param.inalloca(i8* inalloca)
509509 declare void @f.param.sret(i8* sret)
507507 declare void @f.param.inreg(i8 inreg)
508508 ; CHECK: declare void @f.param.inreg(i8 inreg)
509509 declare void @f.param.byval({ i8, i8 }* byval)
510 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 }))
510 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval)
511511 declare void @f.param.inalloca(i8* inalloca)
512512 ; CHECK: declare void @f.param.inalloca(i8* inalloca)
513513 declare void @f.param.sret(i8* sret)
514514 declare void @f.param.inreg(i8 inreg)
515515 ; CHECK: declare void @f.param.inreg(i8 inreg)
516516 declare void @f.param.byval({ i8, i8 }* byval)
517 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 }))
517 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval)
518518 declare void @f.param.inalloca(i8* inalloca)
519519 ; CHECK: declare void @f.param.inalloca(i8* inalloca)
520520 declare void @f.param.sret(i8* sret)
528528 declare void @f.param.inreg(i8 inreg)
529529 ; CHECK: declare void @f.param.inreg(i8 inreg)
530530 declare void @f.param.byval({ i8, i8 }* byval)
531 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 }))
531 ; CHECK: declare void @f.param.byval({ i8, i8 }* byval)
532532 declare void @f.param.inalloca(i8* inalloca)
533533 ; CHECK: declare void @f.param.inalloca(i8* inalloca)
534534 declare void @f.param.sret(i8* sret)
17341734 declare void @llvm.test.immarg.intrinsic(i32 immarg)
17351735 ; CHECK: declare void @llvm.test.immarg.intrinsic(i32 immarg)
17361736
1737 ; byval attribute with type
1738 %named_type = type [8 x i8]
1739 declare void @byval_type(i32* byval(i32) align 2)
1740 declare void @byval_type2({ i8, i8* }* byval({ i8, i8* }))
1741 declare void @byval_named_type(%named_type* byval(%named_type))
1742 ; CHECK: declare void @byval_type(i32* byval(i32) align 2)
1743 ; CHECK: declare void @byval_type2({ i8, i8* }* byval({ i8, i8* }))
1744 ; CHECK: declare void @byval_named_type([8 x i8]* byval([8 x i8]))
1745
17461737 ; CHECK: attributes #0 = { alignstack=4 }
17471738 ; CHECK: attributes #1 = { alignstack=8 }
17481739 ; CHECK: attributes #2 = { alwaysinline }
4040 declare void @ParamAttr4(i8 signext)
4141 ; CHECK: declare void @ParamAttr5(i8* inreg)
4242 declare void @ParamAttr5(i8* inreg)
43 ; CHECK: declare void @ParamAttr6(i8* byval(i8))
43 ; CHECK: declare void @ParamAttr6(i8* byval)
4444 declare void @ParamAttr6(i8* byval)
4545 ; CHECK: declare void @ParamAttr7(i8* noalias)
4646 declare void @ParamAttr7(i8* noalias)
5050 declare void @ParamAttr9(i8* nest noalias nocapture)
5151 ; CHECK: declare void @ParamAttr10{{[(i8* sret noalias nocapture) | (i8* noalias nocapture sret)]}}
5252 declare void @ParamAttr10(i8* sret noalias nocapture)
53 ;CHECK: declare void @ParamAttr11{{[(i8* byval(i8) noalias nocapture) | (i8* noalias nocapture byval(i8))]}}
53 ;CHECK: declare void @ParamAttr11{{[(i8* byval noalias nocapture) | (i8* noalias nocapture byval)]}}
5454 declare void @ParamAttr11(i8* byval noalias nocapture)
5555 ;CHECK: declare void @ParamAttr12{{[(i8* inreg noalias nocapture) | (i8* noalias nocapture inreg)]}}
5656 declare void @ParamAttr12(i8* inreg noalias nocapture)
+0
-37
test/CodeGen/AArch64/byval-type.ll less more
None ; RUN: llc -mtriple=aarch64-linux-gnu %s -o - | FileCheck %s
1
2 define i8 @byval_match(i8* byval(i8) align 1, i8* byval %ptr) {
3 ; CHECK-LABEL: byval_match:
4 ; CHECK: ldrb w0, [sp, #8]
5 %res = load i8, i8* %ptr
6 ret i8 %res
7 }
8
9 define void @caller_match(i8* %p0, i8* %p1) {
10 ; CHECK-LABEL: caller_match:
11 ; CHECK: ldrb [[P1:w[0-9]+]], [x1]
12 ; CHECK: strb [[P1]], [sp, #8]
13 ; CHECK: ldrb [[P0:w[0-9]+]], [x0]
14 ; CHECK: strb [[P0]], [sp]
15 ; CHECK: bl byval_match
16 call i8 @byval_match(i8* byval(i8) align 1 %p0, i8* byval %p1)
17 ret void
18 }
19
20 define i8 @byval_large([3 x i64]* byval([3 x i64]) align 8, i8* byval %ptr) {
21 ; CHECK-LABEL: byval_large:
22 ; CHECK: ldrb w0, [sp, #24]
23 %res = load i8, i8* %ptr
24 ret i8 %res
25 }
26
27 define void @caller_large([3 x i64]* %p0, i8* %p1) {
28 ; CHECK-LABEL: caller_large:
29 ; CHECK: ldr [[P0HI:x[0-9]+]], [x0, #16]
30 ; CHECK: ldr [[P0LO:q[0-9]+]], [x0]
31 ; CHECK: str [[P0HI]], [sp, #16]
32 ; CHECK: str [[P0LO]], [sp]
33 ; CHECK: bl byval_large
34 call i8 @byval_large([3 x i64]* byval([3 x i64]) align 8 %p0, i8* byval %p1)
35 ret void
36 }
5555 ; CHECK: %[[POS:.*]] = alloca i32
5656 ; CHECK: %[[VAL:.*]] = load i32, i32* %x
5757 ; CHECK: store i32 %[[VAL]], i32* %[[POS]]
58 ; CHECK: tail call void @ext2(i32* nonnull byval %[[POS]]
58 ; CHECK: tail call void @ext2(i32* byval nonnull %[[POS]]
5959 ; CHECK: ret void
6060 tail call void @bar2(i32* byval %x)
6161 ret void
6666 ; CHECK: %[[POS:.*]] = alloca i32
6767 ; CHECK: %[[VAL:.*]] = load i32, i32* %x
6868 ; CHECK: store i32 %[[VAL]], i32* %[[POS]]
69 ; CHECK: tail call void @ext2(i32* nonnull byval %[[POS]]
69 ; CHECK: tail call void @ext2(i32* byval nonnull %[[POS]]
7070 ; CHECK: ret void
7171 %x = alloca i32
7272 tail call void @bar2(i32* byval %x)
77
88 #include "llvm/IR/Attributes.h"
99 #include "llvm/IR/LLVMContext.h"
10 #include "llvm/IR/DerivedTypes.h"
1110 #include "gtest/gtest.h"
1211 using namespace llvm;
1312
3938 EXPECT_TRUE(Align4 < Deref4);
4039 EXPECT_TRUE(Align4 < Deref5);
4140 EXPECT_TRUE(Align5 < Deref4);
42
43 Attribute ByVal = Attribute::get(C, Attribute::ByVal, Type::getInt32Ty(C));
44 EXPECT_FALSE(ByVal < Attribute::get(C, Attribute::ZExt));
45 EXPECT_TRUE(ByVal < Align4);
4641
4742 AttributeList ASs[] = {AttributeList::get(C, 2, Attribute::ZExt),
4843 AttributeList::get(C, 1, Attribute::SExt)};
170165 EXPECT_EQ(2U, AL.getNumAttrSets());
171166 }
172167
173 TEST(Attributes, StringRepresentation) {
174 LLVMContext C;
175 StructType *Ty = StructType::create(Type::getInt32Ty(C), "mystruct");
176
177 // Insufficiently careful printing can result in byval(%mystruct = { i32 })
178 Attribute A = Attribute::getWithByValType(C, Ty);
179 EXPECT_EQ(A.getAsString(), "byval(%mystruct)");
180
181 A = Attribute::getWithByValType(C, nullptr);
182 EXPECT_EQ(A.getAsString(), "byval");
183
184 A = Attribute::getWithByValType(C, Type::getInt32Ty(C));
185 EXPECT_EQ(A.getAsString(), "byval(i32)");
186 }
187
188168 } // end anonymous namespace