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_OPERATOR_H 16 #define LLVM_OPERATOR_H 17 18 #include "llvm/Instruction.h" 19 #include "llvm/Constants.h" 20 21 namespace llvm { 22 23 class GetElementPtrInst; 24 class BinaryOperator; 25 class ConstantExpr; 26 27 /// Operator - This is a utility class that provides an abstraction for the 28 /// common functionality between Instructions and ConstantExprs. 29 /// 30 class Operator : public User { 31 private: 32 // Do not implement any of these. The Operator class is intended to be used 33 // as a utility, and is never itself instantiated. 34 void *operator new(size_t, unsigned); 35 void *operator new(size_t s); 36 Operator(); 37 ~Operator(); 38 39 public: 40 /// getOpcode - Return the opcode for this Instruction or ConstantExpr. 41 /// getOpcode()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 /// getOpcode - If V is an Instruction or ConstantExpr, return its 49 /// opcode. Otherwise return UserOp1. 50 /// getOpcode(const Value * V)51 static unsigned getOpcode(const Value *V) { 52 if (const Instruction *I = dyn_cast<Instruction>(V)) 53 return I->getOpcode(); 54 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) 55 return CE->getOpcode(); 56 return Instruction::UserOp1; 57 } 58 classof(const Operator *)59 static inline bool classof(const Operator *) { return true; } classof(const Instruction *)60 static inline bool classof(const Instruction *) { return true; } classof(const ConstantExpr *)61 static inline bool classof(const ConstantExpr *) { return true; } classof(const Value * V)62 static inline bool classof(const Value *V) { 63 return isa<Instruction>(V) || isa<ConstantExpr>(V); 64 } 65 }; 66 67 /// OverflowingBinaryOperator - Utility class for integer arithmetic operators 68 /// which may exhibit overflow - Add, Sub, and Mul. It does not include SDiv, 69 /// despite that operator having the potential for overflow. 70 /// 71 class OverflowingBinaryOperator : public Operator { 72 public: 73 enum { 74 NoUnsignedWrap = (1 << 0), 75 NoSignedWrap = (1 << 1) 76 }; 77 78 private: 79 ~OverflowingBinaryOperator(); // do not implement 80 81 friend class BinaryOperator; 82 friend class ConstantExpr; setHasNoUnsignedWrap(bool B)83 void setHasNoUnsignedWrap(bool B) { 84 SubclassOptionalData = 85 (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap); 86 } setHasNoSignedWrap(bool B)87 void setHasNoSignedWrap(bool B) { 88 SubclassOptionalData = 89 (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap); 90 } 91 92 public: 93 /// hasNoUnsignedWrap - Test whether this operation is known to never 94 /// undergo unsigned overflow, aka the nuw property. hasNoUnsignedWrap()95 bool hasNoUnsignedWrap() const { 96 return SubclassOptionalData & NoUnsignedWrap; 97 } 98 99 /// hasNoSignedWrap - Test whether this operation is known to never 100 /// undergo signed overflow, aka the nsw property. hasNoSignedWrap()101 bool hasNoSignedWrap() const { 102 return SubclassOptionalData & NoSignedWrap; 103 } 104 classof(const OverflowingBinaryOperator *)105 static inline bool classof(const OverflowingBinaryOperator *) { return true; } classof(const Instruction * I)106 static inline bool classof(const Instruction *I) { 107 return I->getOpcode() == Instruction::Add || 108 I->getOpcode() == Instruction::Sub || 109 I->getOpcode() == Instruction::Mul; 110 } classof(const ConstantExpr * CE)111 static inline bool classof(const ConstantExpr *CE) { 112 return CE->getOpcode() == Instruction::Add || 113 CE->getOpcode() == Instruction::Sub || 114 CE->getOpcode() == Instruction::Mul; 115 } classof(const Value * V)116 static inline bool classof(const Value *V) { 117 return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 118 (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 119 } 120 }; 121 122 /// AddOperator - Utility class for integer addition operators. 123 /// 124 class AddOperator : public OverflowingBinaryOperator { 125 ~AddOperator(); // do not implement 126 public: classof(const AddOperator *)127 static inline bool classof(const AddOperator *) { return true; } classof(const Instruction * I)128 static inline bool classof(const Instruction *I) { 129 return I->getOpcode() == Instruction::Add; 130 } classof(const ConstantExpr * CE)131 static inline bool classof(const ConstantExpr *CE) { 132 return CE->getOpcode() == Instruction::Add; 133 } classof(const Value * V)134 static inline bool classof(const Value *V) { 135 return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 136 (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 137 } 138 }; 139 140 /// SubOperator - Utility class for integer subtraction operators. 141 /// 142 class SubOperator : public OverflowingBinaryOperator { 143 ~SubOperator(); // do not implement 144 public: classof(const SubOperator *)145 static inline bool classof(const SubOperator *) { return true; } classof(const Instruction * I)146 static inline bool classof(const Instruction *I) { 147 return I->getOpcode() == Instruction::Sub; 148 } classof(const ConstantExpr * CE)149 static inline bool classof(const ConstantExpr *CE) { 150 return CE->getOpcode() == Instruction::Sub; 151 } classof(const Value * V)152 static inline bool classof(const Value *V) { 153 return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 154 (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 155 } 156 }; 157 158 /// MulOperator - Utility class for integer multiplication operators. 159 /// 160 class MulOperator : public OverflowingBinaryOperator { 161 ~MulOperator(); // do not implement 162 public: classof(const MulOperator *)163 static inline bool classof(const MulOperator *) { return true; } classof(const Instruction * I)164 static inline bool classof(const Instruction *I) { 165 return I->getOpcode() == Instruction::Mul; 166 } classof(const ConstantExpr * CE)167 static inline bool classof(const ConstantExpr *CE) { 168 return CE->getOpcode() == Instruction::Mul; 169 } classof(const Value * V)170 static inline bool classof(const Value *V) { 171 return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 172 (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 173 } 174 }; 175 176 /// SDivOperator - An Operator with opcode Instruction::SDiv. 177 /// 178 class SDivOperator : public Operator { 179 public: 180 enum { 181 IsExact = (1 << 0) 182 }; 183 184 private: 185 ~SDivOperator(); // do not implement 186 187 friend class BinaryOperator; 188 friend class ConstantExpr; setIsExact(bool B)189 void setIsExact(bool B) { 190 SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); 191 } 192 193 public: 194 /// isExact - Test whether this division is known to be exact, with 195 /// zero remainder. isExact()196 bool isExact() const { 197 return SubclassOptionalData & IsExact; 198 } 199 200 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const SDivOperator *)201 static inline bool classof(const SDivOperator *) { return true; } classof(const ConstantExpr * CE)202 static inline bool classof(const ConstantExpr *CE) { 203 return CE->getOpcode() == Instruction::SDiv; 204 } classof(const Instruction * I)205 static inline bool classof(const Instruction *I) { 206 return I->getOpcode() == Instruction::SDiv; 207 } classof(const Value * V)208 static inline bool classof(const Value *V) { 209 return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 210 (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 211 } 212 }; 213 214 class GEPOperator : public Operator { 215 enum { 216 IsInBounds = (1 << 0) 217 }; 218 219 ~GEPOperator(); // do not implement 220 221 friend class GetElementPtrInst; 222 friend class ConstantExpr; setIsInBounds(bool B)223 void setIsInBounds(bool B) { 224 SubclassOptionalData = 225 (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds); 226 } 227 228 public: 229 /// isInBounds - Test whether this is an inbounds GEP, as defined 230 /// by LangRef.html. isInBounds()231 bool isInBounds() const { 232 return SubclassOptionalData & IsInBounds; 233 } 234 idx_begin()235 inline op_iterator idx_begin() { return op_begin()+1; } idx_begin()236 inline const_op_iterator idx_begin() const { return op_begin()+1; } idx_end()237 inline op_iterator idx_end() { return op_end(); } idx_end()238 inline const_op_iterator idx_end() const { return op_end(); } 239 getPointerOperand()240 Value *getPointerOperand() { 241 return getOperand(0); 242 } getPointerOperand()243 const Value *getPointerOperand() const { 244 return getOperand(0); 245 } getPointerOperandIndex()246 static unsigned getPointerOperandIndex() { 247 return 0U; // get index for modifying correct operand 248 } 249 250 /// getPointerOperandType - Method to return the pointer operand as a 251 /// PointerType. getPointerOperandType()252 const PointerType *getPointerOperandType() const { 253 return reinterpret_cast<const PointerType*>(getPointerOperand()->getType()); 254 } 255 getNumIndices()256 unsigned getNumIndices() const { // Note: always non-negative 257 return getNumOperands() - 1; 258 } 259 hasIndices()260 bool hasIndices() const { 261 return getNumOperands() > 1; 262 } 263 264 /// hasAllZeroIndices - Return true if all of the indices of this GEP are 265 /// zeros. If so, the result pointer and the first operand have the same 266 /// value, just potentially different types. hasAllZeroIndices()267 bool hasAllZeroIndices() const { 268 for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { 269 if (Constant *C = dyn_cast<Constant>(I)) 270 if (C->isNullValue()) 271 continue; 272 return false; 273 } 274 return true; 275 } 276 277 /// hasAllConstantIndices - Return true if all of the indices of this GEP are 278 /// constant integers. If so, the result pointer and the first operand have 279 /// a constant offset between them. hasAllConstantIndices()280 bool hasAllConstantIndices() const { 281 for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { 282 if (!isa<ConstantInt>(I)) 283 return false; 284 } 285 return true; 286 } 287 288 289 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const GEPOperator *)290 static inline bool classof(const GEPOperator *) { return true; } classof(const GetElementPtrInst *)291 static inline bool classof(const GetElementPtrInst *) { return true; } classof(const ConstantExpr * CE)292 static inline bool classof(const ConstantExpr *CE) { 293 return CE->getOpcode() == Instruction::GetElementPtr; 294 } classof(const Instruction * I)295 static inline bool classof(const Instruction *I) { 296 return I->getOpcode() == Instruction::GetElementPtr; 297 } classof(const Value * V)298 static inline bool classof(const Value *V) { 299 return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 300 (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 301 } 302 }; 303 304 } // End llvm namespace 305 306 #endif 307