[ownership] Update SROA to support OSSA.

Use destructure to chop up allocations. Other than that, just add
correct load/store qualifiers.
This commit is contained in:
zoecarver
2020-04-10 15:10:09 -07:00
committed by Michael Gottesman
parent c6ea30c963
commit 12d652e39f
3 changed files with 532 additions and 54 deletions

View File

@@ -67,8 +67,6 @@ public:
private:
SILValue createAgg(SILBuilder &B, SILLocation Loc, SILType Ty,
ArrayRef<SILValue> Elements);
SILValue createAggProjection(SILBuilder &B, SILLocation Loc,
SILValue Operand, unsigned EltNo);
unsigned getEltNoForProjection(SILInstruction *Inst);
void createAllocas(llvm::SmallVector<AllocStackInst *, 4> &NewAllocations);
};
@@ -87,24 +85,6 @@ SROAMemoryUseAnalyzer::createAgg(SILBuilder &B, SILLocation Loc,
return B.createStruct(Loc, Ty, Elements);
}
SILValue
SROAMemoryUseAnalyzer::createAggProjection(SILBuilder &B, SILLocation Loc,
SILValue Operand,
unsigned EltNo) {
if (TT)
return B.createTupleExtract(Loc, Operand, EltNo);
assert(SD && "SD should not be null since either it or TT must be set at "
"this point.");
auto Properties = SD->getStoredProperties();
unsigned Counter = 0;
for (auto *D : Properties)
if (Counter++ == EltNo)
return B.createStructExtract(Loc, Operand, D);
llvm_unreachable("Unknown field.");
}
unsigned SROAMemoryUseAnalyzer::getEltNoForProjection(SILInstruction *Inst) {
if (TT)
return cast<TupleElementAddrInst>(Inst)->getFieldNo();
@@ -249,9 +229,10 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector<AllocStackInst *> &Worklist
for (auto *LI : Loads) {
SILBuilderWithScope B(LI);
llvm::SmallVector<SILValue, 4> Elements;
for (auto *NewAI : NewAllocations)
Elements.push_back(B.createLoad(LI->getLoc(), NewAI,
LoadOwnershipQualifier::Unqualified));
for (auto *NewAI : NewAllocations) {
Elements.push_back(B.emitLoadValueOperation(LI->getLoc(), NewAI,
LI->getOwnershipQualifier()));
}
SILValue Agg = createAgg(B, LI->getLoc(), LI->getType().getObjectType(),
Elements);
LI->replaceAllUsesWith(Agg);
@@ -260,12 +241,15 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector<AllocStackInst *> &Worklist
// Change any aggregate stores into extracts + field stores.
for (auto *SI : Stores) {
SILBuilderWithScope B(SI);
for (unsigned EltNo : indices(NewAllocations))
B.createStore(SI->getLoc(),
createAggProjection(B, SI->getLoc(), SI->getSrc(), EltNo),
NewAllocations[EltNo],
StoreOwnershipQualifier::Unqualified);
SILBuilderWithScope builder(SI);
SmallVector<SILValue, 8> destructured;
builder.emitDestructureValueOperation(SI->getLoc(), SI->getSrc(),
destructured);
for (unsigned eltNo : indices(NewAllocations)) {
builder.emitStoreValueOperation(SI->getLoc(), destructured[eltNo],
NewAllocations[eltNo],
StoreOwnershipQualifier::Init);
}
SI->eraseFromParent();
}
@@ -356,10 +340,6 @@ public:
void run() override {
SILFunction *F = getFunction();
// FIXME: We should be able to handle ownership.
if (F->hasOwnership())
return;
LLVM_DEBUG(llvm::dbgs() << "***** SROA on function: " << F->getName()
<< " *****\n");