mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Fix LICM to avoid hoisting never-executed traps
It is legal for the optimizer to consider code after a loop always reachable, but when a loop has no exits, or when the loops exits are dominated by a conditional statement, we should not consider conditional statements within the loop as dominating all possible execution paths through the loop. At least not when there is at least one path through the loop that contains a "synchronization point", such as a function that may contain a memory barrier, perform I/O, or exit the program. Sadly, we still don't model synchronization points in the optimizer, so we need to conservatively assume all loops have a synchronization point and avoid hoisting conditional traps that may never be executed. Fixes rdar://66791257 (Print statement provokes "Can't unsafeBitCast between types of different sizes" when optimizations enabled) Originated in 2014.
This commit is contained in:
@@ -214,8 +214,8 @@ static void getDominatingBlocks(SmallVectorImpl<SILBasicBlock *> &domBlocks,
|
||||
SILLoop *Loop, DominanceInfo *DT) {
|
||||
auto HeaderBB = Loop->getHeader();
|
||||
auto DTRoot = DT->getNode(HeaderBB);
|
||||
SmallVector<SILBasicBlock *, 8> ExitingBBs;
|
||||
Loop->getExitingBlocks(ExitingBBs);
|
||||
SmallVector<SILBasicBlock *, 8> ExitingAndLatchBBs;
|
||||
Loop->getExitingAndLatchBlocks(ExitingAndLatchBBs);
|
||||
for (llvm::df_iterator<DominanceInfoNode *> It = llvm::df_begin(DTRoot),
|
||||
E = llvm::df_end(DTRoot);
|
||||
It != E;) {
|
||||
@@ -223,7 +223,7 @@ static void getDominatingBlocks(SmallVectorImpl<SILBasicBlock *> &domBlocks,
|
||||
|
||||
// Don't decent into control-dependent code. Only traverse into basic blocks
|
||||
// that dominate all exits.
|
||||
if (!std::all_of(ExitingBBs.begin(), ExitingBBs.end(),
|
||||
if (!std::all_of(ExitingAndLatchBBs.begin(), ExitingAndLatchBBs.end(),
|
||||
[=](SILBasicBlock *ExitBB) {
|
||||
return DT->dominates(CurBB, ExitBB);
|
||||
})) {
|
||||
|
||||
Reference in New Issue
Block a user