mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SILOptimizer: add basic block utilities ReachingReturnBlocks and NonErrorHandlingBlocks
* ReachingReturnBlocks: computes the set of blocks from which a path to the return-block exists (does not include paths to a throw-block) * NonErrorHandlingBlocks: computes the set of blocks which are not used for error handling, i.e. not (exclusively) reachable from the error-block of a try_apply
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
#include "swift/SIL/BasicBlockBits.h"
|
#include "swift/SIL/BasicBlockBits.h"
|
||||||
#include "swift/SIL/SILCloner.h"
|
#include "swift/SIL/SILCloner.h"
|
||||||
#include "swift/SIL/SILInstruction.h"
|
#include "swift/SIL/SILInstruction.h"
|
||||||
|
#include "swift/SIL/BasicBlockDatastructures.h"
|
||||||
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
|
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
@@ -54,6 +55,34 @@ public:
|
|||||||
bool isVisited(SILBasicBlock *bb) const { return visited.contains(bb); }
|
bool isVisited(SILBasicBlock *bb) const { return visited.contains(bb); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Computes the set of blocks from which a path to the return-block exists.
|
||||||
|
/// This does not include pathes to a throw-block.
|
||||||
|
class ReachingReturnBlocks {
|
||||||
|
BasicBlockWorklist worklist;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ReachingReturnBlocks(SILFunction *function);
|
||||||
|
|
||||||
|
/// Returns true if there exists a path from \p block to the return-block.
|
||||||
|
bool reachesReturn(SILBasicBlock *block) const {
|
||||||
|
return worklist.isVisited(block);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Computes the set of blocks which are not used for error handling, i.e. not
|
||||||
|
/// (exclusively) reachable from the error-block of a try_apply.
|
||||||
|
class NonErrorHandlingBlocks {
|
||||||
|
BasicBlockWorklist worklist;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NonErrorHandlingBlocks(SILFunction *function);
|
||||||
|
|
||||||
|
/// Returns true if there exists a path from \p block to the return-block.
|
||||||
|
bool isNonErrorHandling(SILBasicBlock *block) const {
|
||||||
|
return worklist.isVisited(block);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Remove all instructions in the body of \p bb in safe manner by using
|
/// Remove all instructions in the body of \p bb in safe manner by using
|
||||||
/// undef.
|
/// undef.
|
||||||
void clearBlockBody(SILBasicBlock *bb);
|
void clearBlockBody(SILBasicBlock *bb);
|
||||||
|
|||||||
@@ -39,6 +39,33 @@ bool ReachableBlocks::visit(function_ref<bool(SILBasicBlock *)> visitor) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReachingReturnBlocks::ReachingReturnBlocks(SILFunction *function)
|
||||||
|
: worklist(function) {
|
||||||
|
for (SILBasicBlock &block : *function) {
|
||||||
|
if (isa<ReturnInst>(block.getTerminator()))
|
||||||
|
worklist.push(&block);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (SILBasicBlock *block = worklist.pop()) {
|
||||||
|
for (SILBasicBlock *pred : block->getPredecessorBlocks()) {
|
||||||
|
worklist.pushIfNotVisited(pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NonErrorHandlingBlocks::NonErrorHandlingBlocks(SILFunction *function)
|
||||||
|
: worklist(function->getEntryBlock()) {
|
||||||
|
while (SILBasicBlock *block = worklist.pop()) {
|
||||||
|
if (auto ta = dyn_cast<TryApplyInst>(block->getTerminator())) {
|
||||||
|
worklist.pushIfNotVisited(ta->getNormalBB());
|
||||||
|
} else {
|
||||||
|
for (SILBasicBlock *succ : block->getSuccessorBlocks()) {
|
||||||
|
worklist.pushIfNotVisited(succ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Remove all instructions in the body of \p bb in safe manner by using
|
/// Remove all instructions in the body of \p bb in safe manner by using
|
||||||
/// undef.
|
/// undef.
|
||||||
void swift::clearBlockBody(SILBasicBlock *bb) {
|
void swift::clearBlockBody(SILBasicBlock *bb) {
|
||||||
|
|||||||
Reference in New Issue
Block a user