Line data Source code
1 : //===-- ConstantsContext.h - Constants-related Context Interals -*- C++ -*-===//
2 : //
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_LIB_IR_CONSTANTSCONTEXT_H
16 : #define LLVM_LIB_IR_CONSTANTSCONTEXT_H
17 :
18 : #include "llvm/ADT/ArrayRef.h"
19 : #include "llvm/ADT/DenseMapInfo.h"
20 : #include "llvm/ADT/DenseSet.h"
21 : #include "llvm/ADT/Hashing.h"
22 : #include "llvm/ADT/None.h"
23 : #include "llvm/ADT/SmallVector.h"
24 : #include "llvm/ADT/StringRef.h"
25 : #include "llvm/IR/Constant.h"
26 : #include "llvm/IR/Constants.h"
27 : #include "llvm/IR/DerivedTypes.h"
28 : #include "llvm/IR/InlineAsm.h"
29 : #include "llvm/IR/Instruction.h"
30 : #include "llvm/IR/OperandTraits.h"
31 : #include "llvm/Support/Casting.h"
32 : #include "llvm/Support/Debug.h"
33 : #include "llvm/Support/ErrorHandling.h"
34 : #include "llvm/Support/raw_ostream.h"
35 : #include <cassert>
36 : #include <cstddef>
37 : #include <cstdint>
38 : #include <utility>
39 :
40 : #define DEBUG_TYPE "ir"
41 :
42 : namespace llvm {
43 :
44 : /// UnaryConstantExpr - This class is private to Constants.cpp, and is used
45 : /// behind the scenes to implement unary constant exprs.
46 : class UnaryConstantExpr : public ConstantExpr {
47 : public:
48 : UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
49 : : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
50 : Op<0>() = C;
51 : }
52 :
53 : // allocate space for exactly one operand
54 : void *operator new(size_t s) {
55 216345 : return User::operator new(s, 1);
56 : }
57 :
58 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
59 : };
60 :
61 : /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
62 : /// behind the scenes to implement binary constant exprs.
63 : class BinaryConstantExpr : public ConstantExpr {
64 : public:
65 3460 : BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
66 : unsigned Flags)
67 6920 : : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
68 : Op<0>() = C1;
69 : Op<1>() = C2;
70 3460 : SubclassOptionalData = Flags;
71 3460 : }
72 :
73 : // allocate space for exactly two operands
74 : void *operator new(size_t s) {
75 3460 : return User::operator new(s, 2);
76 : }
77 :
78 : /// Transparently provide more efficient getOperand methods.
79 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
80 : };
81 :
82 : /// SelectConstantExpr - This class is private to Constants.cpp, and is used
83 : /// behind the scenes to implement select constant exprs.
84 : class SelectConstantExpr : public ConstantExpr {
85 : public:
86 92 : SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
87 184 : : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
88 : Op<0>() = C1;
89 : Op<1>() = C2;
90 : Op<2>() = C3;
91 92 : }
92 :
93 : // allocate space for exactly three operands
94 : void *operator new(size_t s) {
95 92 : return User::operator new(s, 3);
96 : }
97 :
98 : /// Transparently provide more efficient getOperand methods.
99 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
100 : };
101 :
102 : /// ExtractElementConstantExpr - This class is private to
103 : /// Constants.cpp, and is used behind the scenes to implement
104 : /// extractelement constant exprs.
105 : class ExtractElementConstantExpr : public ConstantExpr {
106 : public:
107 98 : ExtractElementConstantExpr(Constant *C1, Constant *C2)
108 98 : : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
109 98 : Instruction::ExtractElement, &Op<0>(), 2) {
110 : Op<0>() = C1;
111 : Op<1>() = C2;
112 98 : }
113 :
114 : // allocate space for exactly two operands
115 : void *operator new(size_t s) {
116 98 : return User::operator new(s, 2);
117 : }
118 :
119 : /// Transparently provide more efficient getOperand methods.
120 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
121 : };
122 :
123 : /// InsertElementConstantExpr - This class is private to
124 : /// Constants.cpp, and is used behind the scenes to implement
125 : /// insertelement constant exprs.
126 : class InsertElementConstantExpr : public ConstantExpr {
127 : public:
128 0 : InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
129 0 : : ConstantExpr(C1->getType(), Instruction::InsertElement,
130 0 : &Op<0>(), 3) {
131 : Op<0>() = C1;
132 : Op<1>() = C2;
133 : Op<2>() = C3;
134 0 : }
135 :
136 : // allocate space for exactly three operands
137 : void *operator new(size_t s) {
138 0 : return User::operator new(s, 3);
139 : }
140 :
141 : /// Transparently provide more efficient getOperand methods.
142 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
143 : };
144 :
145 : /// ShuffleVectorConstantExpr - This class is private to
146 : /// Constants.cpp, and is used behind the scenes to implement
147 : /// shufflevector constant exprs.
148 : class ShuffleVectorConstantExpr : public ConstantExpr {
149 : public:
150 0 : ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
151 0 : : ConstantExpr(VectorType::get(
152 0 : cast<VectorType>(C1->getType())->getElementType(),
153 0 : cast<VectorType>(C3->getType())->getNumElements()),
154 : Instruction::ShuffleVector,
155 : &Op<0>(), 3) {
156 : Op<0>() = C1;
157 : Op<1>() = C2;
158 : Op<2>() = C3;
159 0 : }
160 :
161 : // allocate space for exactly three operands
162 : void *operator new(size_t s) {
163 0 : return User::operator new(s, 3);
164 : }
165 :
166 : /// Transparently provide more efficient getOperand methods.
167 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
168 : };
169 :
170 : /// ExtractValueConstantExpr - This class is private to
171 : /// Constants.cpp, and is used behind the scenes to implement
172 : /// extractvalue constant exprs.
173 : class ExtractValueConstantExpr : public ConstantExpr {
174 : public:
175 5 : ExtractValueConstantExpr(Constant *Agg, ArrayRef<unsigned> IdxList,
176 : Type *DestTy)
177 5 : : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
178 5 : Indices(IdxList.begin(), IdxList.end()) {
179 : Op<0>() = Agg;
180 5 : }
181 :
182 : // allocate space for exactly one operand
183 : void *operator new(size_t s) {
184 5 : return User::operator new(s, 1);
185 : }
186 :
187 : /// Indices - These identify which value to extract.
188 : const SmallVector<unsigned, 4> Indices;
189 :
190 : /// Transparently provide more efficient getOperand methods.
191 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
192 :
193 : static bool classof(const ConstantExpr *CE) {
194 0 : return CE->getOpcode() == Instruction::ExtractValue;
195 : }
196 : static bool classof(const Value *V) {
197 : return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
198 : }
199 : };
200 :
201 : /// InsertValueConstantExpr - This class is private to
202 : /// Constants.cpp, and is used behind the scenes to implement
203 : /// insertvalue constant exprs.
204 : class InsertValueConstantExpr : public ConstantExpr {
205 : public:
206 1 : InsertValueConstantExpr(Constant *Agg, Constant *Val,
207 : ArrayRef<unsigned> IdxList, Type *DestTy)
208 1 : : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
209 1 : Indices(IdxList.begin(), IdxList.end()) {
210 : Op<0>() = Agg;
211 : Op<1>() = Val;
212 1 : }
213 :
214 : // allocate space for exactly one operand
215 : void *operator new(size_t s) {
216 1 : return User::operator new(s, 2);
217 : }
218 :
219 : /// Indices - These identify the position for the insertion.
220 : const SmallVector<unsigned, 4> Indices;
221 :
222 : /// Transparently provide more efficient getOperand methods.
223 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
224 :
225 : static bool classof(const ConstantExpr *CE) {
226 : return CE->getOpcode() == Instruction::InsertValue;
227 : }
228 : static bool classof(const Value *V) {
229 : return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
230 : }
231 : };
232 :
233 : /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
234 : /// used behind the scenes to implement getelementpr constant exprs.
235 : class GetElementPtrConstantExpr : public ConstantExpr {
236 : Type *SrcElementTy;
237 : Type *ResElementTy;
238 :
239 : GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C,
240 : ArrayRef<Constant *> IdxList, Type *DestTy);
241 :
242 : public:
243 550810 : static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C,
244 : ArrayRef<Constant *> IdxList,
245 : Type *DestTy, unsigned Flags) {
246 550810 : GetElementPtrConstantExpr *Result = new (IdxList.size() + 1)
247 550810 : GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy);
248 550810 : Result->SubclassOptionalData = Flags;
249 550810 : return Result;
250 : }
251 :
252 : Type *getSourceElementType() const;
253 : Type *getResultElementType() const;
254 :
255 : /// Transparently provide more efficient getOperand methods.
256 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
257 :
258 : static bool classof(const ConstantExpr *CE) {
259 : return CE->getOpcode() == Instruction::GetElementPtr;
260 : }
261 : static bool classof(const Value *V) {
262 : return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
263 : }
264 : };
265 :
266 : // CompareConstantExpr - This class is private to Constants.cpp, and is used
267 : // behind the scenes to implement ICmp and FCmp constant expressions. This is
268 : // needed in order to store the predicate value for these instructions.
269 : class CompareConstantExpr : public ConstantExpr {
270 : public:
271 : unsigned short predicate;
272 456 : CompareConstantExpr(Type *ty, Instruction::OtherOps opc,
273 : unsigned short pred, Constant* LHS, Constant* RHS)
274 456 : : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
275 : Op<0>() = LHS;
276 : Op<1>() = RHS;
277 456 : }
278 :
279 : // allocate space for exactly two operands
280 : void *operator new(size_t s) {
281 456 : return User::operator new(s, 2);
282 : }
283 :
284 : /// Transparently provide more efficient getOperand methods.
285 : DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
286 :
287 : static bool classof(const ConstantExpr *CE) {
288 : return CE->getOpcode() == Instruction::ICmp ||
289 : CE->getOpcode() == Instruction::FCmp;
290 : }
291 : static bool classof(const Value *V) {
292 : return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
293 : }
294 : };
295 :
296 : template <>
297 : struct OperandTraits<UnaryConstantExpr>
298 : : public FixedNumOperandTraits<UnaryConstantExpr, 1> {};
299 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
300 :
301 : template <>
302 : struct OperandTraits<BinaryConstantExpr>
303 : : public FixedNumOperandTraits<BinaryConstantExpr, 2> {};
304 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
305 :
306 : template <>
307 : struct OperandTraits<SelectConstantExpr>
308 : : public FixedNumOperandTraits<SelectConstantExpr, 3> {};
309 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
310 :
311 : template <>
312 : struct OperandTraits<ExtractElementConstantExpr>
313 : : public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {};
314 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
315 :
316 : template <>
317 : struct OperandTraits<InsertElementConstantExpr>
318 : : public FixedNumOperandTraits<InsertElementConstantExpr, 3> {};
319 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
320 :
321 : template <>
322 : struct OperandTraits<ShuffleVectorConstantExpr>
323 : : public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {};
324 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
325 :
326 : template <>
327 : struct OperandTraits<ExtractValueConstantExpr>
328 : : public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {};
329 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
330 :
331 : template <>
332 : struct OperandTraits<InsertValueConstantExpr>
333 : : public FixedNumOperandTraits<InsertValueConstantExpr, 2> {};
334 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
335 :
336 : template <>
337 : struct OperandTraits<GetElementPtrConstantExpr>
338 : : public VariadicOperandTraits<GetElementPtrConstantExpr, 1> {};
339 :
340 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
341 :
342 : template <>
343 : struct OperandTraits<CompareConstantExpr>
344 : : public FixedNumOperandTraits<CompareConstantExpr, 2> {};
345 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
346 :
347 : template <class ConstantClass> struct ConstantAggrKeyType;
348 : struct InlineAsmKeyType;
349 : struct ConstantExprKeyType;
350 :
351 : template <class ConstantClass> struct ConstantInfo;
352 : template <> struct ConstantInfo<ConstantExpr> {
353 : using ValType = ConstantExprKeyType;
354 : using TypeClass = Type;
355 : };
356 : template <> struct ConstantInfo<InlineAsm> {
357 : using ValType = InlineAsmKeyType;
358 : using TypeClass = PointerType;
359 : };
360 : template <> struct ConstantInfo<ConstantArray> {
361 : using ValType = ConstantAggrKeyType<ConstantArray>;
362 : using TypeClass = ArrayType;
363 : };
364 : template <> struct ConstantInfo<ConstantStruct> {
365 : using ValType = ConstantAggrKeyType<ConstantStruct>;
366 : using TypeClass = StructType;
367 : };
368 : template <> struct ConstantInfo<ConstantVector> {
369 : using ValType = ConstantAggrKeyType<ConstantVector>;
370 : using TypeClass = VectorType;
371 : };
372 :
373 : template <class ConstantClass> struct ConstantAggrKeyType {
374 : ArrayRef<Constant *> Operands;
375 :
376 293032 : ConstantAggrKeyType(ArrayRef<Constant *> Operands) : Operands(Operands) {}
377 :
378 : ConstantAggrKeyType(ArrayRef<Constant *> Operands, const ConstantClass *)
379 : : Operands(Operands) {}
380 :
381 182583 : ConstantAggrKeyType(const ConstantClass *C,
382 : SmallVectorImpl<Constant *> &Storage) {
383 : assert(Storage.empty() && "Expected empty storage");
384 841005 : for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I)
385 658422 : Storage.push_back(C->getOperand(I));
386 182583 : Operands = Storage;
387 182583 : }
388 2570 :
389 : bool operator==(const ConstantAggrKeyType &X) const {
390 : return Operands == X.Operands;
391 91676 : }
392 89106 :
393 2570 : bool operator==(const ConstantClass *C) const {
394 2570 : if (Operands.size() != C->getNumOperands())
395 116032 : return false;
396 : for (unsigned I = 0, E = Operands.size(); I != E; ++I)
397 : if (Operands[I] != C->getOperand(I))
398 524697 : return false;
399 408665 : return true;
400 116032 : }
401 116032 :
402 63981 : unsigned getHash() const {
403 : return hash_combine_range(Operands.begin(), Operands.end());
404 : }
405 224632 :
406 160651 : using TypeClass = typename ConstantInfo<ConstantClass>::TypeClass;
407 63981 :
408 63981 : ConstantClass *create(TypeClass *Ty) const {
409 : return new (Operands.size()) ConstantClass(Ty, Operands);
410 : }
411 : };
412 :
413 : struct InlineAsmKeyType {
414 : StringRef AsmString;
415 644542 : StringRef Constraints;
416 : FunctionType *FTy;
417 813996 : bool HasSideEffects;
418 1379762 : bool IsAlignStack;
419 : InlineAsm::AsmDialect AsmDialect;
420 :
421 : InlineAsmKeyType(StringRef AsmString, StringRef Constraints,
422 : FunctionType *FTy, bool HasSideEffects, bool IsAlignStack,
423 : InlineAsm::AsmDialect AsmDialect)
424 973888 : : AsmString(AsmString), Constraints(Constraints), FTy(FTy),
425 : HasSideEffects(HasSideEffects), IsAlignStack(IsAlignStack),
426 19488 : AsmDialect(AsmDialect) {}
427 :
428 : InlineAsmKeyType(const InlineAsm *Asm, SmallVectorImpl<Constant *> &)
429 168925 : : AsmString(Asm->getAsmString()), Constraints(Asm->getConstraintString()),
430 171526 : FTy(Asm->getFunctionType()), HasSideEffects(Asm->hasSideEffects()),
431 2601 : IsAlignStack(Asm->isAlignStack()), AsmDialect(Asm->getDialect()) {}
432 15196 :
433 15196 : bool operator==(const InlineAsmKeyType &X) const {
434 : return HasSideEffects == X.HasSideEffects &&
435 103841 : IsAlignStack == X.IsAlignStack && AsmDialect == X.AsmDialect &&
436 103841 : AsmString == X.AsmString && Constraints == X.Constraints &&
437 : FTy == X.FTy;
438 49888 : }
439 49888 :
440 13413 : bool operator==(const InlineAsm *Asm) const {
441 26772 : return HasSideEffects == Asm->hasSideEffects() &&
442 13359 : IsAlignStack == Asm->isAlignStack() &&
443 13359 : AsmDialect == Asm->getDialect() &&
444 : AsmString == Asm->getAsmString() &&
445 24798 : Constraints == Asm->getConstraintString() &&
446 11385 : FTy == Asm->getFunctionType();
447 : }
448 :
449 : unsigned getHash() const {
450 44178 : return hash_combine(AsmString, Constraints, HasSideEffects, IsAlignStack,
451 66267 : AsmDialect, FTy);
452 : }
453 :
454 : using TypeClass = ConstantInfo<InlineAsm>::TypeClass;
455 :
456 8103 : InlineAsm *create(TypeClass *Ty) const {
457 : assert(PointerType::getUnqual(FTy) == Ty);
458 16206 : return new InlineAsm(FTy, AsmString, Constraints, HasSideEffects,
459 16206 : IsAlignStack, AsmDialect);
460 : }
461 : };
462 :
463 : struct ConstantExprKeyType {
464 : uint8_t Opcode;
465 : uint8_t SubclassOptionalData;
466 : uint16_t SubclassData;
467 : ArrayRef<Constant *> Ops;
468 : ArrayRef<unsigned> Indexes;
469 : Type *ExplicitTy;
470 :
471 : ConstantExprKeyType(unsigned Opcode, ArrayRef<Constant *> Ops,
472 : unsigned short SubclassData = 0,
473 : unsigned short SubclassOptionalData = 0,
474 : ArrayRef<unsigned> Indexes = None,
475 : Type *ExplicitTy = nullptr)
476 : : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData),
477 : SubclassData(SubclassData), Ops(Ops), Indexes(Indexes),
478 : ExplicitTy(ExplicitTy) {}
479 :
480 : ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE)
481 : : Opcode(CE->getOpcode()),
482 : SubclassOptionalData(CE->getRawSubclassOptionalData()),
483 : SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands),
484 : Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {}
485 :
486 : ConstantExprKeyType(const ConstantExpr *CE,
487 : SmallVectorImpl<Constant *> &Storage)
488 : : Opcode(CE->getOpcode()),
489 : SubclassOptionalData(CE->getRawSubclassOptionalData()),
490 : SubclassData(CE->isCompare() ? CE->getPredicate() : 0),
491 : Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {
492 : assert(Storage.empty() && "Expected empty storage");
493 : for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I)
494 : Storage.push_back(CE->getOperand(I));
495 : Ops = Storage;
496 : }
497 :
498 : bool operator==(const ConstantExprKeyType &X) const {
499 : return Opcode == X.Opcode && SubclassData == X.SubclassData &&
500 : SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops &&
501 : Indexes == X.Indexes;
502 : }
503 :
504 : bool operator==(const ConstantExpr *CE) const {
505 : if (Opcode != CE->getOpcode())
506 20137666 : return false;
507 : if (SubclassOptionalData != CE->getRawSubclassOptionalData())
508 20137666 : return false;
509 : if (Ops.size() != CE->getNumOperands())
510 5481 : return false;
511 5481 : if (SubclassData != (CE->isCompare() ? CE->getPredicate() : 0))
512 : return false;
513 8 : for (unsigned I = 0, E = Ops.size(); I != E; ++I)
514 10970 : if (Ops[I] != CE->getOperand(I))
515 : return false;
516 1104640 : if (Indexes != (CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()))
517 : return false;
518 1104640 : return true;
519 : }
520 541 :
521 2209821 : unsigned getHash() const {
522 : return hash_combine(Opcode, SubclassOptionalData, SubclassData,
523 4013357 : hash_combine_range(Ops.begin(), Ops.end()),
524 2908717 : hash_combine_range(Indexes.begin(), Indexes.end()));
525 1104640 : }
526 1104640 :
527 : using TypeClass = ConstantInfo<ConstantExpr>::TypeClass;
528 :
529 : ConstantExpr *create(TypeClass *Ty) const {
530 : switch (Opcode) {
531 : default:
532 : if (Instruction::isCast(Opcode))
533 : return new UnaryConstantExpr(Opcode, Ops[0], Ty);
534 29443936 : if ((Opcode >= Instruction::BinaryOpsBegin &&
535 58887872 : Opcode < Instruction::BinaryOpsEnd))
536 : return new BinaryConstantExpr(Opcode, Ops[0], Ops[1],
537 58485454 : SubclassOptionalData);
538 : llvm_unreachable("Invalid ConstantExpr!");
539 58475598 : case Instruction::Select:
540 : return new SelectConstantExpr(Ops[0], Ops[1], Ops[2]);
541 29235047 : case Instruction::ExtractElement:
542 : return new ExtractElementConstantExpr(Ops[0], Ops[1]);
543 83577406 : case Instruction::InsertElement:
544 128421732 : return new InsertElementConstantExpr(Ops[0], Ops[1], Ops[2]);
545 : case Instruction::ShuffleVector:
546 19366540 : return new ShuffleVectorConstantExpr(Ops[0], Ops[1], Ops[2]);
547 0 : case Instruction::InsertValue:
548 : return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty);
549 : case Instruction::ExtractValue:
550 : return new ExtractValueConstantExpr(Ops[0], Indexes, Ty);
551 21247787 : case Instruction::GetElementPtr:
552 42495574 : return GetElementPtrConstantExpr::Create(
553 63743361 : ExplicitTy ? ExplicitTy
554 21247787 : : cast<PointerType>(Ops[0]->getType()->getScalarType())
555 : ->getElementType(),
556 : Ops[0], Ops.slice(1), Ty, SubclassOptionalData);
557 : case Instruction::ICmp:
558 : return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData,
559 771267 : Ops[0], Ops[1]);
560 771267 : case Instruction::FCmp:
561 219805 : return new CompareConstantExpr(Ty, Instruction::FCmp, SubclassData,
562 439610 : Ops[0], Ops[1]);
563 432690 : }
564 3460 : }
565 : };
566 6920 :
567 169020 : template <class ConstantClass> class ConstantUniqueMap {
568 0 : public:
569 92 : using ValType = typename ConstantInfo<ConstantClass>::ValType;
570 92 : using TypeClass = typename ConstantInfo<ConstantClass>::TypeClass;
571 98 : using LookupKey = std::pair<TypeClass *, ValType>;
572 98 :
573 0 : /// Key and hash together, so that we compute the hash only once and reuse it.
574 0 : using LookupKeyHashed = std::pair<unsigned, LookupKey>;
575 0 :
576 0 : private:
577 1 : struct MapInfo {
578 1 : using ConstantClassInfo = DenseMapInfo<ConstantClass *>;
579 5 :
580 5 : static inline ConstantClass *getEmptyKey() {
581 550810 : return ConstantClassInfo::getEmptyKey();
582 550810 : }
583 550810 :
584 : static inline ConstantClass *getTombstoneKey() {
585 0 : return ConstantClassInfo::getTombstoneKey();
586 1101620 : }
587 452 :
588 3053 : static unsigned getHashValue(const ConstantClass *CP) {
589 452 : SmallVector<Constant *, 32> Storage;
590 2605 : return getHashValue(LookupKey(CP->getType(), ValType(CP, Storage)));
591 4 : }
592 4 :
593 : static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) {
594 25130 : return LHS == RHS;
595 : }
596 :
597 22089 : static unsigned getHashValue(const LookupKey &Val) {
598 22089 : return hash_combine(Val.first, Val.second.getHash());
599 : }
600 :
601 0 : static unsigned getHashValue(const LookupKeyHashed &Val) {
602 0 : return Val.first;
603 : }
604 :
605 : static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) {
606 33222 : if (RHS == getEmptyKey() || RHS == getTombstoneKey())
607 : return false;
608 37552 : if (LHS.first != RHS->getType())
609 : return false;
610 13413 : return LHS.second == RHS;
611 : }
612 :
613 : static bool isEqual(const LookupKeyHashed &LHS, const ConstantClass *RHS) {
614 : return isEqual(LHS.second, RHS);
615 : }
616 : };
617 :
618 1287223 : public:
619 : using MapTy = DenseSet<ConstantClass *, MapInfo>;
620 1287223 :
621 : private:
622 1104640 : MapTy Map;
623 :
624 1104640 : public:
625 : typename MapTy::iterator begin() { return Map.begin(); }
626 2570 : typename MapTy::iterator end() { return Map.end(); }
627 :
628 416470 : void freeConstants() {
629 443001 : for (auto &I : Map)
630 166611 : delete I; // Asserts that use_empty().
631 413900 : }
632 198812 :
633 90403 : private:
634 71604 : ConstantClass *create(TypeClass *Ty, ValType V, LookupKeyHashed &HashKey) {
635 90883 : ConstantClass *Result = V.create(Ty);
636 146761 :
637 97172 : assert(Result->getType() == Ty && "Type specified is not correct!");
638 28784 : Map.insert_as(Result, HashKey);
639 82780 :
640 18934892 : return Result;
641 85190 : }
642 4820 :
643 21807767 : public:
644 21807767 : /// Return the specified constant from the map, creating it if necessary.
645 102724 : ConstantClass *getOrCreate(TypeClass *Ty, ValType V) {
646 21248699 : LookupKey Key(Ty, V);
647 21330567 : /// Hash once, and reuse it for the lookup and the insertion if needed.
648 102268 : LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
649 221243 :
650 142683 : ConstantClass *Result = nullptr;
651 82780 :
652 224620 : auto I = Map.find_as(Lookup);
653 244108 : if (I == Map.end())
654 8103 : Result = create(Ty, V, Lookup);
655 118337 : else
656 129722 : Result = *I;
657 : assert(Result && "Unexpected nullptr");
658 :
659 19488 : return Result;
660 0 : }
661 :
662 0 : /// Remove this constant from the map
663 0 : void remove(ConstantClass *CP) {
664 : typename MapTy::iterator I = Map.find(CP);
665 0 : assert(I != Map.end() && "Constant not found in constant table!");
666 0 : assert(*I == CP && "Didn't find correct element?");
667 : Map.erase(I);
668 0 : }
669 0 :
670 : ConstantClass *replaceOperandsInPlace(ArrayRef<Constant *> Operands,
671 0 : ConstantClass *CP, Value *From,
672 0 : Constant *To, unsigned NumUpdated = 0,
673 : unsigned OperandNo = ~0u) {
674 : LookupKey Key(CP->getType(), ValType(Operands, CP));
675 767703 : /// Hash once, and reuse it for the lookup and the insertion if needed.
676 36680194 : LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
677 :
678 34084609 : auto I = Map.find_as(Lookup);
679 : if (I != Map.end())
680 29443936 : return *I;
681 :
682 162505 : // Update to the new value. Optimize for the case when we have a single
683 162505 : // operand that we're changing, but handle bulk updates efficiently.
684 : remove(CP);
685 268388 : if (NumUpdated == 1) {
686 : assert(OperandNo < CP->getNumOperands() && "Invalid index");
687 : assert(CP->getOperand(OperandNo) != To && "I didn't contain From!");
688 : CP->setOperand(OperandNo, To);
689 399428 : } else {
690 399428 : for (unsigned I = 0, E = CP->getNumOperands(); I != E; ++I)
691 : if (CP->getOperand(I) == From)
692 396038 : CP->setOperand(I, To);
693 : }
694 : Map.insert_as(CP, Lookup);
695 : return nullptr;
696 205770 : }
697 205770 :
698 : void dump() const {
699 215010 : LLVM_DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");
700 : }
701 : };
702 :
703 : } // end namespace llvm
704 :
705 767703 : #endif // LLVM_LIB_IR_CONSTANTSCONTEXT_H
|