1249259Sdim//===-- ConstantsContext.h - Constants-related Context Interals -----------===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim//  This file defines various helper methods and classes used by
11249259Sdim// LLVMContextImpl for creating and managing constants.
12249259Sdim//
13249259Sdim//===----------------------------------------------------------------------===//
14249259Sdim
15249259Sdim#ifndef LLVM_CONSTANTSCONTEXT_H
16249259Sdim#define LLVM_CONSTANTSCONTEXT_H
17249259Sdim
18249259Sdim#include "llvm/ADT/DenseMap.h"
19249259Sdim#include "llvm/ADT/Hashing.h"
20249259Sdim#include "llvm/IR/InlineAsm.h"
21249259Sdim#include "llvm/IR/Instructions.h"
22249259Sdim#include "llvm/IR/Operator.h"
23249259Sdim#include "llvm/Support/Debug.h"
24249259Sdim#include "llvm/Support/ErrorHandling.h"
25249259Sdim#include "llvm/Support/raw_ostream.h"
26249259Sdim#include <map>
27249259Sdim
28249259Sdimnamespace llvm {
29249259Sdimtemplate<class ValType>
30249259Sdimstruct ConstantTraits;
31249259Sdim
32249259Sdim/// UnaryConstantExpr - This class is private to Constants.cpp, and is used
33249259Sdim/// behind the scenes to implement unary constant exprs.
34249259Sdimclass UnaryConstantExpr : public ConstantExpr {
35249259Sdim  virtual void anchor();
36249259Sdim  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
37249259Sdimpublic:
38249259Sdim  // allocate space for exactly one operand
39249259Sdim  void *operator new(size_t s) {
40249259Sdim    return User::operator new(s, 1);
41249259Sdim  }
42249259Sdim  UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
43249259Sdim    : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
44249259Sdim    Op<0>() = C;
45249259Sdim  }
46249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
47249259Sdim};
48249259Sdim
49249259Sdim/// BinaryConstantExpr - This class is private to Constants.cpp, and is used
50249259Sdim/// behind the scenes to implement binary constant exprs.
51249259Sdimclass BinaryConstantExpr : public ConstantExpr {
52249259Sdim  virtual void anchor();
53249259Sdim  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
54249259Sdimpublic:
55249259Sdim  // allocate space for exactly two operands
56249259Sdim  void *operator new(size_t s) {
57249259Sdim    return User::operator new(s, 2);
58249259Sdim  }
59249259Sdim  BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
60249259Sdim                     unsigned Flags)
61249259Sdim    : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
62249259Sdim    Op<0>() = C1;
63249259Sdim    Op<1>() = C2;
64249259Sdim    SubclassOptionalData = Flags;
65249259Sdim  }
66249259Sdim  /// Transparently provide more efficient getOperand methods.
67249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
68249259Sdim};
69249259Sdim
70249259Sdim/// SelectConstantExpr - This class is private to Constants.cpp, and is used
71249259Sdim/// behind the scenes to implement select constant exprs.
72249259Sdimclass SelectConstantExpr : public ConstantExpr {
73249259Sdim  virtual void anchor();
74249259Sdim  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
75249259Sdimpublic:
76249259Sdim  // allocate space for exactly three operands
77249259Sdim  void *operator new(size_t s) {
78249259Sdim    return User::operator new(s, 3);
79249259Sdim  }
80249259Sdim  SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
81249259Sdim    : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
82249259Sdim    Op<0>() = C1;
83249259Sdim    Op<1>() = C2;
84249259Sdim    Op<2>() = C3;
85249259Sdim  }
86249259Sdim  /// Transparently provide more efficient getOperand methods.
87249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
88249259Sdim};
89249259Sdim
90249259Sdim/// ExtractElementConstantExpr - This class is private to
91249259Sdim/// Constants.cpp, and is used behind the scenes to implement
92249259Sdim/// extractelement constant exprs.
93249259Sdimclass ExtractElementConstantExpr : public ConstantExpr {
94249259Sdim  virtual void anchor();
95249259Sdim  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
96249259Sdimpublic:
97249259Sdim  // allocate space for exactly two operands
98249259Sdim  void *operator new(size_t s) {
99249259Sdim    return User::operator new(s, 2);
100249259Sdim  }
101249259Sdim  ExtractElementConstantExpr(Constant *C1, Constant *C2)
102249259Sdim    : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
103249259Sdim                   Instruction::ExtractElement, &Op<0>(), 2) {
104249259Sdim    Op<0>() = C1;
105249259Sdim    Op<1>() = C2;
106249259Sdim  }
107249259Sdim  /// Transparently provide more efficient getOperand methods.
108249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
109249259Sdim};
110249259Sdim
111249259Sdim/// InsertElementConstantExpr - This class is private to
112249259Sdim/// Constants.cpp, and is used behind the scenes to implement
113249259Sdim/// insertelement constant exprs.
114249259Sdimclass InsertElementConstantExpr : public ConstantExpr {
115249259Sdim  virtual void anchor();
116249259Sdim  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
117249259Sdimpublic:
118249259Sdim  // allocate space for exactly three operands
119249259Sdim  void *operator new(size_t s) {
120249259Sdim    return User::operator new(s, 3);
121249259Sdim  }
122249259Sdim  InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
123249259Sdim    : ConstantExpr(C1->getType(), Instruction::InsertElement,
124249259Sdim                   &Op<0>(), 3) {
125249259Sdim    Op<0>() = C1;
126249259Sdim    Op<1>() = C2;
127249259Sdim    Op<2>() = C3;
128249259Sdim  }
129249259Sdim  /// Transparently provide more efficient getOperand methods.
130249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
131249259Sdim};
132249259Sdim
133249259Sdim/// ShuffleVectorConstantExpr - This class is private to
134249259Sdim/// Constants.cpp, and is used behind the scenes to implement
135249259Sdim/// shufflevector constant exprs.
136249259Sdimclass ShuffleVectorConstantExpr : public ConstantExpr {
137249259Sdim  virtual void anchor();
138249259Sdim  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
139249259Sdimpublic:
140249259Sdim  // allocate space for exactly three operands
141249259Sdim  void *operator new(size_t s) {
142249259Sdim    return User::operator new(s, 3);
143249259Sdim  }
144249259Sdim  ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
145249259Sdim  : ConstantExpr(VectorType::get(
146249259Sdim                   cast<VectorType>(C1->getType())->getElementType(),
147249259Sdim                   cast<VectorType>(C3->getType())->getNumElements()),
148249259Sdim                 Instruction::ShuffleVector,
149249259Sdim                 &Op<0>(), 3) {
150249259Sdim    Op<0>() = C1;
151249259Sdim    Op<1>() = C2;
152249259Sdim    Op<2>() = C3;
153249259Sdim  }
154249259Sdim  /// Transparently provide more efficient getOperand methods.
155249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
156249259Sdim};
157249259Sdim
158249259Sdim/// ExtractValueConstantExpr - This class is private to
159249259Sdim/// Constants.cpp, and is used behind the scenes to implement
160249259Sdim/// extractvalue constant exprs.
161249259Sdimclass ExtractValueConstantExpr : public ConstantExpr {
162249259Sdim  virtual void anchor();
163249259Sdim  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
164249259Sdimpublic:
165249259Sdim  // allocate space for exactly one operand
166249259Sdim  void *operator new(size_t s) {
167249259Sdim    return User::operator new(s, 1);
168249259Sdim  }
169249259Sdim  ExtractValueConstantExpr(Constant *Agg,
170249259Sdim                           const SmallVector<unsigned, 4> &IdxList,
171249259Sdim                           Type *DestTy)
172249259Sdim    : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
173249259Sdim      Indices(IdxList) {
174249259Sdim    Op<0>() = Agg;
175249259Sdim  }
176249259Sdim
177249259Sdim  /// Indices - These identify which value to extract.
178249259Sdim  const SmallVector<unsigned, 4> Indices;
179249259Sdim
180249259Sdim  /// Transparently provide more efficient getOperand methods.
181249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
182249259Sdim};
183249259Sdim
184249259Sdim/// InsertValueConstantExpr - This class is private to
185249259Sdim/// Constants.cpp, and is used behind the scenes to implement
186249259Sdim/// insertvalue constant exprs.
187249259Sdimclass InsertValueConstantExpr : public ConstantExpr {
188249259Sdim  virtual void anchor();
189249259Sdim  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
190249259Sdimpublic:
191249259Sdim  // allocate space for exactly one operand
192249259Sdim  void *operator new(size_t s) {
193249259Sdim    return User::operator new(s, 2);
194249259Sdim  }
195249259Sdim  InsertValueConstantExpr(Constant *Agg, Constant *Val,
196249259Sdim                          const SmallVector<unsigned, 4> &IdxList,
197249259Sdim                          Type *DestTy)
198249259Sdim    : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
199249259Sdim      Indices(IdxList) {
200249259Sdim    Op<0>() = Agg;
201249259Sdim    Op<1>() = Val;
202249259Sdim  }
203249259Sdim
204249259Sdim  /// Indices - These identify the position for the insertion.
205249259Sdim  const SmallVector<unsigned, 4> Indices;
206249259Sdim
207249259Sdim  /// Transparently provide more efficient getOperand methods.
208249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
209249259Sdim};
210249259Sdim
211249259Sdim
212249259Sdim/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
213249259Sdim/// used behind the scenes to implement getelementpr constant exprs.
214249259Sdimclass GetElementPtrConstantExpr : public ConstantExpr {
215249259Sdim  virtual void anchor();
216249259Sdim  GetElementPtrConstantExpr(Constant *C, ArrayRef<Constant*> IdxList,
217249259Sdim                            Type *DestTy);
218249259Sdimpublic:
219249259Sdim  static GetElementPtrConstantExpr *Create(Constant *C,
220249259Sdim                                           ArrayRef<Constant*> IdxList,
221249259Sdim                                           Type *DestTy,
222249259Sdim                                           unsigned Flags) {
223249259Sdim    GetElementPtrConstantExpr *Result =
224249259Sdim      new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
225249259Sdim    Result->SubclassOptionalData = Flags;
226249259Sdim    return Result;
227249259Sdim  }
228249259Sdim  /// Transparently provide more efficient getOperand methods.
229249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
230249259Sdim};
231249259Sdim
232249259Sdim// CompareConstantExpr - This class is private to Constants.cpp, and is used
233249259Sdim// behind the scenes to implement ICmp and FCmp constant expressions. This is
234249259Sdim// needed in order to store the predicate value for these instructions.
235249259Sdimclass CompareConstantExpr : public ConstantExpr {
236249259Sdim  virtual void anchor();
237249259Sdim  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
238249259Sdimpublic:
239249259Sdim  // allocate space for exactly two operands
240249259Sdim  void *operator new(size_t s) {
241249259Sdim    return User::operator new(s, 2);
242249259Sdim  }
243249259Sdim  unsigned short predicate;
244249259Sdim  CompareConstantExpr(Type *ty, Instruction::OtherOps opc,
245249259Sdim                      unsigned short pred,  Constant* LHS, Constant* RHS)
246249259Sdim    : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
247249259Sdim    Op<0>() = LHS;
248249259Sdim    Op<1>() = RHS;
249249259Sdim  }
250249259Sdim  /// Transparently provide more efficient getOperand methods.
251249259Sdim  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
252249259Sdim};
253249259Sdim
254249259Sdimtemplate <>
255249259Sdimstruct OperandTraits<UnaryConstantExpr> :
256249259Sdim  public FixedNumOperandTraits<UnaryConstantExpr, 1> {
257249259Sdim};
258249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
259249259Sdim
260249259Sdimtemplate <>
261249259Sdimstruct OperandTraits<BinaryConstantExpr> :
262249259Sdim  public FixedNumOperandTraits<BinaryConstantExpr, 2> {
263249259Sdim};
264249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
265249259Sdim
266249259Sdimtemplate <>
267249259Sdimstruct OperandTraits<SelectConstantExpr> :
268249259Sdim  public FixedNumOperandTraits<SelectConstantExpr, 3> {
269249259Sdim};
270249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
271249259Sdim
272249259Sdimtemplate <>
273249259Sdimstruct OperandTraits<ExtractElementConstantExpr> :
274249259Sdim  public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {
275249259Sdim};
276249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
277249259Sdim
278249259Sdimtemplate <>
279249259Sdimstruct OperandTraits<InsertElementConstantExpr> :
280249259Sdim  public FixedNumOperandTraits<InsertElementConstantExpr, 3> {
281249259Sdim};
282249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
283249259Sdim
284249259Sdimtemplate <>
285249259Sdimstruct OperandTraits<ShuffleVectorConstantExpr> :
286249259Sdim    public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {
287249259Sdim};
288249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
289249259Sdim
290249259Sdimtemplate <>
291249259Sdimstruct OperandTraits<ExtractValueConstantExpr> :
292249259Sdim  public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {
293249259Sdim};
294249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
295249259Sdim
296249259Sdimtemplate <>
297249259Sdimstruct OperandTraits<InsertValueConstantExpr> :
298249259Sdim  public FixedNumOperandTraits<InsertValueConstantExpr, 2> {
299249259Sdim};
300249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
301249259Sdim
302249259Sdimtemplate <>
303249259Sdimstruct OperandTraits<GetElementPtrConstantExpr> :
304249259Sdim  public VariadicOperandTraits<GetElementPtrConstantExpr, 1> {
305249259Sdim};
306249259Sdim
307249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
308249259Sdim
309249259Sdim
310249259Sdimtemplate <>
311249259Sdimstruct OperandTraits<CompareConstantExpr> :
312249259Sdim  public FixedNumOperandTraits<CompareConstantExpr, 2> {
313249259Sdim};
314249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
315249259Sdim
316249259Sdimstruct ExprMapKeyType {
317249259Sdim  ExprMapKeyType(unsigned opc,
318249259Sdim      ArrayRef<Constant*> ops,
319249259Sdim      unsigned short flags = 0,
320249259Sdim      unsigned short optionalflags = 0,
321251662Sdim      ArrayRef<unsigned> inds = None)
322249259Sdim        : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
323249259Sdim        operands(ops.begin(), ops.end()), indices(inds.begin(), inds.end()) {}
324249259Sdim  uint8_t opcode;
325249259Sdim  uint8_t subclassoptionaldata;
326249259Sdim  uint16_t subclassdata;
327249259Sdim  std::vector<Constant*> operands;
328249259Sdim  SmallVector<unsigned, 4> indices;
329249259Sdim  bool operator==(const ExprMapKeyType& that) const {
330249259Sdim    return this->opcode == that.opcode &&
331249259Sdim           this->subclassdata == that.subclassdata &&
332249259Sdim           this->subclassoptionaldata == that.subclassoptionaldata &&
333249259Sdim           this->operands == that.operands &&
334249259Sdim           this->indices == that.indices;
335249259Sdim  }
336249259Sdim  bool operator<(const ExprMapKeyType & that) const {
337249259Sdim    if (this->opcode != that.opcode) return this->opcode < that.opcode;
338249259Sdim    if (this->operands != that.operands) return this->operands < that.operands;
339249259Sdim    if (this->subclassdata != that.subclassdata)
340249259Sdim      return this->subclassdata < that.subclassdata;
341249259Sdim    if (this->subclassoptionaldata != that.subclassoptionaldata)
342249259Sdim      return this->subclassoptionaldata < that.subclassoptionaldata;
343249259Sdim    if (this->indices != that.indices) return this->indices < that.indices;
344249259Sdim    return false;
345249259Sdim  }
346249259Sdim
347249259Sdim  bool operator!=(const ExprMapKeyType& that) const {
348249259Sdim    return !(*this == that);
349249259Sdim  }
350249259Sdim};
351249259Sdim
352249259Sdimstruct InlineAsmKeyType {
353249259Sdim  InlineAsmKeyType(StringRef AsmString,
354249259Sdim                   StringRef Constraints, bool hasSideEffects,
355249259Sdim                   bool isAlignStack, InlineAsm::AsmDialect asmDialect)
356249259Sdim    : asm_string(AsmString), constraints(Constraints),
357249259Sdim      has_side_effects(hasSideEffects), is_align_stack(isAlignStack),
358249259Sdim      asm_dialect(asmDialect) {}
359249259Sdim  std::string asm_string;
360249259Sdim  std::string constraints;
361249259Sdim  bool has_side_effects;
362249259Sdim  bool is_align_stack;
363249259Sdim  InlineAsm::AsmDialect asm_dialect;
364249259Sdim  bool operator==(const InlineAsmKeyType& that) const {
365249259Sdim    return this->asm_string == that.asm_string &&
366249259Sdim           this->constraints == that.constraints &&
367249259Sdim           this->has_side_effects == that.has_side_effects &&
368249259Sdim           this->is_align_stack == that.is_align_stack &&
369249259Sdim           this->asm_dialect == that.asm_dialect;
370249259Sdim  }
371249259Sdim  bool operator<(const InlineAsmKeyType& that) const {
372249259Sdim    if (this->asm_string != that.asm_string)
373249259Sdim      return this->asm_string < that.asm_string;
374249259Sdim    if (this->constraints != that.constraints)
375249259Sdim      return this->constraints < that.constraints;
376249259Sdim    if (this->has_side_effects != that.has_side_effects)
377249259Sdim      return this->has_side_effects < that.has_side_effects;
378249259Sdim    if (this->is_align_stack != that.is_align_stack)
379249259Sdim      return this->is_align_stack < that.is_align_stack;
380249259Sdim    if (this->asm_dialect != that.asm_dialect)
381249259Sdim      return this->asm_dialect < that.asm_dialect;
382249259Sdim    return false;
383249259Sdim  }
384249259Sdim
385249259Sdim  bool operator!=(const InlineAsmKeyType& that) const {
386249259Sdim    return !(*this == that);
387249259Sdim  }
388249259Sdim};
389249259Sdim
390249259Sdim// The number of operands for each ConstantCreator::create method is
391249259Sdim// determined by the ConstantTraits template.
392249259Sdim// ConstantCreator - A class that is used to create constants by
393249259Sdim// ConstantUniqueMap*.  This class should be partially specialized if there is
394249259Sdim// something strange that needs to be done to interface to the ctor for the
395249259Sdim// constant.
396249259Sdim//
397249259Sdimtemplate<typename T, typename Alloc>
398249259Sdimstruct ConstantTraits< std::vector<T, Alloc> > {
399249259Sdim  static unsigned uses(const std::vector<T, Alloc>& v) {
400249259Sdim    return v.size();
401249259Sdim  }
402249259Sdim};
403249259Sdim
404249259Sdimtemplate<>
405249259Sdimstruct ConstantTraits<Constant *> {
406249259Sdim  static unsigned uses(Constant * const & v) {
407249259Sdim    return 1;
408249259Sdim  }
409249259Sdim};
410249259Sdim
411249259Sdimtemplate<class ConstantClass, class TypeClass, class ValType>
412249259Sdimstruct ConstantCreator {
413249259Sdim  static ConstantClass *create(TypeClass *Ty, const ValType &V) {
414249259Sdim    return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V);
415249259Sdim  }
416249259Sdim};
417249259Sdim
418249259Sdimtemplate<class ConstantClass, class TypeClass>
419249259Sdimstruct ConstantArrayCreator {
420249259Sdim  static ConstantClass *create(TypeClass *Ty, ArrayRef<Constant*> V) {
421249259Sdim    return new(V.size()) ConstantClass(Ty, V);
422249259Sdim  }
423249259Sdim};
424249259Sdim
425249259Sdimtemplate<class ConstantClass>
426249259Sdimstruct ConstantKeyData {
427249259Sdim  typedef void ValType;
428249259Sdim  static ValType getValType(ConstantClass *C) {
429249259Sdim    llvm_unreachable("Unknown Constant type!");
430249259Sdim  }
431249259Sdim};
432249259Sdim
433249259Sdimtemplate<>
434249259Sdimstruct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
435249259Sdim  static ConstantExpr *create(Type *Ty, const ExprMapKeyType &V,
436249259Sdim      unsigned short pred = 0) {
437249259Sdim    if (Instruction::isCast(V.opcode))
438249259Sdim      return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
439249259Sdim    if ((V.opcode >= Instruction::BinaryOpsBegin &&
440249259Sdim         V.opcode < Instruction::BinaryOpsEnd))
441249259Sdim      return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1],
442249259Sdim                                    V.subclassoptionaldata);
443249259Sdim    if (V.opcode == Instruction::Select)
444249259Sdim      return new SelectConstantExpr(V.operands[0], V.operands[1],
445249259Sdim                                    V.operands[2]);
446249259Sdim    if (V.opcode == Instruction::ExtractElement)
447249259Sdim      return new ExtractElementConstantExpr(V.operands[0], V.operands[1]);
448249259Sdim    if (V.opcode == Instruction::InsertElement)
449249259Sdim      return new InsertElementConstantExpr(V.operands[0], V.operands[1],
450249259Sdim                                           V.operands[2]);
451249259Sdim    if (V.opcode == Instruction::ShuffleVector)
452249259Sdim      return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
453249259Sdim                                           V.operands[2]);
454249259Sdim    if (V.opcode == Instruction::InsertValue)
455249259Sdim      return new InsertValueConstantExpr(V.operands[0], V.operands[1],
456249259Sdim                                         V.indices, Ty);
457249259Sdim    if (V.opcode == Instruction::ExtractValue)
458249259Sdim      return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
459249259Sdim    if (V.opcode == Instruction::GetElementPtr) {
460249259Sdim      std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
461249259Sdim      return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty,
462249259Sdim                                               V.subclassoptionaldata);
463249259Sdim    }
464249259Sdim
465249259Sdim    // The compare instructions are weird. We have to encode the predicate
466249259Sdim    // value and it is combined with the instruction opcode by multiplying
467249259Sdim    // the opcode by one hundred. We must decode this to get the predicate.
468249259Sdim    if (V.opcode == Instruction::ICmp)
469249259Sdim      return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata,
470249259Sdim                                     V.operands[0], V.operands[1]);
471249259Sdim    if (V.opcode == Instruction::FCmp)
472249259Sdim      return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata,
473249259Sdim                                     V.operands[0], V.operands[1]);
474249259Sdim    llvm_unreachable("Invalid ConstantExpr!");
475249259Sdim  }
476249259Sdim};
477249259Sdim
478249259Sdimtemplate<>
479249259Sdimstruct ConstantKeyData<ConstantExpr> {
480249259Sdim  typedef ExprMapKeyType ValType;
481249259Sdim  static ValType getValType(ConstantExpr *CE) {
482249259Sdim    std::vector<Constant*> Operands;
483249259Sdim    Operands.reserve(CE->getNumOperands());
484249259Sdim    for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
485249259Sdim      Operands.push_back(cast<Constant>(CE->getOperand(i)));
486249259Sdim    return ExprMapKeyType(CE->getOpcode(), Operands,
487249259Sdim        CE->isCompare() ? CE->getPredicate() : 0,
488249259Sdim        CE->getRawSubclassOptionalData(),
489249259Sdim        CE->hasIndices() ?
490249259Sdim          CE->getIndices() : ArrayRef<unsigned>());
491249259Sdim  }
492249259Sdim};
493249259Sdim
494249259Sdimtemplate<>
495249259Sdimstruct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> {
496249259Sdim  static InlineAsm *create(PointerType *Ty, const InlineAsmKeyType &Key) {
497249259Sdim    return new InlineAsm(Ty, Key.asm_string, Key.constraints,
498249259Sdim                         Key.has_side_effects, Key.is_align_stack,
499249259Sdim                         Key.asm_dialect);
500249259Sdim  }
501249259Sdim};
502249259Sdim
503249259Sdimtemplate<>
504249259Sdimstruct ConstantKeyData<InlineAsm> {
505249259Sdim  typedef InlineAsmKeyType ValType;
506249259Sdim  static ValType getValType(InlineAsm *Asm) {
507249259Sdim    return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(),
508249259Sdim                            Asm->hasSideEffects(), Asm->isAlignStack(),
509249259Sdim                            Asm->getDialect());
510249259Sdim  }
511249259Sdim};
512249259Sdim
513249259Sdimtemplate<class ValType, class ValRefType, class TypeClass, class ConstantClass,
514249259Sdim         bool HasLargeKey = false /*true for arrays and structs*/ >
515249259Sdimclass ConstantUniqueMap {
516249259Sdimpublic:
517249259Sdim  typedef std::pair<TypeClass*, ValType> MapKey;
518249259Sdim  typedef std::map<MapKey, ConstantClass *> MapTy;
519249259Sdim  typedef std::map<ConstantClass *, typename MapTy::iterator> InverseMapTy;
520249259Sdimprivate:
521249259Sdim  /// Map - This is the main map from the element descriptor to the Constants.
522249259Sdim  /// This is the primary way we avoid creating two of the same shape
523249259Sdim  /// constant.
524249259Sdim  MapTy Map;
525249259Sdim
526249259Sdim  /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping
527249259Sdim  /// from the constants to their element in Map.  This is important for
528249259Sdim  /// removal of constants from the array, which would otherwise have to scan
529249259Sdim  /// through the map with very large keys.
530249259Sdim  InverseMapTy InverseMap;
531249259Sdim
532249259Sdimpublic:
533249259Sdim  typename MapTy::iterator map_begin() { return Map.begin(); }
534249259Sdim  typename MapTy::iterator map_end() { return Map.end(); }
535249259Sdim
536249259Sdim  void freeConstants() {
537249259Sdim    for (typename MapTy::iterator I=Map.begin(), E=Map.end();
538249259Sdim         I != E; ++I) {
539249259Sdim      // Asserts that use_empty().
540249259Sdim      delete I->second;
541249259Sdim    }
542249259Sdim  }
543249259Sdim
544249259Sdim  /// InsertOrGetItem - Return an iterator for the specified element.
545249259Sdim  /// If the element exists in the map, the returned iterator points to the
546249259Sdim  /// entry and Exists=true.  If not, the iterator points to the newly
547249259Sdim  /// inserted entry and returns Exists=false.  Newly inserted entries have
548249259Sdim  /// I->second == 0, and should be filled in.
549249259Sdim  typename MapTy::iterator InsertOrGetItem(std::pair<MapKey, ConstantClass *>
550249259Sdim                                 &InsertVal,
551249259Sdim                                 bool &Exists) {
552249259Sdim    std::pair<typename MapTy::iterator, bool> IP = Map.insert(InsertVal);
553249259Sdim    Exists = !IP.second;
554249259Sdim    return IP.first;
555249259Sdim  }
556249259Sdim
557249259Sdimprivate:
558249259Sdim  typename MapTy::iterator FindExistingElement(ConstantClass *CP) {
559249259Sdim    if (HasLargeKey) {
560249259Sdim      typename InverseMapTy::iterator IMI = InverseMap.find(CP);
561249259Sdim      assert(IMI != InverseMap.end() && IMI->second != Map.end() &&
562249259Sdim             IMI->second->second == CP &&
563249259Sdim             "InverseMap corrupt!");
564249259Sdim      return IMI->second;
565249259Sdim    }
566249259Sdim
567249259Sdim    typename MapTy::iterator I =
568249259Sdim      Map.find(MapKey(static_cast<TypeClass*>(CP->getType()),
569249259Sdim                      ConstantKeyData<ConstantClass>::getValType(CP)));
570249259Sdim    if (I == Map.end() || I->second != CP) {
571249259Sdim      // FIXME: This should not use a linear scan.  If this gets to be a
572249259Sdim      // performance problem, someone should look at this.
573249259Sdim      for (I = Map.begin(); I != Map.end() && I->second != CP; ++I)
574249259Sdim        /* empty */;
575249259Sdim    }
576249259Sdim    return I;
577249259Sdim  }
578249259Sdim
579249259Sdim  ConstantClass *Create(TypeClass *Ty, ValRefType V,
580249259Sdim                        typename MapTy::iterator I) {
581249259Sdim    ConstantClass* Result =
582249259Sdim      ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V);
583249259Sdim
584249259Sdim    assert(Result->getType() == Ty && "Type specified is not correct!");
585249259Sdim    I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result));
586249259Sdim
587249259Sdim    if (HasLargeKey)  // Remember the reverse mapping if needed.
588249259Sdim      InverseMap.insert(std::make_pair(Result, I));
589249259Sdim
590249259Sdim    return Result;
591249259Sdim  }
592249259Sdimpublic:
593249259Sdim
594249259Sdim  /// getOrCreate - Return the specified constant from the map, creating it if
595249259Sdim  /// necessary.
596249259Sdim  ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) {
597249259Sdim    MapKey Lookup(Ty, V);
598249259Sdim    ConstantClass* Result = 0;
599249259Sdim
600249259Sdim    typename MapTy::iterator I = Map.find(Lookup);
601249259Sdim    // Is it in the map?
602249259Sdim    if (I != Map.end())
603249259Sdim      Result = I->second;
604249259Sdim
605249259Sdim    if (!Result) {
606249259Sdim      // If no preexisting value, create one now...
607249259Sdim      Result = Create(Ty, V, I);
608249259Sdim    }
609249259Sdim
610249259Sdim    return Result;
611249259Sdim  }
612249259Sdim
613249259Sdim  void remove(ConstantClass *CP) {
614249259Sdim    typename MapTy::iterator I = FindExistingElement(CP);
615249259Sdim    assert(I != Map.end() && "Constant not found in constant table!");
616249259Sdim    assert(I->second == CP && "Didn't find correct element?");
617249259Sdim
618249259Sdim    if (HasLargeKey)  // Remember the reverse mapping if needed.
619249259Sdim      InverseMap.erase(CP);
620249259Sdim
621249259Sdim    Map.erase(I);
622249259Sdim  }
623249259Sdim
624249259Sdim  /// MoveConstantToNewSlot - If we are about to change C to be the element
625249259Sdim  /// specified by I, update our internal data structures to reflect this
626249259Sdim  /// fact.
627249259Sdim  void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) {
628249259Sdim    // First, remove the old location of the specified constant in the map.
629249259Sdim    typename MapTy::iterator OldI = FindExistingElement(C);
630249259Sdim    assert(OldI != Map.end() && "Constant not found in constant table!");
631249259Sdim    assert(OldI->second == C && "Didn't find correct element?");
632249259Sdim
633249259Sdim     // Remove the old entry from the map.
634249259Sdim    Map.erase(OldI);
635249259Sdim
636249259Sdim    // Update the inverse map so that we know that this constant is now
637249259Sdim    // located at descriptor I.
638249259Sdim    if (HasLargeKey) {
639249259Sdim      assert(I->second == C && "Bad inversemap entry!");
640249259Sdim      InverseMap[C] = I;
641249259Sdim    }
642249259Sdim  }
643249259Sdim
644249259Sdim  void dump() const {
645249259Sdim    DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");
646249259Sdim  }
647249259Sdim};
648249259Sdim
649249259Sdim// Unique map for aggregate constants
650249259Sdimtemplate<class TypeClass, class ConstantClass>
651249259Sdimclass ConstantAggrUniqueMap {
652249259Sdimpublic:
653249259Sdim  typedef ArrayRef<Constant*> Operands;
654249259Sdim  typedef std::pair<TypeClass*, Operands> LookupKey;
655249259Sdimprivate:
656249259Sdim  struct MapInfo {
657249259Sdim    typedef DenseMapInfo<ConstantClass*> ConstantClassInfo;
658249259Sdim    typedef DenseMapInfo<Constant*> ConstantInfo;
659249259Sdim    typedef DenseMapInfo<TypeClass*> TypeClassInfo;
660249259Sdim    static inline ConstantClass* getEmptyKey() {
661249259Sdim      return ConstantClassInfo::getEmptyKey();
662249259Sdim    }
663249259Sdim    static inline ConstantClass* getTombstoneKey() {
664249259Sdim      return ConstantClassInfo::getTombstoneKey();
665249259Sdim    }
666249259Sdim    static unsigned getHashValue(const ConstantClass *CP) {
667249259Sdim      SmallVector<Constant*, 8> CPOperands;
668249259Sdim      CPOperands.reserve(CP->getNumOperands());
669249259Sdim      for (unsigned I = 0, E = CP->getNumOperands(); I < E; ++I)
670249259Sdim        CPOperands.push_back(CP->getOperand(I));
671249259Sdim      return getHashValue(LookupKey(CP->getType(), CPOperands));
672249259Sdim    }
673249259Sdim    static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) {
674249259Sdim      return LHS == RHS;
675249259Sdim    }
676249259Sdim    static unsigned getHashValue(const LookupKey &Val) {
677249259Sdim      return hash_combine(Val.first, hash_combine_range(Val.second.begin(),
678249259Sdim                                                        Val.second.end()));
679249259Sdim    }
680249259Sdim    static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) {
681249259Sdim      if (RHS == getEmptyKey() || RHS == getTombstoneKey())
682249259Sdim        return false;
683249259Sdim      if (LHS.first != RHS->getType()
684249259Sdim          || LHS.second.size() != RHS->getNumOperands())
685249259Sdim        return false;
686249259Sdim      for (unsigned I = 0, E = RHS->getNumOperands(); I < E; ++I) {
687249259Sdim        if (LHS.second[I] != RHS->getOperand(I))
688249259Sdim          return false;
689249259Sdim      }
690249259Sdim      return true;
691249259Sdim    }
692249259Sdim  };
693249259Sdimpublic:
694249259Sdim  typedef DenseMap<ConstantClass *, char, MapInfo> MapTy;
695249259Sdim
696249259Sdimprivate:
697249259Sdim  /// Map - This is the main map from the element descriptor to the Constants.
698249259Sdim  /// This is the primary way we avoid creating two of the same shape
699249259Sdim  /// constant.
700249259Sdim  MapTy Map;
701249259Sdim
702249259Sdimpublic:
703249259Sdim  typename MapTy::iterator map_begin() { return Map.begin(); }
704249259Sdim  typename MapTy::iterator map_end() { return Map.end(); }
705249259Sdim
706249259Sdim  void freeConstants() {
707249259Sdim    for (typename MapTy::iterator I=Map.begin(), E=Map.end();
708249259Sdim         I != E; ++I) {
709249259Sdim      // Asserts that use_empty().
710249259Sdim      delete I->first;
711249259Sdim    }
712249259Sdim  }
713249259Sdim
714249259Sdimprivate:
715249259Sdim  typename MapTy::iterator findExistingElement(ConstantClass *CP) {
716249259Sdim    return Map.find(CP);
717249259Sdim  }
718249259Sdim
719249259Sdim  ConstantClass *Create(TypeClass *Ty, Operands V, typename MapTy::iterator I) {
720249259Sdim    ConstantClass* Result =
721249259Sdim      ConstantArrayCreator<ConstantClass,TypeClass>::create(Ty, V);
722249259Sdim
723249259Sdim    assert(Result->getType() == Ty && "Type specified is not correct!");
724249259Sdim    Map[Result] = '\0';
725249259Sdim
726249259Sdim    return Result;
727249259Sdim  }
728249259Sdimpublic:
729249259Sdim
730249259Sdim  /// getOrCreate - Return the specified constant from the map, creating it if
731249259Sdim  /// necessary.
732249259Sdim  ConstantClass *getOrCreate(TypeClass *Ty, Operands V) {
733249259Sdim    LookupKey Lookup(Ty, V);
734249259Sdim    ConstantClass* Result = 0;
735249259Sdim
736249259Sdim    typename MapTy::iterator I = Map.find_as(Lookup);
737249259Sdim    // Is it in the map?
738249259Sdim    if (I != Map.end())
739249259Sdim      Result = I->first;
740249259Sdim
741249259Sdim    if (!Result) {
742249259Sdim      // If no preexisting value, create one now...
743249259Sdim      Result = Create(Ty, V, I);
744249259Sdim    }
745249259Sdim
746249259Sdim    return Result;
747249259Sdim  }
748249259Sdim
749249259Sdim  /// Find the constant by lookup key.
750249259Sdim  typename MapTy::iterator find(LookupKey Lookup) {
751249259Sdim    return Map.find_as(Lookup);
752249259Sdim  }
753249259Sdim
754249259Sdim  /// Insert the constant into its proper slot.
755249259Sdim  void insert(ConstantClass *CP) {
756249259Sdim    Map[CP] = '\0';
757249259Sdim  }
758249259Sdim
759249259Sdim  /// Remove this constant from the map
760249259Sdim  void remove(ConstantClass *CP) {
761249259Sdim    typename MapTy::iterator I = findExistingElement(CP);
762249259Sdim    assert(I != Map.end() && "Constant not found in constant table!");
763249259Sdim    assert(I->first == CP && "Didn't find correct element?");
764249259Sdim    Map.erase(I);
765249259Sdim  }
766249259Sdim
767249259Sdim  void dump() const {
768249259Sdim    DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");
769249259Sdim  }
770249259Sdim};
771249259Sdim
772249259Sdim}
773249259Sdim
774249259Sdim#endif
775