1//===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines various classes for working with Instructions and
11// ConstantExprs.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_IR_OPERATOR_H
16#define LLVM_IR_OPERATOR_H
17
18#include "llvm/ADT/None.h"
19#include "llvm/ADT/Optional.h"
20#include "llvm/IR/Constants.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 <cstddef>
26
27namespace llvm {
28
29/// This is a utility class that provides an abstraction for the common
30/// functionality between Instructions and ConstantExprs.
31class Operator : public User {
32public:
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.
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.
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
57  static inline bool classof(const Instruction *) { return true; }
58  static inline bool classof(const ConstantExpr *) { return true; }
59  static inline bool classof(const Value *V) {
60    return isa<Instruction>(V) || isa<ConstantExpr>(V);
61  }
62};
63
64/// Utility class for integer arithmetic operators which may exhibit overflow -
65/// Add, Sub, and Mul. It does not include SDiv, despite that operator having
66/// the potential for overflow.
67class OverflowingBinaryOperator : public Operator {
68public:
69  enum {
70    NoUnsignedWrap = (1 << 0),
71    NoSignedWrap   = (1 << 1)
72  };
73
74private:
75  friend class Instruction;
76  friend class ConstantExpr;
77
78  void setHasNoUnsignedWrap(bool B) {
79    SubclassOptionalData =
80      (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
81  }
82  void setHasNoSignedWrap(bool B) {
83    SubclassOptionalData =
84      (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
85  }
86
87public:
88  /// Test whether this operation is known to never
89  /// undergo unsigned overflow, aka the nuw property.
90  bool hasNoUnsignedWrap() const {
91    return SubclassOptionalData & NoUnsignedWrap;
92  }
93
94  /// Test whether this operation is known to never
95  /// undergo signed overflow, aka the nsw property.
96  bool hasNoSignedWrap() const {
97    return (SubclassOptionalData & NoSignedWrap) != 0;
98  }
99
100  static inline bool classof(const Instruction *I) {
101    return I->getOpcode() == Instruction::Add ||
102           I->getOpcode() == Instruction::Sub ||
103           I->getOpcode() == Instruction::Mul ||
104           I->getOpcode() == Instruction::Shl;
105  }
106  static inline bool classof(const ConstantExpr *CE) {
107    return CE->getOpcode() == Instruction::Add ||
108           CE->getOpcode() == Instruction::Sub ||
109           CE->getOpcode() == Instruction::Mul ||
110           CE->getOpcode() == Instruction::Shl;
111  }
112  static inline bool classof(const Value *V) {
113    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
114           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
115  }
116};
117
118/// A udiv or sdiv instruction, which can be marked as "exact",
119/// indicating that no bits are destroyed.
120class PossiblyExactOperator : public Operator {
121public:
122  enum {
123    IsExact = (1 << 0)
124  };
125
126private:
127  friend class Instruction;
128  friend class ConstantExpr;
129
130  void setIsExact(bool B) {
131    SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
132  }
133
134public:
135  /// Test whether this division is known to be exact, with zero remainder.
136  bool isExact() const {
137    return SubclassOptionalData & IsExact;
138  }
139
140  static bool isPossiblyExactOpcode(unsigned OpC) {
141    return OpC == Instruction::SDiv ||
142           OpC == Instruction::UDiv ||
143           OpC == Instruction::AShr ||
144           OpC == Instruction::LShr;
145  }
146
147  static inline bool classof(const ConstantExpr *CE) {
148    return isPossiblyExactOpcode(CE->getOpcode());
149  }
150  static inline bool classof(const Instruction *I) {
151    return isPossiblyExactOpcode(I->getOpcode());
152  }
153  static inline bool classof(const Value *V) {
154    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
155           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
156  }
157};
158
159/// Convenience struct for specifying and reasoning about fast-math flags.
160class FastMathFlags {
161private:
162  friend class FPMathOperator;
163
164  unsigned Flags = 0;
165
166  FastMathFlags(unsigned F) : Flags(F) { }
167
168public:
169  /// This is how the bits are used in Value::SubclassOptionalData so they
170  /// should fit there too.
171  enum {
172    UnsafeAlgebra   = (1 << 0),
173    NoNaNs          = (1 << 1),
174    NoInfs          = (1 << 2),
175    NoSignedZeros   = (1 << 3),
176    AllowReciprocal = (1 << 4),
177    AllowContract   = (1 << 5)
178  };
179
180  FastMathFlags() = default;
181
182  /// Whether any flag is set
183  bool any() const { return Flags != 0; }
184
185  /// Set all the flags to false
186  void clear() { Flags = 0; }
187
188  /// Flag queries
189  bool noNaNs() const          { return 0 != (Flags & NoNaNs); }
190  bool noInfs() const          { return 0 != (Flags & NoInfs); }
191  bool noSignedZeros() const   { return 0 != (Flags & NoSignedZeros); }
192  bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
193  bool allowContract() const { return 0 != (Flags & AllowContract); }
194  bool unsafeAlgebra() const   { return 0 != (Flags & UnsafeAlgebra); }
195
196  /// Flag setters
197  void setNoNaNs()          { Flags |= NoNaNs; }
198  void setNoInfs()          { Flags |= NoInfs; }
199  void setNoSignedZeros()   { Flags |= NoSignedZeros; }
200  void setAllowReciprocal() { Flags |= AllowReciprocal; }
201  void setAllowContract(bool B) {
202    Flags = (Flags & ~AllowContract) | B * AllowContract;
203  }
204  void setUnsafeAlgebra() {
205    Flags |= UnsafeAlgebra;
206    setNoNaNs();
207    setNoInfs();
208    setNoSignedZeros();
209    setAllowReciprocal();
210    setAllowContract(true);
211  }
212
213  void operator&=(const FastMathFlags &OtherFlags) {
214    Flags &= OtherFlags.Flags;
215  }
216};
217
218/// Utility class for floating point operations which can have
219/// information about relaxed accuracy requirements attached to them.
220class FPMathOperator : public Operator {
221private:
222  friend class Instruction;
223
224  void setHasUnsafeAlgebra(bool B) {
225    SubclassOptionalData =
226      (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) |
227      (B * FastMathFlags::UnsafeAlgebra);
228
229    // Unsafe algebra implies all the others
230    if (B) {
231      setHasNoNaNs(true);
232      setHasNoInfs(true);
233      setHasNoSignedZeros(true);
234      setHasAllowReciprocal(true);
235    }
236  }
237
238  void setHasNoNaNs(bool B) {
239    SubclassOptionalData =
240      (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
241      (B * FastMathFlags::NoNaNs);
242  }
243
244  void setHasNoInfs(bool B) {
245    SubclassOptionalData =
246      (SubclassOptionalData & ~FastMathFlags::NoInfs) |
247      (B * FastMathFlags::NoInfs);
248  }
249
250  void setHasNoSignedZeros(bool B) {
251    SubclassOptionalData =
252      (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
253      (B * FastMathFlags::NoSignedZeros);
254  }
255
256  void setHasAllowReciprocal(bool B) {
257    SubclassOptionalData =
258      (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
259      (B * FastMathFlags::AllowReciprocal);
260  }
261
262  void setHasAllowContract(bool B) {
263    SubclassOptionalData =
264        (SubclassOptionalData & ~FastMathFlags::AllowContract) |
265        (B * FastMathFlags::AllowContract);
266  }
267
268  /// Convenience function for setting multiple fast-math flags.
269  /// FMF is a mask of the bits to set.
270  void setFastMathFlags(FastMathFlags FMF) {
271    SubclassOptionalData |= FMF.Flags;
272  }
273
274  /// Convenience function for copying all fast-math flags.
275  /// All values in FMF are transferred to this operator.
276  void copyFastMathFlags(FastMathFlags FMF) {
277    SubclassOptionalData = FMF.Flags;
278  }
279
280public:
281  /// Test whether this operation is permitted to be
282  /// algebraically transformed, aka the 'A' fast-math property.
283  bool hasUnsafeAlgebra() const {
284    return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0;
285  }
286
287  /// Test whether this operation's arguments and results are to be
288  /// treated as non-NaN, aka the 'N' fast-math property.
289  bool hasNoNaNs() const {
290    return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
291  }
292
293  /// Test whether this operation's arguments and results are to be
294  /// treated as NoN-Inf, aka the 'I' fast-math property.
295  bool hasNoInfs() const {
296    return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
297  }
298
299  /// Test whether this operation can treat the sign of zero
300  /// as insignificant, aka the 'S' fast-math property.
301  bool hasNoSignedZeros() const {
302    return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
303  }
304
305  /// Test whether this operation is permitted to use
306  /// reciprocal instead of division, aka the 'R' fast-math property.
307  bool hasAllowReciprocal() const {
308    return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
309  }
310
311  /// Test whether this operation is permitted to
312  /// be floating-point contracted.
313  bool hasAllowContract() const {
314    return (SubclassOptionalData & FastMathFlags::AllowContract) != 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 inline bool classof(const Instruction *I) {
328    return I->getType()->isFPOrFPVectorTy() ||
329      I->getOpcode() == Instruction::FCmp;
330  }
331
332  static inline bool classof(const ConstantExpr *CE) {
333    return CE->getType()->isFPOrFPVectorTy() ||
334           CE->getOpcode() == Instruction::FCmp;
335  }
336
337  static inline bool classof(const Value *V) {
338    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
339           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
340  }
341};
342
343/// A helper template for defining operators for individual opcodes.
344template<typename SuperClass, unsigned Opc>
345class ConcreteOperator : public SuperClass {
346public:
347  static inline bool classof(const Instruction *I) {
348    return I->getOpcode() == Opc;
349  }
350  static inline bool classof(const ConstantExpr *CE) {
351    return CE->getOpcode() == Opc;
352  }
353  static inline bool classof(const Value *V) {
354    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
355           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
356  }
357};
358
359class AddOperator
360  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
361};
362class SubOperator
363  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
364};
365class MulOperator
366  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
367};
368class ShlOperator
369  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
370};
371
372class SDivOperator
373  : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
374};
375class UDivOperator
376  : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
377};
378class AShrOperator
379  : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
380};
381class LShrOperator
382  : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
383};
384
385class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {};
386
387class GEPOperator
388  : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
389  friend class GetElementPtrInst;
390  friend class ConstantExpr;
391
392  enum {
393    IsInBounds = (1 << 0),
394    // InRangeIndex: bits 1-6
395  };
396
397  void setIsInBounds(bool B) {
398    SubclassOptionalData =
399      (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
400  }
401
402public:
403  /// Test whether this is an inbounds GEP, as defined by LangRef.html.
404  bool isInBounds() const {
405    return SubclassOptionalData & IsInBounds;
406  }
407
408  /// Returns the offset of the index with an inrange attachment, or None if
409  /// none.
410  Optional<unsigned> getInRangeIndex() const {
411    if (SubclassOptionalData >> 1 == 0) return None;
412    return (SubclassOptionalData >> 1) - 1;
413  }
414
415  inline op_iterator       idx_begin()       { return op_begin()+1; }
416  inline const_op_iterator idx_begin() const { return op_begin()+1; }
417  inline op_iterator       idx_end()         { return op_end(); }
418  inline const_op_iterator idx_end()   const { return op_end(); }
419
420  Value *getPointerOperand() {
421    return getOperand(0);
422  }
423  const Value *getPointerOperand() const {
424    return getOperand(0);
425  }
426  static unsigned getPointerOperandIndex() {
427    return 0U;                      // get index for modifying correct operand
428  }
429
430  /// Method to return the pointer operand as a PointerType.
431  Type *getPointerOperandType() const {
432    return getPointerOperand()->getType();
433  }
434
435  Type *getSourceElementType() const;
436  Type *getResultElementType() const;
437
438  /// Method to return the address space of the pointer operand.
439  unsigned getPointerAddressSpace() const {
440    return getPointerOperandType()->getPointerAddressSpace();
441  }
442
443  unsigned getNumIndices() const {  // Note: always non-negative
444    return getNumOperands() - 1;
445  }
446
447  bool hasIndices() const {
448    return getNumOperands() > 1;
449  }
450
451  /// Return true if all of the indices of this GEP are zeros.
452  /// If so, the result pointer and the first operand have the same
453  /// value, just potentially different types.
454  bool hasAllZeroIndices() const {
455    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
456      if (ConstantInt *C = dyn_cast<ConstantInt>(I))
457        if (C->isZero())
458          continue;
459      return false;
460    }
461    return true;
462  }
463
464  /// Return true if all of the indices of this GEP are constant integers.
465  /// If so, the result pointer and the first operand have
466  /// a constant offset between them.
467  bool hasAllConstantIndices() const {
468    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
469      if (!isa<ConstantInt>(I))
470        return false;
471    }
472    return true;
473  }
474
475  /// \brief Accumulate the constant address offset of this GEP if possible.
476  ///
477  /// This routine accepts an APInt into which it will accumulate the constant
478  /// offset of this GEP if the GEP is in fact constant. If the GEP is not
479  /// all-constant, it returns false and the value of the offset APInt is
480  /// undefined (it is *not* preserved!). The APInt passed into this routine
481  /// must be at exactly as wide as the IntPtr type for the address space of the
482  /// base GEP pointer.
483  bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
484};
485
486class PtrToIntOperator
487    : public ConcreteOperator<Operator, Instruction::PtrToInt> {
488  friend class PtrToInt;
489  friend class ConstantExpr;
490
491public:
492  Value *getPointerOperand() {
493    return getOperand(0);
494  }
495  const Value *getPointerOperand() const {
496    return getOperand(0);
497  }
498
499  static unsigned getPointerOperandIndex() {
500    return 0U;                      // get index for modifying correct operand
501  }
502
503  /// Method to return the pointer operand as a PointerType.
504  Type *getPointerOperandType() const {
505    return getPointerOperand()->getType();
506  }
507
508  /// Method to return the address space of the pointer operand.
509  unsigned getPointerAddressSpace() const {
510    return cast<PointerType>(getPointerOperandType())->getAddressSpace();
511  }
512};
513
514class BitCastOperator
515    : public ConcreteOperator<Operator, Instruction::BitCast> {
516  friend class BitCastInst;
517  friend class ConstantExpr;
518
519public:
520  Type *getSrcTy() const {
521    return getOperand(0)->getType();
522  }
523
524  Type *getDestTy() const {
525    return getType();
526  }
527};
528
529} // end namespace llvm
530
531#endif // LLVM_IR_OPERATOR_H
532