Changeset View
Changeset View
Standalone View
Standalone View
include/llvm/CodeGen/GlobalISel/GISelWorkList.h
Show All 26 Lines | |||||
// | // | ||||
// FIXME: Does it make sense to factor out common code with the | // FIXME: Does it make sense to factor out common code with the | ||||
// instcombinerWorkList? | // instcombinerWorkList? | ||||
template<unsigned N> | template<unsigned N> | ||||
class GISelWorkList { | class GISelWorkList { | ||||
SmallVector<MachineInstr *, N> Worklist; | SmallVector<MachineInstr *, N> Worklist; | ||||
DenseMap<MachineInstr *, unsigned> WorklistMap; | DenseMap<MachineInstr *, unsigned> WorklistMap; | ||||
#ifndef NDEBUG | |||||
bool Finalized = true; | |||||
#endif | |||||
public: | public: | ||||
GISelWorkList() : WorklistMap(N) {} | GISelWorkList() : WorklistMap(N) {} | ||||
bool empty() const { return WorklistMap.empty(); } | bool empty() const { return WorklistMap.empty(); } | ||||
unsigned size() const { return WorklistMap.size(); } | unsigned size() const { return WorklistMap.size(); } | ||||
// Since we don't know ahead of time how many instructions we're going to add | |||||
arsenm: size_t | |||||
// to the worklist, and migrating densemap's elements is quite expensive | |||||
// everytime we resize, only insert to the smallvector (typically during the | |||||
// initial phase of populating lists). Before the worklist can be used, | |||||
// finalize should be called. Also assert with NDEBUG if list is ever used | |||||
// without finalizing. Note that unlike insert, we won't check for duplicates | |||||
// - so the ideal place to use this is during the initial prepopulating phase | |||||
// of most passes. | |||||
void deferred_insert(MachineInstr *I) { | |||||
Worklist.push_back(I); | |||||
#ifndef NDEBUG | |||||
Finalized = false; | |||||
#endif | |||||
} | |||||
// This should only be called when using deferred_insert. | |||||
// This asserts that the WorklistMap is empty, and then | |||||
// inserts all the elements in the Worklist into the map. | |||||
// It also asserts if there are any duplicate elements found. | |||||
void finalize() { | |||||
assert(WorklistMap.empty() && "Expecting empty worklistmap"); | |||||
if (Worklist.size() > N) | |||||
WorklistMap.reserve(Worklist.size()); | |||||
for (unsigned i = 0; i < Worklist.size(); ++i) | |||||
if (!WorklistMap.try_emplace(Worklist[i], i).second) | |||||
llvm_unreachable("Duplicate elements in the list"); | |||||
#ifndef NDEBUG | |||||
Don't need braces here. paquette: Don't need braces here. | |||||
Finalized = true; | |||||
#endif | |||||
} | |||||
/// Add the specified instruction to the worklist if it isn't already in it. | /// Add the specified instruction to the worklist if it isn't already in it. | ||||
void insert(MachineInstr *I) { | void insert(MachineInstr *I) { | ||||
assert(Finalized && "GISelWorkList used without finalizing"); | |||||
if (WorklistMap.try_emplace(I, Worklist.size()).second) | if (WorklistMap.try_emplace(I, Worklist.size()).second) | ||||
Worklist.push_back(I); | Worklist.push_back(I); | ||||
} | } | ||||
/// Remove I from the worklist if it exists. | /// Remove I from the worklist if it exists. | ||||
void remove(const MachineInstr *I) { | void remove(const MachineInstr *I) { | ||||
assert((Finalized || WorklistMap.empty()) && "Neither finalized nor empty"); | |||||
This is redundant arsenm: This is redundant | |||||
auto It = WorklistMap.find(I); | auto It = WorklistMap.find(I); | ||||
if (It == WorklistMap.end()) return; // Not in worklist. | if (It == WorklistMap.end()) | ||||
return; // Not in worklist. | |||||
I think that in standard LLVM code style, the return should be on a newline. (Or, that's what clang-format does on my end anyway) if (It == WorklistMap.end()) return; paquette: I think that in standard LLVM code style, the return should be on a newline. (Or, that's what… | |||||
Clang format does not do that for me. aditya_nandakumar: Clang format does not do that for me. | |||||
// Don't bother moving everything down, just null out the slot. | // Don't bother moving everything down, just null out the slot. | ||||
Worklist[It->second] = nullptr; | Worklist[It->second] = nullptr; | ||||
WorklistMap.erase(It); | WorklistMap.erase(It); | ||||
} | } | ||||
void clear() { | void clear() { | ||||
Worklist.clear(); | Worklist.clear(); | ||||
WorklistMap.clear(); | WorklistMap.clear(); | ||||
} | } | ||||
MachineInstr *pop_back_val() { | MachineInstr *pop_back_val() { | ||||
assert(Finalized && "GISelWorkList used without finalizing"); | |||||
Ditto arsenm: Ditto | |||||
MachineInstr *I; | MachineInstr *I; | ||||
do { | do { | ||||
I = Worklist.pop_back_val(); | I = Worklist.pop_back_val(); | ||||
} while(!I); | } while(!I); | ||||
assert(I && "Pop back on empty worklist"); | assert(I && "Pop back on empty worklist"); | ||||
WorklistMap.erase(I); | WorklistMap.erase(I); | ||||
return I; | return I; | ||||
} | } | ||||
}; | }; | ||||
} // end namespace llvm. | } // end namespace llvm. | ||||
#endif | #endif |
size_t