Implement a few silcombine transformations for arrays (#13652)

* Implement a few silcombine transformations for arrays

 - Useless existential_ref <-> class conversions.
 - mark_dependence_inst depending on uninteresting instructions.
 - release(init_existential_ref(x)) -> release(x) when hasOneUse(x)
 - Update COWArrayOpt to handle the new forms generated by this.

these aren't massive performance wins, but do shrink the size of SIL when
dealing with arrays.

* Generalize testcase to work on linux and on mac when checking stdlib is enabled.
This commit is contained in:
Chris Lattner
2017-12-30 22:30:37 -08:00
committed by GitHub
parent b236feb02d
commit de289752fe
6 changed files with 160 additions and 23 deletions

View File

@@ -797,7 +797,7 @@ bool COWArrayOpt::checkSafeElementValueUses(UserOperList &ElementValueUsers) {
static bool isArrayEltStore(StoreInst *SI) {
SILValue Dest = stripAddressProjections(SI->getDest());
if (auto *MD = dyn_cast<MarkDependenceInst>(Dest))
Dest = MD->getOperand(0);
Dest = MD->getValue();
if (auto *PtrToAddr =
dyn_cast<PointerToAddressInst>(stripAddressProjections(Dest)))
@@ -1095,17 +1095,21 @@ private:
DepInsts.push_back(StructExtractArrayAddr);
// Check the base the array element address is dependent on.
auto *EnumArrayAddr = dyn_cast<EnumInst>(MarkDependence->getBase());
if (!EnumArrayAddr)
return false;
DepInsts.push_back(EnumArrayAddr);
auto *UncheckedRefCast =
dyn_cast<UncheckedRefCastInst>(EnumArrayAddr->getOperand());
if (!UncheckedRefCast)
return false;
DepInsts.push_back(UncheckedRefCast);
SILValue base = MarkDependence->getBase();
SILValue ArrayBuffer = stripValueProjections(UncheckedRefCast->getOperand(), DepInsts);
// We can optionally have an enum instruction here.
if (auto *EnumArrayAddr = dyn_cast<EnumInst>(base)) {
DepInsts.push_back(EnumArrayAddr);
base = EnumArrayAddr->getOperand();
}
// We can optionally have an unchecked cast.
if (auto *UncheckedRefCast = dyn_cast<UncheckedRefCastInst>(base)) {
DepInsts.push_back(UncheckedRefCast);
base = UncheckedRefCast->getOperand();
}
SILValue ArrayBuffer = stripValueProjections(base, DepInsts);
auto *BaseLoad = dyn_cast<LoadInst>(ArrayBuffer);
if (!BaseLoad || Loop->contains(BaseLoad->getOperand()->getParentBlock()))
return false;