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"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/GetElementPtrTypeIterator.h"
220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instruction.h"
230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.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  }
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void operator&=(const FastMathFlags &OtherFlags) {
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Flags &= OtherFlags.Flags;
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
217ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman};
218ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
219ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
2208883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands/// FPMathOperator - Utility class for floating point operations which can have
2218883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands/// information about relaxed accuracy requirements attached to them.
2228883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sandsclass FPMathOperator : public Operator {
223ab4649b25f13af911594631174b9358aab4e89d3Michael Ilsemanprivate:
224ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  friend class Instruction;
225ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
226ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  void setHasUnsafeAlgebra(bool B) {
227ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman    SubclassOptionalData =
2281638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) |
2291638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (B * FastMathFlags::UnsafeAlgebra);
230ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
231ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman    // Unsafe algebra implies all the others
232ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman    if (B) {
233ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman      setHasNoNaNs(true);
234ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman      setHasNoInfs(true);
235ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman      setHasNoSignedZeros(true);
236ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman      setHasAllowReciprocal(true);
237ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman    }
238ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
239ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  void setHasNoNaNs(bool B) {
240ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman    SubclassOptionalData =
2411638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
2421638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (B * FastMathFlags::NoNaNs);
243ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
244ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  void setHasNoInfs(bool B) {
245ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman    SubclassOptionalData =
2461638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (SubclassOptionalData & ~FastMathFlags::NoInfs) |
2471638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (B * FastMathFlags::NoInfs);
248ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
249ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  void setHasNoSignedZeros(bool B) {
250ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman    SubclassOptionalData =
2511638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
2521638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (B * FastMathFlags::NoSignedZeros);
253ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
254ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  void setHasAllowReciprocal(bool B) {
255ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman    SubclassOptionalData =
2561638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
2571638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman      (B * FastMathFlags::AllowReciprocal);
258ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
259ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
260ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// Convenience function for setting all the fast-math flags
261ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  void setFastMathFlags(FastMathFlags FMF) {
2621638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman    SubclassOptionalData |= FMF.Flags;
263ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
264ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
265ab4649b25f13af911594631174b9358aab4e89d3Michael Ilsemanpublic:
266ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// Test whether this operation is permitted to be
267ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// algebraically transformed, aka the 'A' fast-math property.
268ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  bool hasUnsafeAlgebra() const {
2691638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman    return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0;
270ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
271ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
272ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// Test whether this operation's arguments and results are to be
273ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// treated as non-NaN, aka the 'N' fast-math property.
274ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  bool hasNoNaNs() const {
2751638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman    return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
276ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
277ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
278ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// Test whether this operation's arguments and results are to be
279ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// treated as NoN-Inf, aka the 'I' fast-math property.
280ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  bool hasNoInfs() const {
2811638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman    return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
282ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
283ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
284ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// Test whether this operation can treat the sign of zero
285ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// as insignificant, aka the 'S' fast-math property.
286ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  bool hasNoSignedZeros() const {
2871638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman    return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
288ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
289ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
290ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// Test whether this operation is permitted to use
291ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// reciprocal instead of division, aka the 'R' fast-math property.
292ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  bool hasAllowReciprocal() const {
2931638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman    return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
294ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
295ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
296ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  /// Convenience function for getting all the fast-math flags
297ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  FastMathFlags getFastMathFlags() const {
2981638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman    return FastMathFlags(SubclassOptionalData);
299ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman  }
300ab4649b25f13af911594631174b9358aab4e89d3Michael Ilseman
3018883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands  /// \brief Get the maximum error permitted by this operation in ULPs.  An
3028883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands  /// accuracy of 0.0 means that the operation should be performed with the
3032867c85a3754320f96e36afb63325bb76269caa4Duncan Sands  /// default precision.
3048883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands  float getFPAccuracy() const;
3058883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands
3068883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands  static inline bool classof(const Instruction *I) {
3078883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands    return I->getType()->isFPOrFPVectorTy();
3088883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands  }
3098883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands  static inline bool classof(const Value *V) {
3108883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands    return isa<Instruction>(V) && classof(cast<Instruction>(V));
3118883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands  }
3128883c43ddc13e5f92ba8dfe00f2116a153a570d5Duncan Sands};
313ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman
314407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman
315f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner/// ConcreteOperator - A helper template for defining operators for individual
316f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner/// opcodes.
317f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnertemplate<typename SuperClass, unsigned Opc>
318f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass ConcreteOperator : public SuperClass {
31935bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattnerpublic:
32035bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner  static inline bool classof(const Instruction *I) {
321f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner    return I->getOpcode() == Opc;
322f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner  }
323f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner  static inline bool classof(const ConstantExpr *CE) {
324f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner    return CE->getOpcode() == Opc;
32535bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner  }
32635bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner  static inline bool classof(const Value *V) {
32735bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
328f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
32935bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner  }
33035bda8914c0d1c02a6f90f42e7810c83150737e1Chris Lattner};
331f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner
332f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass AddOperator
3336a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
3346a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman};
335f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass SubOperator
3366a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
3376a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman};
338f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass MulOperator
3396a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
3406a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman};
341f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass ShlOperator
3426a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
3436a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman};
344f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner
345fda458c2df6c282a4fbe335157676f7fa4117021Craig Topper
346f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass SDivOperator
3476a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman  : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
3486a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman};
349f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass UDivOperator
3506a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman  : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
3516a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman};
352f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass AShrOperator
3536a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman  : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
3546a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman};
355f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass LShrOperator
3566a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman  : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
3576a61834d1c41971f80669a0484f1a0d2d8a1c286Eli Friedman};
358fda458c2df6c282a4fbe335157676f7fa4117021Craig Topper
359fda458c2df6c282a4fbe335157676f7fa4117021Craig Topper
360fda458c2df6c282a4fbe335157676f7fa4117021Craig Topper
361f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattnerclass GEPOperator
362f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner  : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
363f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  enum {
364f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    IsInBounds = (1 << 0)
365f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  };
366f8dbee7cea072eb63ae343759975109553697bcbDan Gohman
367f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  friend class GetElementPtrInst;
368f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  friend class ConstantExpr;
369f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  void setIsInBounds(bool B) {
370f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    SubclassOptionalData =
371f8dbee7cea072eb63ae343759975109553697bcbDan Gohman      (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
372f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  }
373f8dbee7cea072eb63ae343759975109553697bcbDan Gohman
3745c2cb324d8d6380e8753b7022a6bc0b49809701bDan Gohmanpublic:
375dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman  /// isInBounds - Test whether this is an inbounds GEP, as defined
376dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman  /// by LangRef.html.
377dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman  bool isInBounds() const {
378f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    return SubclassOptionalData & IsInBounds;
379dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman  }
380dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman
381016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  inline op_iterator       idx_begin()       { return op_begin()+1; }
382016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  inline const_op_iterator idx_begin() const { return op_begin()+1; }
383016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  inline op_iterator       idx_end()         { return op_end(); }
384016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  inline const_op_iterator idx_end()   const { return op_end(); }
385016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman
386016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  Value *getPointerOperand() {
387016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman    return getOperand(0);
388016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  }
389016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  const Value *getPointerOperand() const {
390016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman    return getOperand(0);
391016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  }
392016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  static unsigned getPointerOperandIndex() {
393016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman    return 0U;                      // get index for modifying correct operand
394016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  }
395016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman
396016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  /// getPointerOperandType - Method to return the pointer operand as a
397016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  /// PointerType.
3981608769abeb1430dc34f31ffac0d9850f99ae36aNadav Rotem  Type *getPointerOperandType() const {
3991608769abeb1430dc34f31ffac0d9850f99ae36aNadav Rotem    return getPointerOperand()->getType();
400016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  }
401016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman
40263b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow  /// getPointerAddressSpace - Method to return the address space of the
40363b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow  /// pointer operand.
40463b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow  unsigned getPointerAddressSpace() const {
40563b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow    return cast<PointerType>(getPointerOperandType())->getAddressSpace();
40663b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow  }
40763b8ab29c420703dc5ef32e6d76d9e4d8f60f19eMicah Villmow
408016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  unsigned getNumIndices() const {  // Note: always non-negative
409016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman    return getNumOperands() - 1;
410016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  }
411016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman
412016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  bool hasIndices() const {
413016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman    return getNumOperands() > 1;
414016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  }
415016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman
416016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  /// hasAllZeroIndices - Return true if all of the indices of this GEP are
417016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  /// zeros.  If so, the result pointer and the first operand have the same
418016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  /// value, just potentially different types.
419016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  bool hasAllZeroIndices() const {
420016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
421f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner      if (ConstantInt *C = dyn_cast<ConstantInt>(I))
422f067d584a81ae771d301304ea885e55e2de8ee9aChris Lattner        if (C->isZero())
423016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman          continue;
424016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman      return false;
425016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman    }
426016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman    return true;
427016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman  }
428016de81177ec5c950f1668be4a48992bc1ee0d75Dan Gohman
4290c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner  /// hasAllConstantIndices - Return true if all of the indices of this GEP are
4300c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner  /// constant integers.  If so, the result pointer and the first operand have
4310c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner  /// a constant offset between them.
4320c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner  bool hasAllConstantIndices() const {
4330c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
4340c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner      if (!isa<ConstantInt>(I))
4350c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner        return false;
4360c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner    }
4370c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner    return true;
4380c1f688954a087017bcaa0d4e88c1ebd64f11c45Chris Lattner  }
4397550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth
4407550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth  /// \brief Accumulate the constant address offset of this GEP if possible.
4417550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth  ///
4427550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth  /// This routine accepts an APInt into which it will accumulate the constant
4437550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth  /// offset of this GEP if the GEP is in fact constant. If the GEP is not
4447550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth  /// all-constant, it returns false and the value of the offset APInt is
4457550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth  /// undefined (it is *not* preserved!). The APInt passed into this routine
446b95237f10cf718c63b153e362b3b5b548ce50698Matt Arsenault  /// must be at exactly as wide as the IntPtr type for the address space of the
447b95237f10cf718c63b153e362b3b5b548ce50698Matt Arsenault  /// base GEP pointer.
4487550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth  bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const {
4497550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth    assert(Offset.getBitWidth() ==
4507550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth           DL.getPointerSizeInBits(getPointerAddressSpace()) &&
4517550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth           "The offset must have exactly as many bits as our pointer.");
4527550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth
4537550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth    for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this);
4547550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth         GTI != GTE; ++GTI) {
4557550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth      ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand());
4567550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth      if (!OpC)
4577550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth        return false;
4587550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth      if (OpC->isZero())
4597550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth        continue;
4607550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth
4617550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth      // Handle a struct index, which adds its field offset to the pointer.
4627550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth      if (StructType *STy = dyn_cast<StructType>(*GTI)) {
4637550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth        unsigned ElementIdx = OpC->getZExtValue();
4647550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth        const StructLayout *SL = DL.getStructLayout(STy);
4657550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth        Offset += APInt(Offset.getBitWidth(),
4667550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth                        SL->getElementOffset(ElementIdx));
4677550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth        continue;
4687550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth      }
4697550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth
4707550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth      // For array or vector indices, scale the index by the size of the type.
4717550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth      APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth());
4727550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth      Offset += Index * APInt(Offset.getBitWidth(),
4737550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth                              DL.getTypeAllocSize(GTI.getIndexedType()));
4747550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth    }
4757550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth    return true;
4767550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth  }
4777550f96b2f3a5e187f737ddad45563962fbd509cChandler Carruth
4785c2cb324d8d6380e8753b7022a6bc0b49809701bDan Gohman};
4795c2cb324d8d6380e8753b7022a6bc0b49809701bDan Gohman
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass PtrToIntOperator
48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    : public ConcreteOperator<Operator, Instruction::PtrToInt> {
48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  friend class PtrToInt;
48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  friend class ConstantExpr;
48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *getPointerOperand() {
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return getOperand(0);
48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const Value *getPointerOperand() const {
49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return getOperand(0);
49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static unsigned getPointerOperandIndex() {
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return 0U;                      // get index for modifying correct operand
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// getPointerOperandType - Method to return the pointer operand as a
49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// PointerType.
49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Type *getPointerOperandType() const {
49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return getPointerOperand()->getType();
50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// getPointerAddressSpace - Method to return the address space of the
50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// pointer operand.
50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getPointerAddressSpace() const {
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return cast<PointerType>(getPointerOperandType())->getAddressSpace();
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
510ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman} // End llvm namespace
511ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman
512ca178908c8dc2303a1fb54a8a93bab0f0b964e11Dan Gohman#endif
513