blob: b7726944a22fcc21e80ed0d5c3186973d3ef3747 [file] [log] [blame]
Owen Anderson3fb4aab2009-08-23 04:24:24 +00001//===-- ConstantsContext.h - Constants-related Context Interals -----------===//
Owen Anderson9b676982009-08-04 22:55:26 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines various helper methods and classes used by
11// LLVMContextImpl for creating and managing constants.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CONSTANTSCONTEXT_H
16#define LLVM_CONSTANTSCONTEXT_H
17
Jeffrey Yasskinade270e2010-03-21 20:37:19 +000018#include "llvm/InlineAsm.h"
Owen Anderson9b676982009-08-04 22:55:26 +000019#include "llvm/Instructions.h"
20#include "llvm/Operator.h"
David Greene338a9032010-01-05 01:34:26 +000021#include "llvm/Support/Debug.h"
Owen Anderson9b676982009-08-04 22:55:26 +000022#include "llvm/Support/ErrorHandling.h"
Chris Lattner34822f62009-08-23 04:44:11 +000023#include "llvm/Support/raw_ostream.h"
Owen Anderson9b676982009-08-04 22:55:26 +000024#include <map>
25
26namespace llvm {
27template<class ValType>
28struct ConstantTraits;
29
30/// UnaryConstantExpr - This class is private to Constants.cpp, and is used
31/// behind the scenes to implement unary constant exprs.
32class UnaryConstantExpr : public ConstantExpr {
David Blaikiea379b1812011-12-20 02:50:00 +000033 virtual void anchor();
Owen Anderson9b676982009-08-04 22:55:26 +000034 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
35public:
36 // allocate space for exactly one operand
37 void *operator new(size_t s) {
38 return User::operator new(s, 1);
39 }
Chris Lattner229907c2011-07-18 04:54:35 +000040 UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
Owen Anderson9b676982009-08-04 22:55:26 +000041 : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
42 Op<0>() = C;
43 }
44 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
45};
46
47/// BinaryConstantExpr - This class is private to Constants.cpp, and is used
48/// behind the scenes to implement binary constant exprs.
49class BinaryConstantExpr : public ConstantExpr {
David Blaikiea379b1812011-12-20 02:50:00 +000050 virtual void anchor();
Owen Anderson9b676982009-08-04 22:55:26 +000051 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
52public:
53 // allocate space for exactly two operands
54 void *operator new(size_t s) {
55 return User::operator new(s, 2);
56 }
Dan Gohman1b849082009-09-07 23:54:19 +000057 BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
58 unsigned Flags)
Owen Anderson9b676982009-08-04 22:55:26 +000059 : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
60 Op<0>() = C1;
61 Op<1>() = C2;
Dan Gohman1b849082009-09-07 23:54:19 +000062 SubclassOptionalData = Flags;
Owen Anderson9b676982009-08-04 22:55:26 +000063 }
64 /// Transparently provide more efficient getOperand methods.
65 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
66};
67
68/// SelectConstantExpr - This class is private to Constants.cpp, and is used
69/// behind the scenes to implement select constant exprs.
70class SelectConstantExpr : public ConstantExpr {
David Blaikiea379b1812011-12-20 02:50:00 +000071 virtual void anchor();
Owen Anderson9b676982009-08-04 22:55:26 +000072 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
73public:
74 // allocate space for exactly three operands
75 void *operator new(size_t s) {
76 return User::operator new(s, 3);
77 }
78 SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
79 : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
80 Op<0>() = C1;
81 Op<1>() = C2;
82 Op<2>() = C3;
83 }
84 /// Transparently provide more efficient getOperand methods.
85 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
86};
87
88/// ExtractElementConstantExpr - This class is private to
89/// Constants.cpp, and is used behind the scenes to implement
90/// extractelement constant exprs.
91class ExtractElementConstantExpr : public ConstantExpr {
David Blaikiea379b1812011-12-20 02:50:00 +000092 virtual void anchor();
Owen Anderson9b676982009-08-04 22:55:26 +000093 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
94public:
95 // allocate space for exactly two operands
96 void *operator new(size_t s) {
97 return User::operator new(s, 2);
98 }
99 ExtractElementConstantExpr(Constant *C1, Constant *C2)
100 : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
101 Instruction::ExtractElement, &Op<0>(), 2) {
102 Op<0>() = C1;
103 Op<1>() = C2;
104 }
105 /// Transparently provide more efficient getOperand methods.
106 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
107};
108
109/// InsertElementConstantExpr - This class is private to
110/// Constants.cpp, and is used behind the scenes to implement
111/// insertelement constant exprs.
112class InsertElementConstantExpr : public ConstantExpr {
David Blaikiea379b1812011-12-20 02:50:00 +0000113 virtual void anchor();
Owen Anderson9b676982009-08-04 22:55:26 +0000114 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
115public:
116 // allocate space for exactly three operands
117 void *operator new(size_t s) {
118 return User::operator new(s, 3);
119 }
120 InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
121 : ConstantExpr(C1->getType(), Instruction::InsertElement,
122 &Op<0>(), 3) {
123 Op<0>() = C1;
124 Op<1>() = C2;
125 Op<2>() = C3;
126 }
127 /// Transparently provide more efficient getOperand methods.
128 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
129};
130
131/// ShuffleVectorConstantExpr - This class is private to
132/// Constants.cpp, and is used behind the scenes to implement
133/// shufflevector constant exprs.
134class ShuffleVectorConstantExpr : public ConstantExpr {
David Blaikiea379b1812011-12-20 02:50:00 +0000135 virtual void anchor();
Owen Anderson9b676982009-08-04 22:55:26 +0000136 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
137public:
138 // allocate space for exactly three operands
139 void *operator new(size_t s) {
140 return User::operator new(s, 3);
141 }
142 ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
143 : ConstantExpr(VectorType::get(
144 cast<VectorType>(C1->getType())->getElementType(),
145 cast<VectorType>(C3->getType())->getNumElements()),
146 Instruction::ShuffleVector,
147 &Op<0>(), 3) {
148 Op<0>() = C1;
149 Op<1>() = C2;
150 Op<2>() = C3;
151 }
152 /// Transparently provide more efficient getOperand methods.
153 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
154};
155
156/// ExtractValueConstantExpr - This class is private to
157/// Constants.cpp, and is used behind the scenes to implement
158/// extractvalue constant exprs.
159class ExtractValueConstantExpr : public ConstantExpr {
David Blaikiea379b1812011-12-20 02:50:00 +0000160 virtual void anchor();
Owen Anderson9b676982009-08-04 22:55:26 +0000161 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
162public:
163 // allocate space for exactly one operand
164 void *operator new(size_t s) {
165 return User::operator new(s, 1);
166 }
167 ExtractValueConstantExpr(Constant *Agg,
168 const SmallVector<unsigned, 4> &IdxList,
Chris Lattner229907c2011-07-18 04:54:35 +0000169 Type *DestTy)
Owen Anderson9b676982009-08-04 22:55:26 +0000170 : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
171 Indices(IdxList) {
172 Op<0>() = Agg;
173 }
174
175 /// Indices - These identify which value to extract.
176 const SmallVector<unsigned, 4> Indices;
177
178 /// Transparently provide more efficient getOperand methods.
179 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
180};
181
182/// InsertValueConstantExpr - This class is private to
183/// Constants.cpp, and is used behind the scenes to implement
184/// insertvalue constant exprs.
185class InsertValueConstantExpr : public ConstantExpr {
David Blaikiea379b1812011-12-20 02:50:00 +0000186 virtual void anchor();
Owen Anderson9b676982009-08-04 22:55:26 +0000187 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
188public:
189 // allocate space for exactly one operand
190 void *operator new(size_t s) {
191 return User::operator new(s, 2);
192 }
193 InsertValueConstantExpr(Constant *Agg, Constant *Val,
194 const SmallVector<unsigned, 4> &IdxList,
Chris Lattner229907c2011-07-18 04:54:35 +0000195 Type *DestTy)
Owen Anderson9b676982009-08-04 22:55:26 +0000196 : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
197 Indices(IdxList) {
198 Op<0>() = Agg;
199 Op<1>() = Val;
200 }
201
202 /// Indices - These identify the position for the insertion.
203 const SmallVector<unsigned, 4> Indices;
204
205 /// Transparently provide more efficient getOperand methods.
206 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
207};
208
209
210/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
211/// used behind the scenes to implement getelementpr constant exprs.
212class GetElementPtrConstantExpr : public ConstantExpr {
David Blaikiea379b1812011-12-20 02:50:00 +0000213 virtual void anchor();
Chris Lattnera474bb22012-01-26 20:40:56 +0000214 GetElementPtrConstantExpr(Constant *C, ArrayRef<Constant*> IdxList,
Chris Lattner229907c2011-07-18 04:54:35 +0000215 Type *DestTy);
Owen Anderson9b676982009-08-04 22:55:26 +0000216public:
217 static GetElementPtrConstantExpr *Create(Constant *C,
Chris Lattnera474bb22012-01-26 20:40:56 +0000218 ArrayRef<Constant*> IdxList,
Chris Lattner229907c2011-07-18 04:54:35 +0000219 Type *DestTy,
Dan Gohman1b849082009-09-07 23:54:19 +0000220 unsigned Flags) {
221 GetElementPtrConstantExpr *Result =
Owen Anderson9b676982009-08-04 22:55:26 +0000222 new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
Dan Gohman1b849082009-09-07 23:54:19 +0000223 Result->SubclassOptionalData = Flags;
224 return Result;
Owen Anderson9b676982009-08-04 22:55:26 +0000225 }
226 /// Transparently provide more efficient getOperand methods.
227 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
228};
229
230// CompareConstantExpr - This class is private to Constants.cpp, and is used
231// behind the scenes to implement ICmp and FCmp constant expressions. This is
232// needed in order to store the predicate value for these instructions.
David Blaikiea379b1812011-12-20 02:50:00 +0000233class CompareConstantExpr : public ConstantExpr {
234 virtual void anchor();
Owen Anderson9b676982009-08-04 22:55:26 +0000235 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
David Blaikiea379b1812011-12-20 02:50:00 +0000236public:
Owen Anderson9b676982009-08-04 22:55:26 +0000237 // allocate space for exactly two operands
238 void *operator new(size_t s) {
239 return User::operator new(s, 2);
240 }
241 unsigned short predicate;
Chris Lattner229907c2011-07-18 04:54:35 +0000242 CompareConstantExpr(Type *ty, Instruction::OtherOps opc,
Owen Anderson9b676982009-08-04 22:55:26 +0000243 unsigned short pred, Constant* LHS, Constant* RHS)
244 : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
245 Op<0>() = LHS;
246 Op<1>() = RHS;
247 }
248 /// Transparently provide more efficient getOperand methods.
249 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
250};
251
252template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000253struct OperandTraits<UnaryConstantExpr> :
254 public FixedNumOperandTraits<UnaryConstantExpr, 1> {
Owen Anderson9b676982009-08-04 22:55:26 +0000255};
256DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
257
258template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000259struct OperandTraits<BinaryConstantExpr> :
260 public FixedNumOperandTraits<BinaryConstantExpr, 2> {
Owen Anderson9b676982009-08-04 22:55:26 +0000261};
262DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
263
264template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000265struct OperandTraits<SelectConstantExpr> :
266 public FixedNumOperandTraits<SelectConstantExpr, 3> {
Owen Anderson9b676982009-08-04 22:55:26 +0000267};
268DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
269
270template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000271struct OperandTraits<ExtractElementConstantExpr> :
272 public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {
Owen Anderson9b676982009-08-04 22:55:26 +0000273};
274DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
275
276template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000277struct OperandTraits<InsertElementConstantExpr> :
278 public FixedNumOperandTraits<InsertElementConstantExpr, 3> {
Owen Anderson9b676982009-08-04 22:55:26 +0000279};
280DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
281
282template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000283struct OperandTraits<ShuffleVectorConstantExpr> :
284 public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {
Owen Anderson9b676982009-08-04 22:55:26 +0000285};
286DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
287
288template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000289struct OperandTraits<ExtractValueConstantExpr> :
290 public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {
Owen Anderson9b676982009-08-04 22:55:26 +0000291};
292DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
293
294template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000295struct OperandTraits<InsertValueConstantExpr> :
296 public FixedNumOperandTraits<InsertValueConstantExpr, 2> {
Owen Anderson9b676982009-08-04 22:55:26 +0000297};
298DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
299
300template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000301struct OperandTraits<GetElementPtrConstantExpr> :
302 public VariadicOperandTraits<GetElementPtrConstantExpr, 1> {
Owen Anderson9b676982009-08-04 22:55:26 +0000303};
304
305DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
306
307
308template <>
Jay Foadc8adf5f2011-01-11 15:07:38 +0000309struct OperandTraits<CompareConstantExpr> :
310 public FixedNumOperandTraits<CompareConstantExpr, 2> {
Owen Anderson9b676982009-08-04 22:55:26 +0000311};
312DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
313
314struct ExprMapKeyType {
Owen Anderson9b676982009-08-04 22:55:26 +0000315 ExprMapKeyType(unsigned opc,
Jay Foad0091fe82011-04-13 15:22:40 +0000316 ArrayRef<Constant*> ops,
Dan Gohman1b849082009-09-07 23:54:19 +0000317 unsigned short flags = 0,
318 unsigned short optionalflags = 0,
Jay Foad0091fe82011-04-13 15:22:40 +0000319 ArrayRef<unsigned> inds = ArrayRef<unsigned>())
Dan Gohman1b849082009-09-07 23:54:19 +0000320 : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
Jay Foad0091fe82011-04-13 15:22:40 +0000321 operands(ops.begin(), ops.end()), indices(inds.begin(), inds.end()) {}
Dan Gohman1b849082009-09-07 23:54:19 +0000322 uint8_t opcode;
323 uint8_t subclassoptionaldata;
324 uint16_t subclassdata;
Owen Anderson9b676982009-08-04 22:55:26 +0000325 std::vector<Constant*> operands;
Jay Foad0091fe82011-04-13 15:22:40 +0000326 SmallVector<unsigned, 4> indices;
Owen Anderson9b676982009-08-04 22:55:26 +0000327 bool operator==(const ExprMapKeyType& that) const {
328 return this->opcode == that.opcode &&
Dan Gohman1b849082009-09-07 23:54:19 +0000329 this->subclassdata == that.subclassdata &&
330 this->subclassoptionaldata == that.subclassoptionaldata &&
Owen Anderson9b676982009-08-04 22:55:26 +0000331 this->operands == that.operands &&
332 this->indices == that.indices;
333 }
334 bool operator<(const ExprMapKeyType & that) const {
Dan Gohman1b849082009-09-07 23:54:19 +0000335 if (this->opcode != that.opcode) return this->opcode < that.opcode;
336 if (this->operands != that.operands) return this->operands < that.operands;
337 if (this->subclassdata != that.subclassdata)
338 return this->subclassdata < that.subclassdata;
339 if (this->subclassoptionaldata != that.subclassoptionaldata)
340 return this->subclassoptionaldata < that.subclassoptionaldata;
341 if (this->indices != that.indices) return this->indices < that.indices;
342 return false;
Owen Anderson9b676982009-08-04 22:55:26 +0000343 }
344
345 bool operator!=(const ExprMapKeyType& that) const {
346 return !(*this == that);
347 }
348};
349
Jeffrey Yasskinade270e2010-03-21 20:37:19 +0000350struct InlineAsmKeyType {
351 InlineAsmKeyType(StringRef AsmString,
352 StringRef Constraints, bool hasSideEffects,
353 bool isAlignStack)
354 : asm_string(AsmString), constraints(Constraints),
355 has_side_effects(hasSideEffects), is_align_stack(isAlignStack) {}
356 std::string asm_string;
357 std::string constraints;
358 bool has_side_effects;
359 bool is_align_stack;
360 bool operator==(const InlineAsmKeyType& that) const {
361 return this->asm_string == that.asm_string &&
362 this->constraints == that.constraints &&
363 this->has_side_effects == that.has_side_effects &&
364 this->is_align_stack == that.is_align_stack;
365 }
366 bool operator<(const InlineAsmKeyType& that) const {
367 if (this->asm_string != that.asm_string)
368 return this->asm_string < that.asm_string;
369 if (this->constraints != that.constraints)
370 return this->constraints < that.constraints;
371 if (this->has_side_effects != that.has_side_effects)
372 return this->has_side_effects < that.has_side_effects;
373 if (this->is_align_stack != that.is_align_stack)
374 return this->is_align_stack < that.is_align_stack;
375 return false;
376 }
377
378 bool operator!=(const InlineAsmKeyType& that) const {
379 return !(*this == that);
380 }
381};
382
Owen Anderson9b676982009-08-04 22:55:26 +0000383// The number of operands for each ConstantCreator::create method is
384// determined by the ConstantTraits template.
385// ConstantCreator - A class that is used to create constants by
Jeffrey Yasskinf6ee7be2009-10-27 23:45:55 +0000386// ConstantUniqueMap*. This class should be partially specialized if there is
Owen Anderson9b676982009-08-04 22:55:26 +0000387// something strange that needs to be done to interface to the ctor for the
388// constant.
389//
390template<typename T, typename Alloc>
391struct ConstantTraits< std::vector<T, Alloc> > {
392 static unsigned uses(const std::vector<T, Alloc>& v) {
393 return v.size();
394 }
395};
396
Chris Lattner392be582010-02-12 20:49:41 +0000397template<>
398struct ConstantTraits<Constant *> {
399 static unsigned uses(Constant * const & v) {
400 return 1;
401 }
402};
403
Owen Anderson9b676982009-08-04 22:55:26 +0000404template<class ConstantClass, class TypeClass, class ValType>
405struct ConstantCreator {
Chris Lattner229907c2011-07-18 04:54:35 +0000406 static ConstantClass *create(TypeClass *Ty, const ValType &V) {
Owen Anderson9b676982009-08-04 22:55:26 +0000407 return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V);
408 }
409};
410
Dan Gohmane4532f32009-09-15 15:58:07 +0000411template<class ConstantClass>
412struct ConstantKeyData {
413 typedef void ValType;
414 static ValType getValType(ConstantClass *C) {
415 llvm_unreachable("Unknown Constant type!");
Owen Anderson9b676982009-08-04 22:55:26 +0000416 }
417};
418
419template<>
420struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
Chris Lattner229907c2011-07-18 04:54:35 +0000421 static ConstantExpr *create(Type *Ty, const ExprMapKeyType &V,
Owen Anderson9b676982009-08-04 22:55:26 +0000422 unsigned short pred = 0) {
423 if (Instruction::isCast(V.opcode))
424 return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
425 if ((V.opcode >= Instruction::BinaryOpsBegin &&
426 V.opcode < Instruction::BinaryOpsEnd))
Dan Gohman1b849082009-09-07 23:54:19 +0000427 return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1],
428 V.subclassoptionaldata);
Owen Anderson9b676982009-08-04 22:55:26 +0000429 if (V.opcode == Instruction::Select)
430 return new SelectConstantExpr(V.operands[0], V.operands[1],
431 V.operands[2]);
432 if (V.opcode == Instruction::ExtractElement)
433 return new ExtractElementConstantExpr(V.operands[0], V.operands[1]);
434 if (V.opcode == Instruction::InsertElement)
435 return new InsertElementConstantExpr(V.operands[0], V.operands[1],
436 V.operands[2]);
437 if (V.opcode == Instruction::ShuffleVector)
438 return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
439 V.operands[2]);
440 if (V.opcode == Instruction::InsertValue)
441 return new InsertValueConstantExpr(V.operands[0], V.operands[1],
442 V.indices, Ty);
443 if (V.opcode == Instruction::ExtractValue)
444 return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
445 if (V.opcode == Instruction::GetElementPtr) {
446 std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
Dan Gohman1b849082009-09-07 23:54:19 +0000447 return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty,
448 V.subclassoptionaldata);
Owen Anderson9b676982009-08-04 22:55:26 +0000449 }
450
451 // The compare instructions are weird. We have to encode the predicate
452 // value and it is combined with the instruction opcode by multiplying
453 // the opcode by one hundred. We must decode this to get the predicate.
454 if (V.opcode == Instruction::ICmp)
Dan Gohman1b849082009-09-07 23:54:19 +0000455 return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata,
Owen Anderson9b676982009-08-04 22:55:26 +0000456 V.operands[0], V.operands[1]);
457 if (V.opcode == Instruction::FCmp)
Dan Gohman1b849082009-09-07 23:54:19 +0000458 return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata,
Owen Anderson9b676982009-08-04 22:55:26 +0000459 V.operands[0], V.operands[1]);
460 llvm_unreachable("Invalid ConstantExpr!");
Owen Anderson9b676982009-08-04 22:55:26 +0000461 }
462};
463
464template<>
Dan Gohmane4532f32009-09-15 15:58:07 +0000465struct ConstantKeyData<ConstantExpr> {
466 typedef ExprMapKeyType ValType;
467 static ValType getValType(ConstantExpr *CE) {
468 std::vector<Constant*> Operands;
469 Operands.reserve(CE->getNumOperands());
470 for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
471 Operands.push_back(cast<Constant>(CE->getOperand(i)));
472 return ExprMapKeyType(CE->getOpcode(), Operands,
473 CE->isCompare() ? CE->getPredicate() : 0,
474 CE->getRawSubclassOptionalData(),
475 CE->hasIndices() ?
Jay Foad0091fe82011-04-13 15:22:40 +0000476 CE->getIndices() : ArrayRef<unsigned>());
Owen Anderson9b676982009-08-04 22:55:26 +0000477 }
478};
479
Owen Anderson9b676982009-08-04 22:55:26 +0000480
481template<>
Dan Gohmane4532f32009-09-15 15:58:07 +0000482struct ConstantKeyData<ConstantVector> {
483 typedef std::vector<Constant*> ValType;
484 static ValType getValType(ConstantVector *CP) {
485 std::vector<Constant*> Elements;
486 Elements.reserve(CP->getNumOperands());
487 for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
488 Elements.push_back(CP->getOperand(i));
489 return Elements;
Owen Anderson9b676982009-08-04 22:55:26 +0000490 }
491};
492
493template<>
Dan Gohmane4532f32009-09-15 15:58:07 +0000494struct ConstantKeyData<ConstantArray> {
495 typedef std::vector<Constant*> ValType;
496 static ValType getValType(ConstantArray *CA) {
497 std::vector<Constant*> Elements;
498 Elements.reserve(CA->getNumOperands());
499 for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
500 Elements.push_back(cast<Constant>(CA->getOperand(i)));
501 return Elements;
Owen Anderson9b676982009-08-04 22:55:26 +0000502 }
503};
504
505template<>
Dan Gohmane4532f32009-09-15 15:58:07 +0000506struct ConstantKeyData<ConstantStruct> {
507 typedef std::vector<Constant*> ValType;
508 static ValType getValType(ConstantStruct *CS) {
509 std::vector<Constant*> Elements;
510 Elements.reserve(CS->getNumOperands());
511 for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i)
512 Elements.push_back(cast<Constant>(CS->getOperand(i)));
513 return Elements;
Owen Anderson9b676982009-08-04 22:55:26 +0000514 }
515};
516
Owen Anderson9b676982009-08-04 22:55:26 +0000517
Jeffrey Yasskinade270e2010-03-21 20:37:19 +0000518template<>
519struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> {
Chris Lattner229907c2011-07-18 04:54:35 +0000520 static InlineAsm *create(PointerType *Ty, const InlineAsmKeyType &Key) {
Jeffrey Yasskinade270e2010-03-21 20:37:19 +0000521 return new InlineAsm(Ty, Key.asm_string, Key.constraints,
522 Key.has_side_effects, Key.is_align_stack);
523 }
524};
525
526template<>
527struct ConstantKeyData<InlineAsm> {
528 typedef InlineAsmKeyType ValType;
529 static ValType getValType(InlineAsm *Asm) {
530 return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(),
531 Asm->hasSideEffects(), Asm->isAlignStack());
532 }
533};
534
Jay Foadc365eea2011-06-22 08:50:06 +0000535template<class ValType, class ValRefType, class TypeClass, class ConstantClass,
Owen Anderson9b676982009-08-04 22:55:26 +0000536 bool HasLargeKey = false /*true for arrays and structs*/ >
Chris Lattnerb1ed91f2011-07-09 17:41:24 +0000537class ConstantUniqueMap {
Owen Anderson9b676982009-08-04 22:55:26 +0000538public:
Chris Lattner229907c2011-07-18 04:54:35 +0000539 typedef std::pair<TypeClass*, ValType> MapKey;
Dan Gohmane4532f32009-09-15 15:58:07 +0000540 typedef std::map<MapKey, ConstantClass *> MapTy;
541 typedef std::map<ConstantClass *, typename MapTy::iterator> InverseMapTy;
Owen Anderson9b676982009-08-04 22:55:26 +0000542private:
543 /// Map - This is the main map from the element descriptor to the Constants.
544 /// This is the primary way we avoid creating two of the same shape
545 /// constant.
546 MapTy Map;
547
548 /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping
549 /// from the constants to their element in Map. This is important for
550 /// removal of constants from the array, which would otherwise have to scan
551 /// through the map with very large keys.
552 InverseMapTy InverseMap;
553
Owen Anderson9b676982009-08-04 22:55:26 +0000554public:
Devang Patelc5aa8c62009-08-11 06:31:57 +0000555 typename MapTy::iterator map_begin() { return Map.begin(); }
Owen Anderson9b676982009-08-04 22:55:26 +0000556 typename MapTy::iterator map_end() { return Map.end(); }
Torok Edwind18e6682009-08-31 16:14:59 +0000557
558 void freeConstants() {
559 for (typename MapTy::iterator I=Map.begin(), E=Map.end();
560 I != E; ++I) {
Jeffrey Yasskina6eedc32010-03-22 05:23:37 +0000561 // Asserts that use_empty().
562 delete I->second;
Torok Edwind18e6682009-08-31 16:14:59 +0000563 }
564 }
Owen Anderson9b676982009-08-04 22:55:26 +0000565
566 /// InsertOrGetItem - Return an iterator for the specified element.
567 /// If the element exists in the map, the returned iterator points to the
568 /// entry and Exists=true. If not, the iterator points to the newly
569 /// inserted entry and returns Exists=false. Newly inserted entries have
570 /// I->second == 0, and should be filled in.
Dan Gohmane4532f32009-09-15 15:58:07 +0000571 typename MapTy::iterator InsertOrGetItem(std::pair<MapKey, ConstantClass *>
Owen Anderson9b676982009-08-04 22:55:26 +0000572 &InsertVal,
573 bool &Exists) {
574 std::pair<typename MapTy::iterator, bool> IP = Map.insert(InsertVal);
575 Exists = !IP.second;
576 return IP.first;
577 }
578
579private:
580 typename MapTy::iterator FindExistingElement(ConstantClass *CP) {
581 if (HasLargeKey) {
582 typename InverseMapTy::iterator IMI = InverseMap.find(CP);
583 assert(IMI != InverseMap.end() && IMI->second != Map.end() &&
584 IMI->second->second == CP &&
585 "InverseMap corrupt!");
586 return IMI->second;
587 }
588
589 typename MapTy::iterator I =
Chris Lattner229907c2011-07-18 04:54:35 +0000590 Map.find(MapKey(static_cast<TypeClass*>(CP->getType()),
Dan Gohmane4532f32009-09-15 15:58:07 +0000591 ConstantKeyData<ConstantClass>::getValType(CP)));
Owen Anderson9b676982009-08-04 22:55:26 +0000592 if (I == Map.end() || I->second != CP) {
593 // FIXME: This should not use a linear scan. If this gets to be a
594 // performance problem, someone should look at this.
595 for (I = Map.begin(); I != Map.end() && I->second != CP; ++I)
596 /* empty */;
597 }
598 return I;
599 }
Dan Gohmane4532f32009-09-15 15:58:07 +0000600
Chris Lattner229907c2011-07-18 04:54:35 +0000601 ConstantClass *Create(TypeClass *Ty, ValRefType V,
Owen Anderson9b676982009-08-04 22:55:26 +0000602 typename MapTy::iterator I) {
603 ConstantClass* Result =
604 ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V);
605
606 assert(Result->getType() == Ty && "Type specified is not correct!");
607 I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result));
608
609 if (HasLargeKey) // Remember the reverse mapping if needed.
610 InverseMap.insert(std::make_pair(Result, I));
611
Owen Anderson9b676982009-08-04 22:55:26 +0000612 return Result;
613 }
614public:
615
616 /// getOrCreate - Return the specified constant from the map, creating it if
617 /// necessary.
Chris Lattner229907c2011-07-18 04:54:35 +0000618 ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) {
Owen Anderson9b676982009-08-04 22:55:26 +0000619 MapKey Lookup(Ty, V);
620 ConstantClass* Result = 0;
621
622 typename MapTy::iterator I = Map.find(Lookup);
623 // Is it in the map?
624 if (I != Map.end())
Dan Gohmane4532f32009-09-15 15:58:07 +0000625 Result = I->second;
Owen Anderson9b676982009-08-04 22:55:26 +0000626
627 if (!Result) {
628 // If no preexisting value, create one now...
629 Result = Create(Ty, V, I);
630 }
631
632 return Result;
633 }
634
635 void remove(ConstantClass *CP) {
Owen Anderson9b676982009-08-04 22:55:26 +0000636 typename MapTy::iterator I = FindExistingElement(CP);
637 assert(I != Map.end() && "Constant not found in constant table!");
638 assert(I->second == CP && "Didn't find correct element?");
639
640 if (HasLargeKey) // Remember the reverse mapping if needed.
641 InverseMap.erase(CP);
Owen Anderson9b676982009-08-04 22:55:26 +0000642
643 Map.erase(I);
644 }
645
Owen Anderson9b676982009-08-04 22:55:26 +0000646 /// MoveConstantToNewSlot - If we are about to change C to be the element
647 /// specified by I, update our internal data structures to reflect this
648 /// fact.
Owen Anderson9b676982009-08-04 22:55:26 +0000649 void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) {
650 // First, remove the old location of the specified constant in the map.
651 typename MapTy::iterator OldI = FindExistingElement(C);
652 assert(OldI != Map.end() && "Constant not found in constant table!");
653 assert(OldI->second == C && "Didn't find correct element?");
654
Chris Lattnerb1ed91f2011-07-09 17:41:24 +0000655 // Remove the old entry from the map.
Owen Anderson9b676982009-08-04 22:55:26 +0000656 Map.erase(OldI);
657
658 // Update the inverse map so that we know that this constant is now
659 // located at descriptor I.
660 if (HasLargeKey) {
661 assert(I->second == C && "Bad inversemap entry!");
662 InverseMap[C] = I;
663 }
664 }
Owen Anderson9b676982009-08-04 22:55:26 +0000665
666 void dump() const {
David Greene338a9032010-01-05 01:34:26 +0000667 DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");
Owen Anderson9b676982009-08-04 22:55:26 +0000668 }
669};
670
671}
672
673#endif