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