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