Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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.
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 bool classof(const Instruction *) { return true; }
58
  static bool classof(const ConstantExpr *) { return true; }
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
 
87
  void setHasNoUnsignedWrap(bool B) {
88
    SubclassOptionalData =
89
      (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
90
  }
91
  void setHasNoSignedWrap(bool B) {
92
    SubclassOptionalData =
93
      (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
94
  }
95
 
96
public:
97
  /// Test whether this operation is known to never
98
  /// undergo unsigned overflow, aka the nuw property.
99
  bool hasNoUnsignedWrap() const {
100
    return SubclassOptionalData & NoUnsignedWrap;
101
  }
102
 
103
  /// Test whether this operation is known to never
104
  /// undergo signed overflow, aka the nsw property.
105
  bool hasNoSignedWrap() const {
106
    return (SubclassOptionalData & NoSignedWrap) != 0;
107
  }
108
 
109
  static bool classof(const Instruction *I) {
110
    return I->getOpcode() == Instruction::Add ||
111
           I->getOpcode() == Instruction::Sub ||
112
           I->getOpcode() == Instruction::Mul ||
113
           I->getOpcode() == Instruction::Shl;
114
  }
115
  static bool classof(const ConstantExpr *CE) {
116
    return CE->getOpcode() == Instruction::Add ||
117
           CE->getOpcode() == Instruction::Sub ||
118
           CE->getOpcode() == Instruction::Mul ||
119
           CE->getOpcode() == Instruction::Shl;
120
  }
121
  static bool classof(const Value *V) {
122
    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
123
           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
124
  }
125
};
126
 
127
/// A udiv or sdiv instruction, which can be marked as "exact",
128
/// indicating that no bits are destroyed.
129
class PossiblyExactOperator : public Operator {
130
public:
131
  enum {
132
    IsExact = (1 << 0)
133
  };
134
 
135
private:
136
  friend class Instruction;
137
  friend class ConstantExpr;
138
 
139
  void setIsExact(bool B) {
140
    SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
141
  }
142
 
143
public:
144
  /// Test whether this division is known to be exact, with zero remainder.
145
  bool isExact() const {
146
    return SubclassOptionalData & IsExact;
147
  }
148
 
149
  static bool isPossiblyExactOpcode(unsigned OpC) {
150
    return OpC == Instruction::SDiv ||
151
           OpC == Instruction::UDiv ||
152
           OpC == Instruction::AShr ||
153
           OpC == Instruction::LShr;
154
  }
155
 
156
  static bool classof(const ConstantExpr *CE) {
157
    return isPossiblyExactOpcode(CE->getOpcode());
158
  }
159
  static bool classof(const Instruction *I) {
160
    return isPossiblyExactOpcode(I->getOpcode());
161
  }
162
  static bool classof(const Value *V) {
163
    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
164
           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
165
  }
166
};
167
 
168
/// Utility class for floating point operations which can have
169
/// information about relaxed accuracy requirements attached to them.
170
class FPMathOperator : public Operator {
171
private:
172
  friend class Instruction;
173
 
174
  /// 'Fast' means all bits are set.
175
  void setFast(bool B) {
176
    setHasAllowReassoc(B);
177
    setHasNoNaNs(B);
178
    setHasNoInfs(B);
179
    setHasNoSignedZeros(B);
180
    setHasAllowReciprocal(B);
181
    setHasAllowContract(B);
182
    setHasApproxFunc(B);
183
  }
184
 
185
  void setHasAllowReassoc(bool B) {
186
    SubclassOptionalData =
187
    (SubclassOptionalData & ~FastMathFlags::AllowReassoc) |
188
    (B * FastMathFlags::AllowReassoc);
189
  }
190
 
191
  void setHasNoNaNs(bool B) {
192
    SubclassOptionalData =
193
      (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
194
      (B * FastMathFlags::NoNaNs);
195
  }
196
 
197
  void setHasNoInfs(bool B) {
198
    SubclassOptionalData =
199
      (SubclassOptionalData & ~FastMathFlags::NoInfs) |
200
      (B * FastMathFlags::NoInfs);
201
  }
202
 
203
  void setHasNoSignedZeros(bool B) {
204
    SubclassOptionalData =
205
      (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
206
      (B * FastMathFlags::NoSignedZeros);
207
  }
208
 
209
  void setHasAllowReciprocal(bool B) {
210
    SubclassOptionalData =
211
      (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
212
      (B * FastMathFlags::AllowReciprocal);
213
  }
214
 
215
  void setHasAllowContract(bool B) {
216
    SubclassOptionalData =
217
        (SubclassOptionalData & ~FastMathFlags::AllowContract) |
218
        (B * FastMathFlags::AllowContract);
219
  }
220
 
221
  void setHasApproxFunc(bool B) {
222
    SubclassOptionalData =
223
        (SubclassOptionalData & ~FastMathFlags::ApproxFunc) |
224
        (B * FastMathFlags::ApproxFunc);
225
  }
226
 
227
  /// Convenience function for setting multiple fast-math flags.
228
  /// FMF is a mask of the bits to set.
229
  void setFastMathFlags(FastMathFlags FMF) {
230
    SubclassOptionalData |= FMF.Flags;
231
  }
232
 
233
  /// Convenience function for copying all fast-math flags.
234
  /// All values in FMF are transferred to this operator.
235
  void copyFastMathFlags(FastMathFlags FMF) {
236
    SubclassOptionalData = FMF.Flags;
237
  }
238
 
239
public:
240
  /// Test if this operation allows all non-strict floating-point transforms.
241
  bool isFast() const {
242
    return ((SubclassOptionalData & FastMathFlags::AllowReassoc) != 0 &&
243
            (SubclassOptionalData & FastMathFlags::NoNaNs) != 0 &&
244
            (SubclassOptionalData & FastMathFlags::NoInfs) != 0 &&
245
            (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0 &&
246
            (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0 &&
247
            (SubclassOptionalData & FastMathFlags::AllowContract) != 0 &&
248
            (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0);
249
  }
250
 
251
  /// Test if this operation may be simplified with reassociative transforms.
252
  bool hasAllowReassoc() const {
253
    return (SubclassOptionalData & FastMathFlags::AllowReassoc) != 0;
254
  }
255
 
256
  /// Test if this operation's arguments and results are assumed not-NaN.
257
  bool hasNoNaNs() const {
258
    return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
259
  }
260
 
261
  /// Test if this operation's arguments and results are assumed not-infinite.
262
  bool hasNoInfs() const {
263
    return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
264
  }
265
 
266
  /// Test if this operation can ignore the sign of zero.
267
  bool hasNoSignedZeros() const {
268
    return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
269
  }
270
 
271
  /// Test if this operation can use reciprocal multiply instead of division.
272
  bool hasAllowReciprocal() const {
273
    return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
274
  }
275
 
276
  /// Test if this operation can be floating-point contracted (FMA).
277
  bool hasAllowContract() const {
278
    return (SubclassOptionalData & FastMathFlags::AllowContract) != 0;
279
  }
280
 
281
  /// Test if this operation allows approximations of math library functions or
282
  /// intrinsics.
283
  bool hasApproxFunc() const {
284
    return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0;
285
  }
286
 
287
  /// Convenience function for getting all the fast-math flags
288
  FastMathFlags getFastMathFlags() const {
289
    return FastMathFlags(SubclassOptionalData);
290
  }
291
 
292
  /// Get the maximum error permitted by this operation in ULPs. An accuracy of
293
  /// 0.0 means that the operation should be performed with the default
294
  /// precision.
295
  float getFPAccuracy() const;
296
 
297
  static bool classof(const Value *V) {
298
    unsigned Opcode;
299
    if (auto *I = dyn_cast<Instruction>(V))
300
      Opcode = I->getOpcode();
301
    else if (auto *CE = dyn_cast<ConstantExpr>(V))
302
      Opcode = CE->getOpcode();
303
    else
304
      return false;
305
 
306
    switch (Opcode) {
307
    case Instruction::FNeg:
308
    case Instruction::FAdd:
309
    case Instruction::FSub:
310
    case Instruction::FMul:
311
    case Instruction::FDiv:
312
    case Instruction::FRem:
313
    // FIXME: To clean up and correct the semantics of fast-math-flags, FCmp
314
    //        should not be treated as a math op, but the other opcodes should.
315
    //        This would make things consistent with Select/PHI (FP value type
316
    //        determines whether they are math ops and, therefore, capable of
317
    //        having fast-math-flags).
318
    case Instruction::FCmp:
319
      return true;
320
    case Instruction::PHI:
321
    case Instruction::Select:
322
    case Instruction::Call: {
323
      Type *Ty = V->getType();
324
      while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty))
325
        Ty = ArrTy->getElementType();
326
      return Ty->isFPOrFPVectorTy();
327
    }
328
    default:
329
      return false;
330
    }
331
  }
332
};
333
 
334
/// A helper template for defining operators for individual opcodes.
335
template<typename SuperClass, unsigned Opc>
336
class ConcreteOperator : public SuperClass {
337
public:
338
  static bool classof(const Instruction *I) {
339
    return I->getOpcode() == Opc;
340
  }
341
  static bool classof(const ConstantExpr *CE) {
342
    return CE->getOpcode() == Opc;
343
  }
344
  static bool classof(const Value *V) {
345
    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
346
           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
347
  }
348
};
349
 
350
class AddOperator
351
  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
352
};
353
class SubOperator
354
  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
355
};
356
class MulOperator
357
  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
358
};
359
class ShlOperator
360
  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
361
};
362
 
363
class SDivOperator
364
  : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
365
};
366
class UDivOperator
367
  : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
368
};
369
class AShrOperator
370
  : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
371
};
372
class LShrOperator
373
  : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
374
};
375
 
376
class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {};
377
 
378
class GEPOperator
379
  : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
380
  friend class GetElementPtrInst;
381
  friend class ConstantExpr;
382
 
383
  enum {
384
    IsInBounds = (1 << 0),
385
    // InRangeIndex: bits 1-6
386
  };
387
 
388
  void setIsInBounds(bool B) {
389
    SubclassOptionalData =
390
      (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
391
  }
392
 
393
public:
394
  /// Test whether this is an inbounds GEP, as defined by LangRef.html.
395
  bool isInBounds() const {
396
    return SubclassOptionalData & IsInBounds;
397
  }
398
 
399
  /// Returns the offset of the index with an inrange attachment, or
400
  /// std::nullopt if none.
401
  std::optional<unsigned> getInRangeIndex() const {
402
    if (SubclassOptionalData >> 1 == 0)
403
      return std::nullopt;
404
    return (SubclassOptionalData >> 1) - 1;
405
  }
406
 
407
  inline op_iterator       idx_begin()       { return op_begin()+1; }
408
  inline const_op_iterator idx_begin() const { return op_begin()+1; }
409
  inline op_iterator       idx_end()         { return op_end(); }
410
  inline const_op_iterator idx_end()   const { return op_end(); }
411
 
412
  inline iterator_range<op_iterator> indices() {
413
    return make_range(idx_begin(), idx_end());
414
  }
415
 
416
  inline iterator_range<const_op_iterator> indices() const {
417
    return make_range(idx_begin(), idx_end());
418
  }
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
  unsigned countNonConstantIndices() const {
476
    return count_if(indices(), [](const Use& use) {
477
        return !isa<ConstantInt>(*use);
478
      });
479
  }
480
 
481
  /// Compute the maximum alignment that this GEP is garranteed to preserve.
482
  Align getMaxPreservedAlignment(const DataLayout &DL) const;
483
 
484
  /// Accumulate the constant address offset of this GEP if possible.
485
  ///
486
  /// This routine accepts an APInt into which it will try to accumulate the
487
  /// constant offset of this GEP.
488
  ///
489
  /// If \p ExternalAnalysis is provided it will be used to calculate a offset
490
  /// when a operand of GEP is not constant.
491
  /// For example, for a value \p ExternalAnalysis might try to calculate a
492
  /// lower bound. If \p ExternalAnalysis is successful, it should return true.
493
  ///
494
  /// If the \p ExternalAnalysis returns false or the value returned by \p
495
  /// ExternalAnalysis results in a overflow/underflow, this routine returns
496
  /// false and the value of the offset APInt is undefined (it is *not*
497
  /// preserved!).
498
  ///
499
  /// The APInt passed into this routine must be at exactly as wide as the
500
  /// IntPtr type for the address space of the base GEP pointer.
501
  bool accumulateConstantOffset(
502
      const DataLayout &DL, APInt &Offset,
503
      function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const;
504
 
505
  static bool accumulateConstantOffset(
506
      Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
507
      APInt &Offset,
508
      function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr);
509
 
510
  /// Collect the offset of this GEP as a map of Values to their associated
511
  /// APInt multipliers, as well as a total Constant Offset.
512
  bool collectOffset(const DataLayout &DL, unsigned BitWidth,
513
                     MapVector<Value *, APInt> &VariableOffsets,
514
                     APInt &ConstantOffset) const;
515
};
516
 
517
class PtrToIntOperator
518
    : public ConcreteOperator<Operator, Instruction::PtrToInt> {
519
  friend class PtrToInt;
520
  friend class ConstantExpr;
521
 
522
public:
523
  Value *getPointerOperand() {
524
    return getOperand(0);
525
  }
526
  const Value *getPointerOperand() const {
527
    return getOperand(0);
528
  }
529
 
530
  static unsigned getPointerOperandIndex() {
531
    return 0U;                      // get index for modifying correct operand
532
  }
533
 
534
  /// Method to return the pointer operand as a PointerType.
535
  Type *getPointerOperandType() const {
536
    return getPointerOperand()->getType();
537
  }
538
 
539
  /// Method to return the address space of the pointer operand.
540
  unsigned getPointerAddressSpace() const {
541
    return cast<PointerType>(getPointerOperandType())->getAddressSpace();
542
  }
543
};
544
 
545
class BitCastOperator
546
    : public ConcreteOperator<Operator, Instruction::BitCast> {
547
  friend class BitCastInst;
548
  friend class ConstantExpr;
549
 
550
public:
551
  Type *getSrcTy() const {
552
    return getOperand(0)->getType();
553
  }
554
 
555
  Type *getDestTy() const {
556
    return getType();
557
  }
558
};
559
 
560
class AddrSpaceCastOperator
561
    : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> {
562
  friend class AddrSpaceCastInst;
563
  friend class ConstantExpr;
564
 
565
public:
566
  Value *getPointerOperand() { return getOperand(0); }
567
 
568
  const Value *getPointerOperand() const { return getOperand(0); }
569
 
570
  unsigned getSrcAddressSpace() const {
571
    return getPointerOperand()->getType()->getPointerAddressSpace();
572
  }
573
 
574
  unsigned getDestAddressSpace() const {
575
    return getType()->getPointerAddressSpace();
576
  }
577
};
578
 
579
} // end namespace llvm
580
 
581
#endif // LLVM_IR_OPERATOR_H