[SelectionDAG] Stop storing EVTs in a function scoped static std::set. (#118715)

EVTs potentially contain a Type * that points into memory owned by an
LLVMContext. Storing them in a function scoped static means they may
outlive the LLVMContext they point to.

This std::set is used to unique single element VT lists containing a
single extended EVT. Single element VT list with a simple EVT are
uniqued by a separate cache indexed by the MVT::SimpleValueType enum. VT
lists with more than one element are uniqued by a FoldingSet owned by
the SelectionDAG object.

This patch moves the single element cache into SelectionDAG so that it
will be destroyed when SelectionDAG is destroyed.

Fixes #88233
This commit is contained in:
Craig Topper
2024-12-05 12:56:36 -08:00
committed by GitHub
parent 2393ab65ed
commit 1d3f9f8862
3 changed files with 13 additions and 12 deletions

View File

@@ -44,6 +44,7 @@
#include <cstdint>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <tuple>
#include <utility>
@@ -247,6 +248,9 @@ class SelectionDAG {
BlockFrequencyInfo *BFI = nullptr;
MachineModuleInfo *MMI = nullptr;
/// Extended EVTs used for single value VTLists.
std::set<EVT, EVT::compareRawBits> EVTs;
/// List of non-single value types.
FoldingSet<SDVTListNode> VTListMap;

View File

@@ -664,7 +664,7 @@ private:
DebugLoc debugLoc;
/// Return a pointer to the specified value type.
static const EVT *getValueTypeList(EVT VT);
static const EVT *getValueTypeList(MVT VT);
/// Index in worklist of DAGCombiner, or negative if the node is not in the
/// worklist. -1 = not in worklist; -2 = not in worklist, but has already been
@@ -1124,7 +1124,7 @@ public:
void addUse(SDUse &U) { U.addToList(&UseList); }
protected:
static SDVTList getSDVTList(EVT VT) {
static SDVTList getSDVTList(MVT VT) {
SDVTList Ret = { getValueTypeList(VT), 1 };
return Ret;
}

View File

@@ -10623,7 +10623,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
}
SDVTList SelectionDAG::getVTList(EVT VT) {
return makeVTList(SDNode::getValueTypeList(VT), 1);
if (!VT.isExtended())
return makeVTList(SDNode::getValueTypeList(VT.getSimpleVT()), 1);
return makeVTList(&(*EVTs.insert(VT).first), 1);
}
SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2) {
@@ -12383,17 +12386,11 @@ namespace {
/// getValueTypeList - Return a pointer to the specified value type.
///
const EVT *SDNode::getValueTypeList(EVT VT) {
static std::set<EVT, EVT::compareRawBits> EVTs;
const EVT *SDNode::getValueTypeList(MVT VT) {
static EVTArray SimpleVTArray;
static sys::SmartMutex<true> VTMutex;
if (VT.isExtended()) {
sys::SmartScopedLock<true> Lock(VTMutex);
return &(*EVTs.insert(VT).first);
}
assert(VT.getSimpleVT() < MVT::VALUETYPE_SIZE && "Value type out of range!");
return &SimpleVTArray.VTs[VT.getSimpleVT().SimpleTy];
assert(VT < MVT::VALUETYPE_SIZE && "Value type out of range!");
return &SimpleVTArray.VTs[VT.SimpleTy];
}
/// hasNUsesOfValue - Return true if there are exactly NUSES uses of the