mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #62480 from eeckstein/instruction-iteration
SIL: simplify deleting instructions while iterating over instructions.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 *
|
||||
|
||||
Reference in New Issue
Block a user