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