File indexing completed on 2026-05-10 08:44:43
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_TRANSFORMS_UTILS_INSTRUCTIONWORKLIST_H
0010 #define LLVM_TRANSFORMS_UTILS_INSTRUCTIONWORKLIST_H
0011
0012 #include "llvm/ADT/DenseMap.h"
0013 #include "llvm/ADT/STLExtras.h"
0014 #include "llvm/ADT/SetVector.h"
0015 #include "llvm/ADT/SmallVector.h"
0016 #include "llvm/IR/Instruction.h"
0017 #include "llvm/Support/Compiler.h"
0018 #include "llvm/Support/Debug.h"
0019 #include "llvm/Support/raw_ostream.h"
0020
0021 namespace llvm {
0022
0023
0024
0025 class InstructionWorklist {
0026 SmallVector<Instruction *, 256> Worklist;
0027 DenseMap<Instruction *, unsigned> WorklistMap;
0028
0029
0030
0031 SmallSetVector<Instruction *, 16> Deferred;
0032
0033 public:
0034 InstructionWorklist() = default;
0035
0036 InstructionWorklist(InstructionWorklist &&) = default;
0037 InstructionWorklist &operator=(InstructionWorklist &&) = default;
0038
0039 bool isEmpty() const { return Worklist.empty() && Deferred.empty(); }
0040
0041
0042
0043
0044 void add(Instruction *I) {
0045 if (Deferred.insert(I))
0046 LLVM_DEBUG(dbgs() << "ADD DEFERRED: " << *I << '\n');
0047 }
0048
0049
0050
0051 void addValue(Value *V) {
0052 if (Instruction *I = dyn_cast<Instruction>(V))
0053 add(I);
0054 }
0055
0056
0057
0058 void push(Instruction *I) {
0059 assert(I);
0060 assert(I->getParent() && "Instruction not inserted yet?");
0061
0062 if (WorklistMap.insert(std::make_pair(I, Worklist.size())).second) {
0063 LLVM_DEBUG(dbgs() << "ADD: " << *I << '\n');
0064 Worklist.push_back(I);
0065 }
0066 }
0067
0068 void pushValue(Value *V) {
0069 if (Instruction *I = dyn_cast<Instruction>(V))
0070 push(I);
0071 }
0072
0073 Instruction *popDeferred() {
0074 if (Deferred.empty())
0075 return nullptr;
0076 return Deferred.pop_back_val();
0077 }
0078
0079 void reserve(size_t Size) {
0080 Worklist.reserve(Size + 16);
0081 WorklistMap.reserve(Size);
0082 }
0083
0084
0085 void remove(Instruction *I) {
0086 DenseMap<Instruction *, unsigned>::iterator It = WorklistMap.find(I);
0087 if (It != WorklistMap.end()) {
0088
0089 Worklist[It->second] = nullptr;
0090 WorklistMap.erase(It);
0091 }
0092
0093 Deferred.remove(I);
0094 }
0095
0096 Instruction *removeOne() {
0097 if (Worklist.empty())
0098 return nullptr;
0099 Instruction *I = Worklist.pop_back_val();
0100 WorklistMap.erase(I);
0101 return I;
0102 }
0103
0104
0105
0106 void pushUsersToWorkList(Instruction &I) {
0107 for (User *U : I.users())
0108 push(cast<Instruction>(U));
0109 }
0110
0111
0112 void handleUseCountDecrement(Value *V) {
0113 if (auto *I = dyn_cast<Instruction>(V)) {
0114 add(I);
0115
0116
0117 if (I->hasOneUse())
0118 add(cast<Instruction>(*I->user_begin()));
0119 }
0120 }
0121
0122
0123 void zap() {
0124 assert(WorklistMap.empty() && "Worklist empty, but map not?");
0125 assert(Deferred.empty() && "Deferred instructions left over");
0126
0127
0128 WorklistMap.clear();
0129 }
0130 };
0131
0132 }
0133
0134 #endif