forked from OSchip/llvm-project
[TableGen] Allocate `Operator` object on heap in `RecordOperatorMap`
Iterators for a `llvm::DenseMap` can be invalidated when an insertion occurs. In Pattern's `collectBoundArguments()`, we recursively handle all nested DAG nodes and grow the the `RecordOperatorMap`, while retaining a reference. This can cause the reference to be invalid and the program to behave randomly. Allocate each `Operator` object specifically to solve this issue. Also, `llvm::DenseMap` is a great way to map pointers to pointers, or map other small types to each other. This avoids placing the `Operator` object directly into the map. -- PiperOrigin-RevId: 243281486
This commit is contained in:
parent
138c972d11
commit
2dc6d205ac
|
@ -39,8 +39,14 @@ class Record;
|
||||||
namespace mlir {
|
namespace mlir {
|
||||||
namespace tblgen {
|
namespace tblgen {
|
||||||
|
|
||||||
// Mapping from TableGen Record to Operator wrapper object
|
// Mapping from TableGen Record to Operator wrapper object.
|
||||||
using RecordOperatorMap = llvm::DenseMap<const llvm::Record *, Operator>;
|
//
|
||||||
|
// We allocate each wrapper object in heap to make sure the pointer to it is
|
||||||
|
// valid throughout the lifetime of this map. This is important because this map
|
||||||
|
// is shared among multiple patterns to avoid creating the wrapper object for
|
||||||
|
// the same op again and again. But this map will continuously grow.
|
||||||
|
using RecordOperatorMap =
|
||||||
|
llvm::DenseMap<const llvm::Record *, std::unique_ptr<Operator>>;
|
||||||
|
|
||||||
class Pattern;
|
class Pattern;
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,11 @@ llvm::StringRef tblgen::DagNode::getOpName() const {
|
||||||
|
|
||||||
Operator &tblgen::DagNode::getDialectOp(RecordOperatorMap *mapper) const {
|
Operator &tblgen::DagNode::getDialectOp(RecordOperatorMap *mapper) const {
|
||||||
llvm::Record *opDef = cast<llvm::DefInit>(node->getOperator())->getDef();
|
llvm::Record *opDef = cast<llvm::DefInit>(node->getOperator())->getDef();
|
||||||
return mapper->try_emplace(opDef, opDef).first->second;
|
auto it = mapper->find(opDef);
|
||||||
|
if (it != mapper->end())
|
||||||
|
return *it->second;
|
||||||
|
return *mapper->try_emplace(opDef, llvm::make_unique<Operator>(opDef))
|
||||||
|
.first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned tblgen::DagNode::getNumOps() const {
|
unsigned tblgen::DagNode::getNumOps() const {
|
||||||
|
|
Loading…
Reference in New Issue