Merge pull request #62480 from eeckstein/instruction-iteration

SIL: simplify deleting instructions while iterating over instructions.
This commit is contained in:
eeckstein
2022-12-13 10:45:06 +01:00
committed by GitHub
34 changed files with 642 additions and 476 deletions

View File

@@ -91,10 +91,6 @@ void SILBasicBlock::push_front(SILInstruction *I) {
InstList.push_front(I);
}
void SILBasicBlock::remove(SILInstruction *I) {
InstList.remove(I);
}
void SILBasicBlock::eraseAllInstructions(SILModule &module) {
while (!empty()) {
erase(&*begin(), module);
@@ -107,11 +103,26 @@ void SILBasicBlock::erase(SILInstruction *I) {
}
void SILBasicBlock::erase(SILInstruction *I, SILModule &module) {
assert(!I->isDeleted() && "double delete of instruction");
module.willDeleteInstruction(I);
InstList.remove(I);
I->asSILNode()->markAsDeleted();
module.scheduleForDeletion(I);
}
void SILBasicBlock::moveInstruction(SILInstruction *inst,
SILInstruction *beforeInst) {
if (inst == beforeInst)
return;
inst->getParent()->InstList.remove(inst);
beforeInst->getParent()->insert(beforeInst->getIterator(), inst);
}
void SILBasicBlock::moveInstructionToFront(SILInstruction *inst) {
inst->getParent()->InstList.remove(inst);
push_front(inst);
}
/// This method unlinks 'self' from the containing SILFunction and deletes it.
void SILBasicBlock::eraseFromParent() {
getParent()->eraseBlock(this);

View File

@@ -61,15 +61,9 @@ SILBasicBlock *llvm::ilist_traits<SILInstruction>::getContainingBlock() {
void llvm::ilist_traits<SILInstruction>::addNodeToList(SILInstruction *I) {
assert(I->ParentBB == nullptr && "Already in a list!");
I->ParentBB = getContainingBlock();
}
void llvm::ilist_traits<SILInstruction>::removeNodeFromList(SILInstruction *I) {
// When an instruction is removed from a BB, clear the parent pointer.
I->ParentBB = nullptr;
}
void llvm::ilist_traits<SILInstruction>::
transferNodesFromList(llvm::ilist_traits<SILInstruction> &L2,
instr_iterator first, instr_iterator last) {
@@ -103,16 +97,6 @@ transferNodesFromList(llvm::ilist_traits<SILInstruction> &L2,
ASSERT_IMPLEMENTS_STATIC(CLASS, PARENT, classof, bool(SILNodePointer));
#include "swift/SIL/SILNodes.def"
void SILInstruction::removeFromParent() {
#ifndef NDEBUG
for (auto result : getResults()) {
assert(result->use_empty() && "Uses of SILInstruction remain at deletion.");
}
#endif
getParent()->remove(this);
ParentBB = nullptr;
}
/// eraseFromParent - This method unlinks 'self' from the containing basic
/// block and deletes it.
///
@@ -126,18 +110,13 @@ void SILInstruction::eraseFromParent() {
}
void SILInstruction::moveFront(SILBasicBlock *Block) {
getParent()->remove(this);
Block->push_front(this);
Block->moveInstructionToFront(this);
}
/// Unlink this instruction from its current basic block and insert it into
/// the basic block that Later lives in, right before Later.
void SILInstruction::moveBefore(SILInstruction *Later) {
if (this == Later)
return;
getParent()->remove(this);
Later->getParent()->insert(Later, this);
SILBasicBlock::moveInstruction(this, Later);
}
/// Unlink this instruction from its current basic block and insert it into

View File

@@ -164,8 +164,8 @@ void SILModule::checkForLeaks() const {
if (!getOptions().checkSILModuleLeaks)
return;
int instsInModule = std::distance(scheduledForDeletion.begin(),
scheduledForDeletion.end());
int instsInModule = scheduledForDeletion.size();
for (const SILFunction &F : *this) {
const SILFunction *sn = &F;
do {
@@ -264,9 +264,11 @@ void SILModule::willDeleteInstruction(SILInstruction *I) {
if (const CanOpenedArchetypeType archeTy =
svi->getDefinedOpenedArchetype()) {
OpenedArchetypeKey key = {archeTy, svi->getFunction()};
assert(RootOpenedArchetypeDefs.lookup(key) == svi &&
"archetype def was not registered");
RootOpenedArchetypeDefs.erase(key);
// In case `willDeleteInstruction` is called twice for the same instruction,
// we need to check if the archetype is really still in the map for this
// instruction.
if (RootOpenedArchetypeDefs.lookup(key) == svi)
RootOpenedArchetypeDefs.erase(key);
}
}
}
@@ -274,15 +276,14 @@ void SILModule::willDeleteInstruction(SILInstruction *I) {
void SILModule::scheduleForDeletion(SILInstruction *I) {
I->dropAllReferences();
scheduledForDeletion.push_back(I);
I->ParentBB = nullptr;
}
void SILModule::flushDeletedInsts() {
while (!scheduledForDeletion.empty()) {
SILInstruction *inst = &*scheduledForDeletion.begin();
scheduledForDeletion.erase(inst);
AlignedFree(inst);
for (SILInstruction *instToDelete : scheduledForDeletion) {
SILInstruction::destroy(instToDelete);
AlignedFree(instToDelete);
}
scheduledForDeletion.clear();
}
SILWitnessTable *