<rdar://problem/20402026> Remove scope entry/exit log entries

Don't emit scope entry/exit logging code in instrumentation for
playgrounds if -playground-high-performance option is passed.

Swift SVN r27046
This commit is contained in:
Chris Willmore
2015-04-06 22:09:20 +00:00
parent c5f65bd7a4
commit d3a977d824
7 changed files with 71 additions and 10 deletions

View File

@@ -196,6 +196,10 @@ public:
/// Indicates whether the playground transformation should be applied.
bool PlaygroundTransform = false;
/// Indicates whether the playground transformation should omit
/// instrumentation that has a high runtime performance impact.
bool PlaygroundHighPerformance = false;
/// Indicates whether standard help should be shown.
bool PrintHelp = false;

View File

@@ -209,6 +209,9 @@ def print_stats : Flag<["-"], "print-stats">,
def playground : Flag<["-"], "playground">,
HelpText<"Apply the playground semantics and transformation">;
def playground_high_performance : Flag<["-"], "playground-high-performance">,
HelpText<"Omit instrumentation that has a high runtime performance impact">;
def disable_playground_transform : Flag<["-"], "disable-playground-transform">,
HelpText<"Disable playground transformation">;

View File

@@ -133,7 +133,10 @@ namespace swift {
/// Once parsing and name-binding are complete, this optionally transforms the
/// ASTs to add calls to external logging functions.
void performPlaygroundTransform(SourceFile &SF);
///
/// \param HighPerformance True if the playground transform should omit
/// instrumentation that has a high runtime performance impact.
void performPlaygroundTransform(SourceFile &SF, bool HighPerformance);
/// Flags used to control type checking.
enum class TypeCheckingFlags : unsigned {

View File

@@ -112,6 +112,8 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.PlaygroundTransform |= Args.hasArg(OPT_playground);
if (Args.hasArg(OPT_disable_playground_transform))
Opts.PlaygroundTransform = false;
Opts.PlaygroundHighPerformance |=
Args.hasArg(OPT_playground_high_performance);
if (const Arg *A = Args.getLastArg(OPT_help, OPT_help_hidden)) {
if (A->getOption().matches(OPT_help)) {

View File

@@ -425,7 +425,7 @@ void CompilerInstance::performSema() {
} while (!Done);
if (mainIsPrimary && Invocation.getFrontendOptions().PlaygroundTransform)
performPlaygroundTransform(MainFile);
performPlaygroundTransform(MainFile, Invocation.getFrontendOptions().PlaygroundHighPerformance);
if (!mainIsPrimary)
performNameBinding(MainFile);
}

View File

@@ -45,6 +45,7 @@ private:
ASTContext &Context;
DeclContext *TypeCheckDC;
unsigned TmpNameIndex = 0;
bool HighPerformance;
struct BracePair {
public:
@@ -110,6 +111,9 @@ private:
// all the braces up to its target.
size_t escapeToTarget(BracePair::TargetKinds TargetKind,
ElementVector &Elements, size_t EI) {
if (HighPerformance)
return EI;
for (const BracePair &BP : BracePairs) {
if (BP.TargetKind == TargetKind) {
break;
@@ -151,8 +155,9 @@ private:
ClosureFinder CF;
public:
Instrumenter (ASTContext &C, DeclContext *DC, std::mt19937_64 &RNG) :
RNG(RNG), Context(C), TypeCheckDC(DC), CF(*this) { }
Instrumenter (ASTContext &C, DeclContext *DC, std::mt19937_64 &RNG,
bool HP) :
RNG(RNG), Context(C), TypeCheckDC(DC), HighPerformance(HP), CF(*this) { }
Stmt *transformStmt(Stmt *S) {
switch (S->getKind()) {
@@ -558,7 +563,7 @@ public:
}
}
if (!TopLevel) {
if (!TopLevel && !HighPerformance) {
Elements.insert(Elements.begin(), buildScopeEntry(BS->getSourceRange()));
Elements.insert(Elements.end(), buildScopeExit(BS->getSourceRange()));
}
@@ -579,7 +584,8 @@ public:
}
// log*() functions return a newly-created log expression to be inserted
// after or instead of the expression they're looking at.
// after or instead of the expression they're looking at. Only call this
// if the variable has an initializer.
Expr *logVarDecl(VarDecl *VD) {
if (llvm::dyn_cast<ConstructorDecl>(TypeCheckDC) &&
VD->getNameStr().equals("self")) {
@@ -812,16 +818,20 @@ public:
} // end anonymous namespace
void swift::performPlaygroundTransform(SourceFile &SF) {
void swift::performPlaygroundTransform(SourceFile &SF,
bool HighPerformance) {
class ExpressionFinder : public ASTWalker {
private:
std::mt19937_64 RNG;
bool HighPerformance;
public:
ExpressionFinder(bool HP) : HighPerformance(HP) { }
virtual bool walkToDeclPre(Decl *D) {
if (AbstractFunctionDecl *FD = llvm::dyn_cast<AbstractFunctionDecl>(D)) {
if (!FD->isImplicit()) {
if (BraceStmt *Body = FD->getBody()) {
Instrumenter I(FD->getASTContext(), FD, RNG);
Instrumenter I(FD->getASTContext(), FD, RNG, HighPerformance);
BraceStmt *NewBody = I.transformBraceStmt(Body);
if (NewBody != Body) {
FD->setBody(NewBody);
@@ -832,7 +842,7 @@ void swift::performPlaygroundTransform(SourceFile &SF) {
} else if (TopLevelCodeDecl *TLCD = llvm::dyn_cast<TopLevelCodeDecl>(D)) {
if (!TLCD->isImplicit()) {
if (BraceStmt *Body = TLCD->getBody()) {
Instrumenter I(((Decl*)TLCD)->getASTContext(), TLCD, RNG);
Instrumenter I(((Decl*)TLCD)->getASTContext(), TLCD, RNG, HighPerformance);
BraceStmt *NewBody = I.transformBraceStmt(Body, true);
if (NewBody != Body) {
TLCD->setBody(NewBody);
@@ -845,7 +855,7 @@ void swift::performPlaygroundTransform(SourceFile &SF) {
}
};
ExpressionFinder EF;
ExpressionFinder EF(HighPerformance);
for (Decl* D : SF.Decls) {
D->walk(EF);
}

View File

@@ -0,0 +1,39 @@
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: cp %s %t/main.swift
// RUN: %target-build-swift -Xfrontend -playground -Xfrontend -playground-high-performance -Xfrontend -debugger-support -o %t/main %S/Inputs/PlaygroundsRuntime.swift %t/main.swift
// RUN: %target-run %t/main | FileCheck %s
var a = true
if (a) {
5
} else {
7
}
for i in 0..<3 {
i
}
// CHECK: [{{.*}}] $builtin_log[a='true']
// CHECK-NEXT: [{{.*}}] $builtin_log[='5']
// CHECK-NEXT: [{{.*}}] $builtin_log[='0']
// CHECK-NEXT: [{{.*}}] $builtin_log[='1']
// CHECK-NEXT: [{{.*}}] $builtin_log[='2']
var b = true
for i in 0..<3 {
i
continue
}
// CHECK-NEXT: [{{.*}}] $builtin_log[b='true']
// CHECK-NEXT: [{{.*}}] $builtin_log[='0']
// CHECK-NEXT: [{{.*}}] $builtin_log[='1']
// CHECK-NEXT: [{{.*}}] $builtin_log[='2']
var c = true
for i in 0..<3 {
i
break
}
// CHECK-NEXT: [{{.*}}] $builtin_log[c='true']
// CHECK-NEXT: [{{.*}}] $builtin_log[='0']