1ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman//===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===// 2ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// 3ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// The LLVM Compiler Infrastructure 4ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// 5ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// This file is distributed under the University of Illinois Open Source 6ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// License. See LICENSE.TXT for details. 7ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// 8ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman//===----------------------------------------------------------------------===// 9ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// 10ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// This file defines various classes for working with Instructions and 11ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// ConstantExprs. 12ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman// 13ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman//===----------------------------------------------------------------------===// 14ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 15674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#ifndef LLVM_IR_OPERATOR_H 16674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#define LLVM_IR_OPERATOR_H 17ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instruction.h" 220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 237550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth#include "llvm/Support/GetElementPtrTypeIterator.h" 24ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 25ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohmannamespace llvm { 26ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 27d30658c3ffd1e33e98b82750202a9375bf5963edDan Gohmanclass GetElementPtrInst; 28f8dbee7cea072eb63ae343759975109553697bcbDan Gohmanclass BinaryOperator; 29f8dbee7cea072eb63ae343759975109553697bcbDan Gohmanclass ConstantExpr; 30d30658c3ffd1e33e98b82750202a9375bf5963edDan Gohman 31ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman/// Operator - This is a utility class that provides an abstraction for the 32ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman/// common functionality between Instructions and ConstantExprs. 33ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman/// 34ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohmanclass Operator : public User { 35ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohmanprivate: 36a39058aaed4540fc37681cad728b99546595b2e8David Blaikie // The Operator class is intended to be used as a utility, and is never itself 37a39058aaed4540fc37681cad728b99546595b2e8David Blaikie // instantiated. 380cb0a3533788c6c622518cb030048012eb69af15Craig Topper void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 390cb0a3533788c6c622518cb030048012eb69af15Craig Topper void *operator new(size_t s) LLVM_DELETED_FUNCTION; 400cb0a3533788c6c622518cb030048012eb69af15Craig Topper Operator() LLVM_DELETED_FUNCTION; 4130f57da439dc6313e8704dec09da0a3789060608Richard Smith 4299abc17832b36007c66369321c0c2f5a2a7713f1Kaelyn Uhrainprotected: 4330f57da439dc6313e8704dec09da0a3789060608Richard Smith // NOTE: Cannot use LLVM_DELETED_FUNCTION because it's not legal to delete 4430f57da439dc6313e8704dec09da0a3789060608Richard Smith // an overridden method that's not deleted in the base class. Cannot leave 4530f57da439dc6313e8704dec09da0a3789060608Richard Smith // this unimplemented because that leads to an ODR-violation. 468bb12aeeb4f38f62f2d97618d0c688f47c9bd972Craig Topper ~Operator(); 47ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 48ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohmanpublic: 49ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman /// getOpcode - Return the opcode for this Instruction or ConstantExpr. 50ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman /// 51ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman unsigned getOpcode() const { 52ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman if (const Instruction *I = dyn_cast<Instruction>(this)) 53ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman return I->getOpcode(); 54ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman return cast<ConstantExpr>(this)->getOpcode(); 55ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 56ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 57ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman /// getOpcode - If V is an Instruction or ConstantExpr, return its 58ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman /// opcode. Otherwise return UserOp1. 59ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman /// 60ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman static unsigned getOpcode(const Value *V) { 61ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman if (const Instruction *I = dyn_cast<Instruction>(V)) 62ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman return I->getOpcode(); 63ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) 64ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman return CE->getOpcode(); 65ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman return Instruction::UserOp1; 66ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 67ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 6841b5adf20208f46e4b1104d6d473710fbfa61eb9Eric Christopher static inline bool classof(const Instruction *) { return true; } 6941b5adf20208f46e4b1104d6d473710fbfa61eb9Eric Christopher static inline bool classof(const ConstantExpr *) { return true; } 70ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman static inline bool classof(const Value *V) { 71ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman return isa<Instruction>(V) || isa<ConstantExpr>(V); 72ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 73ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman}; 74ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 75ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman/// OverflowingBinaryOperator - Utility class for integer arithmetic operators 76344df5ecdfc406476a627c29974ba7481d6a3313Dan Gohman/// which may exhibit overflow - Add, Sub, and Mul. It does not include SDiv, 77344df5ecdfc406476a627c29974ba7481d6a3313Dan Gohman/// despite that operator having the potential for overflow. 78ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman/// 79ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohmanclass OverflowingBinaryOperator : public Operator { 80f8dbee7cea072eb63ae343759975109553697bcbDan Gohmanpublic: 81f8dbee7cea072eb63ae343759975109553697bcbDan Gohman enum { 82f8dbee7cea072eb63ae343759975109553697bcbDan Gohman NoUnsignedWrap = (1 << 0), 83f8dbee7cea072eb63ae343759975109553697bcbDan Gohman NoSignedWrap = (1 << 1) 84f8dbee7cea072eb63ae343759975109553697bcbDan Gohman }; 85f8dbee7cea072eb63ae343759975109553697bcbDan Gohman 86f8dbee7cea072eb63ae343759975109553697bcbDan Gohmanprivate: 87f8dbee7cea072eb63ae343759975109553697bcbDan Gohman friend class BinaryOperator; 88f8dbee7cea072eb63ae343759975109553697bcbDan Gohman friend class ConstantExpr; 89f8dbee7cea072eb63ae343759975109553697bcbDan Gohman void setHasNoUnsignedWrap(bool B) { 90f8dbee7cea072eb63ae343759975109553697bcbDan Gohman SubclassOptionalData = 91f8dbee7cea072eb63ae343759975109553697bcbDan Gohman (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap); 92f8dbee7cea072eb63ae343759975109553697bcbDan Gohman } 93f8dbee7cea072eb63ae343759975109553697bcbDan Gohman void setHasNoSignedWrap(bool B) { 94f8dbee7cea072eb63ae343759975109553697bcbDan Gohman SubclassOptionalData = 95f8dbee7cea072eb63ae343759975109553697bcbDan Gohman (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap); 96f8dbee7cea072eb63ae343759975109553697bcbDan Gohman } 97f8dbee7cea072eb63ae343759975109553697bcbDan Gohman 98ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohmanpublic: 995078f84c82814e4d33846f9ef54281619d362f8aDan Gohman /// hasNoUnsignedWrap - Test whether this operation is known to never 1005078f84c82814e4d33846f9ef54281619d362f8aDan Gohman /// undergo unsigned overflow, aka the nuw property. 1015078f84c82814e4d33846f9ef54281619d362f8aDan Gohman bool hasNoUnsignedWrap() const { 102f8dbee7cea072eb63ae343759975109553697bcbDan Gohman return SubclassOptionalData & NoUnsignedWrap; 103ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 104ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 1055078f84c82814e4d33846f9ef54281619d362f8aDan Gohman /// hasNoSignedWrap - Test whether this operation is known to never 1065078f84c82814e4d33846f9ef54281619d362f8aDan Gohman /// undergo signed overflow, aka the nsw property. 1075078f84c82814e4d33846f9ef54281619d362f8aDan Gohman bool hasNoSignedWrap() const { 108429c75b8654b0d1069f1897375f5801a4c5de017Oscar Fuentes return (SubclassOptionalData & NoSignedWrap) != 0; 109ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 110ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 111ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman static inline bool classof(const Instruction *I) { 112ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman return I->getOpcode() == Instruction::Add || 113ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman I->getOpcode() == Instruction::Sub || 114f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner I->getOpcode() == Instruction::Mul || 115f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner I->getOpcode() == Instruction::Shl; 116ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 117ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman static inline bool classof(const ConstantExpr *CE) { 118ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman return CE->getOpcode() == Instruction::Add || 119ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman CE->getOpcode() == Instruction::Sub || 120f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner CE->getOpcode() == Instruction::Mul || 121f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner CE->getOpcode() == Instruction::Shl; 1226b118a2122f8f7da954fbfbcdec05c331e3fd625Dan Gohman } 1236b118a2122f8f7da954fbfbcdec05c331e3fd625Dan Gohman static inline bool classof(const Value *V) { 1246b118a2122f8f7da954fbfbcdec05c331e3fd625Dan Gohman return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 1256b118a2122f8f7da954fbfbcdec05c331e3fd625Dan Gohman (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 126ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 127ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman}; 128ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 12935bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as 13035bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner/// "exact", indicating that no bits are destroyed. 13135bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattnerclass PossiblyExactOperator : public Operator { 132f8dbee7cea072eb63ae343759975109553697bcbDan Gohmanpublic: 133f8dbee7cea072eb63ae343759975109553697bcbDan Gohman enum { 134f8dbee7cea072eb63ae343759975109553697bcbDan Gohman IsExact = (1 << 0) 135f8dbee7cea072eb63ae343759975109553697bcbDan Gohman }; 136407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 13735de7619a0599b11c2f1e0644ddea2b1bd1f9ae2Duncan Sandsprivate: 138f8dbee7cea072eb63ae343759975109553697bcbDan Gohman friend class BinaryOperator; 139f8dbee7cea072eb63ae343759975109553697bcbDan Gohman friend class ConstantExpr; 140f8dbee7cea072eb63ae343759975109553697bcbDan Gohman void setIsExact(bool B) { 141f8dbee7cea072eb63ae343759975109553697bcbDan Gohman SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); 142f8dbee7cea072eb63ae343759975109553697bcbDan Gohman } 143407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 144ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohmanpublic: 145ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman /// isExact - Test whether this division is known to be exact, with 146ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman /// zero remainder. 147ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman bool isExact() const { 148f8dbee7cea072eb63ae343759975109553697bcbDan Gohman return SubclassOptionalData & IsExact; 149ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 150407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 151f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner static bool isPossiblyExactOpcode(unsigned OpC) { 152f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner return OpC == Instruction::SDiv || 153f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner OpC == Instruction::UDiv || 154f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner OpC == Instruction::AShr || 155f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner OpC == Instruction::LShr; 15635bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner } 157ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman static inline bool classof(const ConstantExpr *CE) { 158f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner return isPossiblyExactOpcode(CE->getOpcode()); 159ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 160ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman static inline bool classof(const Instruction *I) { 161f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner return isPossiblyExactOpcode(I->getOpcode()); 162ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 163ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman static inline bool classof(const Value *V) { 164ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 165ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 166ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman } 167ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman}; 1688883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands 169ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman/// Convenience struct for specifying and reasoning about fast-math flags. 1701638b839090a35adcd5a4b4cc0a649352276e703Michael Ilsemanclass FastMathFlags { 1711638b839090a35adcd5a4b4cc0a649352276e703Michael Ilsemanprivate: 1721638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman friend class FPMathOperator; 1731638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman unsigned Flags; 1741638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman FastMathFlags(unsigned F) : Flags(F) { } 1751638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman 1761638b839090a35adcd5a4b4cc0a649352276e703Michael Ilsemanpublic: 1771638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman enum { 1781638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman UnsafeAlgebra = (1 << 0), 1791638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman NoNaNs = (1 << 1), 1801638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman NoInfs = (1 << 2), 1811638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman NoSignedZeros = (1 << 3), 1821638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman AllowReciprocal = (1 << 4) 1831638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman }; 1841638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman 1851638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman FastMathFlags() : Flags(0) 186ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman { } 187ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 1880d38424bbebf2b52cb4ed93eff08e1085c859e91Michael Ilseman /// Whether any flag is set 1891638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman bool any() { return Flags != 0; } 1900d38424bbebf2b52cb4ed93eff08e1085c859e91Michael Ilseman 1910d38424bbebf2b52cb4ed93eff08e1085c859e91Michael Ilseman /// Set all the flags to false 1921638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman void clear() { Flags = 0; } 1931638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman 1941638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman /// Flag queries 1951638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman bool noNaNs() { return 0 != (Flags & NoNaNs); } 1961638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman bool noInfs() { return 0 != (Flags & NoInfs); } 1971638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman bool noSignedZeros() { return 0 != (Flags & NoSignedZeros); } 1981638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); } 1991638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman bool unsafeAlgebra() { return 0 != (Flags & UnsafeAlgebra); } 2001638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman 2011638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman /// Flag setters 2021638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman void setNoNaNs() { Flags |= NoNaNs; } 2031638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman void setNoInfs() { Flags |= NoInfs; } 2041638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman void setNoSignedZeros() { Flags |= NoSignedZeros; } 2051638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman void setAllowReciprocal() { Flags |= AllowReciprocal; } 2061638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman void setUnsafeAlgebra() { 2071638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman Flags |= UnsafeAlgebra; 2081638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman setNoNaNs(); 2091638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman setNoInfs(); 2101638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman setNoSignedZeros(); 2111638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman setAllowReciprocal(); 2120d38424bbebf2b52cb4ed93eff08e1085c859e91Michael Ilseman } 213ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman}; 214ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 215ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 2168883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands/// FPMathOperator - Utility class for floating point operations which can have 2178883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands/// information about relaxed accuracy requirements attached to them. 2188883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sandsclass FPMathOperator : public Operator { 219ab4649b25f13af911594631174b9358aab4e89d3Michael Ilsemanprivate: 220ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman friend class Instruction; 221ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 222ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman void setHasUnsafeAlgebra(bool B) { 223ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman SubclassOptionalData = 2241638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) | 2251638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (B * FastMathFlags::UnsafeAlgebra); 226ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 227ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman // Unsafe algebra implies all the others 228ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman if (B) { 229ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman setHasNoNaNs(true); 230ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman setHasNoInfs(true); 231ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman setHasNoSignedZeros(true); 232ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman setHasAllowReciprocal(true); 233ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 234ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 235ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman void setHasNoNaNs(bool B) { 236ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman SubclassOptionalData = 2371638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (SubclassOptionalData & ~FastMathFlags::NoNaNs) | 2381638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (B * FastMathFlags::NoNaNs); 239ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 240ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman void setHasNoInfs(bool B) { 241ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman SubclassOptionalData = 2421638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (SubclassOptionalData & ~FastMathFlags::NoInfs) | 2431638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (B * FastMathFlags::NoInfs); 244ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 245ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman void setHasNoSignedZeros(bool B) { 246ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman SubclassOptionalData = 2471638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) | 2481638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (B * FastMathFlags::NoSignedZeros); 249ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 250ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman void setHasAllowReciprocal(bool B) { 251ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman SubclassOptionalData = 2521638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) | 2531638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman (B * FastMathFlags::AllowReciprocal); 254ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 255ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 256ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// Convenience function for setting all the fast-math flags 257ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman void setFastMathFlags(FastMathFlags FMF) { 2581638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman SubclassOptionalData |= FMF.Flags; 259ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 260ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 261ab4649b25f13af911594631174b9358aab4e89d3Michael Ilsemanpublic: 262ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// Test whether this operation is permitted to be 263ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// algebraically transformed, aka the 'A' fast-math property. 264ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman bool hasUnsafeAlgebra() const { 2651638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0; 266ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 267ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 268ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// Test whether this operation's arguments and results are to be 269ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// treated as non-NaN, aka the 'N' fast-math property. 270ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman bool hasNoNaNs() const { 2711638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0; 272ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 273ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 274ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// Test whether this operation's arguments and results are to be 275ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// treated as NoN-Inf, aka the 'I' fast-math property. 276ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman bool hasNoInfs() const { 2771638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman return (SubclassOptionalData & FastMathFlags::NoInfs) != 0; 278ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 279ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 280ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// Test whether this operation can treat the sign of zero 281ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// as insignificant, aka the 'S' fast-math property. 282ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman bool hasNoSignedZeros() const { 2831638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0; 284ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 285ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 286ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// Test whether this operation is permitted to use 287ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// reciprocal instead of division, aka the 'R' fast-math property. 288ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman bool hasAllowReciprocal() const { 2891638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0; 290ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 291ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 292ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman /// Convenience function for getting all the fast-math flags 293ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman FastMathFlags getFastMathFlags() const { 2941638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman return FastMathFlags(SubclassOptionalData); 295ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman } 296ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman 2978883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands /// \brief Get the maximum error permitted by this operation in ULPs. An 2988883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands /// accuracy of 0.0 means that the operation should be performed with the 2992867c85a3754320f96e36afb63325bb76269caa4Duncan Sands /// default precision. 3008883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands float getFPAccuracy() const; 3018883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands 3028883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands static inline bool classof(const Instruction *I) { 3038883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands return I->getType()->isFPOrFPVectorTy(); 3048883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands } 3058883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands static inline bool classof(const Value *V) { 3068883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands return isa<Instruction>(V) && classof(cast<Instruction>(V)); 3078883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands } 3088883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands}; 309ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 310407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 311f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner/// ConcreteOperator - A helper template for defining operators for individual 312f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner/// opcodes. 313f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnertemplate<typename SuperClass, unsigned Opc> 314f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass ConcreteOperator : public SuperClass { 31535bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattnerpublic: 31635bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner static inline bool classof(const Instruction *I) { 317f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner return I->getOpcode() == Opc; 318f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner } 319f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner static inline bool classof(const ConstantExpr *CE) { 320f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner return CE->getOpcode() == Opc; 32135bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner } 32235bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner static inline bool classof(const Value *V) { 32335bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 324f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 32535bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner } 32635bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner}; 327f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner 328f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass AddOperator 3296a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> { 3306a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman}; 331f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass SubOperator 3326a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> { 3336a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman}; 334f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass MulOperator 3356a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> { 3366a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman}; 337f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass ShlOperator 3386a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> { 3396a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman}; 340f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner 341fda458c2df6c282a4fbe335157676f7fa4117021Craig Topper 342f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass SDivOperator 3436a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> { 3446a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman}; 345f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass UDivOperator 3466a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> { 3476a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman}; 348f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass AShrOperator 3496a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> { 3506a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman}; 351f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass LShrOperator 3526a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> { 3536a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman}; 354fda458c2df6c282a4fbe335157676f7fa4117021Craig Topper 355fda458c2df6c282a4fbe335157676f7fa4117021Craig Topper 356fda458c2df6c282a4fbe335157676f7fa4117021Craig Topper 357f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass GEPOperator 358f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner : public ConcreteOperator<Operator, Instruction::GetElementPtr> { 359f8dbee7cea072eb63ae343759975109553697bcbDan Gohman enum { 360f8dbee7cea072eb63ae343759975109553697bcbDan Gohman IsInBounds = (1 << 0) 361f8dbee7cea072eb63ae343759975109553697bcbDan Gohman }; 362f8dbee7cea072eb63ae343759975109553697bcbDan Gohman 363f8dbee7cea072eb63ae343759975109553697bcbDan Gohman friend class GetElementPtrInst; 364f8dbee7cea072eb63ae343759975109553697bcbDan Gohman friend class ConstantExpr; 365f8dbee7cea072eb63ae343759975109553697bcbDan Gohman void setIsInBounds(bool B) { 366f8dbee7cea072eb63ae343759975109553697bcbDan Gohman SubclassOptionalData = 367f8dbee7cea072eb63ae343759975109553697bcbDan Gohman (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds); 368f8dbee7cea072eb63ae343759975109553697bcbDan Gohman } 369f8dbee7cea072eb63ae343759975109553697bcbDan Gohman 3705c2cb324d8d6380e8753b7022a6bc0b49809701bDan Gohmanpublic: 371dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman /// isInBounds - Test whether this is an inbounds GEP, as defined 372dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman /// by LangRef.html. 373dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman bool isInBounds() const { 374f8dbee7cea072eb63ae343759975109553697bcbDan Gohman return SubclassOptionalData & IsInBounds; 375dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman } 376dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman 377016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman inline op_iterator idx_begin() { return op_begin()+1; } 378016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman inline const_op_iterator idx_begin() const { return op_begin()+1; } 379016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman inline op_iterator idx_end() { return op_end(); } 380016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman inline const_op_iterator idx_end() const { return op_end(); } 381016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman 382016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman Value *getPointerOperand() { 383016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman return getOperand(0); 384016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman } 385016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman const Value *getPointerOperand() const { 386016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman return getOperand(0); 387016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman } 388016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman static unsigned getPointerOperandIndex() { 389016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman return 0U; // get index for modifying correct operand 390016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman } 391016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman 392016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman /// getPointerOperandType - Method to return the pointer operand as a 393016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman /// PointerType. 3941608769abeb1430dc34f31ffac0d9850f99ae36aNadav Rotem Type *getPointerOperandType() const { 3951608769abeb1430dc34f31ffac0d9850f99ae36aNadav Rotem return getPointerOperand()->getType(); 396016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman } 397016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman 39863b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow /// getPointerAddressSpace - Method to return the address space of the 39963b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow /// pointer operand. 40063b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow unsigned getPointerAddressSpace() const { 40163b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow return cast<PointerType>(getPointerOperandType())->getAddressSpace(); 40263b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow } 40363b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow 404016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman unsigned getNumIndices() const { // Note: always non-negative 405016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman return getNumOperands() - 1; 406016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman } 407016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman 408016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman bool hasIndices() const { 409016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman return getNumOperands() > 1; 410016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman } 411016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman 412016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman /// hasAllZeroIndices - Return true if all of the indices of this GEP are 413016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman /// zeros. If so, the result pointer and the first operand have the same 414016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman /// value, just potentially different types. 415016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman bool hasAllZeroIndices() const { 416016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { 417f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner if (ConstantInt *C = dyn_cast<ConstantInt>(I)) 418f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner if (C->isZero()) 419016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman continue; 420016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman return false; 421016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman } 422016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman return true; 423016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman } 424016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman 4250c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner /// hasAllConstantIndices - Return true if all of the indices of this GEP are 4260c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner /// constant integers. If so, the result pointer and the first operand have 4270c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner /// a constant offset between them. 4280c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner bool hasAllConstantIndices() const { 4290c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { 4300c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner if (!isa<ConstantInt>(I)) 4310c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner return false; 4320c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner } 4330c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner return true; 4340c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner } 4357550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth 4367550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth /// \brief Accumulate the constant address offset of this GEP if possible. 4377550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth /// 4387550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth /// This routine accepts an APInt into which it will accumulate the constant 4397550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth /// offset of this GEP if the GEP is in fact constant. If the GEP is not 4407550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth /// all-constant, it returns false and the value of the offset APInt is 4417550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth /// undefined (it is *not* preserved!). The APInt passed into this routine 4427550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth /// must be at least as wide as the IntPtr type for the address space of 4437550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth /// the base GEP pointer. 4447550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const { 4457550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth assert(Offset.getBitWidth() == 4467550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth DL.getPointerSizeInBits(getPointerAddressSpace()) && 4477550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth "The offset must have exactly as many bits as our pointer."); 4487550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth 4497550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this); 4507550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth GTI != GTE; ++GTI) { 4517550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand()); 4527550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth if (!OpC) 4537550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth return false; 4547550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth if (OpC->isZero()) 4557550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth continue; 4567550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth 4577550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth // Handle a struct index, which adds its field offset to the pointer. 4587550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth if (StructType *STy = dyn_cast<StructType>(*GTI)) { 4597550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth unsigned ElementIdx = OpC->getZExtValue(); 4607550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth const StructLayout *SL = DL.getStructLayout(STy); 4617550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth Offset += APInt(Offset.getBitWidth(), 4627550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth SL->getElementOffset(ElementIdx)); 4637550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth continue; 4647550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth } 4657550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth 4667550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth // For array or vector indices, scale the index by the size of the type. 4677550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth()); 4687550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth Offset += Index * APInt(Offset.getBitWidth(), 4697550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth DL.getTypeAllocSize(GTI.getIndexedType())); 4707550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth } 4717550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth return true; 4727550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth } 4737550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth 4745c2cb324d8d6380e8753b7022a6bc0b49809701bDan Gohman}; 4755c2cb324d8d6380e8753b7022a6bc0b49809701bDan Gohman 476ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman} // End llvm namespace 477ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman 478ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman#endif 479