llvm.org GIT mirror llvm / a6abdeb
[IR] Add a `data_operand` abstraction Summary: Data operands of a call or invoke consist of the call arguments, and the bundle operands associated with the `call` (or `invoke`) instruction. The motivation for this change is that we'd like to be able to query "argument attributes" like `readonly` and `nocapture` for bundle operands naturally. This change also provides a conservative "implementation" for these attributes for any bundle operand, and an extension point for future work. Reviewers: chandlerc, majnemer, reames Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D14305 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252077 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 4 years ago
4 changed file(s) with 131 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
162162 bool arg_empty() const { return arg_end() == arg_begin(); }
163163 unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
164164
165 /// Type of iterator to use when looping over data operands at this call site
166 /// (see below).
167 typedef IterTy data_operand_iterator;
168
169 /// data_operands_begin/data_operands_end - Return iterators iterating over
170 /// the call / invoke argument list and bundle operands. For invokes, this is
171 /// the set of instruction operands except the invoke target and the two
172 /// successor blocks; and for calls this is the set of instruction operands
173 /// except the call target.
174
175 IterTy data_operands_begin() const {
176 assert(getInstruction() && "Not a call or invoke instruction!");
177 return (*this)->op_begin();
178 }
179 IterTy data_operands_end() const {
180 assert(getInstruction() && "Not a call or invoke instruction!");
181 return (*this)->op_end() - (isCall() ? 1 : 3);
182 }
183 iterator_range data_ops() const {
184 return iterator_range(data_operands_begin(), data_operands_end());
185 }
186 bool data_operands_empty() const {
187 return data_operands_end() == data_operands_begin();
188 }
189 unsigned data_operands_size() const {
190 return std::distance(data_operands_begin(), data_operands_end());
191 }
192
165193 /// getType - Return the type of the instruction that generated this call site
166194 ///
167195 Type *getType() const { return (*this)->getType(); }
244272 CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A));
245273 }
246274
275 /// \brief Return true if the data operand at index \p i directly or
276 /// indirectly has the attribute \p A.
277 ///
278 /// Normal call or invoke arguments have per operand attributes, as specified
279 /// in the attribute set attached to this instruction, while operand bundle
280 /// operands may have some attributes implied by the type of its containing
281 /// operand bundle.
282 bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind A) const {
283 CALLSITE_DELEGATE_GETTER(dataOperandHasImpliedAttr(i, A));
284 }
285
247286 /// @brief Extract the alignment for a call or parameter (0=unknown).
248287 uint16_t getParamAlignment(uint16_t i) const {
249288 CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
346385 #undef CALLSITE_DELEGATE_GETTER
347386 #undef CALLSITE_DELEGATE_SETTER
348387
349 /// @brief Determine whether this argument is not captured.
350 bool doesNotCapture(unsigned ArgNo) const {
351 return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
388 /// @brief Determine whether this data operand is not captured.
389 bool doesNotCapture(unsigned OpNo) const {
390 return dataOperandHasImpliedAttr(OpNo + 1, Attribute::NoCapture);
352391 }
353392
354393 /// @brief Determine whether this argument is passed by value.
373412 return paramHasAttr(arg_size(), Attribute::InAlloca);
374413 }
375414
376 bool doesNotAccessMemory(unsigned ArgNo) const {
377 return paramHasAttr(ArgNo + 1, Attribute::ReadNone);
378 }
379
380 bool onlyReadsMemory(unsigned ArgNo) const {
381 return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) ||
382 paramHasAttr(ArgNo + 1, Attribute::ReadNone);
415 bool doesNotAccessMemory(unsigned OpNo) const {
416 return dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone);
417 }
418
419 bool onlyReadsMemory(unsigned OpNo) const {
420 return dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadOnly) ||
421 dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone);
383422 }
384423
385424 /// @brief Return true if the return value is known to be not null.
11191119 OperandBundleUse() {}
11201120 explicit OperandBundleUse(StringRef Tag, ArrayRef Inputs)
11211121 : Tag(Tag), Inputs(Inputs) {}
1122
1123 /// \brief Return true if all the operands in this operand bundle have the
1124 /// attribute A.
1125 ///
1126 /// Currently there is no way to have attributes on operand bundles differ on
1127 /// a per operand granularity.
1128 bool operandsHaveAttr(Attribute::AttrKind A) const {
1129 // Conservative answer: no operands have any attributes.
1130 return false;
1131 };
11221132 };
11231133
11241134 /// \brief A container for an operand bundle being viewed as a set of values
12531263 return None;
12541264 }
12551265
1266 /// \brief Return the operand bundle for the operand at index OpIdx.
1267 ///
1268 /// It is an error to call this with an OpIdx that does not correspond to an
1269 /// bundle operand.
1270 OperandBundleUse getOperandBundleForOperand(unsigned OpIdx) const {
1271 for (auto &BOI : bundle_op_infos())
1272 if (BOI.Begin <= OpIdx && OpIdx < BOI.End)
1273 return operandBundleFromBundleOpInfo(BOI);
1274
1275 llvm_unreachable("Did not find operand bundle for operand!");
1276 }
1277
12561278 /// \brief Return true if this operand bundle user has operand bundles that
12571279 /// may read from the heap.
12581280 bool hasReadingOperandBundles() const {
16011601
16021602 /// \brief Determine whether the call or the callee has the given attributes.
16031603 bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;
1604
1605 /// \brief Return true if the data operand at index \p i has the attribute \p
1606 /// A.
1607 ///
1608 /// Data operands include call arguments and values used in operand bundles,
1609 /// but does not include the callee operand. This routine dispatches to the
1610 /// underlying AttributeList or the OperandBundleUser as appropriate.
1611 ///
1612 /// The index \p i is interpreted as
1613 ///
1614 /// \p i == Attribute::ReturnIndex -> the return value
1615 /// \p i in [1, arg_size + 1) -> argument number (\p i - 1)
1616 /// \p i in [arg_size + 1, data_operand_size + 1) -> bundle operand at index
1617 /// (\p i - 1) in the operand list.
1618 bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind A) const;
16041619
16051620 /// \brief Extract the alignment for a call or parameter (0=unknown).
16061621 unsigned getParamAlignment(unsigned i) const {
34733488 /// \brief Determine whether the call or the callee has the given attributes.
34743489 bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;
34753490
3491 /// \brief Return true if the data operand at index \p i has the attribute \p
3492 /// A.
3493 ///
3494 /// Data operands include invoke arguments and values used in operand bundles,
3495 /// but does not include the invokee operand, or the two successor blocks.
3496 /// This routine dispatches to the underlying AttributeList or the
3497 /// OperandBundleUser as appropriate.
3498 ///
3499 /// The index \p i is interpreted as
3500 ///
3501 /// \p i == Attribute::ReturnIndex -> the return value
3502 /// \p i in [1, arg_size + 1) -> argument number (\p i - 1)
3503 /// \p i in [arg_size + 1, data_operand_size + 1) -> bundle operand at index
3504 /// (\p i - 1) in the operand list.
3505 bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind A) const;
3506
34763507 /// \brief Extract the alignment for a call or parameter (0=unknown).
34773508 unsigned getParamAlignment(unsigned i) const {
34783509 return AttributeList.getParamAlignment(i);
337337 if (const Function *F = getCalledFunction())
338338 return F->getAttributes().hasAttribute(i, A);
339339 return false;
340 }
341
342 bool CallInst::dataOperandHasImpliedAttr(unsigned i,
343 Attribute::AttrKind A) const {
344
345 // The attribute A can either be directly specified, if the operand in
346 // question is a call argument; or be indirectly implied by the kind of its
347 // containing operand bundle, if the operand is a bundle operand.
348
349 if (i < (getNumArgOperands() + 1))
350 return paramHasAttr(i, A);
351
352 assert(hasOperandBundles() && i >= (getBundleOperandsStartIndex() + 1) &&
353 "Must be either a call argument or an operand bundle!");
354 return getOperandBundleForOperand(i - 1).operandsHaveAttr(A);
340355 }
341356
342357 /// IsConstantOne - Return true only if val is constant int 1
583598 if (const Function *F = getCalledFunction())
584599 return F->getAttributes().hasAttribute(i, A);
585600 return false;
601 }
602
603 bool InvokeInst::dataOperandHasImpliedAttr(unsigned i,
604 Attribute::AttrKind A) const {
605 // The attribute A can either be directly specified, if the operand in
606 // question is an invoke argument; or be indirectly implied by the kind of its
607 // containing operand bundle, if the operand is a bundle operand.
608
609 if (i < (getNumArgOperands() + 1))
610 return paramHasAttr(i, A);
611
612 assert(hasOperandBundles() && i >= (getBundleOperandsStartIndex() + 1) &&
613 "Must be either an invoke argument or an operand bundle!");
614 return getOperandBundleForOperand(i - 1).operandsHaveAttr(A);
586615 }
587616
588617 void InvokeInst::addAttribute(unsigned i, Attribute::AttrKind attr) {