ConstantsContext.h 23 KB

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