1//===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines various classes for working with Instructions and
10// ConstantExprs.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_IR_OPERATOR_H
15#define LLVM_IR_OPERATOR_H
16
17#include "llvm/ADT/MapVector.h"
18#include "llvm/IR/Constants.h"
19#include "llvm/IR/FMF.h"
20#include "llvm/IR/GEPNoWrapFlags.h"
21#include "llvm/IR/Instruction.h"
22#include "llvm/IR/Type.h"
23#include "llvm/IR/Value.h"
24#include "llvm/Support/Casting.h"
25#include "llvm/Support/Compiler.h"
26#include <cstddef>
27#include <optional>
28
29namespace llvm {
30
31/// This is a utility class that provides an abstraction for the common
32/// functionality between Instructions and ConstantExprs.
33class Operator : public User {
34public:
35 // The Operator class is intended to be used as a utility, and is never itself
36 // instantiated.
37 Operator() = delete;
38 ~Operator() = delete;
39
40 void *operator new(size_t s) = delete;
41
42 /// Return the opcode for this Instruction or ConstantExpr.
43 unsigned getOpcode() const {
44 if (const Instruction *I = dyn_cast<Instruction>(Val: this))
45 return I->getOpcode();
46 return cast<ConstantExpr>(Val: this)->getOpcode();
47 }
48
49 /// If V is an Instruction or ConstantExpr, return its opcode.
50 /// Otherwise return UserOp1.
51 static unsigned getOpcode(const Value *V) {
52 if (const Instruction *I = dyn_cast<Instruction>(Val: V))
53 return I->getOpcode();
54 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(Val: V))
55 return CE->getOpcode();
56 return Instruction::UserOp1;
57 }
58
59 static bool classof(const Instruction *) { return true; }
60 static bool classof(const ConstantExpr *) { return true; }
61 static bool classof(const Value *V) {
62 return isa<Instruction>(Val: V) || isa<ConstantExpr>(Val: V);
63 }
64
65 /// Return true if this operator has flags which may cause this operator
66 /// to evaluate to poison despite having non-poison inputs.
67 LLVM_ABI bool hasPoisonGeneratingFlags() const;
68
69 /// Return true if this operator has poison-generating flags,
70 /// return attributes or metadata. The latter two is only possible for
71 /// instructions.
72 LLVM_ABI bool hasPoisonGeneratingAnnotations() const;
73};
74
75/// Utility class for integer operators which may exhibit overflow - Add, Sub,
76/// Mul, and Shl. It does not include SDiv, despite that operator having the
77/// potential for overflow.
78class OverflowingBinaryOperator : public Operator {
79public:
80 enum {
81 AnyWrap = 0,
82 NoUnsignedWrap = (1 << 0),
83 NoSignedWrap = (1 << 1)
84 };
85
86private:
87 friend class Instruction;
88 friend class ConstantExpr;
89
90 void setHasNoUnsignedWrap(bool B) {
91 SubclassOptionalData =
92 (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
93 }
94 void setHasNoSignedWrap(bool B) {
95 SubclassOptionalData =
96 (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
97 }
98
99public:
100 /// Transparently provide more efficient getOperand methods.
101 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
102
103 /// Test whether this operation is known to never
104 /// undergo unsigned overflow, aka the nuw property.
105 bool hasNoUnsignedWrap() const {
106 return SubclassOptionalData & NoUnsignedWrap;
107 }
108
109 /// Test whether this operation is known to never
110 /// undergo signed overflow, aka the nsw property.
111 bool hasNoSignedWrap() const {
112 return (SubclassOptionalData & NoSignedWrap) != 0;
113 }
114
115 /// Returns the no-wrap kind of the operation.
116 unsigned getNoWrapKind() const {
117 unsigned NoWrapKind = 0;
118 if (hasNoUnsignedWrap())
119 NoWrapKind |= NoUnsignedWrap;
120
121 if (hasNoSignedWrap())
122 NoWrapKind |= NoSignedWrap;
123
124 return NoWrapKind;
125 }
126
127 /// Return true if the instruction is commutative
128 bool isCommutative() const { return Instruction::isCommutative(Opcode: getOpcode()); }
129
130 static bool classof(const Instruction *I) {
131 return I->getOpcode() == Instruction::Add ||
132 I->getOpcode() == Instruction::Sub ||
133 I->getOpcode() == Instruction::Mul ||
134 I->getOpcode() == Instruction::Shl;
135 }
136 static bool classof(const ConstantExpr *CE) {
137 return CE->getOpcode() == Instruction::Add ||
138 CE->getOpcode() == Instruction::Sub;
139 }
140 static bool classof(const Value *V) {
141 return (isa<Instruction>(Val: V) && classof(I: cast<Instruction>(Val: V))) ||
142 (isa<ConstantExpr>(Val: V) && classof(CE: cast<ConstantExpr>(Val: V)));
143 }
144};
145
146template <>
147struct OperandTraits<OverflowingBinaryOperator>
148 : public FixedNumOperandTraits<OverflowingBinaryOperator, 2> {};
149
150DEFINE_TRANSPARENT_OPERAND_ACCESSORS(OverflowingBinaryOperator, Value)
151
152/// A udiv, sdiv, lshr, or ashr instruction, which can be marked as "exact",
153/// indicating that no bits are destroyed.
154class PossiblyExactOperator : public Operator {
155public:
156 enum {
157 IsExact = (1 << 0)
158 };
159
160private:
161 friend class Instruction;
162 friend class ConstantExpr;
163
164 void setIsExact(bool B) {
165 SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
166 }
167
168public:
169 /// Transparently provide more efficient getOperand methods.
170 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
171
172 /// Test whether this division is known to be exact, with zero remainder.
173 bool isExact() const {
174 return SubclassOptionalData & IsExact;
175 }
176
177 static bool isPossiblyExactOpcode(unsigned OpC) {
178 return OpC == Instruction::SDiv ||
179 OpC == Instruction::UDiv ||
180 OpC == Instruction::AShr ||
181 OpC == Instruction::LShr;
182 }
183
184 static bool classof(const Instruction *I) {
185 return isPossiblyExactOpcode(OpC: I->getOpcode());
186 }
187 static bool classof(const Value *V) {
188 return (isa<Instruction>(Val: V) && classof(I: cast<Instruction>(Val: V)));
189 }
190};
191
192template <>
193struct OperandTraits<PossiblyExactOperator>
194 : public FixedNumOperandTraits<PossiblyExactOperator, 2> {};
195
196DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PossiblyExactOperator, Value)
197
198/// Utility class for floating point operations which can have
199/// information about relaxed accuracy requirements attached to them.
200class FPMathOperator : public Operator {
201private:
202 friend class Instruction;
203
204 /// 'Fast' means all bits are set.
205 void setFast(bool B) {
206 setHasAllowReassoc(B);
207 setHasNoNaNs(B);
208 setHasNoInfs(B);
209 setHasNoSignedZeros(B);
210 setHasAllowReciprocal(B);
211 setHasAllowContract(B);
212 setHasApproxFunc(B);
213 }
214
215 void setHasAllowReassoc(bool B) {
216 SubclassOptionalData =
217 (SubclassOptionalData & ~FastMathFlags::AllowReassoc) |
218 (B * FastMathFlags::AllowReassoc);
219 }
220
221 void setHasNoNaNs(bool B) {
222 SubclassOptionalData =
223 (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
224 (B * FastMathFlags::NoNaNs);
225 }
226
227 void setHasNoInfs(bool B) {
228 SubclassOptionalData =
229 (SubclassOptionalData & ~FastMathFlags::NoInfs) |
230 (B * FastMathFlags::NoInfs);
231 }
232
233 void setHasNoSignedZeros(bool B) {
234 SubclassOptionalData =
235 (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
236 (B * FastMathFlags::NoSignedZeros);
237 }
238
239 void setHasAllowReciprocal(bool B) {
240 SubclassOptionalData =
241 (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
242 (B * FastMathFlags::AllowReciprocal);
243 }
244
245 void setHasAllowContract(bool B) {
246 SubclassOptionalData =
247 (SubclassOptionalData & ~FastMathFlags::AllowContract) |
248 (B * FastMathFlags::AllowContract);
249 }
250
251 void setHasApproxFunc(bool B) {
252 SubclassOptionalData =
253 (SubclassOptionalData & ~FastMathFlags::ApproxFunc) |
254 (B * FastMathFlags::ApproxFunc);
255 }
256
257 /// Convenience function for setting multiple fast-math flags.
258 /// FMF is a mask of the bits to set.
259 void setFastMathFlags(FastMathFlags FMF) {
260 SubclassOptionalData |= FMF.Flags;
261 }
262
263 /// Convenience function for copying all fast-math flags.
264 /// All values in FMF are transferred to this operator.
265 void copyFastMathFlags(FastMathFlags FMF) {
266 SubclassOptionalData = FMF.Flags;
267 }
268
269 /// Returns true if `Ty` is composed of a single kind of float-poing type
270 /// (possibly repeated within an aggregate).
271 static bool isComposedOfHomogeneousFloatingPointTypes(Type *Ty) {
272 if (auto *StructTy = dyn_cast<StructType>(Val: Ty)) {
273 if (!StructTy->isLiteral() || !StructTy->containsHomogeneousTypes())
274 return false;
275 Ty = StructTy->elements().front();
276 } else if (auto *ArrayTy = dyn_cast<ArrayType>(Val: Ty)) {
277 do {
278 Ty = ArrayTy->getElementType();
279 } while ((ArrayTy = dyn_cast<ArrayType>(Val: Ty)));
280 }
281 return Ty->isFPOrFPVectorTy();
282 };
283
284public:
285 /// Test if this operation allows all non-strict floating-point transforms.
286 bool isFast() const {
287 return ((SubclassOptionalData & FastMathFlags::AllowReassoc) != 0 &&
288 (SubclassOptionalData & FastMathFlags::NoNaNs) != 0 &&
289 (SubclassOptionalData & FastMathFlags::NoInfs) != 0 &&
290 (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0 &&
291 (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0 &&
292 (SubclassOptionalData & FastMathFlags::AllowContract) != 0 &&
293 (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0);
294 }
295
296 /// Test if this operation may be simplified with reassociative transforms.
297 bool hasAllowReassoc() const {
298 return (SubclassOptionalData & FastMathFlags::AllowReassoc) != 0;
299 }
300
301 /// Test if this operation's arguments and results are assumed not-NaN.
302 bool hasNoNaNs() const {
303 return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
304 }
305
306 /// Test if this operation's arguments and results are assumed not-infinite.
307 bool hasNoInfs() const {
308 return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
309 }
310
311 /// Test if this operation can ignore the sign of zero.
312 bool hasNoSignedZeros() const {
313 return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
314 }
315
316 /// Test if this operation can use reciprocal multiply instead of division.
317 bool hasAllowReciprocal() const {
318 return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
319 }
320
321 /// Test if this operation can be floating-point contracted (FMA).
322 bool hasAllowContract() const {
323 return (SubclassOptionalData & FastMathFlags::AllowContract) != 0;
324 }
325
326 /// Test if this operation allows approximations of math library functions or
327 /// intrinsics.
328 bool hasApproxFunc() const {
329 return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0;
330 }
331
332 /// Convenience function for getting all the fast-math flags
333 FastMathFlags getFastMathFlags() const {
334 return FastMathFlags(SubclassOptionalData);
335 }
336
337 /// Get the maximum error permitted by this operation in ULPs. An accuracy of
338 /// 0.0 means that the operation should be performed with the default
339 /// precision.
340 LLVM_ABI float getFPAccuracy() const;
341
342 /// Returns true if `Ty` is a supported floating-point type for phi, select,
343 /// or call FPMathOperators.
344 static bool isSupportedFloatingPointType(Type *Ty) {
345 return Ty->isFPOrFPVectorTy() ||
346 isComposedOfHomogeneousFloatingPointTypes(Ty);
347 }
348
349 static bool classof(const Value *V) {
350 unsigned Opcode;
351 if (auto *I = dyn_cast<Instruction>(Val: V))
352 Opcode = I->getOpcode();
353 else
354 return false;
355
356 switch (Opcode) {
357 case Instruction::FNeg:
358 case Instruction::FAdd:
359 case Instruction::FSub:
360 case Instruction::FMul:
361 case Instruction::FDiv:
362 case Instruction::FRem:
363 case Instruction::FPTrunc:
364 case Instruction::FPExt:
365 // FIXME: To clean up and correct the semantics of fast-math-flags, FCmp
366 // should not be treated as a math op, but the other opcodes should.
367 // This would make things consistent with Select/PHI (FP value type
368 // determines whether they are math ops and, therefore, capable of
369 // having fast-math-flags).
370 case Instruction::FCmp:
371 return true;
372 case Instruction::PHI:
373 case Instruction::Select:
374 case Instruction::Call: {
375 return isSupportedFloatingPointType(Ty: V->getType());
376 }
377 default:
378 return false;
379 }
380 }
381};
382
383/// A helper template for defining operators for individual opcodes.
384template<typename SuperClass, unsigned Opc>
385class ConcreteOperator : public SuperClass {
386public:
387 static bool classof(const Instruction *I) {
388 return I->getOpcode() == Opc;
389 }
390 static bool classof(const ConstantExpr *CE) {
391 return CE->getOpcode() == Opc;
392 }
393 static bool classof(const Value *V) {
394 return (isa<Instruction>(Val: V) && classof(cast<Instruction>(Val: V))) ||
395 (isa<ConstantExpr>(Val: V) && classof(cast<ConstantExpr>(Val: V)));
396 }
397};
398
399class AddOperator
400 : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
401};
402class SubOperator
403 : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
404};
405class MulOperator
406 : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
407};
408class ShlOperator
409 : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
410};
411
412class AShrOperator
413 : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
414};
415class LShrOperator
416 : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
417};
418
419class GEPOperator
420 : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
421public:
422 /// Transparently provide more efficient getOperand methods.
423 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
424
425 GEPNoWrapFlags getNoWrapFlags() const {
426 return GEPNoWrapFlags::fromRaw(Flags: SubclassOptionalData);
427 }
428
429 /// Test whether this is an inbounds GEP, as defined by LangRef.html.
430 bool isInBounds() const { return getNoWrapFlags().isInBounds(); }
431
432 bool hasNoUnsignedSignedWrap() const {
433 return getNoWrapFlags().hasNoUnsignedSignedWrap();
434 }
435
436 bool hasNoUnsignedWrap() const {
437 return getNoWrapFlags().hasNoUnsignedWrap();
438 }
439
440 /// Returns the offset of the index with an inrange attachment, or
441 /// std::nullopt if none.
442 LLVM_ABI std::optional<ConstantRange> getInRange() const;
443
444 inline op_iterator idx_begin() { return op_begin()+1; }
445 inline const_op_iterator idx_begin() const { return op_begin()+1; }
446 inline op_iterator idx_end() { return op_end(); }
447 inline const_op_iterator idx_end() const { return op_end(); }
448
449 inline iterator_range<op_iterator> indices() {
450 return make_range(x: idx_begin(), y: idx_end());
451 }
452
453 inline iterator_range<const_op_iterator> indices() const {
454 return make_range(x: idx_begin(), y: idx_end());
455 }
456
457 Value *getPointerOperand() {
458 return getOperand(0);
459 }
460 const Value *getPointerOperand() const {
461 return getOperand(0);
462 }
463 static unsigned getPointerOperandIndex() {
464 return 0U; // get index for modifying correct operand
465 }
466
467 /// Method to return the pointer operand as a PointerType.
468 Type *getPointerOperandType() const {
469 return getPointerOperand()->getType();
470 }
471
472 LLVM_ABI Type *getSourceElementType() const;
473 LLVM_ABI Type *getResultElementType() const;
474
475 /// Method to return the address space of the pointer operand.
476 unsigned getPointerAddressSpace() const {
477 return getPointerOperandType()->getPointerAddressSpace();
478 }
479
480 unsigned getNumIndices() const { // Note: always non-negative
481 return getNumOperands() - 1;
482 }
483
484 bool hasIndices() const {
485 return getNumOperands() > 1;
486 }
487
488 /// Return true if all of the indices of this GEP are zeros.
489 /// If so, the result pointer and the first operand have the same
490 /// value, just potentially different types.
491 bool hasAllZeroIndices() const {
492 for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
493 if (ConstantInt *C = dyn_cast<ConstantInt>(Val: I))
494 if (C->isZero())
495 continue;
496 return false;
497 }
498 return true;
499 }
500
501 /// Return true if all of the indices of this GEP are constant integers.
502 /// If so, the result pointer and the first operand have
503 /// a constant offset between them.
504 bool hasAllConstantIndices() const {
505 for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
506 if (!isa<ConstantInt>(Val: I))
507 return false;
508 }
509 return true;
510 }
511
512 unsigned countNonConstantIndices() const {
513 return count_if(Range: indices(), P: [](const Use& use) {
514 return !isa<ConstantInt>(Val: *use);
515 });
516 }
517
518 /// Compute the maximum alignment that this GEP is garranteed to preserve.
519 LLVM_ABI Align getMaxPreservedAlignment(const DataLayout &DL) const;
520
521 /// Accumulate the constant address offset of this GEP if possible.
522 ///
523 /// This routine accepts an APInt into which it will try to accumulate the
524 /// constant offset of this GEP.
525 ///
526 /// If \p ExternalAnalysis is provided it will be used to calculate a offset
527 /// when a operand of GEP is not constant.
528 /// For example, for a value \p ExternalAnalysis might try to calculate a
529 /// lower bound. If \p ExternalAnalysis is successful, it should return true.
530 ///
531 /// If the \p ExternalAnalysis returns false or the value returned by \p
532 /// ExternalAnalysis results in a overflow/underflow, this routine returns
533 /// false and the value of the offset APInt is undefined (it is *not*
534 /// preserved!).
535 ///
536 /// The APInt passed into this routine must be at exactly as wide as the
537 /// IntPtr type for the address space of the base GEP pointer.
538 LLVM_ABI bool accumulateConstantOffset(
539 const DataLayout &DL, APInt &Offset,
540 function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const;
541
542 LLVM_ABI static bool accumulateConstantOffset(
543 Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
544 APInt &Offset,
545 function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr);
546
547 /// Collect the offset of this GEP as a map of Values to their associated
548 /// APInt multipliers, as well as a total Constant Offset.
549 LLVM_ABI bool
550 collectOffset(const DataLayout &DL, unsigned BitWidth,
551 SmallMapVector<Value *, APInt, 4> &VariableOffsets,
552 APInt &ConstantOffset) const;
553};
554
555template <>
556struct OperandTraits<GEPOperator> : public VariadicOperandTraits<GEPOperator> {
557};
558
559DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GEPOperator, Value)
560
561class PtrToIntOperator
562 : public ConcreteOperator<Operator, Instruction::PtrToInt> {
563 friend class PtrToInt;
564 friend class ConstantExpr;
565
566public:
567 /// Transparently provide more efficient getOperand methods.
568 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
569
570 Value *getPointerOperand() {
571 return getOperand(0);
572 }
573 const Value *getPointerOperand() const {
574 return getOperand(0);
575 }
576
577 static unsigned getPointerOperandIndex() {
578 return 0U; // get index for modifying correct operand
579 }
580
581 /// Method to return the pointer operand as a PointerType.
582 Type *getPointerOperandType() const {
583 return getPointerOperand()->getType();
584 }
585
586 /// Method to return the address space of the pointer operand.
587 unsigned getPointerAddressSpace() const {
588 return cast<PointerType>(Val: getPointerOperandType())->getAddressSpace();
589 }
590};
591
592template <>
593struct OperandTraits<PtrToIntOperator>
594 : public FixedNumOperandTraits<PtrToIntOperator, 1> {};
595
596DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PtrToIntOperator, Value)
597
598class BitCastOperator
599 : public ConcreteOperator<Operator, Instruction::BitCast> {
600 friend class BitCastInst;
601 friend class ConstantExpr;
602
603public:
604 /// Transparently provide more efficient getOperand methods.
605 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
606
607 Type *getSrcTy() const {
608 return getOperand(0)->getType();
609 }
610
611 Type *getDestTy() const {
612 return getType();
613 }
614};
615
616template <>
617struct OperandTraits<BitCastOperator>
618 : public FixedNumOperandTraits<BitCastOperator, 1> {};
619
620DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitCastOperator, Value)
621
622class AddrSpaceCastOperator
623 : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> {
624 friend class AddrSpaceCastInst;
625 friend class ConstantExpr;
626
627public:
628 /// Transparently provide more efficient getOperand methods.
629 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
630
631 Value *getPointerOperand() { return getOperand(0); }
632
633 const Value *getPointerOperand() const { return getOperand(0); }
634
635 unsigned getSrcAddressSpace() const {
636 return getPointerOperand()->getType()->getPointerAddressSpace();
637 }
638
639 unsigned getDestAddressSpace() const {
640 return getType()->getPointerAddressSpace();
641 }
642};
643
644template <>
645struct OperandTraits<AddrSpaceCastOperator>
646 : public FixedNumOperandTraits<AddrSpaceCastOperator, 1> {};
647
648DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AddrSpaceCastOperator, Value)
649
650} // end namespace llvm
651
652#endif // LLVM_IR_OPERATOR_H
653

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of llvm/include/llvm/IR/Operator.h