1b1352e953458711bcceb5600e25e9c5c94ad9013Owen Anderson//===-- ConstantsContext.h - Constants-related Context Interals -----------===//
2e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//
3e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//                     The LLVM Compiler Infrastructure
4e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//
5e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// This file is distributed under the University of Illinois Open Source
6e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// License. See LICENSE.TXT for details.
7e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//
8e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//===----------------------------------------------------------------------===//
9e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//
10e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//  This file defines various helper methods and classes used by
11e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// LLVMContextImpl for creating and managing constants.
12e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//
13e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//===----------------------------------------------------------------------===//
14e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
15e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson#ifndef LLVM_CONSTANTSCONTEXT_H
16e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson#define LLVM_CONSTANTSCONTEXT_H
17e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
182cb395eae71dacda49ca3fe758618fc3e0701659Talin#include "llvm/ADT/DenseMap.h"
194e3e5dec1a2a479891b4081c1c715a97fd85644dJay Foad#include "llvm/ADT/Hashing.h"
200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h"
210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h"
220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Operator.h"
23da23d93d9bb6238757e29b1abee571a0052ab8fcDavid Greene#include "llvm/Support/Debug.h"
24e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson#include "llvm/Support/ErrorHandling.h"
25569f121f4ecc53f8ab505c4ccb6e1e77c78e188dChris Lattner#include "llvm/Support/raw_ostream.h"
26e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson#include <map>
27e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
28e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonnamespace llvm {
29e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate<class ValType>
30e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonstruct ConstantTraits;
31e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
32e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// UnaryConstantExpr - This class is private to Constants.cpp, and is used
33e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// behind the scenes to implement unary constant exprs.
34e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonclass UnaryConstantExpr : public ConstantExpr {
352d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
3686a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
37e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
38e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  // allocate space for exactly one operand
39e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void *operator new(size_t s) {
40e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return User::operator new(s, 1);
41e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
42db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
43e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
44e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<0>() = C;
45e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
46e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
47e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
48e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
49e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// BinaryConstantExpr - This class is private to Constants.cpp, and is used
50e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// behind the scenes to implement binary constant exprs.
51e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonclass BinaryConstantExpr : public ConstantExpr {
522d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
5386a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
54e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
55e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  // allocate space for exactly two operands
56e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void *operator new(size_t s) {
57e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return User::operator new(s, 2);
58e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
59f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
60f8dbee7cea072eb63ae343759975109553697bcbDan Gohman                     unsigned Flags)
61e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
62e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<0>() = C1;
63e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<1>() = C2;
64f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    SubclassOptionalData = Flags;
65e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
66e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Transparently provide more efficient getOperand methods.
67e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
68e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
69e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
70e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// SelectConstantExpr - This class is private to Constants.cpp, and is used
71e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// behind the scenes to implement select constant exprs.
72e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonclass SelectConstantExpr : public ConstantExpr {
732d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
7486a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
75e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
76e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  // allocate space for exactly three operands
77e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void *operator new(size_t s) {
78e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return User::operator new(s, 3);
79e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
80e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
81e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
82e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<0>() = C1;
83e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<1>() = C2;
84e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<2>() = C3;
85e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
86e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Transparently provide more efficient getOperand methods.
87e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
88e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
89e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
90e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// ExtractElementConstantExpr - This class is private to
91e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// Constants.cpp, and is used behind the scenes to implement
92e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// extractelement constant exprs.
93e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonclass ExtractElementConstantExpr : public ConstantExpr {
942d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
9586a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
96e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
97e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  // allocate space for exactly two operands
98e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void *operator new(size_t s) {
99e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return User::operator new(s, 2);
100e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
101e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  ExtractElementConstantExpr(Constant *C1, Constant *C2)
102e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
103e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                   Instruction::ExtractElement, &Op<0>(), 2) {
104e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<0>() = C1;
105e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<1>() = C2;
106e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
107e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Transparently provide more efficient getOperand methods.
108e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
109e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
110e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
111e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// InsertElementConstantExpr - This class is private to
112e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// Constants.cpp, and is used behind the scenes to implement
113e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// insertelement constant exprs.
114e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonclass InsertElementConstantExpr : public ConstantExpr {
1152d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
11686a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
117e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
118e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  // allocate space for exactly three operands
119e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void *operator new(size_t s) {
120e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return User::operator new(s, 3);
121e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
122e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
123e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    : ConstantExpr(C1->getType(), Instruction::InsertElement,
124e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                   &Op<0>(), 3) {
125e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<0>() = C1;
126e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<1>() = C2;
127e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<2>() = C3;
128e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
129e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Transparently provide more efficient getOperand methods.
130e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
131e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
132e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
133e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// ShuffleVectorConstantExpr - This class is private to
134e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// Constants.cpp, and is used behind the scenes to implement
135e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// shufflevector constant exprs.
136e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonclass ShuffleVectorConstantExpr : public ConstantExpr {
1372d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
13886a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
139e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
140e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  // allocate space for exactly three operands
141e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void *operator new(size_t s) {
142e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return User::operator new(s, 3);
143e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
144e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
145e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  : ConstantExpr(VectorType::get(
146e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                   cast<VectorType>(C1->getType())->getElementType(),
147e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                   cast<VectorType>(C3->getType())->getNumElements()),
148e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                 Instruction::ShuffleVector,
149e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                 &Op<0>(), 3) {
150e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<0>() = C1;
151e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<1>() = C2;
152e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<2>() = C3;
153e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
154e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Transparently provide more efficient getOperand methods.
155e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
156e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
157e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
158e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// ExtractValueConstantExpr - This class is private to
159e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// Constants.cpp, and is used behind the scenes to implement
160e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// extractvalue constant exprs.
161e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonclass ExtractValueConstantExpr : public ConstantExpr {
1622d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
16386a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
164e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
165e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  // allocate space for exactly one operand
166e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void *operator new(size_t s) {
167e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return User::operator new(s, 1);
168e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
169e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  ExtractValueConstantExpr(Constant *Agg,
170e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                           const SmallVector<unsigned, 4> &IdxList,
171db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                           Type *DestTy)
172e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
173e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      Indices(IdxList) {
174e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<0>() = Agg;
175e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
176e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
177e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Indices - These identify which value to extract.
178e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  const SmallVector<unsigned, 4> Indices;
179e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
180e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Transparently provide more efficient getOperand methods.
181e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
182e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
183e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
184e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// InsertValueConstantExpr - This class is private to
185e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// Constants.cpp, and is used behind the scenes to implement
186e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// insertvalue constant exprs.
187e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonclass InsertValueConstantExpr : public ConstantExpr {
1882d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
18986a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
190e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
191e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  // allocate space for exactly one operand
192e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void *operator new(size_t s) {
193e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return User::operator new(s, 2);
194e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
195e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  InsertValueConstantExpr(Constant *Agg, Constant *Val,
196e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                          const SmallVector<unsigned, 4> &IdxList,
197db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                          Type *DestTy)
198e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
199e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      Indices(IdxList) {
200e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<0>() = Agg;
201e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<1>() = Val;
202e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
203e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
204e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Indices - These identify the position for the insertion.
205e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  const SmallVector<unsigned, 4> Indices;
206e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
207e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Transparently provide more efficient getOperand methods.
208e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
209e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
210e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
211e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
212e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
213e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson/// used behind the scenes to implement getelementpr constant exprs.
214e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonclass GetElementPtrConstantExpr : public ConstantExpr {
2152d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
216a7c698823e4ffa4589bde1ff6de60b6af0cdba5aChris Lattner  GetElementPtrConstantExpr(Constant *C, ArrayRef<Constant*> IdxList,
217db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                            Type *DestTy);
218e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
219e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  static GetElementPtrConstantExpr *Create(Constant *C,
220a7c698823e4ffa4589bde1ff6de60b6af0cdba5aChris Lattner                                           ArrayRef<Constant*> IdxList,
221db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                                           Type *DestTy,
222f8dbee7cea072eb63ae343759975109553697bcbDan Gohman                                           unsigned Flags) {
223f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    GetElementPtrConstantExpr *Result =
224e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
225f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    Result->SubclassOptionalData = Flags;
226f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    return Result;
227e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
228e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Transparently provide more efficient getOperand methods.
229e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
230e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
231e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
232e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// CompareConstantExpr - This class is private to Constants.cpp, and is used
233e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// behind the scenes to implement ICmp and FCmp constant expressions. This is
234e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// needed in order to store the predicate value for these instructions.
2352d24e2a396a1d211baaeedf32148a3b657240170David Blaikieclass CompareConstantExpr : public ConstantExpr {
2362d24e2a396a1d211baaeedf32148a3b657240170David Blaikie  virtual void anchor();
23786a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
2382d24e2a396a1d211baaeedf32148a3b657240170David Blaikiepublic:
239e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  // allocate space for exactly two operands
240e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void *operator new(size_t s) {
241e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return User::operator new(s, 2);
242e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
243e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  unsigned short predicate;
244db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  CompareConstantExpr(Type *ty, Instruction::OtherOps opc,
245e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                      unsigned short pred,  Constant* LHS, Constant* RHS)
246e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
247e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<0>() = LHS;
248e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Op<1>() = RHS;
249e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
250e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Transparently provide more efficient getOperand methods.
251e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
252e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
253e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
254e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
25567c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<UnaryConstantExpr> :
25667c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad  public FixedNumOperandTraits<UnaryConstantExpr, 1> {
257e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
258e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
259e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
260e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
26167c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<BinaryConstantExpr> :
26267c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad  public FixedNumOperandTraits<BinaryConstantExpr, 2> {
263e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
264e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
265e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
266e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
26767c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<SelectConstantExpr> :
26867c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad  public FixedNumOperandTraits<SelectConstantExpr, 3> {
269e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
270e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
271e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
272e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
27367c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<ExtractElementConstantExpr> :
27467c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad  public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {
275e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
276e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
277e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
278e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
27967c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<InsertElementConstantExpr> :
28067c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad  public FixedNumOperandTraits<InsertElementConstantExpr, 3> {
281e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
282e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
283e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
284e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
28567c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<ShuffleVectorConstantExpr> :
28667c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad    public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {
287e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
288e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
289e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
290e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
29167c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<ExtractValueConstantExpr> :
29267c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad  public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {
293e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
294e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
295e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
296e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
29767c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<InsertValueConstantExpr> :
29867c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad  public FixedNumOperandTraits<InsertValueConstantExpr, 2> {
299e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
300e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
301e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
302e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
30367c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<GetElementPtrConstantExpr> :
30467c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad  public VariadicOperandTraits<GetElementPtrConstantExpr, 1> {
305e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
306e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
307e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
308e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
309e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
310e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate <>
31167c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foadstruct OperandTraits<CompareConstantExpr> :
31267c619ba3eae68dcdb3f9340d82b33173aa0c256Jay Foad  public FixedNumOperandTraits<CompareConstantExpr, 2> {
313e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
314e2942c0c7da45686b74e8e8248fd84e98fee435eOwen AndersonDEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
315e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
316e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonstruct ExprMapKeyType {
317e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  ExprMapKeyType(unsigned opc,
318d30aa5a1edac5256573e8d76dd155df3d3fdec84Jay Foad      ArrayRef<Constant*> ops,
319f8dbee7cea072eb63ae343759975109553697bcbDan Gohman      unsigned short flags = 0,
320f8dbee7cea072eb63ae343759975109553697bcbDan Gohman      unsigned short optionalflags = 0,
321d30aa5a1edac5256573e8d76dd155df3d3fdec84Jay Foad      ArrayRef<unsigned> inds = ArrayRef<unsigned>())
322f8dbee7cea072eb63ae343759975109553697bcbDan Gohman        : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
323d30aa5a1edac5256573e8d76dd155df3d3fdec84Jay Foad        operands(ops.begin(), ops.end()), indices(inds.begin(), inds.end()) {}
324f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  uint8_t opcode;
325f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  uint8_t subclassoptionaldata;
326f8dbee7cea072eb63ae343759975109553697bcbDan Gohman  uint16_t subclassdata;
327e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  std::vector<Constant*> operands;
328d30aa5a1edac5256573e8d76dd155df3d3fdec84Jay Foad  SmallVector<unsigned, 4> indices;
329e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  bool operator==(const ExprMapKeyType& that) const {
330e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return this->opcode == that.opcode &&
331f8dbee7cea072eb63ae343759975109553697bcbDan Gohman           this->subclassdata == that.subclassdata &&
332f8dbee7cea072eb63ae343759975109553697bcbDan Gohman           this->subclassoptionaldata == that.subclassoptionaldata &&
333e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson           this->operands == that.operands &&
334e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson           this->indices == that.indices;
335e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
336e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  bool operator<(const ExprMapKeyType & that) const {
337f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    if (this->opcode != that.opcode) return this->opcode < that.opcode;
338f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    if (this->operands != that.operands) return this->operands < that.operands;
339f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    if (this->subclassdata != that.subclassdata)
340f8dbee7cea072eb63ae343759975109553697bcbDan Gohman      return this->subclassdata < that.subclassdata;
341f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    if (this->subclassoptionaldata != that.subclassoptionaldata)
342f8dbee7cea072eb63ae343759975109553697bcbDan Gohman      return this->subclassoptionaldata < that.subclassoptionaldata;
343f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    if (this->indices != that.indices) return this->indices < that.indices;
344f8dbee7cea072eb63ae343759975109553697bcbDan Gohman    return false;
345e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
346e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
347e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  bool operator!=(const ExprMapKeyType& that) const {
348e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return !(*this == that);
349e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
350e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
351e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
352bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskinstruct InlineAsmKeyType {
353bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  InlineAsmKeyType(StringRef AsmString,
354bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin                   StringRef Constraints, bool hasSideEffects,
355581600bfc3060ee13afb278cd87e25da5b5f7db2Chad Rosier                   bool isAlignStack, InlineAsm::AsmDialect asmDialect)
356bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    : asm_string(AsmString), constraints(Constraints),
35703fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier      has_side_effects(hasSideEffects), is_align_stack(isAlignStack),
35803fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier      asm_dialect(asmDialect) {}
359bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  std::string asm_string;
360bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  std::string constraints;
361bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  bool has_side_effects;
362bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  bool is_align_stack;
363581600bfc3060ee13afb278cd87e25da5b5f7db2Chad Rosier  InlineAsm::AsmDialect asm_dialect;
364bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  bool operator==(const InlineAsmKeyType& that) const {
365bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    return this->asm_string == that.asm_string &&
366bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin           this->constraints == that.constraints &&
367bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin           this->has_side_effects == that.has_side_effects &&
36803fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier           this->is_align_stack == that.is_align_stack &&
36903fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier           this->asm_dialect == that.asm_dialect;
370bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  }
371bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  bool operator<(const InlineAsmKeyType& that) const {
372bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    if (this->asm_string != that.asm_string)
373bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin      return this->asm_string < that.asm_string;
374bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    if (this->constraints != that.constraints)
375bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin      return this->constraints < that.constraints;
376bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    if (this->has_side_effects != that.has_side_effects)
377bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin      return this->has_side_effects < that.has_side_effects;
378bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    if (this->is_align_stack != that.is_align_stack)
379bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin      return this->is_align_stack < that.is_align_stack;
38003fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier    if (this->asm_dialect != that.asm_dialect)
38103fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier      return this->asm_dialect < that.asm_dialect;
382bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    return false;
383bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  }
384bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin
385bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  bool operator!=(const InlineAsmKeyType& that) const {
386bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    return !(*this == that);
387bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  }
388bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin};
389bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin
390e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// The number of operands for each ConstantCreator::create method is
391e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// determined by the ConstantTraits template.
392e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// ConstantCreator - A class that is used to create constants by
39303236140fa4ef316a605717e090276d6a0d42828Jeffrey Yasskin// ConstantUniqueMap*.  This class should be partially specialized if there is
394e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// something strange that needs to be done to interface to the ctor for the
395e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson// constant.
396e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson//
397e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate<typename T, typename Alloc>
398e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonstruct ConstantTraits< std::vector<T, Alloc> > {
399e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  static unsigned uses(const std::vector<T, Alloc>& v) {
400e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return v.size();
401e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
402e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
403e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
404fdfeb6976f07ad10d809b922ed7376ba2a3539beChris Lattnertemplate<>
405fdfeb6976f07ad10d809b922ed7376ba2a3539beChris Lattnerstruct ConstantTraits<Constant *> {
406fdfeb6976f07ad10d809b922ed7376ba2a3539beChris Lattner  static unsigned uses(Constant * const & v) {
407fdfeb6976f07ad10d809b922ed7376ba2a3539beChris Lattner    return 1;
408fdfeb6976f07ad10d809b922ed7376ba2a3539beChris Lattner  }
409fdfeb6976f07ad10d809b922ed7376ba2a3539beChris Lattner};
410fdfeb6976f07ad10d809b922ed7376ba2a3539beChris Lattner
411e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate<class ConstantClass, class TypeClass, class ValType>
412e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonstruct ConstantCreator {
413db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  static ConstantClass *create(TypeClass *Ty, const ValType &V) {
414e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V);
415e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
416e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
417e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
4182cb395eae71dacda49ca3fe758618fc3e0701659Talintemplate<class ConstantClass, class TypeClass>
4192cb395eae71dacda49ca3fe758618fc3e0701659Talinstruct ConstantArrayCreator {
4202cb395eae71dacda49ca3fe758618fc3e0701659Talin  static ConstantClass *create(TypeClass *Ty, ArrayRef<Constant*> V) {
4212cb395eae71dacda49ca3fe758618fc3e0701659Talin    return new(V.size()) ConstantClass(Ty, V);
4222cb395eae71dacda49ca3fe758618fc3e0701659Talin  }
4232cb395eae71dacda49ca3fe758618fc3e0701659Talin};
4242cb395eae71dacda49ca3fe758618fc3e0701659Talin
425e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohmantemplate<class ConstantClass>
426e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohmanstruct ConstantKeyData {
427e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman  typedef void ValType;
428e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman  static ValType getValType(ConstantClass *C) {
429e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman    llvm_unreachable("Unknown Constant type!");
430e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
431e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
432e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
433e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate<>
434e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonstruct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
435db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  static ConstantExpr *create(Type *Ty, const ExprMapKeyType &V,
436e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      unsigned short pred = 0) {
437e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (Instruction::isCast(V.opcode))
438e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
439e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if ((V.opcode >= Instruction::BinaryOpsBegin &&
440e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson         V.opcode < Instruction::BinaryOpsEnd))
441f8dbee7cea072eb63ae343759975109553697bcbDan Gohman      return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1],
442f8dbee7cea072eb63ae343759975109553697bcbDan Gohman                                    V.subclassoptionaldata);
443e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (V.opcode == Instruction::Select)
444e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      return new SelectConstantExpr(V.operands[0], V.operands[1],
445e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                                    V.operands[2]);
446e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (V.opcode == Instruction::ExtractElement)
447e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      return new ExtractElementConstantExpr(V.operands[0], V.operands[1]);
448e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (V.opcode == Instruction::InsertElement)
449e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      return new InsertElementConstantExpr(V.operands[0], V.operands[1],
450e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                                           V.operands[2]);
451e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (V.opcode == Instruction::ShuffleVector)
452e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
453e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                                           V.operands[2]);
454e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (V.opcode == Instruction::InsertValue)
455e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      return new InsertValueConstantExpr(V.operands[0], V.operands[1],
456e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                                         V.indices, Ty);
457e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (V.opcode == Instruction::ExtractValue)
458e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
459e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (V.opcode == Instruction::GetElementPtr) {
460e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
461f8dbee7cea072eb63ae343759975109553697bcbDan Gohman      return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty,
462f8dbee7cea072eb63ae343759975109553697bcbDan Gohman                                               V.subclassoptionaldata);
463e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    }
464e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
465e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    // The compare instructions are weird. We have to encode the predicate
466e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    // value and it is combined with the instruction opcode by multiplying
467e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    // the opcode by one hundred. We must decode this to get the predicate.
468e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (V.opcode == Instruction::ICmp)
469f8dbee7cea072eb63ae343759975109553697bcbDan Gohman      return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata,
470e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                                     V.operands[0], V.operands[1]);
471e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (V.opcode == Instruction::FCmp)
472f8dbee7cea072eb63ae343759975109553697bcbDan Gohman      return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata,
473e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                                     V.operands[0], V.operands[1]);
474e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    llvm_unreachable("Invalid ConstantExpr!");
475e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
476e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
477e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
478e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersontemplate<>
479e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohmanstruct ConstantKeyData<ConstantExpr> {
480e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman  typedef ExprMapKeyType ValType;
481e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman  static ValType getValType(ConstantExpr *CE) {
482e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman    std::vector<Constant*> Operands;
483e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman    Operands.reserve(CE->getNumOperands());
484e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman    for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
485e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman      Operands.push_back(cast<Constant>(CE->getOperand(i)));
486e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman    return ExprMapKeyType(CE->getOpcode(), Operands,
487e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman        CE->isCompare() ? CE->getPredicate() : 0,
488e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman        CE->getRawSubclassOptionalData(),
489e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman        CE->hasIndices() ?
490d30aa5a1edac5256573e8d76dd155df3d3fdec84Jay Foad          CE->getIndices() : ArrayRef<unsigned>());
491e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
492e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
493e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
494bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskintemplate<>
495bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskinstruct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> {
496db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  static InlineAsm *create(PointerType *Ty, const InlineAsmKeyType &Key) {
497bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    return new InlineAsm(Ty, Key.asm_string, Key.constraints,
49803fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier                         Key.has_side_effects, Key.is_align_stack,
49903fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier                         Key.asm_dialect);
500bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  }
501bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin};
502bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin
503bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskintemplate<>
504bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskinstruct ConstantKeyData<InlineAsm> {
505bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  typedef InlineAsmKeyType ValType;
506bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  static ValType getValType(InlineAsm *Asm) {
507bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin    return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(),
50803fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier                            Asm->hasSideEffects(), Asm->isAlignStack(),
50903fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier                            Asm->getDialect());
510bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin  }
511bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin};
512bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin
5132a4a6fecf0b8c92223f8fdf19545b564b7d3fcdeJay Foadtemplate<class ValType, class ValRefType, class TypeClass, class ConstantClass,
514e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson         bool HasLargeKey = false /*true for arrays and structs*/ >
5151afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattnerclass ConstantUniqueMap {
516e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
517db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  typedef std::pair<TypeClass*, ValType> MapKey;
518e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman  typedef std::map<MapKey, ConstantClass *> MapTy;
519e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman  typedef std::map<ConstantClass *, typename MapTy::iterator> InverseMapTy;
520e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonprivate:
521e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// Map - This is the main map from the element descriptor to the Constants.
522e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// This is the primary way we avoid creating two of the same shape
523e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// constant.
524e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  MapTy Map;
525e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
526e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping
527e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// from the constants to their element in Map.  This is important for
528e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// removal of constants from the array, which would otherwise have to scan
529e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// through the map with very large keys.
530e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  InverseMapTy InverseMap;
531e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
532e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
5339d3627ea27195534242ec8026a9b8c888b85bbbaDevang Patel  typename MapTy::iterator map_begin() { return Map.begin(); }
534e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  typename MapTy::iterator map_end() { return Map.end(); }
5352cd5155c0e8f2448dbdbc9c9cd468e589f9745e9Torok Edwin
5362cd5155c0e8f2448dbdbc9c9cd468e589f9745e9Torok Edwin  void freeConstants() {
5372cd5155c0e8f2448dbdbc9c9cd468e589f9745e9Torok Edwin    for (typename MapTy::iterator I=Map.begin(), E=Map.end();
5382cd5155c0e8f2448dbdbc9c9cd468e589f9745e9Torok Edwin         I != E; ++I) {
539c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey Yasskin      // Asserts that use_empty().
540c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey Yasskin      delete I->second;
5412cd5155c0e8f2448dbdbc9c9cd468e589f9745e9Torok Edwin    }
5422cd5155c0e8f2448dbdbc9c9cd468e589f9745e9Torok Edwin  }
543e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
544e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// InsertOrGetItem - Return an iterator for the specified element.
545e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// If the element exists in the map, the returned iterator points to the
546e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// entry and Exists=true.  If not, the iterator points to the newly
547e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// inserted entry and returns Exists=false.  Newly inserted entries have
548e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// I->second == 0, and should be filled in.
549e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman  typename MapTy::iterator InsertOrGetItem(std::pair<MapKey, ConstantClass *>
550e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                                 &InsertVal,
551e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                                 bool &Exists) {
552e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    std::pair<typename MapTy::iterator, bool> IP = Map.insert(InsertVal);
553e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Exists = !IP.second;
554e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return IP.first;
555e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
556e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
557e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonprivate:
558e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  typename MapTy::iterator FindExistingElement(ConstantClass *CP) {
559e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (HasLargeKey) {
560e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      typename InverseMapTy::iterator IMI = InverseMap.find(CP);
561e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      assert(IMI != InverseMap.end() && IMI->second != Map.end() &&
562e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson             IMI->second->second == CP &&
563e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson             "InverseMap corrupt!");
564e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      return IMI->second;
565e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    }
566e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
567e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    typename MapTy::iterator I =
568db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner      Map.find(MapKey(static_cast<TypeClass*>(CP->getType()),
569e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman                      ConstantKeyData<ConstantClass>::getValType(CP)));
570e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (I == Map.end() || I->second != CP) {
571e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      // FIXME: This should not use a linear scan.  If this gets to be a
572e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      // performance problem, someone should look at this.
573e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      for (I = Map.begin(); I != Map.end() && I->second != CP; ++I)
574e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson        /* empty */;
575e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    }
576e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return I;
577e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
578e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman
579db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  ConstantClass *Create(TypeClass *Ty, ValRefType V,
580e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson                        typename MapTy::iterator I) {
581e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    ConstantClass* Result =
582e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V);
583e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
584e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    assert(Result->getType() == Ty && "Type specified is not correct!");
585e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result));
586e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
587e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (HasLargeKey)  // Remember the reverse mapping if needed.
588e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      InverseMap.insert(std::make_pair(Result, I));
589e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
590e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return Result;
591e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
592e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Andersonpublic:
593e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
594e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// getOrCreate - Return the specified constant from the map, creating it if
595e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// necessary.
596db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) {
597e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    MapKey Lookup(Ty, V);
598e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    ConstantClass* Result = 0;
599e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
600e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    typename MapTy::iterator I = Map.find(Lookup);
601e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    // Is it in the map?
602e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (I != Map.end())
603e3394d4a49db24aa802432e04d1054d83a052ff1Dan Gohman      Result = I->second;
604e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
605e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (!Result) {
606e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      // If no preexisting value, create one now...
607e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      Result = Create(Ty, V, I);
608e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    }
609e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
610e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    return Result;
611e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
612e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
613e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void remove(ConstantClass *CP) {
614e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    typename MapTy::iterator I = FindExistingElement(CP);
615e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    assert(I != Map.end() && "Constant not found in constant table!");
616e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    assert(I->second == CP && "Didn't find correct element?");
617e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
618e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (HasLargeKey)  // Remember the reverse mapping if needed.
619e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      InverseMap.erase(CP);
620e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
621e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Map.erase(I);
622e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
623e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
624e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// MoveConstantToNewSlot - If we are about to change C to be the element
625e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// specified by I, update our internal data structures to reflect this
626e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  /// fact.
627e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) {
628e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    // First, remove the old location of the specified constant in the map.
629e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    typename MapTy::iterator OldI = FindExistingElement(C);
630e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    assert(OldI != Map.end() && "Constant not found in constant table!");
631e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    assert(OldI->second == C && "Didn't find correct element?");
632e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
6331afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner     // Remove the old entry from the map.
634e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    Map.erase(OldI);
635e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
636e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    // Update the inverse map so that we know that this constant is now
637e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    // located at descriptor I.
638e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    if (HasLargeKey) {
639e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      assert(I->second == C && "Bad inversemap entry!");
640e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson      InverseMap[C] = I;
641e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson    }
642e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
643e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
644e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  void dump() const {
645da23d93d9bb6238757e29b1abee571a0052ab8fcDavid Greene    DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");
646e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson  }
647e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson};
648e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
6492cb395eae71dacda49ca3fe758618fc3e0701659Talin// Unique map for aggregate constants
6502cb395eae71dacda49ca3fe758618fc3e0701659Talintemplate<class TypeClass, class ConstantClass>
6512cb395eae71dacda49ca3fe758618fc3e0701659Talinclass ConstantAggrUniqueMap {
6522cb395eae71dacda49ca3fe758618fc3e0701659Talinpublic:
6532cb395eae71dacda49ca3fe758618fc3e0701659Talin  typedef ArrayRef<Constant*> Operands;
6542cb395eae71dacda49ca3fe758618fc3e0701659Talin  typedef std::pair<TypeClass*, Operands> LookupKey;
6552cb395eae71dacda49ca3fe758618fc3e0701659Talinprivate:
6562cb395eae71dacda49ca3fe758618fc3e0701659Talin  struct MapInfo {
6572cb395eae71dacda49ca3fe758618fc3e0701659Talin    typedef DenseMapInfo<ConstantClass*> ConstantClassInfo;
6582cb395eae71dacda49ca3fe758618fc3e0701659Talin    typedef DenseMapInfo<Constant*> ConstantInfo;
6592cb395eae71dacda49ca3fe758618fc3e0701659Talin    typedef DenseMapInfo<TypeClass*> TypeClassInfo;
6602cb395eae71dacda49ca3fe758618fc3e0701659Talin    static inline ConstantClass* getEmptyKey() {
6612cb395eae71dacda49ca3fe758618fc3e0701659Talin      return ConstantClassInfo::getEmptyKey();
6622cb395eae71dacda49ca3fe758618fc3e0701659Talin    }
6632cb395eae71dacda49ca3fe758618fc3e0701659Talin    static inline ConstantClass* getTombstoneKey() {
6642cb395eae71dacda49ca3fe758618fc3e0701659Talin      return ConstantClassInfo::getTombstoneKey();
6652cb395eae71dacda49ca3fe758618fc3e0701659Talin    }
6662cb395eae71dacda49ca3fe758618fc3e0701659Talin    static unsigned getHashValue(const ConstantClass *CP) {
667eea81f32cdd2f0408aaf83878cf45b5024cf6b57Chandler Carruth      SmallVector<Constant*, 8> CPOperands;
668eea81f32cdd2f0408aaf83878cf45b5024cf6b57Chandler Carruth      CPOperands.reserve(CP->getNumOperands());
6694e3e5dec1a2a479891b4081c1c715a97fd85644dJay Foad      for (unsigned I = 0, E = CP->getNumOperands(); I < E; ++I)
670eea81f32cdd2f0408aaf83878cf45b5024cf6b57Chandler Carruth        CPOperands.push_back(CP->getOperand(I));
671eea81f32cdd2f0408aaf83878cf45b5024cf6b57Chandler Carruth      return getHashValue(LookupKey(CP->getType(), CPOperands));
6722cb395eae71dacda49ca3fe758618fc3e0701659Talin    }
6732cb395eae71dacda49ca3fe758618fc3e0701659Talin    static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) {
6742cb395eae71dacda49ca3fe758618fc3e0701659Talin      return LHS == RHS;
6752cb395eae71dacda49ca3fe758618fc3e0701659Talin    }
6762cb395eae71dacda49ca3fe758618fc3e0701659Talin    static unsigned getHashValue(const LookupKey &Val) {
677eea81f32cdd2f0408aaf83878cf45b5024cf6b57Chandler Carruth      return hash_combine(Val.first, hash_combine_range(Val.second.begin(),
678eea81f32cdd2f0408aaf83878cf45b5024cf6b57Chandler Carruth                                                        Val.second.end()));
6792cb395eae71dacda49ca3fe758618fc3e0701659Talin    }
6802cb395eae71dacda49ca3fe758618fc3e0701659Talin    static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) {
6812cb395eae71dacda49ca3fe758618fc3e0701659Talin      if (RHS == getEmptyKey() || RHS == getTombstoneKey())
6822cb395eae71dacda49ca3fe758618fc3e0701659Talin        return false;
6832cb395eae71dacda49ca3fe758618fc3e0701659Talin      if (LHS.first != RHS->getType()
6842cb395eae71dacda49ca3fe758618fc3e0701659Talin          || LHS.second.size() != RHS->getNumOperands())
6852cb395eae71dacda49ca3fe758618fc3e0701659Talin        return false;
6862cb395eae71dacda49ca3fe758618fc3e0701659Talin      for (unsigned I = 0, E = RHS->getNumOperands(); I < E; ++I) {
6872cb395eae71dacda49ca3fe758618fc3e0701659Talin        if (LHS.second[I] != RHS->getOperand(I))
6882cb395eae71dacda49ca3fe758618fc3e0701659Talin          return false;
6892cb395eae71dacda49ca3fe758618fc3e0701659Talin      }
6902cb395eae71dacda49ca3fe758618fc3e0701659Talin      return true;
6912cb395eae71dacda49ca3fe758618fc3e0701659Talin    }
6922cb395eae71dacda49ca3fe758618fc3e0701659Talin  };
6932cb395eae71dacda49ca3fe758618fc3e0701659Talinpublic:
6942cb395eae71dacda49ca3fe758618fc3e0701659Talin  typedef DenseMap<ConstantClass *, char, MapInfo> MapTy;
6952cb395eae71dacda49ca3fe758618fc3e0701659Talin
6962cb395eae71dacda49ca3fe758618fc3e0701659Talinprivate:
6972cb395eae71dacda49ca3fe758618fc3e0701659Talin  /// Map - This is the main map from the element descriptor to the Constants.
6982cb395eae71dacda49ca3fe758618fc3e0701659Talin  /// This is the primary way we avoid creating two of the same shape
6992cb395eae71dacda49ca3fe758618fc3e0701659Talin  /// constant.
7002cb395eae71dacda49ca3fe758618fc3e0701659Talin  MapTy Map;
7012cb395eae71dacda49ca3fe758618fc3e0701659Talin
7022cb395eae71dacda49ca3fe758618fc3e0701659Talinpublic:
7032cb395eae71dacda49ca3fe758618fc3e0701659Talin  typename MapTy::iterator map_begin() { return Map.begin(); }
7042cb395eae71dacda49ca3fe758618fc3e0701659Talin  typename MapTy::iterator map_end() { return Map.end(); }
7052cb395eae71dacda49ca3fe758618fc3e0701659Talin
7062cb395eae71dacda49ca3fe758618fc3e0701659Talin  void freeConstants() {
7072cb395eae71dacda49ca3fe758618fc3e0701659Talin    for (typename MapTy::iterator I=Map.begin(), E=Map.end();
7082cb395eae71dacda49ca3fe758618fc3e0701659Talin         I != E; ++I) {
7092cb395eae71dacda49ca3fe758618fc3e0701659Talin      // Asserts that use_empty().
7102cb395eae71dacda49ca3fe758618fc3e0701659Talin      delete I->first;
7112cb395eae71dacda49ca3fe758618fc3e0701659Talin    }
7122cb395eae71dacda49ca3fe758618fc3e0701659Talin  }
7132cb395eae71dacda49ca3fe758618fc3e0701659Talin
7142cb395eae71dacda49ca3fe758618fc3e0701659Talinprivate:
7152cb395eae71dacda49ca3fe758618fc3e0701659Talin  typename MapTy::iterator findExistingElement(ConstantClass *CP) {
7162cb395eae71dacda49ca3fe758618fc3e0701659Talin    return Map.find(CP);
7172cb395eae71dacda49ca3fe758618fc3e0701659Talin  }
7182cb395eae71dacda49ca3fe758618fc3e0701659Talin
7192cb395eae71dacda49ca3fe758618fc3e0701659Talin  ConstantClass *Create(TypeClass *Ty, Operands V, typename MapTy::iterator I) {
7202cb395eae71dacda49ca3fe758618fc3e0701659Talin    ConstantClass* Result =
7212cb395eae71dacda49ca3fe758618fc3e0701659Talin      ConstantArrayCreator<ConstantClass,TypeClass>::create(Ty, V);
7222cb395eae71dacda49ca3fe758618fc3e0701659Talin
7232cb395eae71dacda49ca3fe758618fc3e0701659Talin    assert(Result->getType() == Ty && "Type specified is not correct!");
7242cb395eae71dacda49ca3fe758618fc3e0701659Talin    Map[Result] = '\0';
7252cb395eae71dacda49ca3fe758618fc3e0701659Talin
7262cb395eae71dacda49ca3fe758618fc3e0701659Talin    return Result;
7272cb395eae71dacda49ca3fe758618fc3e0701659Talin  }
7282cb395eae71dacda49ca3fe758618fc3e0701659Talinpublic:
7292cb395eae71dacda49ca3fe758618fc3e0701659Talin
7302cb395eae71dacda49ca3fe758618fc3e0701659Talin  /// getOrCreate - Return the specified constant from the map, creating it if
7312cb395eae71dacda49ca3fe758618fc3e0701659Talin  /// necessary.
7322cb395eae71dacda49ca3fe758618fc3e0701659Talin  ConstantClass *getOrCreate(TypeClass *Ty, Operands V) {
7332cb395eae71dacda49ca3fe758618fc3e0701659Talin    LookupKey Lookup(Ty, V);
7342cb395eae71dacda49ca3fe758618fc3e0701659Talin    ConstantClass* Result = 0;
7352cb395eae71dacda49ca3fe758618fc3e0701659Talin
7362cb395eae71dacda49ca3fe758618fc3e0701659Talin    typename MapTy::iterator I = Map.find_as(Lookup);
7372cb395eae71dacda49ca3fe758618fc3e0701659Talin    // Is it in the map?
7382cb395eae71dacda49ca3fe758618fc3e0701659Talin    if (I != Map.end())
7392cb395eae71dacda49ca3fe758618fc3e0701659Talin      Result = I->first;
7402cb395eae71dacda49ca3fe758618fc3e0701659Talin
7412cb395eae71dacda49ca3fe758618fc3e0701659Talin    if (!Result) {
7422cb395eae71dacda49ca3fe758618fc3e0701659Talin      // If no preexisting value, create one now...
7432cb395eae71dacda49ca3fe758618fc3e0701659Talin      Result = Create(Ty, V, I);
7442cb395eae71dacda49ca3fe758618fc3e0701659Talin    }
7452cb395eae71dacda49ca3fe758618fc3e0701659Talin
7462cb395eae71dacda49ca3fe758618fc3e0701659Talin    return Result;
7472cb395eae71dacda49ca3fe758618fc3e0701659Talin  }
7482cb395eae71dacda49ca3fe758618fc3e0701659Talin
7492cb395eae71dacda49ca3fe758618fc3e0701659Talin  /// Find the constant by lookup key.
7502cb395eae71dacda49ca3fe758618fc3e0701659Talin  typename MapTy::iterator find(LookupKey Lookup) {
7512cb395eae71dacda49ca3fe758618fc3e0701659Talin    return Map.find_as(Lookup);
7522cb395eae71dacda49ca3fe758618fc3e0701659Talin  }
7532cb395eae71dacda49ca3fe758618fc3e0701659Talin
7542cb395eae71dacda49ca3fe758618fc3e0701659Talin  /// Insert the constant into its proper slot.
7552cb395eae71dacda49ca3fe758618fc3e0701659Talin  void insert(ConstantClass *CP) {
7562cb395eae71dacda49ca3fe758618fc3e0701659Talin    Map[CP] = '\0';
7572cb395eae71dacda49ca3fe758618fc3e0701659Talin  }
7582cb395eae71dacda49ca3fe758618fc3e0701659Talin
7592cb395eae71dacda49ca3fe758618fc3e0701659Talin  /// Remove this constant from the map
7602cb395eae71dacda49ca3fe758618fc3e0701659Talin  void remove(ConstantClass *CP) {
7612cb395eae71dacda49ca3fe758618fc3e0701659Talin    typename MapTy::iterator I = findExistingElement(CP);
7622cb395eae71dacda49ca3fe758618fc3e0701659Talin    assert(I != Map.end() && "Constant not found in constant table!");
7632cb395eae71dacda49ca3fe758618fc3e0701659Talin    assert(I->first == CP && "Didn't find correct element?");
7642cb395eae71dacda49ca3fe758618fc3e0701659Talin    Map.erase(I);
7652cb395eae71dacda49ca3fe758618fc3e0701659Talin  }
7662cb395eae71dacda49ca3fe758618fc3e0701659Talin
7672cb395eae71dacda49ca3fe758618fc3e0701659Talin  void dump() const {
7682cb395eae71dacda49ca3fe758618fc3e0701659Talin    DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");
7692cb395eae71dacda49ca3fe758618fc3e0701659Talin  }
7702cb395eae71dacda49ca3fe758618fc3e0701659Talin};
7712cb395eae71dacda49ca3fe758618fc3e0701659Talin
772e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson}
773e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson
774e2942c0c7da45686b74e8e8248fd84e98fee435eOwen Anderson#endif
775