1249259Sdim//===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file defines various classes for working with Instructions and 11249259Sdim// ConstantExprs. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#ifndef LLVM_IR_OPERATOR_H 16249259Sdim#define LLVM_IR_OPERATOR_H 17249259Sdim 18249259Sdim#include "llvm/IR/Constants.h" 19249259Sdim#include "llvm/IR/DataLayout.h" 20249259Sdim#include "llvm/IR/DerivedTypes.h" 21249259Sdim#include "llvm/IR/Instruction.h" 22249259Sdim#include "llvm/IR/Type.h" 23249259Sdim#include "llvm/Support/GetElementPtrTypeIterator.h" 24249259Sdim 25249259Sdimnamespace llvm { 26249259Sdim 27249259Sdimclass GetElementPtrInst; 28249259Sdimclass BinaryOperator; 29249259Sdimclass ConstantExpr; 30249259Sdim 31249259Sdim/// Operator - This is a utility class that provides an abstraction for the 32249259Sdim/// common functionality between Instructions and ConstantExprs. 33249259Sdim/// 34249259Sdimclass Operator : public User { 35249259Sdimprivate: 36249259Sdim // The Operator class is intended to be used as a utility, and is never itself 37249259Sdim // instantiated. 38249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 39249259Sdim void *operator new(size_t s) LLVM_DELETED_FUNCTION; 40249259Sdim Operator() LLVM_DELETED_FUNCTION; 41249259Sdim 42249259Sdimprotected: 43249259Sdim // NOTE: Cannot use LLVM_DELETED_FUNCTION because it's not legal to delete 44249259Sdim // an overridden method that's not deleted in the base class. Cannot leave 45249259Sdim // this unimplemented because that leads to an ODR-violation. 46249259Sdim ~Operator(); 47249259Sdim 48249259Sdimpublic: 49249259Sdim /// getOpcode - Return the opcode for this Instruction or ConstantExpr. 50249259Sdim /// 51249259Sdim unsigned getOpcode() const { 52249259Sdim if (const Instruction *I = dyn_cast<Instruction>(this)) 53249259Sdim return I->getOpcode(); 54249259Sdim return cast<ConstantExpr>(this)->getOpcode(); 55249259Sdim } 56249259Sdim 57249259Sdim /// getOpcode - If V is an Instruction or ConstantExpr, return its 58249259Sdim /// opcode. Otherwise return UserOp1. 59249259Sdim /// 60249259Sdim static unsigned getOpcode(const Value *V) { 61249259Sdim if (const Instruction *I = dyn_cast<Instruction>(V)) 62249259Sdim return I->getOpcode(); 63249259Sdim if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) 64249259Sdim return CE->getOpcode(); 65249259Sdim return Instruction::UserOp1; 66249259Sdim } 67249259Sdim 68249259Sdim static inline bool classof(const Instruction *) { return true; } 69249259Sdim static inline bool classof(const ConstantExpr *) { return true; } 70249259Sdim static inline bool classof(const Value *V) { 71249259Sdim return isa<Instruction>(V) || isa<ConstantExpr>(V); 72249259Sdim } 73249259Sdim}; 74249259Sdim 75249259Sdim/// OverflowingBinaryOperator - Utility class for integer arithmetic operators 76249259Sdim/// which may exhibit overflow - Add, Sub, and Mul. It does not include SDiv, 77249259Sdim/// despite that operator having the potential for overflow. 78249259Sdim/// 79249259Sdimclass OverflowingBinaryOperator : public Operator { 80249259Sdimpublic: 81249259Sdim enum { 82249259Sdim NoUnsignedWrap = (1 << 0), 83249259Sdim NoSignedWrap = (1 << 1) 84249259Sdim }; 85249259Sdim 86249259Sdimprivate: 87249259Sdim friend class BinaryOperator; 88249259Sdim friend class ConstantExpr; 89249259Sdim void setHasNoUnsignedWrap(bool B) { 90249259Sdim SubclassOptionalData = 91249259Sdim (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap); 92249259Sdim } 93249259Sdim void setHasNoSignedWrap(bool B) { 94249259Sdim SubclassOptionalData = 95249259Sdim (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap); 96249259Sdim } 97249259Sdim 98249259Sdimpublic: 99249259Sdim /// hasNoUnsignedWrap - Test whether this operation is known to never 100249259Sdim /// undergo unsigned overflow, aka the nuw property. 101249259Sdim bool hasNoUnsignedWrap() const { 102249259Sdim return SubclassOptionalData & NoUnsignedWrap; 103249259Sdim } 104249259Sdim 105249259Sdim /// hasNoSignedWrap - Test whether this operation is known to never 106249259Sdim /// undergo signed overflow, aka the nsw property. 107249259Sdim bool hasNoSignedWrap() const { 108249259Sdim return (SubclassOptionalData & NoSignedWrap) != 0; 109249259Sdim } 110249259Sdim 111249259Sdim static inline bool classof(const Instruction *I) { 112249259Sdim return I->getOpcode() == Instruction::Add || 113249259Sdim I->getOpcode() == Instruction::Sub || 114249259Sdim I->getOpcode() == Instruction::Mul || 115249259Sdim I->getOpcode() == Instruction::Shl; 116249259Sdim } 117249259Sdim static inline bool classof(const ConstantExpr *CE) { 118249259Sdim return CE->getOpcode() == Instruction::Add || 119249259Sdim CE->getOpcode() == Instruction::Sub || 120249259Sdim CE->getOpcode() == Instruction::Mul || 121249259Sdim CE->getOpcode() == Instruction::Shl; 122249259Sdim } 123249259Sdim static inline bool classof(const Value *V) { 124249259Sdim return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 125249259Sdim (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 126249259Sdim } 127249259Sdim}; 128249259Sdim 129249259Sdim/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as 130249259Sdim/// "exact", indicating that no bits are destroyed. 131249259Sdimclass PossiblyExactOperator : public Operator { 132249259Sdimpublic: 133249259Sdim enum { 134249259Sdim IsExact = (1 << 0) 135249259Sdim }; 136249259Sdim 137249259Sdimprivate: 138249259Sdim friend class BinaryOperator; 139249259Sdim friend class ConstantExpr; 140249259Sdim void setIsExact(bool B) { 141249259Sdim SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); 142249259Sdim } 143249259Sdim 144249259Sdimpublic: 145249259Sdim /// isExact - Test whether this division is known to be exact, with 146249259Sdim /// zero remainder. 147249259Sdim bool isExact() const { 148249259Sdim return SubclassOptionalData & IsExact; 149249259Sdim } 150249259Sdim 151249259Sdim static bool isPossiblyExactOpcode(unsigned OpC) { 152249259Sdim return OpC == Instruction::SDiv || 153249259Sdim OpC == Instruction::UDiv || 154249259Sdim OpC == Instruction::AShr || 155249259Sdim OpC == Instruction::LShr; 156249259Sdim } 157249259Sdim static inline bool classof(const ConstantExpr *CE) { 158249259Sdim return isPossiblyExactOpcode(CE->getOpcode()); 159249259Sdim } 160249259Sdim static inline bool classof(const Instruction *I) { 161249259Sdim return isPossiblyExactOpcode(I->getOpcode()); 162249259Sdim } 163249259Sdim static inline bool classof(const Value *V) { 164249259Sdim return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 165249259Sdim (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 166249259Sdim } 167249259Sdim}; 168249259Sdim 169249259Sdim/// Convenience struct for specifying and reasoning about fast-math flags. 170249259Sdimclass FastMathFlags { 171249259Sdimprivate: 172249259Sdim friend class FPMathOperator; 173249259Sdim unsigned Flags; 174249259Sdim FastMathFlags(unsigned F) : Flags(F) { } 175249259Sdim 176249259Sdimpublic: 177249259Sdim enum { 178249259Sdim UnsafeAlgebra = (1 << 0), 179249259Sdim NoNaNs = (1 << 1), 180249259Sdim NoInfs = (1 << 2), 181249259Sdim NoSignedZeros = (1 << 3), 182249259Sdim AllowReciprocal = (1 << 4) 183249259Sdim }; 184249259Sdim 185249259Sdim FastMathFlags() : Flags(0) 186249259Sdim { } 187249259Sdim 188249259Sdim /// Whether any flag is set 189249259Sdim bool any() { return Flags != 0; } 190249259Sdim 191249259Sdim /// Set all the flags to false 192249259Sdim void clear() { Flags = 0; } 193249259Sdim 194249259Sdim /// Flag queries 195249259Sdim bool noNaNs() { return 0 != (Flags & NoNaNs); } 196249259Sdim bool noInfs() { return 0 != (Flags & NoInfs); } 197249259Sdim bool noSignedZeros() { return 0 != (Flags & NoSignedZeros); } 198249259Sdim bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); } 199249259Sdim bool unsafeAlgebra() { return 0 != (Flags & UnsafeAlgebra); } 200249259Sdim 201249259Sdim /// Flag setters 202249259Sdim void setNoNaNs() { Flags |= NoNaNs; } 203249259Sdim void setNoInfs() { Flags |= NoInfs; } 204249259Sdim void setNoSignedZeros() { Flags |= NoSignedZeros; } 205249259Sdim void setAllowReciprocal() { Flags |= AllowReciprocal; } 206249259Sdim void setUnsafeAlgebra() { 207249259Sdim Flags |= UnsafeAlgebra; 208249259Sdim setNoNaNs(); 209249259Sdim setNoInfs(); 210249259Sdim setNoSignedZeros(); 211249259Sdim setAllowReciprocal(); 212249259Sdim } 213249259Sdim}; 214249259Sdim 215249259Sdim 216249259Sdim/// FPMathOperator - Utility class for floating point operations which can have 217249259Sdim/// information about relaxed accuracy requirements attached to them. 218249259Sdimclass FPMathOperator : public Operator { 219249259Sdimprivate: 220249259Sdim friend class Instruction; 221249259Sdim 222249259Sdim void setHasUnsafeAlgebra(bool B) { 223249259Sdim SubclassOptionalData = 224249259Sdim (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) | 225249259Sdim (B * FastMathFlags::UnsafeAlgebra); 226249259Sdim 227249259Sdim // Unsafe algebra implies all the others 228249259Sdim if (B) { 229249259Sdim setHasNoNaNs(true); 230249259Sdim setHasNoInfs(true); 231249259Sdim setHasNoSignedZeros(true); 232249259Sdim setHasAllowReciprocal(true); 233249259Sdim } 234249259Sdim } 235249259Sdim void setHasNoNaNs(bool B) { 236249259Sdim SubclassOptionalData = 237249259Sdim (SubclassOptionalData & ~FastMathFlags::NoNaNs) | 238249259Sdim (B * FastMathFlags::NoNaNs); 239249259Sdim } 240249259Sdim void setHasNoInfs(bool B) { 241249259Sdim SubclassOptionalData = 242249259Sdim (SubclassOptionalData & ~FastMathFlags::NoInfs) | 243249259Sdim (B * FastMathFlags::NoInfs); 244249259Sdim } 245249259Sdim void setHasNoSignedZeros(bool B) { 246249259Sdim SubclassOptionalData = 247249259Sdim (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) | 248249259Sdim (B * FastMathFlags::NoSignedZeros); 249249259Sdim } 250249259Sdim void setHasAllowReciprocal(bool B) { 251249259Sdim SubclassOptionalData = 252249259Sdim (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) | 253249259Sdim (B * FastMathFlags::AllowReciprocal); 254249259Sdim } 255249259Sdim 256249259Sdim /// Convenience function for setting all the fast-math flags 257249259Sdim void setFastMathFlags(FastMathFlags FMF) { 258249259Sdim SubclassOptionalData |= FMF.Flags; 259249259Sdim } 260249259Sdim 261249259Sdimpublic: 262249259Sdim /// Test whether this operation is permitted to be 263249259Sdim /// algebraically transformed, aka the 'A' fast-math property. 264249259Sdim bool hasUnsafeAlgebra() const { 265249259Sdim return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0; 266249259Sdim } 267249259Sdim 268249259Sdim /// Test whether this operation's arguments and results are to be 269249259Sdim /// treated as non-NaN, aka the 'N' fast-math property. 270249259Sdim bool hasNoNaNs() const { 271249259Sdim return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0; 272249259Sdim } 273249259Sdim 274249259Sdim /// Test whether this operation's arguments and results are to be 275249259Sdim /// treated as NoN-Inf, aka the 'I' fast-math property. 276249259Sdim bool hasNoInfs() const { 277249259Sdim return (SubclassOptionalData & FastMathFlags::NoInfs) != 0; 278249259Sdim } 279249259Sdim 280249259Sdim /// Test whether this operation can treat the sign of zero 281249259Sdim /// as insignificant, aka the 'S' fast-math property. 282249259Sdim bool hasNoSignedZeros() const { 283249259Sdim return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0; 284249259Sdim } 285249259Sdim 286249259Sdim /// Test whether this operation is permitted to use 287249259Sdim /// reciprocal instead of division, aka the 'R' fast-math property. 288249259Sdim bool hasAllowReciprocal() const { 289249259Sdim return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0; 290249259Sdim } 291249259Sdim 292249259Sdim /// Convenience function for getting all the fast-math flags 293249259Sdim FastMathFlags getFastMathFlags() const { 294249259Sdim return FastMathFlags(SubclassOptionalData); 295249259Sdim } 296249259Sdim 297249259Sdim /// \brief Get the maximum error permitted by this operation in ULPs. An 298249259Sdim /// accuracy of 0.0 means that the operation should be performed with the 299249259Sdim /// default precision. 300249259Sdim float getFPAccuracy() const; 301249259Sdim 302249259Sdim static inline bool classof(const Instruction *I) { 303249259Sdim return I->getType()->isFPOrFPVectorTy(); 304249259Sdim } 305249259Sdim static inline bool classof(const Value *V) { 306249259Sdim return isa<Instruction>(V) && classof(cast<Instruction>(V)); 307249259Sdim } 308249259Sdim}; 309249259Sdim 310249259Sdim 311249259Sdim/// ConcreteOperator - A helper template for defining operators for individual 312249259Sdim/// opcodes. 313249259Sdimtemplate<typename SuperClass, unsigned Opc> 314249259Sdimclass ConcreteOperator : public SuperClass { 315249259Sdimpublic: 316249259Sdim static inline bool classof(const Instruction *I) { 317249259Sdim return I->getOpcode() == Opc; 318249259Sdim } 319249259Sdim static inline bool classof(const ConstantExpr *CE) { 320249259Sdim return CE->getOpcode() == Opc; 321249259Sdim } 322249259Sdim static inline bool classof(const Value *V) { 323249259Sdim return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 324249259Sdim (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 325249259Sdim } 326249259Sdim}; 327249259Sdim 328249259Sdimclass AddOperator 329249259Sdim : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> { 330249259Sdim}; 331249259Sdimclass SubOperator 332249259Sdim : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> { 333249259Sdim}; 334249259Sdimclass MulOperator 335249259Sdim : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> { 336249259Sdim}; 337249259Sdimclass ShlOperator 338249259Sdim : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> { 339249259Sdim}; 340249259Sdim 341249259Sdim 342249259Sdimclass SDivOperator 343249259Sdim : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> { 344249259Sdim}; 345249259Sdimclass UDivOperator 346249259Sdim : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> { 347249259Sdim}; 348249259Sdimclass AShrOperator 349249259Sdim : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> { 350249259Sdim}; 351249259Sdimclass LShrOperator 352249259Sdim : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> { 353249259Sdim}; 354249259Sdim 355249259Sdim 356249259Sdim 357249259Sdimclass GEPOperator 358249259Sdim : public ConcreteOperator<Operator, Instruction::GetElementPtr> { 359249259Sdim enum { 360249259Sdim IsInBounds = (1 << 0) 361249259Sdim }; 362249259Sdim 363249259Sdim friend class GetElementPtrInst; 364249259Sdim friend class ConstantExpr; 365249259Sdim void setIsInBounds(bool B) { 366249259Sdim SubclassOptionalData = 367249259Sdim (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds); 368249259Sdim } 369249259Sdim 370249259Sdimpublic: 371249259Sdim /// isInBounds - Test whether this is an inbounds GEP, as defined 372249259Sdim /// by LangRef.html. 373249259Sdim bool isInBounds() const { 374249259Sdim return SubclassOptionalData & IsInBounds; 375249259Sdim } 376249259Sdim 377249259Sdim inline op_iterator idx_begin() { return op_begin()+1; } 378249259Sdim inline const_op_iterator idx_begin() const { return op_begin()+1; } 379249259Sdim inline op_iterator idx_end() { return op_end(); } 380249259Sdim inline const_op_iterator idx_end() const { return op_end(); } 381249259Sdim 382249259Sdim Value *getPointerOperand() { 383249259Sdim return getOperand(0); 384249259Sdim } 385249259Sdim const Value *getPointerOperand() const { 386249259Sdim return getOperand(0); 387249259Sdim } 388249259Sdim static unsigned getPointerOperandIndex() { 389249259Sdim return 0U; // get index for modifying correct operand 390249259Sdim } 391249259Sdim 392249259Sdim /// getPointerOperandType - Method to return the pointer operand as a 393249259Sdim /// PointerType. 394249259Sdim Type *getPointerOperandType() const { 395249259Sdim return getPointerOperand()->getType(); 396249259Sdim } 397249259Sdim 398249259Sdim /// getPointerAddressSpace - Method to return the address space of the 399249259Sdim /// pointer operand. 400249259Sdim unsigned getPointerAddressSpace() const { 401249259Sdim return cast<PointerType>(getPointerOperandType())->getAddressSpace(); 402249259Sdim } 403249259Sdim 404249259Sdim unsigned getNumIndices() const { // Note: always non-negative 405249259Sdim return getNumOperands() - 1; 406249259Sdim } 407249259Sdim 408249259Sdim bool hasIndices() const { 409249259Sdim return getNumOperands() > 1; 410249259Sdim } 411249259Sdim 412249259Sdim /// hasAllZeroIndices - Return true if all of the indices of this GEP are 413249259Sdim /// zeros. If so, the result pointer and the first operand have the same 414249259Sdim /// value, just potentially different types. 415249259Sdim bool hasAllZeroIndices() const { 416249259Sdim for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { 417249259Sdim if (ConstantInt *C = dyn_cast<ConstantInt>(I)) 418249259Sdim if (C->isZero()) 419249259Sdim continue; 420249259Sdim return false; 421249259Sdim } 422249259Sdim return true; 423249259Sdim } 424249259Sdim 425249259Sdim /// hasAllConstantIndices - Return true if all of the indices of this GEP are 426249259Sdim /// constant integers. If so, the result pointer and the first operand have 427249259Sdim /// a constant offset between them. 428249259Sdim bool hasAllConstantIndices() const { 429249259Sdim for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { 430249259Sdim if (!isa<ConstantInt>(I)) 431249259Sdim return false; 432249259Sdim } 433249259Sdim return true; 434249259Sdim } 435249259Sdim 436249259Sdim /// \brief Accumulate the constant address offset of this GEP if possible. 437249259Sdim /// 438249259Sdim /// This routine accepts an APInt into which it will accumulate the constant 439249259Sdim /// offset of this GEP if the GEP is in fact constant. If the GEP is not 440249259Sdim /// all-constant, it returns false and the value of the offset APInt is 441249259Sdim /// undefined (it is *not* preserved!). The APInt passed into this routine 442249259Sdim /// must be at least as wide as the IntPtr type for the address space of 443249259Sdim /// the base GEP pointer. 444249259Sdim bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const { 445249259Sdim assert(Offset.getBitWidth() == 446249259Sdim DL.getPointerSizeInBits(getPointerAddressSpace()) && 447249259Sdim "The offset must have exactly as many bits as our pointer."); 448249259Sdim 449249259Sdim for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this); 450249259Sdim GTI != GTE; ++GTI) { 451249259Sdim ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand()); 452249259Sdim if (!OpC) 453249259Sdim return false; 454249259Sdim if (OpC->isZero()) 455249259Sdim continue; 456249259Sdim 457249259Sdim // Handle a struct index, which adds its field offset to the pointer. 458249259Sdim if (StructType *STy = dyn_cast<StructType>(*GTI)) { 459249259Sdim unsigned ElementIdx = OpC->getZExtValue(); 460249259Sdim const StructLayout *SL = DL.getStructLayout(STy); 461249259Sdim Offset += APInt(Offset.getBitWidth(), 462249259Sdim SL->getElementOffset(ElementIdx)); 463249259Sdim continue; 464249259Sdim } 465249259Sdim 466249259Sdim // For array or vector indices, scale the index by the size of the type. 467249259Sdim APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth()); 468249259Sdim Offset += Index * APInt(Offset.getBitWidth(), 469249259Sdim DL.getTypeAllocSize(GTI.getIndexedType())); 470249259Sdim } 471249259Sdim return true; 472249259Sdim } 473249259Sdim 474249259Sdim}; 475249259Sdim 476249259Sdim} // End llvm namespace 477249259Sdim 478249259Sdim#endif 479