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