Skip to content

Commit 4409f14

Browse files
authored
Merge pull request swiftlang#33987 from atrick/opt-licm-combined-ldst
Use AccessPath in LICM and split loads for combine load/store hoisting
2 parents cafd293 + 437765e commit 4409f14

File tree

5 files changed

+863
-125
lines changed

5 files changed

+863
-125
lines changed

include/swift/SIL/LoopInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class SILLoop : public llvm::LoopBase<SILBasicBlock, SILLoop> {
6060
}
6161
}
6262

63+
SILFunction *getFunction() const { return getHeader()->getParent(); }
64+
6365
private:
6466
friend class llvm::LoopInfoBase<SILBasicBlock, SILLoop>;
6567

include/swift/SIL/MemAccessUtils.h

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1369,7 +1369,7 @@ class AccessUseDefChainVisitor {
13691369
// Result visitNonAccess(SILValue base);
13701370
// Result visitPhi(SILPhiArgument *phi);
13711371
// Result visitStorageCast(SingleValueInstruction *cast, Operand *sourceOper);
1372-
// Result visitAccessProjection(SingleValueInstruction *cast,
1372+
// Result visitAccessProjection(SingleValueInstruction *projectedAddr,
13731373
// Operand *sourceOper);
13741374

13751375
Result visit(SILValue sourceAddr);
@@ -1480,6 +1480,82 @@ Result AccessUseDefChainVisitor<Impl, Result>::visit(SILValue sourceAddr) {
14801480

14811481
} // end namespace swift
14821482

1483+
//===----------------------------------------------------------------------===//
1484+
// AccessUseDefChainCloner
1485+
//===----------------------------------------------------------------------===//
1486+
1487+
namespace swift {
1488+
1489+
/// Clone all projections and casts on the access use-def chain until either the
1490+
/// specified predicate is true or the access base is reached.
1491+
///
1492+
/// This will not clone ref_element_addr or ref_tail_addr because those aren't
1493+
/// part of the access chain.
1494+
template <typename UnaryPredicate>
1495+
class AccessUseDefChainCloner
1496+
: public AccessUseDefChainVisitor<AccessUseDefChainCloner<UnaryPredicate>,
1497+
SILValue> {
1498+
UnaryPredicate predicate;
1499+
SILInstruction *insertionPoint;
1500+
1501+
public:
1502+
AccessUseDefChainCloner(UnaryPredicate predicate,
1503+
SILInstruction *insertionPoint)
1504+
: predicate(predicate), insertionPoint(insertionPoint) {}
1505+
1506+
// Recursive main entry point
1507+
SILValue cloneUseDefChain(SILValue addr) {
1508+
if (!predicate(addr))
1509+
return addr;
1510+
1511+
return this->visit(addr);
1512+
}
1513+
1514+
// Recursively clone an address on the use-def chain.
1515+
SingleValueInstruction *cloneProjection(SingleValueInstruction *projectedAddr,
1516+
Operand *sourceOper) {
1517+
SILValue projectedSource = cloneUseDefChain(sourceOper->get());
1518+
SILInstruction *clone = projectedAddr->clone(insertionPoint);
1519+
clone->setOperand(sourceOper->getOperandNumber(), projectedSource);
1520+
return cast<SingleValueInstruction>(clone);
1521+
}
1522+
1523+
// MARK: Visitor implementation
1524+
1525+
SILValue visitBase(SILValue base, AccessedStorage::Kind kind) {
1526+
assert(false && "access base cannot be cloned");
1527+
}
1528+
1529+
SILValue visitNonAccess(SILValue base) {
1530+
assert(false && "unknown address root cannot be cloned");
1531+
return SILValue();
1532+
}
1533+
1534+
SILValue visitPhi(SILPhiArgument *phi) {
1535+
assert(false && "unexpected phi on access path");
1536+
return SILValue();
1537+
}
1538+
1539+
SILValue visitStorageCast(SingleValueInstruction *cast, Operand *sourceOper) {
1540+
return cloneProjection(cast, sourceOper);
1541+
}
1542+
1543+
SILValue visitAccessProjection(SingleValueInstruction *projectedAddr,
1544+
Operand *sourceOper) {
1545+
return cloneProjection(projectedAddr, sourceOper);
1546+
}
1547+
};
1548+
1549+
template <typename UnaryPredicate>
1550+
SILValue cloneUseDefChain(SILValue addr, SILInstruction *insertionPoint,
1551+
UnaryPredicate shouldFollowUse) {
1552+
return AccessUseDefChainCloner<UnaryPredicate>(shouldFollowUse,
1553+
insertionPoint)
1554+
.cloneUseDefChain(addr);
1555+
}
1556+
1557+
} // end namespace swift
1558+
14831559
//===----------------------------------------------------------------------===//
14841560
// MARK: Verification
14851561
//===----------------------------------------------------------------------===//

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,13 @@ class AccessPhiVisitor
122122
phiArg->getIncomingPhiValues(pointerWorklist);
123123
}
124124

125-
void visitStorageCast(SingleValueInstruction *projectedAddr,
126-
Operand *sourceOper) {
125+
void visitStorageCast(SingleValueInstruction *cast, Operand *sourceOper) {
127126
// Allow conversions to/from pointers and addresses on disjoint phi paths
128127
// only if the underlying useDefVisitor allows it.
129128
if (storageCastTy == IgnoreStorageCast)
130129
pointerWorklist.push_back(sourceOper->get());
131130
else
132-
visitNonAccess(projectedAddr);
131+
visitNonAccess(cast);
133132
}
134133

135134
void visitAccessProjection(SingleValueInstruction *projectedAddr,
@@ -207,8 +206,7 @@ class FindAccessVisitorImpl : public AccessUseDefChainVisitor<Impl, SILValue> {
207206
return this->asImpl().visitNonAccess(phiArg);
208207
}
209208

210-
SILValue visitStorageCast(SingleValueInstruction *projectedAddr,
211-
Operand *sourceAddr) {
209+
SILValue visitStorageCast(SingleValueInstruction *, Operand *sourceAddr) {
212210
assert(storageCastTy == IgnoreStorageCast);
213211
return sourceAddr->get();
214212
}
@@ -303,12 +301,11 @@ class FindAccessBaseVisitor
303301
}
304302

305303
// Override visitStorageCast to avoid seeing through arbitrary address casts.
306-
SILValue visitStorageCast(SingleValueInstruction *projectedAddr,
307-
Operand *sourceAddr) {
304+
SILValue visitStorageCast(SingleValueInstruction *cast, Operand *sourceAddr) {
308305
if (storageCastTy == StopAtStorageCast)
309-
return visitNonAccess(projectedAddr);
306+
return visitNonAccess(cast);
310307

311-
return SuperTy::visitStorageCast(projectedAddr, sourceAddr);
308+
return SuperTy::visitStorageCast(cast, sourceAddr);
312309
}
313310
};
314311

0 commit comments

Comments
 (0)