File indexing completed on 2026-05-10 08:44:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
0017 #define LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
0018
0019 #include "llvm/ADT/Hashing.h"
0020 #include "llvm/ADT/iterator_range.h"
0021 #include "llvm/Analysis/MemorySSA.h"
0022 #include "llvm/IR/Constant.h"
0023 #include "llvm/IR/Instructions.h"
0024 #include "llvm/IR/Value.h"
0025 #include "llvm/Support/Allocator.h"
0026 #include "llvm/Support/ArrayRecycler.h"
0027 #include "llvm/Support/Casting.h"
0028 #include "llvm/Support/Compiler.h"
0029 #include "llvm/Support/raw_ostream.h"
0030 #include <algorithm>
0031 #include <cassert>
0032 #include <iterator>
0033 #include <utility>
0034
0035 namespace llvm {
0036
0037 class BasicBlock;
0038 class Type;
0039
0040 namespace GVNExpression {
0041
0042 enum ExpressionType {
0043 ET_Base,
0044 ET_Constant,
0045 ET_Variable,
0046 ET_Dead,
0047 ET_Unknown,
0048 ET_BasicStart,
0049 ET_Basic,
0050 ET_AggregateValue,
0051 ET_Phi,
0052 ET_MemoryStart,
0053 ET_Call,
0054 ET_Load,
0055 ET_Store,
0056 ET_MemoryEnd,
0057 ET_BasicEnd
0058 };
0059
0060 class Expression {
0061 private:
0062 ExpressionType EType;
0063 unsigned Opcode;
0064 mutable hash_code HashVal = 0;
0065
0066 public:
0067 Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
0068 : EType(ET), Opcode(O) {}
0069 Expression(const Expression &) = delete;
0070 Expression &operator=(const Expression &) = delete;
0071 virtual ~Expression();
0072
0073 static unsigned getEmptyKey() { return ~0U; }
0074 static unsigned getTombstoneKey() { return ~1U; }
0075
0076 bool operator!=(const Expression &Other) const { return !(*this == Other); }
0077 bool operator==(const Expression &Other) const {
0078 if (getOpcode() != Other.getOpcode())
0079 return false;
0080 if (getOpcode() == getEmptyKey() || getOpcode() == getTombstoneKey())
0081 return true;
0082
0083
0084 if (getExpressionType() != ET_Load && getExpressionType() != ET_Store &&
0085 getExpressionType() != Other.getExpressionType())
0086 return false;
0087
0088 return equals(Other);
0089 }
0090
0091 hash_code getComputedHash() const {
0092
0093
0094
0095 if (static_cast<unsigned>(HashVal) == 0)
0096 HashVal = getHashValue();
0097 return HashVal;
0098 }
0099
0100 virtual bool equals(const Expression &Other) const { return true; }
0101
0102
0103
0104 virtual bool exactlyEquals(const Expression &Other) const {
0105 return getExpressionType() == Other.getExpressionType() && equals(Other);
0106 }
0107
0108 unsigned getOpcode() const { return Opcode; }
0109 void setOpcode(unsigned opcode) { Opcode = opcode; }
0110 ExpressionType getExpressionType() const { return EType; }
0111
0112
0113 virtual hash_code getHashValue() const { return getOpcode(); }
0114
0115
0116 virtual void printInternal(raw_ostream &OS, bool PrintEType) const {
0117 if (PrintEType)
0118 OS << "etype = " << getExpressionType() << ",";
0119 OS << "opcode = " << getOpcode() << ", ";
0120 }
0121
0122 void print(raw_ostream &OS) const {
0123 OS << "{ ";
0124 printInternal(OS, true);
0125 OS << "}";
0126 }
0127
0128 LLVM_DUMP_METHOD void dump() const;
0129 };
0130
0131 inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) {
0132 E.print(OS);
0133 return OS;
0134 }
0135
0136 class BasicExpression : public Expression {
0137 private:
0138 using RecyclerType = ArrayRecycler<Value *>;
0139 using RecyclerCapacity = RecyclerType::Capacity;
0140
0141 Value **Operands = nullptr;
0142 unsigned MaxOperands;
0143 unsigned NumOperands = 0;
0144 Type *ValueType = nullptr;
0145
0146 public:
0147 BasicExpression(unsigned NumOperands)
0148 : BasicExpression(NumOperands, ET_Basic) {}
0149 BasicExpression(unsigned NumOperands, ExpressionType ET)
0150 : Expression(ET), MaxOperands(NumOperands) {}
0151 BasicExpression() = delete;
0152 BasicExpression(const BasicExpression &) = delete;
0153 BasicExpression &operator=(const BasicExpression &) = delete;
0154 ~BasicExpression() override;
0155
0156 static bool classof(const Expression *EB) {
0157 ExpressionType ET = EB->getExpressionType();
0158 return ET > ET_BasicStart && ET < ET_BasicEnd;
0159 }
0160
0161
0162
0163 void swapOperands(unsigned First, unsigned Second) {
0164 std::swap(Operands[First], Operands[Second]);
0165 }
0166
0167 Value *getOperand(unsigned N) const {
0168 assert(Operands && "Operands not allocated");
0169 assert(N < NumOperands && "Operand out of range");
0170 return Operands[N];
0171 }
0172
0173 void setOperand(unsigned N, Value *V) {
0174 assert(Operands && "Operands not allocated before setting");
0175 assert(N < NumOperands && "Operand out of range");
0176 Operands[N] = V;
0177 }
0178
0179 unsigned getNumOperands() const { return NumOperands; }
0180
0181 using op_iterator = Value **;
0182 using const_op_iterator = Value *const *;
0183
0184 op_iterator op_begin() { return Operands; }
0185 op_iterator op_end() { return Operands + NumOperands; }
0186 const_op_iterator op_begin() const { return Operands; }
0187 const_op_iterator op_end() const { return Operands + NumOperands; }
0188 iterator_range<op_iterator> operands() {
0189 return iterator_range<op_iterator>(op_begin(), op_end());
0190 }
0191 iterator_range<const_op_iterator> operands() const {
0192 return iterator_range<const_op_iterator>(op_begin(), op_end());
0193 }
0194
0195 void op_push_back(Value *Arg) {
0196 assert(NumOperands < MaxOperands && "Tried to add too many operands");
0197 assert(Operands && "Operandss not allocated before pushing");
0198 Operands[NumOperands++] = Arg;
0199 }
0200 bool op_empty() const { return getNumOperands() == 0; }
0201
0202 void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator) {
0203 assert(!Operands && "Operands already allocated");
0204 Operands = Recycler.allocate(RecyclerCapacity::get(MaxOperands), Allocator);
0205 }
0206 void deallocateOperands(RecyclerType &Recycler) {
0207 Recycler.deallocate(RecyclerCapacity::get(MaxOperands), Operands);
0208 }
0209
0210 void setType(Type *T) { ValueType = T; }
0211 Type *getType() const { return ValueType; }
0212
0213 bool equals(const Expression &Other) const override {
0214 if (getOpcode() != Other.getOpcode())
0215 return false;
0216
0217 const auto &OE = cast<BasicExpression>(Other);
0218 return getType() == OE.getType() && NumOperands == OE.NumOperands &&
0219 std::equal(op_begin(), op_end(), OE.op_begin());
0220 }
0221
0222 hash_code getHashValue() const override {
0223 return hash_combine(this->Expression::getHashValue(), ValueType,
0224 hash_combine_range(op_begin(), op_end()));
0225 }
0226
0227
0228 void printInternal(raw_ostream &OS, bool PrintEType) const override {
0229 if (PrintEType)
0230 OS << "ExpressionTypeBasic, ";
0231
0232 this->Expression::printInternal(OS, false);
0233 OS << "operands = {";
0234 for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
0235 OS << "[" << i << "] = ";
0236 Operands[i]->printAsOperand(OS);
0237 OS << " ";
0238 }
0239 OS << "} ";
0240 }
0241 };
0242
0243 class op_inserter {
0244 private:
0245 using Container = BasicExpression;
0246
0247 Container *BE;
0248
0249 public:
0250 using iterator_category = std::output_iterator_tag;
0251 using value_type = void;
0252 using difference_type = void;
0253 using pointer = void;
0254 using reference = void;
0255
0256 explicit op_inserter(BasicExpression &E) : BE(&E) {}
0257 explicit op_inserter(BasicExpression *E) : BE(E) {}
0258
0259 op_inserter &operator=(Value *val) {
0260 BE->op_push_back(val);
0261 return *this;
0262 }
0263 op_inserter &operator*() { return *this; }
0264 op_inserter &operator++() { return *this; }
0265 op_inserter &operator++(int) { return *this; }
0266 };
0267
0268 class MemoryExpression : public BasicExpression {
0269 private:
0270 const MemoryAccess *MemoryLeader;
0271
0272 public:
0273 MemoryExpression(unsigned NumOperands, enum ExpressionType EType,
0274 const MemoryAccess *MemoryLeader)
0275 : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader) {}
0276 MemoryExpression() = delete;
0277 MemoryExpression(const MemoryExpression &) = delete;
0278 MemoryExpression &operator=(const MemoryExpression &) = delete;
0279
0280 static bool classof(const Expression *EB) {
0281 return EB->getExpressionType() > ET_MemoryStart &&
0282 EB->getExpressionType() < ET_MemoryEnd;
0283 }
0284
0285 hash_code getHashValue() const override {
0286 return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader);
0287 }
0288
0289 bool equals(const Expression &Other) const override {
0290 if (!this->BasicExpression::equals(Other))
0291 return false;
0292 const MemoryExpression &OtherMCE = cast<MemoryExpression>(Other);
0293
0294 return MemoryLeader == OtherMCE.MemoryLeader;
0295 }
0296
0297 const MemoryAccess *getMemoryLeader() const { return MemoryLeader; }
0298 void setMemoryLeader(const MemoryAccess *ML) { MemoryLeader = ML; }
0299 };
0300
0301 class CallExpression final : public MemoryExpression {
0302 private:
0303 CallInst *Call;
0304
0305 public:
0306 CallExpression(unsigned NumOperands, CallInst *C,
0307 const MemoryAccess *MemoryLeader)
0308 : MemoryExpression(NumOperands, ET_Call, MemoryLeader), Call(C) {}
0309 CallExpression() = delete;
0310 CallExpression(const CallExpression &) = delete;
0311 CallExpression &operator=(const CallExpression &) = delete;
0312 ~CallExpression() override;
0313
0314 static bool classof(const Expression *EB) {
0315 return EB->getExpressionType() == ET_Call;
0316 }
0317
0318 bool equals(const Expression &Other) const override;
0319 bool exactlyEquals(const Expression &Other) const override {
0320 return Expression::exactlyEquals(Other) &&
0321 cast<CallExpression>(Other).Call == Call;
0322 }
0323
0324
0325 void printInternal(raw_ostream &OS, bool PrintEType) const override {
0326 if (PrintEType)
0327 OS << "ExpressionTypeCall, ";
0328 this->BasicExpression::printInternal(OS, false);
0329 OS << " represents call at ";
0330 Call->printAsOperand(OS);
0331 }
0332 };
0333
0334 class LoadExpression final : public MemoryExpression {
0335 private:
0336 LoadInst *Load;
0337
0338 public:
0339 LoadExpression(unsigned NumOperands, LoadInst *L,
0340 const MemoryAccess *MemoryLeader)
0341 : LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {}
0342
0343 LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
0344 const MemoryAccess *MemoryLeader)
0345 : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {}
0346
0347 LoadExpression() = delete;
0348 LoadExpression(const LoadExpression &) = delete;
0349 LoadExpression &operator=(const LoadExpression &) = delete;
0350 ~LoadExpression() override;
0351
0352 static bool classof(const Expression *EB) {
0353 return EB->getExpressionType() == ET_Load;
0354 }
0355
0356 LoadInst *getLoadInst() const { return Load; }
0357 void setLoadInst(LoadInst *L) { Load = L; }
0358
0359 bool equals(const Expression &Other) const override;
0360 bool exactlyEquals(const Expression &Other) const override {
0361 return Expression::exactlyEquals(Other) &&
0362 cast<LoadExpression>(Other).getLoadInst() == getLoadInst();
0363 }
0364
0365
0366 void printInternal(raw_ostream &OS, bool PrintEType) const override {
0367 if (PrintEType)
0368 OS << "ExpressionTypeLoad, ";
0369 this->BasicExpression::printInternal(OS, false);
0370 OS << " represents Load at ";
0371 Load->printAsOperand(OS);
0372 OS << " with MemoryLeader " << *getMemoryLeader();
0373 }
0374 };
0375
0376 class StoreExpression final : public MemoryExpression {
0377 private:
0378 StoreInst *Store;
0379 Value *StoredValue;
0380
0381 public:
0382 StoreExpression(unsigned NumOperands, StoreInst *S, Value *StoredValue,
0383 const MemoryAccess *MemoryLeader)
0384 : MemoryExpression(NumOperands, ET_Store, MemoryLeader), Store(S),
0385 StoredValue(StoredValue) {}
0386 StoreExpression() = delete;
0387 StoreExpression(const StoreExpression &) = delete;
0388 StoreExpression &operator=(const StoreExpression &) = delete;
0389 ~StoreExpression() override;
0390
0391 static bool classof(const Expression *EB) {
0392 return EB->getExpressionType() == ET_Store;
0393 }
0394
0395 StoreInst *getStoreInst() const { return Store; }
0396 Value *getStoredValue() const { return StoredValue; }
0397
0398 bool equals(const Expression &Other) const override;
0399
0400 bool exactlyEquals(const Expression &Other) const override {
0401 return Expression::exactlyEquals(Other) &&
0402 cast<StoreExpression>(Other).getStoreInst() == getStoreInst();
0403 }
0404
0405
0406 void printInternal(raw_ostream &OS, bool PrintEType) const override {
0407 if (PrintEType)
0408 OS << "ExpressionTypeStore, ";
0409 this->BasicExpression::printInternal(OS, false);
0410 OS << " represents Store " << *Store;
0411 OS << " with StoredValue ";
0412 StoredValue->printAsOperand(OS);
0413 OS << " and MemoryLeader " << *getMemoryLeader();
0414 }
0415 };
0416
0417 class AggregateValueExpression final : public BasicExpression {
0418 private:
0419 unsigned MaxIntOperands;
0420 unsigned NumIntOperands = 0;
0421 unsigned *IntOperands = nullptr;
0422
0423 public:
0424 AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands)
0425 : BasicExpression(NumOperands, ET_AggregateValue),
0426 MaxIntOperands(NumIntOperands) {}
0427 AggregateValueExpression() = delete;
0428 AggregateValueExpression(const AggregateValueExpression &) = delete;
0429 AggregateValueExpression &
0430 operator=(const AggregateValueExpression &) = delete;
0431 ~AggregateValueExpression() override;
0432
0433 static bool classof(const Expression *EB) {
0434 return EB->getExpressionType() == ET_AggregateValue;
0435 }
0436
0437 using int_arg_iterator = unsigned *;
0438 using const_int_arg_iterator = const unsigned *;
0439
0440 int_arg_iterator int_op_begin() { return IntOperands; }
0441 int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; }
0442 const_int_arg_iterator int_op_begin() const { return IntOperands; }
0443 const_int_arg_iterator int_op_end() const {
0444 return IntOperands + NumIntOperands;
0445 }
0446 unsigned int_op_size() const { return NumIntOperands; }
0447 bool int_op_empty() const { return NumIntOperands == 0; }
0448 void int_op_push_back(unsigned IntOperand) {
0449 assert(NumIntOperands < MaxIntOperands &&
0450 "Tried to add too many int operands");
0451 assert(IntOperands && "Operands not allocated before pushing");
0452 IntOperands[NumIntOperands++] = IntOperand;
0453 }
0454
0455 virtual void allocateIntOperands(BumpPtrAllocator &Allocator) {
0456 assert(!IntOperands && "Operands already allocated");
0457 IntOperands = Allocator.Allocate<unsigned>(MaxIntOperands);
0458 }
0459
0460 bool equals(const Expression &Other) const override {
0461 if (!this->BasicExpression::equals(Other))
0462 return false;
0463 const AggregateValueExpression &OE = cast<AggregateValueExpression>(Other);
0464 return NumIntOperands == OE.NumIntOperands &&
0465 std::equal(int_op_begin(), int_op_end(), OE.int_op_begin());
0466 }
0467
0468 hash_code getHashValue() const override {
0469 return hash_combine(this->BasicExpression::getHashValue(),
0470 hash_combine_range(int_op_begin(), int_op_end()));
0471 }
0472
0473
0474 void printInternal(raw_ostream &OS, bool PrintEType) const override {
0475 if (PrintEType)
0476 OS << "ExpressionTypeAggregateValue, ";
0477 this->BasicExpression::printInternal(OS, false);
0478 OS << ", intoperands = {";
0479 for (unsigned i = 0, e = int_op_size(); i != e; ++i) {
0480 OS << "[" << i << "] = " << IntOperands[i] << " ";
0481 }
0482 OS << "}";
0483 }
0484 };
0485
0486 class int_op_inserter {
0487 private:
0488 using Container = AggregateValueExpression;
0489
0490 Container *AVE;
0491
0492 public:
0493 using iterator_category = std::output_iterator_tag;
0494 using value_type = void;
0495 using difference_type = void;
0496 using pointer = void;
0497 using reference = void;
0498
0499 explicit int_op_inserter(AggregateValueExpression &E) : AVE(&E) {}
0500 explicit int_op_inserter(AggregateValueExpression *E) : AVE(E) {}
0501
0502 int_op_inserter &operator=(unsigned int val) {
0503 AVE->int_op_push_back(val);
0504 return *this;
0505 }
0506 int_op_inserter &operator*() { return *this; }
0507 int_op_inserter &operator++() { return *this; }
0508 int_op_inserter &operator++(int) { return *this; }
0509 };
0510
0511 class PHIExpression final : public BasicExpression {
0512 private:
0513 BasicBlock *BB;
0514
0515 public:
0516 PHIExpression(unsigned NumOperands, BasicBlock *B)
0517 : BasicExpression(NumOperands, ET_Phi), BB(B) {}
0518 PHIExpression() = delete;
0519 PHIExpression(const PHIExpression &) = delete;
0520 PHIExpression &operator=(const PHIExpression &) = delete;
0521 ~PHIExpression() override;
0522
0523 static bool classof(const Expression *EB) {
0524 return EB->getExpressionType() == ET_Phi;
0525 }
0526
0527 bool equals(const Expression &Other) const override {
0528 if (!this->BasicExpression::equals(Other))
0529 return false;
0530 const PHIExpression &OE = cast<PHIExpression>(Other);
0531 return BB == OE.BB;
0532 }
0533
0534 hash_code getHashValue() const override {
0535 return hash_combine(this->BasicExpression::getHashValue(), BB);
0536 }
0537
0538
0539 void printInternal(raw_ostream &OS, bool PrintEType) const override {
0540 if (PrintEType)
0541 OS << "ExpressionTypePhi, ";
0542 this->BasicExpression::printInternal(OS, false);
0543 OS << "bb = " << BB;
0544 }
0545 };
0546
0547 class DeadExpression final : public Expression {
0548 public:
0549 DeadExpression() : Expression(ET_Dead) {}
0550 DeadExpression(const DeadExpression &) = delete;
0551 DeadExpression &operator=(const DeadExpression &) = delete;
0552
0553 static bool classof(const Expression *E) {
0554 return E->getExpressionType() == ET_Dead;
0555 }
0556 };
0557
0558 class VariableExpression final : public Expression {
0559 private:
0560 Value *VariableValue;
0561
0562 public:
0563 VariableExpression(Value *V) : Expression(ET_Variable), VariableValue(V) {}
0564 VariableExpression() = delete;
0565 VariableExpression(const VariableExpression &) = delete;
0566 VariableExpression &operator=(const VariableExpression &) = delete;
0567
0568 static bool classof(const Expression *EB) {
0569 return EB->getExpressionType() == ET_Variable;
0570 }
0571
0572 Value *getVariableValue() const { return VariableValue; }
0573 void setVariableValue(Value *V) { VariableValue = V; }
0574
0575 bool equals(const Expression &Other) const override {
0576 const VariableExpression &OC = cast<VariableExpression>(Other);
0577 return VariableValue == OC.VariableValue;
0578 }
0579
0580 hash_code getHashValue() const override {
0581 return hash_combine(this->Expression::getHashValue(),
0582 VariableValue->getType(), VariableValue);
0583 }
0584
0585
0586 void printInternal(raw_ostream &OS, bool PrintEType) const override {
0587 if (PrintEType)
0588 OS << "ExpressionTypeVariable, ";
0589 this->Expression::printInternal(OS, false);
0590 OS << " variable = " << *VariableValue;
0591 }
0592 };
0593
0594 class ConstantExpression final : public Expression {
0595 private:
0596 Constant *ConstantValue = nullptr;
0597
0598 public:
0599 ConstantExpression() : Expression(ET_Constant) {}
0600 ConstantExpression(Constant *constantValue)
0601 : Expression(ET_Constant), ConstantValue(constantValue) {}
0602 ConstantExpression(const ConstantExpression &) = delete;
0603 ConstantExpression &operator=(const ConstantExpression &) = delete;
0604
0605 static bool classof(const Expression *EB) {
0606 return EB->getExpressionType() == ET_Constant;
0607 }
0608
0609 Constant *getConstantValue() const { return ConstantValue; }
0610 void setConstantValue(Constant *V) { ConstantValue = V; }
0611
0612 bool equals(const Expression &Other) const override {
0613 const ConstantExpression &OC = cast<ConstantExpression>(Other);
0614 return ConstantValue == OC.ConstantValue;
0615 }
0616
0617 hash_code getHashValue() const override {
0618 return hash_combine(this->Expression::getHashValue(),
0619 ConstantValue->getType(), ConstantValue);
0620 }
0621
0622
0623 void printInternal(raw_ostream &OS, bool PrintEType) const override {
0624 if (PrintEType)
0625 OS << "ExpressionTypeConstant, ";
0626 this->Expression::printInternal(OS, false);
0627 OS << " constant = " << *ConstantValue;
0628 }
0629 };
0630
0631 class UnknownExpression final : public Expression {
0632 private:
0633 Instruction *Inst;
0634
0635 public:
0636 UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {}
0637 UnknownExpression() = delete;
0638 UnknownExpression(const UnknownExpression &) = delete;
0639 UnknownExpression &operator=(const UnknownExpression &) = delete;
0640
0641 static bool classof(const Expression *EB) {
0642 return EB->getExpressionType() == ET_Unknown;
0643 }
0644
0645 Instruction *getInstruction() const { return Inst; }
0646 void setInstruction(Instruction *I) { Inst = I; }
0647
0648 bool equals(const Expression &Other) const override {
0649 const auto &OU = cast<UnknownExpression>(Other);
0650 return Inst == OU.Inst;
0651 }
0652
0653 hash_code getHashValue() const override {
0654 return hash_combine(this->Expression::getHashValue(), Inst);
0655 }
0656
0657
0658 void printInternal(raw_ostream &OS, bool PrintEType) const override {
0659 if (PrintEType)
0660 OS << "ExpressionTypeUnknown, ";
0661 this->Expression::printInternal(OS, false);
0662 OS << " inst = " << *Inst;
0663 }
0664 };
0665
0666 }
0667
0668 }
0669
0670 #endif