Skip to content

Commit 4b7effa

Browse files
committed
---
yaml --- r: 347134 b: refs/heads/master c: 5a8f2b1 h: refs/heads/master
1 parent a16518b commit 4b7effa

File tree

15 files changed

+1456
-452
lines changed

15 files changed

+1456
-452
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 367cc7de10d76b5b4965dcd3f4257e33b5614a14
2+
refs/heads/master: 5a8f2b1836c18673cb2634f91d0377f2a6da0cb7
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/SIL/MemAccessUtils.h

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ class AccessedStorage {
160160
64 - NumAccessedStorageBits,
161161
seenNestedConflict : 1,
162162
beginAccessIndex : 63 - NumAccessedStorageBits);
163+
164+
// Define data flow bits for use in the AccessEnforcementDom pass. Each
165+
// begin_access in the function is mapped to one instance of this subclass.
166+
SWIFT_INLINE_BITFIELD(DomAccessedStorage, AccessedStorage, 1 + 1,
167+
isInner : 1, containsRead : 1);
163168
} Bits;
164169

165170
private:
@@ -190,6 +195,10 @@ class AccessedStorage {
190195

191196
Kind getKind() const { return static_cast<Kind>(Bits.AccessedStorage.Kind); }
192197

198+
// Clear any bits reserved for subclass data. Useful for up-casting back to
199+
// the base class.
200+
void resetSubclassData() { initKind(getKind()); }
201+
193202
SILValue getValue() const {
194203
assert(getKind() != Argument && getKind() != Global && getKind() != Class);
195204
return value;
@@ -215,6 +224,10 @@ class AccessedStorage {
215224
return objProj;
216225
}
217226

227+
/// Return true if the given storage objects have identical storage locations.
228+
///
229+
/// This compares only the AccessedStorage base class bits, ignoring the
230+
/// subclass bits. It is used for hash lookup equality.
218231
bool hasIdenticalBase(const AccessedStorage &other) const {
219232
if (getKind() != other.getKind())
220233
return false;
@@ -233,7 +246,6 @@ class AccessedStorage {
233246
case Class:
234247
return objProj == other.objProj;
235248
}
236-
llvm_unreachable("unhandled kind");
237249
}
238250

239251
/// Return true if the storage is guaranteed local.
@@ -311,31 +323,6 @@ class AccessedStorage {
311323
bool operator!=(const AccessedStorage &) const = delete;
312324
};
313325

314-
/// Return true if the given storage objects have identical storage locations.
315-
///
316-
/// This compares only the AccessedStorage base class bits, ignoring the
317-
/// subclass bits.
318-
inline bool accessingIdenticalLocations(AccessedStorage LHS,
319-
AccessedStorage RHS) {
320-
if (LHS.getKind() != RHS.getKind())
321-
return false;
322-
323-
switch (LHS.getKind()) {
324-
case swift::AccessedStorage::Box:
325-
case swift::AccessedStorage::Stack:
326-
case swift::AccessedStorage::Nested:
327-
case swift::AccessedStorage::Yield:
328-
case swift::AccessedStorage::Unidentified:
329-
return LHS.getValue() == RHS.getValue();
330-
case swift::AccessedStorage::Argument:
331-
return LHS.getParamIndex() == RHS.getParamIndex();
332-
case swift::AccessedStorage::Global:
333-
return LHS.getGlobal() == RHS.getGlobal();
334-
case swift::AccessedStorage::Class:
335-
return LHS.getObjectProjection() == RHS.getObjectProjection();
336-
}
337-
}
338-
339326
template <class ImplTy, class ResultTy = void, typename... ArgTys>
340327
class AccessedStorageVisitor {
341328
ImplTy &asImpl() { return static_cast<ImplTy &>(*this); }
@@ -396,7 +383,7 @@ template <> struct DenseMapInfo<swift::AccessedStorage> {
396383
}
397384

398385
static bool isEqual(swift::AccessedStorage LHS, swift::AccessedStorage RHS) {
399-
return swift::accessingIdenticalLocations(LHS, RHS);
386+
return LHS.hasIdenticalBase(RHS);
400387
}
401388
};
402389

trunk/lib/SIL/MemAccessUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ AccessedStorage swift::findAccessedStorage(SILValue sourceAddr) {
425425
}
426426
// `storage` may still be invalid. If both `storage` and `result` are
427427
// invalid, this check passes, but we return an invalid storage below.
428-
if (!accessingIdenticalLocations(storage.getValue(), result.getStorage()))
428+
if (!storage.getValue().hasIdenticalBase(result.getStorage()))
429429
return AccessedStorage();
430430
}
431431
return storage.getValueOr(AccessedStorage());

trunk/lib/SILGen/SILGenPattern.cpp

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,8 +2318,9 @@ void PatternMatchEmission::initSharedCaseBlockDest(CaseStmt *caseBlock,
23182318

23192319
auto *block = SGF.createBasicBlock();
23202320
result.first->second.first = block;
2321-
2322-
// Add args for any pattern variables
2321+
2322+
// If we do not have any bound decls, we do not need to setup any phi
2323+
// arguments for the shared case block. Just bail early.
23232324
if (!caseBlock->hasBoundDecls()) {
23242325
return;
23252326
}
@@ -2355,6 +2356,7 @@ void PatternMatchEmission::emitAddressOnlyAllocations() {
23552356
for (auto &entry : SharedCases) {
23562357
CaseStmt *caseBlock = entry.first;
23572358

2359+
// If we do not have any bound decls, we can bail early.
23582360
if (!caseBlock->hasBoundDecls()) {
23592361
continue;
23602362
}
@@ -2429,11 +2431,9 @@ void PatternMatchEmission::emitSharedCaseBlocks() {
24292431
SGF.B.setInsertionPoint(predBB);
24302432

24312433
} else {
2432-
// FIXME: Figure out why this is necessary.
2433-
if (caseBB->pred_empty()) {
2434-
SGF.eraseBasicBlock(caseBB);
2435-
continue;
2436-
}
2434+
// If we did not need a shared case block, we shouldn't have emitted one.
2435+
assert(!caseBB->pred_empty() &&
2436+
"Shared case block without predecessors?!");
24372437

24382438
// Otherwise, move the block to after the first predecessor.
24392439
auto predBB = *caseBB->pred_begin();
@@ -2651,32 +2651,36 @@ static void switchCaseStmtSuccessCallback(SILGenFunction &SGF,
26512651
auto caseBlock = row.getClientData<CaseStmt>();
26522652
SGF.emitProfilerIncrement(caseBlock);
26532653

2654-
// Certain case statements can be entered along multiple paths, either
2655-
// because they have multiple labels or because of fallthrough. When we
2656-
// need multiple entrance path, we factor the paths with a shared block.
2657-
if (!caseBlock->hasBoundDecls()) {
2658-
// Don't emit anything yet, we emit it at the cleanup level of the switch
2659-
// statement.
2660-
JumpDest sharedDest = emission.getSharedCaseBlockDest(caseBlock);
2661-
SGF.Cleanups.emitBranchAndCleanups(sharedDest, caseBlock);
2662-
return;
2663-
}
2664-
2665-
// If we don't have a fallthrough or a multi-pattern 'case', we can just
2666-
// emit the body inline and save some dead blocks. Emit the statement here.
2654+
// Certain case statements can be entered along multiple paths, either because
2655+
// they have multiple labels or because of fallthrough. When we need multiple
2656+
// entrance path, we factor the paths with a shared block. If we don't have a
2657+
// fallthrough or a multi-pattern 'case', we can just emit the body inline and
2658+
// save some dead blocks. Emit the statement here and bail early.
26672659
if (!row.hasFallthroughTo() && caseBlock->getCaseLabelItems().size() == 1) {
26682660
emission.emitCaseBody(caseBlock);
26692661
return;
26702662
}
26712663

2664+
// Ok, at this point we know that we have a multiple entrance block. Grab our
2665+
// shared destination in preperation for branching to it.
2666+
//
2667+
// NOTE: We do not emit anything yet, since we will emit the shared block
2668+
// later.
26722669
JumpDest sharedDest = emission.getSharedCaseBlockDest(caseBlock);
26732670

2674-
// Generate the arguments from this row's pattern in the case block's
2675-
// expected order, and keep those arguments from being cleaned up, as
2676-
// we're passing the +1 along to the shared case block dest. (The
2677-
// cleanups still happen, as they are threaded through here messily,
2678-
// but the explicit retains here counteract them, and then the
2679-
// retain/release pair gets optimized out.)
2671+
// If we do not have any bound decls, we do not need to setup any
2672+
// variables. Just jump to the shared destination.
2673+
if (!caseBlock->hasBoundDecls()) {
2674+
JumpDest sharedDest = emission.getSharedCaseBlockDest(caseBlock);
2675+
SGF.Cleanups.emitBranchAndCleanups(sharedDest, caseBlock);
2676+
return;
2677+
}
2678+
2679+
// Generate the arguments from this row's pattern in the case block's expected
2680+
// order, and keep those arguments from being cleaned up, as we're passing the
2681+
// +1 along to the shared case block dest. (The cleanups still happen, as they
2682+
// are threaded through here messily, but the explicit retains here counteract
2683+
// them, and then the retain/release pair gets optimized out.)
26802684
ArrayRef<CaseLabelItem> labelItems = caseBlock->getCaseLabelItems();
26812685
SmallVector<SILValue, 4> args;
26822686
SmallVector<VarDecl *, 4> expectedVarOrder;
@@ -2746,9 +2750,10 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
27462750
clauseRows.reserve(S->getRawCases().size());
27472751
bool hasFallthrough = false;
27482752
for (auto caseBlock : S->getCases()) {
2749-
if (!caseBlock->hasBoundDecls() ||
2750-
caseBlock->getCaseLabelItems().size() > 1 ||
2751-
hasFallthrough) {
2753+
// If the previous block falls through into this block or we have multiple
2754+
// case label itmes, create a shared case block to generate the shared
2755+
// block.
2756+
if (hasFallthrough || caseBlock->getCaseLabelItems().size() > 1) {
27522757
emission.initSharedCaseBlockDest(caseBlock, hasFallthrough);
27532758
}
27542759

0 commit comments

Comments
 (0)