Merge remote-tracking branch 'origin/main' into rebranch

This commit is contained in:
swift-ci
2021-01-27 11:12:39 -08:00
40 changed files with 667 additions and 692 deletions

View File

@@ -97,7 +97,8 @@ class DCE {
typedef llvm::DomTreeNodeBase<SILBasicBlock> PostDomTreeNode;
SILFunction *F;
llvm::SmallPtrSet<SILNode *, 16> LiveValues;
llvm::SmallPtrSet<SILArgument *, 16> LiveArguments;
llvm::SmallPtrSet<SILInstruction *, 16> LiveInstructions;
BasicBlockSet LiveBlocks;
llvm::SmallVector<SILInstruction *, 64> Worklist;
PostDominanceInfo *PDT;
@@ -138,7 +139,8 @@ class DCE {
void computeMinPredecessorLevels(PostDomTreeNode *root);
void insertControllingInfo(SILBasicBlock *Block, unsigned Level);
void markValueLive(SILNode *V);
void markValueLive(SILValue V);
void markInstructionLive(SILInstruction *Inst);
void markTerminatorArgsLive(SILBasicBlock *Pred, SILBasicBlock *Succ,
size_t ArgIndex);
void markControllingTerminatorsLive(SILBasicBlock *Block);
@@ -173,32 +175,33 @@ public:
// Keep track of the fact that V is live and add it to our worklist
// so that we can process the values it depends on.
void DCE::markValueLive(SILNode *V) {
V = V->getRepresentativeSILNodeInObject();
if (LiveValues.count(V) || isa<SILUndef>(V))
void DCE::markValueLive(SILValue V) {
if (SILInstruction *inst = V->getDefiningInstruction())
return markInstructionLive(inst);
if (isa<SILUndef>(V))
return;
LLVM_DEBUG(llvm::dbgs() << "Marking as live:\n");
LLVM_DEBUG(V->dump());
LiveValues.insert(V);
if (auto *Def = dyn_cast<SILInstruction>(V)) {
markControllingTerminatorsLive(Def->getParent());
Worklist.push_back(Def);
return;
}
// TODO: MultiValueInstruction
assert(isa<SILArgument>(V) &&
"Only expected instructions and arguments!");
LLVM_DEBUG(llvm::dbgs() << "Marking as live: " << *V);
auto *Arg = cast<SILArgument>(V);
if (!LiveArguments.insert(Arg).second)
return;
markControllingTerminatorsLive(Arg->getParent());
propagateLiveBlockArgument(Arg);
}
void DCE::markInstructionLive(SILInstruction *Inst) {
if (!LiveInstructions.insert(Inst).second)
return;
LLVM_DEBUG(llvm::dbgs() << "Marking as live: " << *Inst);
markControllingTerminatorsLive(Inst->getParent());
Worklist.push_back(Inst);
}
/// Gets the producing instruction of a cond_fail condition. Currently these
/// are overflow builtins but may be extended to other instructions in the
/// future.
@@ -228,7 +231,7 @@ void DCE::markLive() {
if (auto *Prod = getProducer(cast<CondFailInst>(&I))) {
addReverseDependency(Prod, &I);
} else {
markValueLive(&I);
markInstructionLive(&I);
}
break;
}
@@ -237,7 +240,7 @@ void DCE::markLive() {
if (!Op->getType().isAddress()) {
addReverseDependency(Op, &I);
} else {
markValueLive(&I);
markInstructionLive(&I);
}
break;
}
@@ -255,7 +258,7 @@ void DCE::markLive() {
}
default:
if (seemsUseful(&I))
markValueLive(&I);
markInstructionLive(&I);
}
}
}
@@ -284,7 +287,7 @@ void DCE::markTerminatorArgsLive(SILBasicBlock *Pred,
// If the arguments are live, we need to keep the terminator that
// delivers those arguments.
markValueLive(Term);
markInstructionLive(Term);
switch (Term->getTermKind()) {
case TermKind::ReturnInst:
@@ -345,11 +348,11 @@ void DCE::propagateLiveBlockArgument(SILArgument *Arg) {
// is in reverse direction: Only if its definition (the Arg) is alive, also
// the debug_value instruction is alive.
for (Operand *DU : getDebugUses(Arg))
markValueLive(DU->getUser());
markInstructionLive(DU->getUser());
// Mark all reverse dependencies on the Arg live
for (auto *depInst : ReverseDependencies.lookup(Arg)) {
markValueLive(depInst);
markInstructionLive(depInst);
}
auto *Block = Arg->getParent();
@@ -371,14 +374,14 @@ void DCE::propagateLiveness(SILInstruction *I) {
// debug_value instruction is alive.
for (auto result : I->getResults())
for (Operand *DU : getDebugUses(result))
markValueLive(DU->getUser());
markInstructionLive(DU->getUser());
// Handle all other reverse-dependency instructions, like cond_fail,
// fix_lifetime, destroy_value, etc. Only if the definition is alive, the
// user itself is alive.
for (auto res : I->getResults()) {
for (auto *depInst : ReverseDependencies.lookup(res)) {
markValueLive(depInst);
markInstructionLive(depInst);
}
}
return;
@@ -448,7 +451,7 @@ void DCE::replaceBranchWithJump(SILInstruction *Inst, SILBasicBlock *Block) {
std::vector<SILValue> Args;
auto E = Block->args_end();
for (auto A = Block->args_begin(); A != E; ++A) {
assert(!LiveValues.count(*A) && "Unexpected live block argument!");
assert(!LiveArguments.count(*A) && "Unexpected live block argument!");
Args.push_back(SILUndef::get((*A)->getType(), *(*A)->getFunction()));
}
Branch =
@@ -462,8 +465,12 @@ void DCE::replaceBranchWithJump(SILInstruction *Inst, SILBasicBlock *Block) {
}
void DCE::endLifetimeOfLiveValue(SILValue value, SILInstruction *insertPt) {
if (!LiveValues.count(value->getRepresentativeSILNodeInObject())) {
return;
if (SILInstruction *inst = value->getDefiningInstruction()) {
if (!LiveInstructions.count(inst))
return;
} else if (auto *arg = dyn_cast<SILArgument>(value)) {
if (!LiveArguments.count(arg))
return;
}
SILBuilderWithScope builder(insertPt);
if (value.getOwnershipKind() == OwnershipKind::Owned) {
@@ -483,7 +490,7 @@ bool DCE::removeDead() {
for (auto &BB : *F) {
for (unsigned i = 0; i < BB.getArguments().size();) {
auto *arg = BB.getArgument(i);
if (LiveValues.count(arg)) {
if (LiveArguments.count(arg)) {
i++;
continue;
}
@@ -509,7 +516,7 @@ bool DCE::removeDead() {
auto insertPt = getInsertAfterPoint(arg).getValue();
SILBuilderWithScope builder(insertPt);
auto *destroy = builder.createDestroyValue(insertPt->getLoc(), arg);
LiveValues.insert(destroy->getRepresentativeSILNodeInObject());
LiveInstructions.insert(destroy);
}
i++;
Changed = true;
@@ -534,7 +541,7 @@ bool DCE::removeDead() {
for (auto I = BB.begin(), E = BB.end(); I != E; ) {
auto *Inst = &*I;
++I;
if (LiveValues.count(Inst) || isa<BranchInst>(Inst))
if (LiveInstructions.count(Inst) || isa<BranchInst>(Inst))
continue;
// We want to replace dead terminators with unconditional branches to
@@ -770,7 +777,7 @@ void DCE::markControllingTerminatorsLive(SILBasicBlock *Block) {
collectControllingBlocks(Block, ControllingBlocks);
for (auto BB : ControllingBlocks)
markValueLive(BB->getTerminator());
markInstructionLive(BB->getTerminator());
}
class DCEPass : public SILFunctionTransform {

View File

@@ -663,15 +663,15 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *ASI) {
}
// Remove dead address instructions that may be uses of the allocation.
SILNode *Node = Inst;
while (isa<StructElementAddrInst>(Node) ||
isa<TupleElementAddrInst>(Node) ||
isa<UncheckedAddrCastInst>(Node)) {
auto *I = cast<SingleValueInstruction>(Node);
if (!I->use_empty()) break;
Node = I->getOperand(0);
I->eraseFromParent();
auto *addrInst = dyn_cast<SingleValueInstruction>(Inst);
while (addrInst && addrInst->use_empty() &&
(isa<StructElementAddrInst>(addrInst) ||
isa<TupleElementAddrInst>(addrInst) ||
isa<UncheckedAddrCastInst>(addrInst))) {
SILValue op = addrInst->getOperand(0);
addrInst->eraseFromParent();
++NumInstRemoved;
addrInst = dyn_cast<SingleValueInstruction>(op);
}
}
}