GVNExpression.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- GVNExpression.h - GVN Expression classes -----------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. /// \file
  15. ///
  16. /// The header file for the GVN pass that contains expression handling
  17. /// classes
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
  21. #define LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
  22. #include "llvm/ADT/Hashing.h"
  23. #include "llvm/ADT/iterator_range.h"
  24. #include "llvm/Analysis/MemorySSA.h"
  25. #include "llvm/IR/Constant.h"
  26. #include "llvm/IR/Instructions.h"
  27. #include "llvm/IR/Value.h"
  28. #include "llvm/Support/Allocator.h"
  29. #include "llvm/Support/ArrayRecycler.h"
  30. #include "llvm/Support/Casting.h"
  31. #include "llvm/Support/Compiler.h"
  32. #include "llvm/Support/raw_ostream.h"
  33. #include <algorithm>
  34. #include <cassert>
  35. #include <iterator>
  36. #include <utility>
  37. namespace llvm {
  38. class BasicBlock;
  39. class Type;
  40. namespace GVNExpression {
  41. enum ExpressionType {
  42. ET_Base,
  43. ET_Constant,
  44. ET_Variable,
  45. ET_Dead,
  46. ET_Unknown,
  47. ET_BasicStart,
  48. ET_Basic,
  49. ET_AggregateValue,
  50. ET_Phi,
  51. ET_MemoryStart,
  52. ET_Call,
  53. ET_Load,
  54. ET_Store,
  55. ET_MemoryEnd,
  56. ET_BasicEnd
  57. };
  58. class Expression {
  59. private:
  60. ExpressionType EType;
  61. unsigned Opcode;
  62. mutable hash_code HashVal = 0;
  63. public:
  64. Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
  65. : EType(ET), Opcode(O) {}
  66. Expression(const Expression &) = delete;
  67. Expression &operator=(const Expression &) = delete;
  68. virtual ~Expression();
  69. static unsigned getEmptyKey() { return ~0U; }
  70. static unsigned getTombstoneKey() { return ~1U; }
  71. bool operator!=(const Expression &Other) const { return !(*this == Other); }
  72. bool operator==(const Expression &Other) const {
  73. if (getOpcode() != Other.getOpcode())
  74. return false;
  75. if (getOpcode() == getEmptyKey() || getOpcode() == getTombstoneKey())
  76. return true;
  77. // Compare the expression type for anything but load and store.
  78. // For load and store we set the opcode to zero to make them equal.
  79. if (getExpressionType() != ET_Load && getExpressionType() != ET_Store &&
  80. getExpressionType() != Other.getExpressionType())
  81. return false;
  82. return equals(Other);
  83. }
  84. hash_code getComputedHash() const {
  85. // It's theoretically possible for a thing to hash to zero. In that case,
  86. // we will just compute the hash a few extra times, which is no worse that
  87. // we did before, which was to compute it always.
  88. if (static_cast<unsigned>(HashVal) == 0)
  89. HashVal = getHashValue();
  90. return HashVal;
  91. }
  92. virtual bool equals(const Expression &Other) const { return true; }
  93. // Return true if the two expressions are exactly the same, including the
  94. // normally ignored fields.
  95. virtual bool exactlyEquals(const Expression &Other) const {
  96. return getExpressionType() == Other.getExpressionType() && equals(Other);
  97. }
  98. unsigned getOpcode() const { return Opcode; }
  99. void setOpcode(unsigned opcode) { Opcode = opcode; }
  100. ExpressionType getExpressionType() const { return EType; }
  101. // We deliberately leave the expression type out of the hash value.
  102. virtual hash_code getHashValue() const { return getOpcode(); }
  103. // Debugging support
  104. virtual void printInternal(raw_ostream &OS, bool PrintEType) const {
  105. if (PrintEType)
  106. OS << "etype = " << getExpressionType() << ",";
  107. OS << "opcode = " << getOpcode() << ", ";
  108. }
  109. void print(raw_ostream &OS) const {
  110. OS << "{ ";
  111. printInternal(OS, true);
  112. OS << "}";
  113. }
  114. LLVM_DUMP_METHOD void dump() const;
  115. };
  116. inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) {
  117. E.print(OS);
  118. return OS;
  119. }
  120. class BasicExpression : public Expression {
  121. private:
  122. using RecyclerType = ArrayRecycler<Value *>;
  123. using RecyclerCapacity = RecyclerType::Capacity;
  124. Value **Operands = nullptr;
  125. unsigned MaxOperands;
  126. unsigned NumOperands = 0;
  127. Type *ValueType = nullptr;
  128. public:
  129. BasicExpression(unsigned NumOperands)
  130. : BasicExpression(NumOperands, ET_Basic) {}
  131. BasicExpression(unsigned NumOperands, ExpressionType ET)
  132. : Expression(ET), MaxOperands(NumOperands) {}
  133. BasicExpression() = delete;
  134. BasicExpression(const BasicExpression &) = delete;
  135. BasicExpression &operator=(const BasicExpression &) = delete;
  136. ~BasicExpression() override;
  137. static bool classof(const Expression *EB) {
  138. ExpressionType ET = EB->getExpressionType();
  139. return ET > ET_BasicStart && ET < ET_BasicEnd;
  140. }
  141. /// Swap two operands. Used during GVN to put commutative operands in
  142. /// order.
  143. void swapOperands(unsigned First, unsigned Second) {
  144. std::swap(Operands[First], Operands[Second]);
  145. }
  146. Value *getOperand(unsigned N) const {
  147. assert(Operands && "Operands not allocated");
  148. assert(N < NumOperands && "Operand out of range");
  149. return Operands[N];
  150. }
  151. void setOperand(unsigned N, Value *V) {
  152. assert(Operands && "Operands not allocated before setting");
  153. assert(N < NumOperands && "Operand out of range");
  154. Operands[N] = V;
  155. }
  156. unsigned getNumOperands() const { return NumOperands; }
  157. using op_iterator = Value **;
  158. using const_op_iterator = Value *const *;
  159. op_iterator op_begin() { return Operands; }
  160. op_iterator op_end() { return Operands + NumOperands; }
  161. const_op_iterator op_begin() const { return Operands; }
  162. const_op_iterator op_end() const { return Operands + NumOperands; }
  163. iterator_range<op_iterator> operands() {
  164. return iterator_range<op_iterator>(op_begin(), op_end());
  165. }
  166. iterator_range<const_op_iterator> operands() const {
  167. return iterator_range<const_op_iterator>(op_begin(), op_end());
  168. }
  169. void op_push_back(Value *Arg) {
  170. assert(NumOperands < MaxOperands && "Tried to add too many operands");
  171. assert(Operands && "Operandss not allocated before pushing");
  172. Operands[NumOperands++] = Arg;
  173. }
  174. bool op_empty() const { return getNumOperands() == 0; }
  175. void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator) {
  176. assert(!Operands && "Operands already allocated");
  177. Operands = Recycler.allocate(RecyclerCapacity::get(MaxOperands), Allocator);
  178. }
  179. void deallocateOperands(RecyclerType &Recycler) {
  180. Recycler.deallocate(RecyclerCapacity::get(MaxOperands), Operands);
  181. }
  182. void setType(Type *T) { ValueType = T; }
  183. Type *getType() const { return ValueType; }
  184. bool equals(const Expression &Other) const override {
  185. if (getOpcode() != Other.getOpcode())
  186. return false;
  187. const auto &OE = cast<BasicExpression>(Other);
  188. return getType() == OE.getType() && NumOperands == OE.NumOperands &&
  189. std::equal(op_begin(), op_end(), OE.op_begin());
  190. }
  191. hash_code getHashValue() const override {
  192. return hash_combine(this->Expression::getHashValue(), ValueType,
  193. hash_combine_range(op_begin(), op_end()));
  194. }
  195. // Debugging support
  196. void printInternal(raw_ostream &OS, bool PrintEType) const override {
  197. if (PrintEType)
  198. OS << "ExpressionTypeBasic, ";
  199. this->Expression::printInternal(OS, false);
  200. OS << "operands = {";
  201. for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
  202. OS << "[" << i << "] = ";
  203. Operands[i]->printAsOperand(OS);
  204. OS << " ";
  205. }
  206. OS << "} ";
  207. }
  208. };
  209. class op_inserter {
  210. private:
  211. using Container = BasicExpression;
  212. Container *BE;
  213. public:
  214. using iterator_category = std::output_iterator_tag;
  215. using value_type = void;
  216. using difference_type = void;
  217. using pointer = void;
  218. using reference = void;
  219. explicit op_inserter(BasicExpression &E) : BE(&E) {}
  220. explicit op_inserter(BasicExpression *E) : BE(E) {}
  221. op_inserter &operator=(Value *val) {
  222. BE->op_push_back(val);
  223. return *this;
  224. }
  225. op_inserter &operator*() { return *this; }
  226. op_inserter &operator++() { return *this; }
  227. op_inserter &operator++(int) { return *this; }
  228. };
  229. class MemoryExpression : public BasicExpression {
  230. private:
  231. const MemoryAccess *MemoryLeader;
  232. public:
  233. MemoryExpression(unsigned NumOperands, enum ExpressionType EType,
  234. const MemoryAccess *MemoryLeader)
  235. : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader) {}
  236. MemoryExpression() = delete;
  237. MemoryExpression(const MemoryExpression &) = delete;
  238. MemoryExpression &operator=(const MemoryExpression &) = delete;
  239. static bool classof(const Expression *EB) {
  240. return EB->getExpressionType() > ET_MemoryStart &&
  241. EB->getExpressionType() < ET_MemoryEnd;
  242. }
  243. hash_code getHashValue() const override {
  244. return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader);
  245. }
  246. bool equals(const Expression &Other) const override {
  247. if (!this->BasicExpression::equals(Other))
  248. return false;
  249. const MemoryExpression &OtherMCE = cast<MemoryExpression>(Other);
  250. return MemoryLeader == OtherMCE.MemoryLeader;
  251. }
  252. const MemoryAccess *getMemoryLeader() const { return MemoryLeader; }
  253. void setMemoryLeader(const MemoryAccess *ML) { MemoryLeader = ML; }
  254. };
  255. class CallExpression final : public MemoryExpression {
  256. private:
  257. CallInst *Call;
  258. public:
  259. CallExpression(unsigned NumOperands, CallInst *C,
  260. const MemoryAccess *MemoryLeader)
  261. : MemoryExpression(NumOperands, ET_Call, MemoryLeader), Call(C) {}
  262. CallExpression() = delete;
  263. CallExpression(const CallExpression &) = delete;
  264. CallExpression &operator=(const CallExpression &) = delete;
  265. ~CallExpression() override;
  266. static bool classof(const Expression *EB) {
  267. return EB->getExpressionType() == ET_Call;
  268. }
  269. // Debugging support
  270. void printInternal(raw_ostream &OS, bool PrintEType) const override {
  271. if (PrintEType)
  272. OS << "ExpressionTypeCall, ";
  273. this->BasicExpression::printInternal(OS, false);
  274. OS << " represents call at ";
  275. Call->printAsOperand(OS);
  276. }
  277. };
  278. class LoadExpression final : public MemoryExpression {
  279. private:
  280. LoadInst *Load;
  281. public:
  282. LoadExpression(unsigned NumOperands, LoadInst *L,
  283. const MemoryAccess *MemoryLeader)
  284. : LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {}
  285. LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
  286. const MemoryAccess *MemoryLeader)
  287. : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {}
  288. LoadExpression() = delete;
  289. LoadExpression(const LoadExpression &) = delete;
  290. LoadExpression &operator=(const LoadExpression &) = delete;
  291. ~LoadExpression() override;
  292. static bool classof(const Expression *EB) {
  293. return EB->getExpressionType() == ET_Load;
  294. }
  295. LoadInst *getLoadInst() const { return Load; }
  296. void setLoadInst(LoadInst *L) { Load = L; }
  297. bool equals(const Expression &Other) const override;
  298. bool exactlyEquals(const Expression &Other) const override {
  299. return Expression::exactlyEquals(Other) &&
  300. cast<LoadExpression>(Other).getLoadInst() == getLoadInst();
  301. }
  302. // Debugging support
  303. void printInternal(raw_ostream &OS, bool PrintEType) const override {
  304. if (PrintEType)
  305. OS << "ExpressionTypeLoad, ";
  306. this->BasicExpression::printInternal(OS, false);
  307. OS << " represents Load at ";
  308. Load->printAsOperand(OS);
  309. OS << " with MemoryLeader " << *getMemoryLeader();
  310. }
  311. };
  312. class StoreExpression final : public MemoryExpression {
  313. private:
  314. StoreInst *Store;
  315. Value *StoredValue;
  316. public:
  317. StoreExpression(unsigned NumOperands, StoreInst *S, Value *StoredValue,
  318. const MemoryAccess *MemoryLeader)
  319. : MemoryExpression(NumOperands, ET_Store, MemoryLeader), Store(S),
  320. StoredValue(StoredValue) {}
  321. StoreExpression() = delete;
  322. StoreExpression(const StoreExpression &) = delete;
  323. StoreExpression &operator=(const StoreExpression &) = delete;
  324. ~StoreExpression() override;
  325. static bool classof(const Expression *EB) {
  326. return EB->getExpressionType() == ET_Store;
  327. }
  328. StoreInst *getStoreInst() const { return Store; }
  329. Value *getStoredValue() const { return StoredValue; }
  330. bool equals(const Expression &Other) const override;
  331. bool exactlyEquals(const Expression &Other) const override {
  332. return Expression::exactlyEquals(Other) &&
  333. cast<StoreExpression>(Other).getStoreInst() == getStoreInst();
  334. }
  335. // Debugging support
  336. void printInternal(raw_ostream &OS, bool PrintEType) const override {
  337. if (PrintEType)
  338. OS << "ExpressionTypeStore, ";
  339. this->BasicExpression::printInternal(OS, false);
  340. OS << " represents Store " << *Store;
  341. OS << " with StoredValue ";
  342. StoredValue->printAsOperand(OS);
  343. OS << " and MemoryLeader " << *getMemoryLeader();
  344. }
  345. };
  346. class AggregateValueExpression final : public BasicExpression {
  347. private:
  348. unsigned MaxIntOperands;
  349. unsigned NumIntOperands = 0;
  350. unsigned *IntOperands = nullptr;
  351. public:
  352. AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands)
  353. : BasicExpression(NumOperands, ET_AggregateValue),
  354. MaxIntOperands(NumIntOperands) {}
  355. AggregateValueExpression() = delete;
  356. AggregateValueExpression(const AggregateValueExpression &) = delete;
  357. AggregateValueExpression &
  358. operator=(const AggregateValueExpression &) = delete;
  359. ~AggregateValueExpression() override;
  360. static bool classof(const Expression *EB) {
  361. return EB->getExpressionType() == ET_AggregateValue;
  362. }
  363. using int_arg_iterator = unsigned *;
  364. using const_int_arg_iterator = const unsigned *;
  365. int_arg_iterator int_op_begin() { return IntOperands; }
  366. int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; }
  367. const_int_arg_iterator int_op_begin() const { return IntOperands; }
  368. const_int_arg_iterator int_op_end() const {
  369. return IntOperands + NumIntOperands;
  370. }
  371. unsigned int_op_size() const { return NumIntOperands; }
  372. bool int_op_empty() const { return NumIntOperands == 0; }
  373. void int_op_push_back(unsigned IntOperand) {
  374. assert(NumIntOperands < MaxIntOperands &&
  375. "Tried to add too many int operands");
  376. assert(IntOperands && "Operands not allocated before pushing");
  377. IntOperands[NumIntOperands++] = IntOperand;
  378. }
  379. virtual void allocateIntOperands(BumpPtrAllocator &Allocator) {
  380. assert(!IntOperands && "Operands already allocated");
  381. IntOperands = Allocator.Allocate<unsigned>(MaxIntOperands);
  382. }
  383. bool equals(const Expression &Other) const override {
  384. if (!this->BasicExpression::equals(Other))
  385. return false;
  386. const AggregateValueExpression &OE = cast<AggregateValueExpression>(Other);
  387. return NumIntOperands == OE.NumIntOperands &&
  388. std::equal(int_op_begin(), int_op_end(), OE.int_op_begin());
  389. }
  390. hash_code getHashValue() const override {
  391. return hash_combine(this->BasicExpression::getHashValue(),
  392. hash_combine_range(int_op_begin(), int_op_end()));
  393. }
  394. // Debugging support
  395. void printInternal(raw_ostream &OS, bool PrintEType) const override {
  396. if (PrintEType)
  397. OS << "ExpressionTypeAggregateValue, ";
  398. this->BasicExpression::printInternal(OS, false);
  399. OS << ", intoperands = {";
  400. for (unsigned i = 0, e = int_op_size(); i != e; ++i) {
  401. OS << "[" << i << "] = " << IntOperands[i] << " ";
  402. }
  403. OS << "}";
  404. }
  405. };
  406. class int_op_inserter {
  407. private:
  408. using Container = AggregateValueExpression;
  409. Container *AVE;
  410. public:
  411. using iterator_category = std::output_iterator_tag;
  412. using value_type = void;
  413. using difference_type = void;
  414. using pointer = void;
  415. using reference = void;
  416. explicit int_op_inserter(AggregateValueExpression &E) : AVE(&E) {}
  417. explicit int_op_inserter(AggregateValueExpression *E) : AVE(E) {}
  418. int_op_inserter &operator=(unsigned int val) {
  419. AVE->int_op_push_back(val);
  420. return *this;
  421. }
  422. int_op_inserter &operator*() { return *this; }
  423. int_op_inserter &operator++() { return *this; }
  424. int_op_inserter &operator++(int) { return *this; }
  425. };
  426. class PHIExpression final : public BasicExpression {
  427. private:
  428. BasicBlock *BB;
  429. public:
  430. PHIExpression(unsigned NumOperands, BasicBlock *B)
  431. : BasicExpression(NumOperands, ET_Phi), BB(B) {}
  432. PHIExpression() = delete;
  433. PHIExpression(const PHIExpression &) = delete;
  434. PHIExpression &operator=(const PHIExpression &) = delete;
  435. ~PHIExpression() override;
  436. static bool classof(const Expression *EB) {
  437. return EB->getExpressionType() == ET_Phi;
  438. }
  439. bool equals(const Expression &Other) const override {
  440. if (!this->BasicExpression::equals(Other))
  441. return false;
  442. const PHIExpression &OE = cast<PHIExpression>(Other);
  443. return BB == OE.BB;
  444. }
  445. hash_code getHashValue() const override {
  446. return hash_combine(this->BasicExpression::getHashValue(), BB);
  447. }
  448. // Debugging support
  449. void printInternal(raw_ostream &OS, bool PrintEType) const override {
  450. if (PrintEType)
  451. OS << "ExpressionTypePhi, ";
  452. this->BasicExpression::printInternal(OS, false);
  453. OS << "bb = " << BB;
  454. }
  455. };
  456. class DeadExpression final : public Expression {
  457. public:
  458. DeadExpression() : Expression(ET_Dead) {}
  459. DeadExpression(const DeadExpression &) = delete;
  460. DeadExpression &operator=(const DeadExpression &) = delete;
  461. static bool classof(const Expression *E) {
  462. return E->getExpressionType() == ET_Dead;
  463. }
  464. };
  465. class VariableExpression final : public Expression {
  466. private:
  467. Value *VariableValue;
  468. public:
  469. VariableExpression(Value *V) : Expression(ET_Variable), VariableValue(V) {}
  470. VariableExpression() = delete;
  471. VariableExpression(const VariableExpression &) = delete;
  472. VariableExpression &operator=(const VariableExpression &) = delete;
  473. static bool classof(const Expression *EB) {
  474. return EB->getExpressionType() == ET_Variable;
  475. }
  476. Value *getVariableValue() const { return VariableValue; }
  477. void setVariableValue(Value *V) { VariableValue = V; }
  478. bool equals(const Expression &Other) const override {
  479. const VariableExpression &OC = cast<VariableExpression>(Other);
  480. return VariableValue == OC.VariableValue;
  481. }
  482. hash_code getHashValue() const override {
  483. return hash_combine(this->Expression::getHashValue(),
  484. VariableValue->getType(), VariableValue);
  485. }
  486. // Debugging support
  487. void printInternal(raw_ostream &OS, bool PrintEType) const override {
  488. if (PrintEType)
  489. OS << "ExpressionTypeVariable, ";
  490. this->Expression::printInternal(OS, false);
  491. OS << " variable = " << *VariableValue;
  492. }
  493. };
  494. class ConstantExpression final : public Expression {
  495. private:
  496. Constant *ConstantValue = nullptr;
  497. public:
  498. ConstantExpression() : Expression(ET_Constant) {}
  499. ConstantExpression(Constant *constantValue)
  500. : Expression(ET_Constant), ConstantValue(constantValue) {}
  501. ConstantExpression(const ConstantExpression &) = delete;
  502. ConstantExpression &operator=(const ConstantExpression &) = delete;
  503. static bool classof(const Expression *EB) {
  504. return EB->getExpressionType() == ET_Constant;
  505. }
  506. Constant *getConstantValue() const { return ConstantValue; }
  507. void setConstantValue(Constant *V) { ConstantValue = V; }
  508. bool equals(const Expression &Other) const override {
  509. const ConstantExpression &OC = cast<ConstantExpression>(Other);
  510. return ConstantValue == OC.ConstantValue;
  511. }
  512. hash_code getHashValue() const override {
  513. return hash_combine(this->Expression::getHashValue(),
  514. ConstantValue->getType(), ConstantValue);
  515. }
  516. // Debugging support
  517. void printInternal(raw_ostream &OS, bool PrintEType) const override {
  518. if (PrintEType)
  519. OS << "ExpressionTypeConstant, ";
  520. this->Expression::printInternal(OS, false);
  521. OS << " constant = " << *ConstantValue;
  522. }
  523. };
  524. class UnknownExpression final : public Expression {
  525. private:
  526. Instruction *Inst;
  527. public:
  528. UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {}
  529. UnknownExpression() = delete;
  530. UnknownExpression(const UnknownExpression &) = delete;
  531. UnknownExpression &operator=(const UnknownExpression &) = delete;
  532. static bool classof(const Expression *EB) {
  533. return EB->getExpressionType() == ET_Unknown;
  534. }
  535. Instruction *getInstruction() const { return Inst; }
  536. void setInstruction(Instruction *I) { Inst = I; }
  537. bool equals(const Expression &Other) const override {
  538. const auto &OU = cast<UnknownExpression>(Other);
  539. return Inst == OU.Inst;
  540. }
  541. hash_code getHashValue() const override {
  542. return hash_combine(this->Expression::getHashValue(), Inst);
  543. }
  544. // Debugging support
  545. void printInternal(raw_ostream &OS, bool PrintEType) const override {
  546. if (PrintEType)
  547. OS << "ExpressionTypeUnknown, ";
  548. this->Expression::printInternal(OS, false);
  549. OS << " inst = " << *Inst;
  550. }
  551. };
  552. } // end namespace GVNExpression
  553. } // end namespace llvm
  554. #endif // LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
  555. #ifdef __GNUC__
  556. #pragma GCC diagnostic pop
  557. #endif