1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines various classes for working with Instructions and
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// ConstantExprs.
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef LLVM_OPERATOR_H
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define LLVM_OPERATOR_H
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Instruction.h"
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Constants.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm {
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass GetElementPtrInst;
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass BinaryOperator;
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass ConstantExpr;
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Operator - This is a utility class that provides an abstraction for the
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// common functionality between Instructions and ConstantExprs.
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass Operator : public User {
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate:
32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Do not implement any of these. The Operator class is intended to be used
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // as a utility, and is never itself instantiated.
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void *operator new(size_t, unsigned);
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void *operator new(size_t s);
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Operator();
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ~Operator();
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getOpcode - Return the opcode for this Instruction or ConstantExpr.
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned getOpcode() const {
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (const Instruction *I = dyn_cast<Instruction>(this))
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return I->getOpcode();
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return cast<ConstantExpr>(this)->getOpcode();
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getOpcode - If V is an Instruction or ConstantExpr, return its
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// opcode. Otherwise return UserOp1.
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static unsigned getOpcode(const Value *V) {
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (const Instruction *I = dyn_cast<Instruction>(V))
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return I->getOpcode();
54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return CE->getOpcode();
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Instruction::UserOp1;
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const Operator *) { return true; }
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const Instruction *) { return true; }
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const ConstantExpr *) { return true; }
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const Value *V) {
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return isa<Instruction>(V) || isa<ConstantExpr>(V);
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// OverflowingBinaryOperator - Utility class for integer arithmetic operators
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// which may exhibit overflow - Add, Sub, and Mul. It does not include SDiv,
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// despite that operator having the potential for overflow.
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass OverflowingBinaryOperator : public Operator {
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  enum {
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    NoUnsignedWrap = (1 << 0),
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    NoSignedWrap   = (1 << 1)
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  };
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate:
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ~OverflowingBinaryOperator(); // do not implement
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  friend class BinaryOperator;
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  friend class ConstantExpr;
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void setHasNoUnsignedWrap(bool B) {
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SubclassOptionalData =
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void setHasNoSignedWrap(bool B) {
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SubclassOptionalData =
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// hasNoUnsignedWrap - Test whether this operation is known to never
94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// undergo unsigned overflow, aka the nuw property.
95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool hasNoUnsignedWrap() const {
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return SubclassOptionalData & NoUnsignedWrap;
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// hasNoSignedWrap - Test whether this operation is known to never
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// undergo signed overflow, aka the nsw property.
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool hasNoSignedWrap() const {
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return (SubclassOptionalData & NoSignedWrap) != 0;
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const OverflowingBinaryOperator *) { return true; }
106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const Instruction *I) {
107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return I->getOpcode() == Instruction::Add ||
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           I->getOpcode() == Instruction::Sub ||
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           I->getOpcode() == Instruction::Mul ||
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           I->getOpcode() == Instruction::Shl;
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const ConstantExpr *CE) {
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return CE->getOpcode() == Instruction::Add ||
114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           CE->getOpcode() == Instruction::Sub ||
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           CE->getOpcode() == Instruction::Mul ||
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           CE->getOpcode() == Instruction::Shl;
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const Value *V) {
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// "exact", indicating that no bits are destroyed.
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass PossiblyExactOperator : public Operator {
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  enum {
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IsExact = (1 << 0)
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  friend class BinaryOperator;
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  friend class ConstantExpr;
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void setIsExact(bool B) {
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanprivate:
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~PossiblyExactOperator(); // do not implement
140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// isExact - Test whether this division is known to be exact, with
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// zero remainder.
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool isExact() const {
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return SubclassOptionalData & IsExact;
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static bool isPossiblyExactOpcode(unsigned OpC) {
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return OpC == Instruction::SDiv ||
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           OpC == Instruction::UDiv ||
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           OpC == Instruction::AShr ||
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           OpC == Instruction::LShr;
152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const ConstantExpr *CE) {
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return isPossiblyExactOpcode(CE->getOpcode());
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static inline bool classof(const Instruction *I) {
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return isPossiblyExactOpcode(I->getOpcode());
158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const Value *V) {
160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ConcreteOperator - A helper template for defining operators for individual
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// opcodes.
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumantemplate<typename SuperClass, unsigned Opc>
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass ConcreteOperator : public SuperClass {
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~ConcreteOperator(); // DO NOT IMPLEMENT
172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) {
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const Instruction *I) {
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return I->getOpcode() == Opc;
178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const ConstantExpr *CE) {
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CE->getOpcode() == Opc;
181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static inline bool classof(const Value *V) {
183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass AddOperator
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~AddOperator(); // DO NOT IMPLEMENT
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass SubOperator
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~SubOperator(); // DO NOT IMPLEMENT
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass MulOperator
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~MulOperator(); // DO NOT IMPLEMENT
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass ShlOperator
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~ShlOperator(); // DO NOT IMPLEMENT
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass SDivOperator
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~SDivOperator(); // DO NOT IMPLEMENT
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass UDivOperator
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~UDivOperator(); // DO NOT IMPLEMENT
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass AShrOperator
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~AShrOperator(); // DO NOT IMPLEMENT
217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass LShrOperator
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~LShrOperator(); // DO NOT IMPLEMENT
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass GEPOperator
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ~GEPOperator(); // DO NOT IMPLEMENT
228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  enum {
230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    IsInBounds = (1 << 0)
231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  };
232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  friend class GetElementPtrInst;
234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  friend class ConstantExpr;
235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void setIsInBounds(bool B) {
236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SubclassOptionalData =
237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// isInBounds - Test whether this is an inbounds GEP, as defined
242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// by LangRef.html.
243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool isInBounds() const {
244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return SubclassOptionalData & IsInBounds;
245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  inline op_iterator       idx_begin()       { return op_begin()+1; }
248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  inline const_op_iterator idx_begin() const { return op_begin()+1; }
249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  inline op_iterator       idx_end()         { return op_end(); }
250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  inline const_op_iterator idx_end()   const { return op_end(); }
251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Value *getPointerOperand() {
253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return getOperand(0);
254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const Value *getPointerOperand() const {
256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return getOperand(0);
257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static unsigned getPointerOperandIndex() {
259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 0U;                      // get index for modifying correct operand
260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getPointerOperandType - Method to return the pointer operand as a
263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// PointerType.
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PointerType *getPointerOperandType() const {
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return reinterpret_cast<PointerType*>(getPointerOperand()->getType());
266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned getNumIndices() const {  // Note: always non-negative
269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return getNumOperands() - 1;
270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool hasIndices() const {
273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return getNumOperands() > 1;
274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// hasAllZeroIndices - Return true if all of the indices of this GEP are
277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// zeros.  If so, the result pointer and the first operand have the same
278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// value, just potentially different types.
279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool hasAllZeroIndices() const {
280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (ConstantInt *C = dyn_cast<ConstantInt>(I))
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (C->isZero())
283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          continue;
284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return false;
285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// hasAllConstantIndices - Return true if all of the indices of this GEP are
290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// constant integers.  If so, the result pointer and the first operand have
291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// a constant offset between them.
292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool hasAllConstantIndices() const {
293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (!isa<ConstantInt>(I))
295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return false;
296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // End llvm namespace
302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
304