bool processed;
};
- /// Attempt to eliminate a redundant operation. Returns true if the operation
- /// was marked for removal, false otherwise.
- bool simplifyOperation(Operation *op);
+ /// Attempt to eliminate a redundant operation. Returns success if the
+ /// operation was marked for removal, failure otherwise.
+ LogicalResult simplifyOperation(ScopedMapTy &knownValues, Operation *op);
- void simplifyBlock(DominanceInfo &domInfo, Block *bb);
- void simplifyRegion(DominanceInfo &domInfo, Region ®ion);
+ void simplifyBlock(ScopedMapTy &knownValues, DominanceInfo &domInfo,
+ Block *bb);
+ void simplifyRegion(ScopedMapTy &knownValues, DominanceInfo &domInfo,
+ Region ®ion);
void runOnFunction() override;
private:
- /// A scoped hash table of defining operations within a function.
- ScopedMapTy knownValues;
-
/// Operations marked as dead and to be erased.
std::vector<Operation *> opsToErase;
};
} // end anonymous namespace
/// Attempt to eliminate a redundant operation.
-bool CSE::simplifyOperation(Operation *op) {
+LogicalResult CSE::simplifyOperation(ScopedMapTy &knownValues, Operation *op) {
// Don't simplify operations with nested blocks. We don't currently model
// equality comparisons correctly among other things. It is also unclear
// whether we would want to CSE such operations.
if (op->getNumRegions() != 0)
- return false;
+ return failure();
// TODO(riverriddle) We currently only eliminate non side-effecting
// operations.
if (!op->hasNoSideEffect())
- return false;
+ return failure();
// If the operation is already trivially dead just add it to the erase list.
if (op->use_empty()) {
opsToErase.push_back(op);
- return true;
+ return success();
}
// Look for an existing definition for the operation.
!op->getLoc().isa<UnknownLoc>()) {
existing->setLoc(op->getLoc());
}
- return true;
+ return success();
}
// Otherwise, we add this operation to the known values map.
knownValues.insert(op, op);
- return false;
+ return failure();
}
-void CSE::simplifyBlock(DominanceInfo &domInfo, Block *bb) {
- for (auto &i : *bb) {
+void CSE::simplifyBlock(ScopedMapTy &knownValues, DominanceInfo &domInfo,
+ Block *bb) {
+ for (auto &inst : *bb) {
// If the operation is simplified, we don't process any held regions.
- if (simplifyOperation(&i))
+ if (succeeded(simplifyOperation(knownValues, &inst)))
+ continue;
+
+ // If this operation is isolated above, we can't process nested regions with
+ // the given 'knownValues' map. This would cause the insertion of implicit
+ // captures in explicit capture only regions.
+ if (!inst.isRegistered() || inst.isKnownIsolatedFromAbove()) {
+ ScopedMapTy nestedKnownValues;
+ for (auto ®ion : inst.getRegions())
+ simplifyRegion(nestedKnownValues, domInfo, region);
continue;
+ }
- // Simplify any held blocks.
- for (auto ®ion : i.getRegions())
- simplifyRegion(domInfo, region);
+ // Otherwise, process nested regions normally.
+ for (auto ®ion : inst.getRegions())
+ simplifyRegion(knownValues, domInfo, region);
}
}
-void CSE::simplifyRegion(DominanceInfo &domInfo, Region ®ion) {
+void CSE::simplifyRegion(ScopedMapTy &knownValues, DominanceInfo &domInfo,
+ Region ®ion) {
// If the region is empty there is nothing to do.
if (region.empty())
return;
// If the region only contains one block, then simplify it directly.
if (std::next(region.begin()) == region.end()) {
ScopedMapTy::ScopeTy scope(knownValues);
- simplifyBlock(domInfo, ®ion.front());
+ simplifyBlock(knownValues, domInfo, ®ion.front());
return;
}
// Check to see if we need to process this node.
if (!currentNode->processed) {
currentNode->processed = true;
- simplifyBlock(domInfo, currentNode->node->getBlock());
+ simplifyBlock(knownValues, domInfo, currentNode->node->getBlock());
}
// Otherwise, check to see if we need to process a child node.
}
void CSE::runOnFunction() {
- simplifyRegion(getAnalysis<DominanceInfo>(), getFunction().getBody());
+ /// A scoped hash table of defining operations within a function.
+ ScopedMapTy knownValues;
+ simplifyRegion(knownValues, getAnalysis<DominanceInfo>(),
+ getFunction().getBody());
// If no operations were erased, then we mark all analyses as preserved.
- if (opsToErase.empty()) {
- markAllAnalysesPreserved();
- return;
- }
+ if (opsToErase.empty())
+ return markAllAnalysesPreserved();
/// Erase any operations that were marked as dead during simplification.
for (auto *op : opsToErase)