Skip to content

Commit bb7710c

Browse files
committed
---
yaml --- r: 345061 b: refs/heads/master c: ad3238f h: refs/heads/master i: 345059: ac39123
1 parent 240e636 commit bb7710c

File tree

6 files changed

+380
-40
lines changed

6 files changed

+380
-40
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: 3e439d89b21e9d5b3efdbaaa912cc9250a06ceb3
2+
refs/heads/master: ad3238f943eae0911038131386b1d5671c7f4bda
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/benchmark/utils/DriverUtils.swift

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ func stopTrackingObjects(_: UnsafePointer<CChar>) -> Int
247247
#endif
248248

249249
#if os(Linux)
250-
class Timer {
250+
final class Timer {
251251
typealias TimeT = timespec
252252
func getTime() -> TimeT {
253253
var ticks = timespec(tv_sec: 0, tv_nsec: 0)
@@ -267,7 +267,7 @@ class Timer {
267267
}
268268
}
269269
#else
270-
class Timer {
270+
final class Timer {
271271
typealias TimeT = UInt64
272272
var info = mach_timebase_info_data_t(numer: 0, denom: 0)
273273
init() {
@@ -283,13 +283,18 @@ class Timer {
283283
}
284284
#endif
285285

286-
class SampleRunner {
286+
final class SampleRunner {
287287
let timer = Timer()
288288
let baseline = SampleRunner.getResourceUtilization()
289289
let c: TestConfig
290+
var start, end, lastYield: Timer.TimeT
291+
let schedulerQuantum = UInt64(10_000_000) // nanoseconds (== 10ms, macos)
290292

291293
init(_ config: TestConfig) {
292294
self.c = config
295+
sched_yield()
296+
let now = timer.getTime()
297+
(start, end, lastYield) = (now, now, now)
293298
}
294299

295300
private static func getResourceUtilization() -> rusage {
@@ -298,39 +303,63 @@ class SampleRunner {
298303

299304
/// Returns maximum resident set size (MAX_RSS) delta in bytes
300305
func measureMemoryUsage() -> Int {
301-
var current = SampleRunner.getResourceUtilization()
302-
let maxRSS = current.ru_maxrss - baseline.ru_maxrss
306+
let current = SampleRunner.getResourceUtilization()
307+
let maxRSS = current.ru_maxrss - baseline.ru_maxrss
303308

304-
if c.verbose {
305-
let pages = maxRSS / sysconf(_SC_PAGESIZE)
306-
func deltaEquation(_ stat: KeyPath<rusage, Int>) -> String {
307-
let b = baseline[keyPath: stat], c = current[keyPath: stat]
308-
return "\(c) - \(b) = \(c - b)"
309-
}
310-
print("""
311-
MAX_RSS \(deltaEquation(\rusage.ru_maxrss)) (\(pages) pages)
312-
ICS \(deltaEquation(\rusage.ru_nivcsw))
313-
VCS \(deltaEquation(\rusage.ru_nvcsw))
314-
""")
309+
if c.verbose {
310+
let pages = maxRSS / sysconf(_SC_PAGESIZE)
311+
func deltaEquation(_ stat: KeyPath<rusage, Int>) -> String {
312+
let b = baseline[keyPath: stat], c = current[keyPath: stat]
313+
return "\(c) - \(b) = \(c - b)"
315314
}
316-
return maxRSS
315+
print("""
316+
MAX_RSS \(deltaEquation(\rusage.ru_maxrss)) (\(pages) pages)
317+
ICS \(deltaEquation(\rusage.ru_nivcsw))
318+
VCS \(deltaEquation(\rusage.ru_nvcsw))
319+
""")
320+
}
321+
return maxRSS
322+
}
323+
324+
private func startMeasurement() {
325+
let spent = timer.diffTimeInNanoSeconds(from: lastYield, to: end)
326+
let nextSampleEstimate = UInt64(Double(lastSampleTime) * 1.5)
327+
328+
if (spent + nextSampleEstimate < schedulerQuantum) {
329+
start = timer.getTime()
330+
} else {
331+
if c.verbose {
332+
print(" Yielding again after estimated \(spent/1000) us")
333+
}
334+
sched_yield()
335+
let now = timer.getTime()
336+
(start, lastYield) = (now, now)
337+
}
338+
}
339+
340+
private func stopMeasurement() {
341+
end = timer.getTime()
342+
}
343+
344+
/// Time in nanoseconds spent running the last function
345+
var lastSampleTime: UInt64 {
346+
return timer.diffTimeInNanoSeconds(from: start, to: end)
317347
}
318348

319349
func run(_ name: String, fn: (Int) -> Void, num_iters: UInt) -> UInt64 {
320-
// Start the timer.
321350
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
322351
name.withCString { p in startTrackingObjects(p) }
323352
#endif
324-
let start_ticks = timer.getTime()
353+
354+
self.startMeasurement()
325355
fn(Int(num_iters))
326-
// Stop the timer.
327-
let end_ticks = timer.getTime()
356+
self.stopMeasurement()
357+
328358
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
329359
name.withCString { p in stopTrackingObjects(p) }
330360
#endif
331361

332-
// Compute the spent time and the scaling factor.
333-
return timer.diffTimeInNanoSeconds(from: start_ticks, to: end_ticks)
362+
return lastSampleTime
334363
}
335364
}
336365

trunk/lib/IRGen/LoadableByAddress.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,21 @@ void LoadableStorageAllocation::allocateForArg(SILValue value) {
14911491

14921492
assert(!ApplySite::isa(value) && "Unexpected instruction");
14931493

1494-
SILBuilderWithScope allocBuilder(&*pass.F->begin());
1494+
// Find the first non-AllocStackInst and use its scope when creating
1495+
// the new SILBuilder. An AllocStackInst does not directly cause any
1496+
// code to be generated. The location of an AllocStackInst carries information
1497+
// about the source variable; it doesn't matter where in the instruction
1498+
// stream the AllocStackInst is located.
1499+
auto BBIter = pass.F->begin()->begin();
1500+
SILInstruction *FirstNonAllocStack = &*BBIter;
1501+
while (isa<AllocStackInst>(FirstNonAllocStack) &&
1502+
BBIter != pass.F->begin()->end()) {
1503+
BBIter++;
1504+
FirstNonAllocStack = &*BBIter;
1505+
}
1506+
SILBuilderWithScope allocBuilder(&*pass.F->begin()->begin(),
1507+
FirstNonAllocStack);
1508+
14951509
AllocStackInst *allocInstr =
14961510
allocBuilder.createAllocStack(value.getLoc(), value->getType());
14971511

trunk/lib/Index/Index.cpp

Lines changed: 104 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/Expr.h"
2020
#include "swift/AST/Module.h"
2121
#include "swift/AST/ParameterList.h"
22+
#include "swift/AST/ProtocolConformance.h"
2223
#include "swift/AST/Types.h"
2324
#include "swift/AST/USRGeneration.h"
2425
#include "swift/Basic/SourceManager.h"
@@ -78,6 +79,13 @@ static bool isMemberwiseInit(swift::ValueDecl *D) {
7879
return false;
7980
}
8081

82+
static SourceLoc getLocForExtension(ExtensionDecl *D) {
83+
// Use the 'End' token of the range, in case it is a compound name, e.g.
84+
// extension A.B {}
85+
// we want the location of 'B' token.
86+
return D->getExtendedTypeLoc().getSourceRange().End;
87+
}
88+
8189
namespace {
8290
// Adapter providing a common interface for a SourceFile/Module.
8391
class SourceFileOrModule {
@@ -121,6 +129,11 @@ class SourceFileOrModule {
121129
}
122130
};
123131

132+
struct ValueWitness {
133+
ValueDecl *Member;
134+
ValueDecl *Requirement;
135+
};
136+
124137
class IndexSwiftASTWalker : public SourceEntityWalker {
125138
IndexDataConsumer &IdxConsumer;
126139
SourceManager &SrcMgr;
@@ -133,6 +146,7 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
133146
Decl *D;
134147
SymbolInfo SymInfo;
135148
SymbolRoleSet Roles;
149+
SmallVector<ValueWitness, 6> ExplicitValueWitnesses;
136150
SmallVector<SourceLoc, 6> RefsToSuppress;
137151
};
138152
SmallVector<Entity, 6> EntitiesStack;
@@ -319,7 +333,7 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
319333
IndexSymbol Info;
320334
if (initIndexSymbol(Prop, *LabelIt++, /*IsRef=*/true, Info))
321335
continue;
322-
if (startEntity(Prop, Info))
336+
if (startEntity(Prop, Info, /*IsRef=*/true))
323337
finishCurrentEntity();
324338
}
325339
}
@@ -398,8 +412,10 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
398412
bool reportExtension(ExtensionDecl *D);
399413
bool reportRef(ValueDecl *D, SourceLoc Loc, IndexSymbol &Info,
400414
Optional<AccessKind> AccKind);
415+
bool reportImplicitValueConformance(ValueDecl *witness, ValueDecl *requirement,
416+
Decl *container);
401417

402-
bool startEntity(Decl *D, IndexSymbol &Info);
418+
bool startEntity(Decl *D, IndexSymbol &Info, bool IsRef);
403419
bool startEntityDecl(ValueDecl *D);
404420

405421
bool reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isImplicit, SymbolRoleSet Relations, Decl *Related);
@@ -459,6 +475,14 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
459475
return true;
460476
}
461477

478+
/// Reports all implicit member value decl conformances that \p D introduces
479+
/// as implicit overrides at the source location of \p D, and returns the
480+
/// explicit ones so we can check against them later on when visiting them as
481+
/// members.
482+
///
483+
/// \returns false if AST visitation should stop.
484+
bool handleValueWitnesses(Decl *D, SmallVectorImpl<ValueWitness> &explicitValueWitnesses);
485+
462486
void getModuleHash(SourceFileOrModule SFOrMod, llvm::raw_ostream &OS);
463487
llvm::hash_code hashModule(llvm::hash_code code, SourceFileOrModule SFOrMod);
464488
llvm::hash_code hashFileReference(llvm::hash_code code,
@@ -612,16 +636,53 @@ bool IndexSwiftASTWalker::visitImports(
612636
return true;
613637
}
614638

615-
bool IndexSwiftASTWalker::startEntity(Decl *D, IndexSymbol &Info) {
639+
bool IndexSwiftASTWalker::handleValueWitnesses(Decl *D, SmallVectorImpl<ValueWitness> &explicitValueWitnesses) {
640+
auto DC = dyn_cast<DeclContext>(D);
641+
if (!DC)
642+
return true;
643+
644+
for (auto *conf : DC->getLocalConformances()) {
645+
if (conf->isInvalid())
646+
continue;
647+
648+
auto normal = conf->getRootNormalConformance();
649+
normal->forEachValueWitness(nullptr,
650+
[&](ValueDecl *req, Witness witness) {
651+
if (Cancelled)
652+
return;
653+
654+
auto *decl = witness.getDecl();
655+
if (decl->getDeclContext() == DC) {
656+
explicitValueWitnesses.push_back(ValueWitness{decl, req});
657+
} else {
658+
// Report the implicit conformance.
659+
reportImplicitValueConformance(decl, req, D);
660+
}
661+
});
662+
}
663+
664+
if (Cancelled)
665+
return false;
666+
667+
return true;
668+
}
669+
670+
bool IndexSwiftASTWalker::startEntity(Decl *D, IndexSymbol &Info, bool IsRef) {
616671
switch (IdxConsumer.startSourceEntity(Info)) {
617672
case swift::index::IndexDataConsumer::Abort:
618673
Cancelled = true;
619674
LLVM_FALLTHROUGH;
620675
case swift::index::IndexDataConsumer::Skip:
621676
return false;
622-
case swift::index::IndexDataConsumer::Continue:
623-
EntitiesStack.push_back({D, Info.symInfo, Info.roles, {}});
677+
case swift::index::IndexDataConsumer::Continue: {
678+
SmallVector<ValueWitness, 6> explicitValueWitnesses;
679+
if (!IsRef) {
680+
if (!handleValueWitnesses(D, explicitValueWitnesses))
681+
return false;
682+
}
683+
EntitiesStack.push_back({D, Info.symInfo, Info.roles, std::move(explicitValueWitnesses), {}});
624684
return true;
685+
}
625686
}
626687

627688
llvm_unreachable("Unhandled IndexDataConsumer in switch.");
@@ -649,12 +710,15 @@ bool IndexSwiftASTWalker::startEntityDecl(ValueDecl *D) {
649710
return false;
650711
}
651712

652-
for (auto Overriden: getOverriddenDecls(D, /*IncludeProtocolReqs=*/!isSystemModule)) {
653-
if (addRelation(Info, (SymbolRoleSet) SymbolRole::RelationOverrideOf, Overriden))
654-
return false;
713+
for (auto Overriden: getOverriddenDecls(D, /*IncludeProtocolReqs=*/false)) {
714+
addRelation(Info, (SymbolRoleSet) SymbolRole::RelationOverrideOf, Overriden);
655715
}
656716

657717
if (auto Parent = getParentDecl()) {
718+
for (const ValueWitness &witness : EntitiesStack.back().ExplicitValueWitnesses) {
719+
if (witness.Member == D)
720+
addRelation(Info, (SymbolRoleSet) SymbolRole::RelationOverrideOf, witness.Requirement);
721+
}
658722
if (auto ParentVD = dyn_cast<ValueDecl>(Parent)) {
659723
SymbolRoleSet RelationsToParent = (SymbolRoleSet)SymbolRole::RelationChildOf;
660724
if (Info.symInfo.SubKind == SymbolSubKind::AccessorGetter ||
@@ -673,7 +737,7 @@ bool IndexSwiftASTWalker::startEntityDecl(ValueDecl *D) {
673737
}
674738
}
675739

676-
return startEntity(D, Info);
740+
return startEntity(D, Info, /*IsRef=*/false);
677741
}
678742

679743
bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isImplicit,
@@ -836,10 +900,7 @@ IndexSwiftASTWalker::getTypeLocAsNominalTypeDecl(const TypeLoc &Ty) {
836900
}
837901

838902
bool IndexSwiftASTWalker::reportExtension(ExtensionDecl *D) {
839-
// Use the 'End' token of the range, in case it is a compound name, e.g.
840-
// extension A.B {}
841-
// we want the location of 'B' token.
842-
SourceLoc Loc = D->getExtendedTypeLoc().getSourceRange().End;
903+
SourceLoc Loc = getLocForExtension(D);
843904
NominalTypeDecl *NTD = D->getExtendedNominal();
844905
if (!NTD)
845906
return true;
@@ -850,7 +911,7 @@ bool IndexSwiftASTWalker::reportExtension(ExtensionDecl *D) {
850911
if (initIndexSymbol(D, NTD, Loc, Info))
851912
return true;
852913

853-
if (!startEntity(D, Info))
914+
if (!startEntity(D, Info, /*IsRef=*/false))
854915
return false;
855916

856917
if (!reportRelatedRef(NTD, Loc, /*isImplicit=*/false,
@@ -940,7 +1001,7 @@ bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc,
9401001
if (isSystemModule && !hasUsefulRoleInSystemModule(Info.roles))
9411002
return true;
9421003

943-
if (!startEntity(D, Info))
1004+
if (!startEntity(D, Info, /*IsRef=*/true))
9441005
return true;
9451006

9461007
// Report the accessors that were utilized.
@@ -961,6 +1022,34 @@ bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc,
9611022
return finishCurrentEntity();
9621023
}
9631024

1025+
bool IndexSwiftASTWalker::reportImplicitValueConformance(ValueDecl *witness, ValueDecl *requirement,
1026+
Decl *container) {
1027+
if (!shouldIndex(witness, /*IsRef=*/true))
1028+
return true; // keep walking
1029+
1030+
SourceLoc loc;
1031+
if (auto *extD = dyn_cast<ExtensionDecl>(container))
1032+
loc = getLocForExtension(extD);
1033+
else
1034+
loc = container->getLoc();
1035+
1036+
IndexSymbol info;
1037+
if (initIndexSymbol(witness, loc, /*IsRef=*/true, info))
1038+
return true;
1039+
if (addRelation(info, (SymbolRoleSet) SymbolRole::RelationOverrideOf, requirement))
1040+
return true;
1041+
if (addRelation(info, (SymbolRoleSet) SymbolRole::RelationContainedBy, container))
1042+
return true;
1043+
// Remove the 'ref' role that \c initIndexSymbol introduces. This isn't
1044+
// actually a 'reference', but an 'implicit' override.
1045+
info.roles &= ~(SymbolRoleSet)SymbolRole::Reference;
1046+
info.roles |= (SymbolRoleSet)SymbolRole::Implicit;
1047+
1048+
if (!startEntity(witness, info, /*IsRef=*/true))
1049+
return true;
1050+
return finishCurrentEntity();
1051+
}
1052+
9641053
bool IndexSwiftASTWalker::initIndexSymbol(ValueDecl *D, SourceLoc Loc,
9651054
bool IsRef, IndexSymbol &Info) {
9661055
assert(D);

0 commit comments

Comments
 (0)