mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user