[region-isolation] Track operand info in a separate map rather than inline in a TransferringOperand data structure.

This is backing out an approach that I thought would be superior, but ended up
causing problems.

Originally, we mapped a region number to an immutable pointer set containing
Operand * where the region was tranferred. This worked great for a time... until
I began to need to propagate other information from the transferring code in the
analysis to the actual diagnostic emitter.

To be able to do that, my thought was to make a wrapper type around Operand
called TransferringOperand that contained the operand and the other information
I needed. This seemed to provide me what I wanted but I later found that since
the immutable pointer set was tracking TransferringOperands which were always
newly wrapped with an Operand *, we actually always created new pointer
sets. This is of course wasteful from a memory perspective, but also prevents me
from tracking transferring operand sets during the dataflow since we would never
converge.

In this commit, I fix that issue by again tracking just an Operand * in the
TransferringOperandSet and instead map each operand to a state structure which
we merge dataflow state into whenever we visit it. This provides us with
everything we need to in the next commit to including a region -> transferring
operand set equality check in our dataflow equations and always converge.
This commit is contained in:
Michael Gottesman
2024-04-09 13:21:03 -07:00
parent 13d01394d4
commit ca8179aa7c
7 changed files with 258 additions and 248 deletions

View File

@@ -626,18 +626,8 @@ void Partition::print(llvm::raw_ostream &os) const {
for (auto [regionNo, elementNumbers] : multimap.getRange()) {
auto iter = regionToTransferredOpMap.find(regionNo);
bool isTransferred = iter != regionToTransferredOpMap.end();
bool isClosureCaptured = false;
if (isTransferred) {
isClosureCaptured = llvm::any_of(iter->second->range(),
[](const TransferringOperand *operand) {
return operand->isClosureCaptured();
});
}
if (isTransferred) {
os << '{';
if (isClosureCaptured)
os << '*';
} else {
os << '(';
}
@@ -647,8 +637,6 @@ void Partition::print(llvm::raw_ostream &os) const {
os << (j++ ? " " : "") << i;
}
if (isTransferred) {
if (isClosureCaptured)
os << '*';
os << '}';
} else {
os << ')';
@@ -668,19 +656,10 @@ void Partition::printVerbose(llvm::raw_ostream &os) const {
for (auto [regionNo, elementNumbers] : multimap.getRange()) {
auto iter = regionToTransferredOpMap.find(regionNo);
bool isTransferred = iter != regionToTransferredOpMap.end();
bool isClosureCaptured = false;
if (isTransferred) {
isClosureCaptured = llvm::any_of(iter->second->range(),
[](const TransferringOperand *operand) {
return operand->isClosureCaptured();
});
}
os << "Region: " << regionNo << ". ";
if (isTransferred) {
os << '{';
if (isClosureCaptured)
os << '*';
} else {
os << '(';
}
@@ -690,8 +669,6 @@ void Partition::printVerbose(llvm::raw_ostream &os) const {
os << (j++ ? " " : "") << i;
}
if (isTransferred) {
if (isClosureCaptured)
os << '*';
os << '}';
} else {
os << ')';
@@ -1016,7 +993,8 @@ void IsolationHistory::pushMergeElementRegions(Element elementToMergeInto,
// Push that \p other should be merged into this region.
void IsolationHistory::pushCFGHistoryJoin(Node *otherNode) {
if (!otherNode)
// If otherNode is nullptr or represents our same history, do not merge.
if (!otherNode || otherNode == head)
return;
// If we do not have any history, just take on the history of otherNode. We