LCOV - code coverage report
Current view: top level - /usr/lib/llvm-19/include/llvm/IR - Operator.h (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 0.0 % 14 0
Test Date: 2026-07-03 19:57:34 Functions: 0.0 % 1 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 7 0

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

Generated by: LCOV version 2.0-1