mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Teach the codemotion pass not to invalidate the analysis if no change was made.
Swift SVN r13590
This commit is contained in:
@@ -50,7 +50,8 @@ static bool isWriteMemBehavior(SILInstruction::MemoryBehavior B) {
|
|||||||
|
|
||||||
/// \brief Promote stored values to loads, remove dead stores and merge
|
/// \brief Promote stored values to loads, remove dead stores and merge
|
||||||
/// duplicated loads.
|
/// duplicated loads.
|
||||||
void promoteMemoryOperationsInBlock(SILBasicBlock *BB, AliasAnalysis *AA) {
|
bool promoteMemoryOperationsInBlock(SILBasicBlock *BB, AliasAnalysis *AA) {
|
||||||
|
bool Changed = false;
|
||||||
StoreInst *PrevStore = 0;
|
StoreInst *PrevStore = 0;
|
||||||
llvm::SmallPtrSet<LoadInst *, 8> Loads;
|
llvm::SmallPtrSet<LoadInst *, 8> Loads;
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ void promoteMemoryOperationsInBlock(SILBasicBlock *BB, AliasAnalysis *AA) {
|
|||||||
if (PrevStore && PrevStore->getDest() == SI->getDest()) {
|
if (PrevStore && PrevStore->getDest() == SI->getDest()) {
|
||||||
DEBUG(llvm::dbgs() << " Found a dead previous store... Removing...:"
|
DEBUG(llvm::dbgs() << " Found a dead previous store... Removing...:"
|
||||||
<< *PrevStore);
|
<< *PrevStore);
|
||||||
|
Changed = true;
|
||||||
recursivelyDeleteTriviallyDeadInstructions(PrevStore, true);
|
recursivelyDeleteTriviallyDeadInstructions(PrevStore, true);
|
||||||
PrevStore = SI;
|
PrevStore = SI;
|
||||||
NumDeadStores++;
|
NumDeadStores++;
|
||||||
@@ -93,6 +95,7 @@ void promoteMemoryOperationsInBlock(SILBasicBlock *BB, AliasAnalysis *AA) {
|
|||||||
DEBUG(llvm::dbgs() << " Forwarding store from: " << *PrevStore);
|
DEBUG(llvm::dbgs() << " Forwarding store from: " << *PrevStore);
|
||||||
SILValue(LI, 0).replaceAllUsesWith(PrevStore->getSrc());
|
SILValue(LI, 0).replaceAllUsesWith(PrevStore->getSrc());
|
||||||
recursivelyDeleteTriviallyDeadInstructions(LI, true);
|
recursivelyDeleteTriviallyDeadInstructions(LI, true);
|
||||||
|
Changed = true;
|
||||||
NumDupLoads++;
|
NumDupLoads++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -105,6 +108,7 @@ void promoteMemoryOperationsInBlock(SILBasicBlock *BB, AliasAnalysis *AA) {
|
|||||||
<< *PrevLd);
|
<< *PrevLd);
|
||||||
SILValue(LI, 0).replaceAllUsesWith(PrevLd);
|
SILValue(LI, 0).replaceAllUsesWith(PrevLd);
|
||||||
recursivelyDeleteTriviallyDeadInstructions(LI, true);
|
recursivelyDeleteTriviallyDeadInstructions(LI, true);
|
||||||
|
Changed = true;
|
||||||
LI = 0;
|
LI = 0;
|
||||||
NumDupLoads++;
|
NumDupLoads++;
|
||||||
break;
|
break;
|
||||||
@@ -160,6 +164,8 @@ void promoteMemoryOperationsInBlock(SILBasicBlock *BB, AliasAnalysis *AA) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Returns True if we can sink this instruction to another basic block.
|
/// \brief Returns True if we can sink this instruction to another basic block.
|
||||||
@@ -216,19 +222,20 @@ SILInstruction *findIdenticalInBlock(SILBasicBlock *BB, SILInstruction *Iden) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sinkCodeFromPredecessors(SILBasicBlock *BB) {
|
static bool sinkCodeFromPredecessors(SILBasicBlock *BB) {
|
||||||
|
bool Changed = false;
|
||||||
if (BB->pred_empty())
|
if (BB->pred_empty())
|
||||||
return;
|
return Changed;
|
||||||
|
|
||||||
// This block must be the only successor of all the predecessors.
|
// This block must be the only successor of all the predecessors.
|
||||||
for (auto P : BB->getPreds())
|
for (auto P : BB->getPreds())
|
||||||
if (P->getSingleSuccessor() != BB)
|
if (P->getSingleSuccessor() != BB)
|
||||||
return;
|
return Changed;
|
||||||
|
|
||||||
SILBasicBlock *FirstPred = *BB->pred_begin();
|
SILBasicBlock *FirstPred = *BB->pred_begin();
|
||||||
// The first Pred must have at least one non-terminator.
|
// The first Pred must have at least one non-terminator.
|
||||||
if (FirstPred->getTerminator() == FirstPred->begin())
|
if (FirstPred->getTerminator() == FirstPred->begin())
|
||||||
return;
|
return Changed;
|
||||||
|
|
||||||
DEBUG(llvm::dbgs() << " Sinking values from predecessors.\n");
|
DEBUG(llvm::dbgs() << " Sinking values from predecessors.\n");
|
||||||
|
|
||||||
@@ -264,6 +271,7 @@ static void sinkCodeFromPredecessors(SILBasicBlock *BB) {
|
|||||||
if (Dups.size()) {
|
if (Dups.size()) {
|
||||||
DEBUG(llvm::dbgs() << "Moving: " << *InstToSink);
|
DEBUG(llvm::dbgs() << "Moving: " << *InstToSink);
|
||||||
InstToSink->moveBefore(BB->begin());
|
InstToSink->moveBefore(BB->begin());
|
||||||
|
Changed = true;
|
||||||
for (auto I : Dups) {
|
for (auto I : Dups) {
|
||||||
I->replaceAllUsesWith(InstToSink);
|
I->replaceAllUsesWith(InstToSink);
|
||||||
I->eraseFromParent();
|
I->eraseFromParent();
|
||||||
@@ -280,19 +288,21 @@ static void sinkCodeFromPredecessors(SILBasicBlock *BB) {
|
|||||||
// If this instruction was a barrier then we can't sink anything else.
|
// If this instruction was a barrier then we can't sink anything else.
|
||||||
if (isSinkBarrier(InstToSink)) {
|
if (isSinkBarrier(InstToSink)) {
|
||||||
DEBUG(llvm::dbgs() << "Aborting on barrier: " << *InstToSink);
|
DEBUG(llvm::dbgs() << "Aborting on barrier: " << *InstToSink);
|
||||||
return;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the first instruction, we are done.
|
// This is the first instruction, we are done.
|
||||||
if (InstToSink == FirstPred->begin()) {
|
if (InstToSink == FirstPred->begin()) {
|
||||||
DEBUG(llvm::dbgs() << "Reached the first instruction.");
|
DEBUG(llvm::dbgs() << "Reached the first instruction.");
|
||||||
return;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkipBudget--;
|
SkipBudget--;
|
||||||
InstToSink = std::prev(InstToSink);
|
InstToSink = std::prev(InstToSink);
|
||||||
DEBUG(llvm::dbgs() << "Continuing scan. Next inst: " << *InstToSink);
|
DEBUG(llvm::dbgs() << "Continuing scan. Next inst: " << *InstToSink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SILCodeMotion : public SILFunctionTransform {
|
class SILCodeMotion : public SILFunctionTransform {
|
||||||
@@ -305,14 +315,17 @@ class SILCodeMotion : public SILFunctionTransform {
|
|||||||
|
|
||||||
AliasAnalysis *AA = PM->getAnalysis<AliasAnalysis>();
|
AliasAnalysis *AA = PM->getAnalysis<AliasAnalysis>();
|
||||||
|
|
||||||
|
bool Changed = false;
|
||||||
|
|
||||||
// Remove dead stores and merge duplicate loads.
|
// Remove dead stores and merge duplicate loads.
|
||||||
for (auto &BB : F)
|
for (auto &BB : F)
|
||||||
promoteMemoryOperationsInBlock(&BB, AA);
|
Changed |= promoteMemoryOperationsInBlock(&BB, AA);
|
||||||
|
|
||||||
// Sink duplicated code from predecessors.
|
// Sink duplicated code from predecessors.
|
||||||
for (auto &BB : F)
|
for (auto &BB : F)
|
||||||
sinkCodeFromPredecessors(&BB);
|
Changed |= sinkCodeFromPredecessors(&BB);
|
||||||
|
|
||||||
|
if (Changed)
|
||||||
PM->invalidateAllAnalysis(&F,SILAnalysis::InvalidationKind::Instructions);
|
PM->invalidateAllAnalysis(&F,SILAnalysis::InvalidationKind::Instructions);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user