Skip to content

Commit 0c19814

Browse files
authored
Merge pull request #625 from ahoppen/ahoppen/instruction-counter
Add option to print number of instructions executed by `swift-format`
2 parents 2a6868a + 39ee8df commit 0c19814

File tree

6 files changed

+111
-8
lines changed

6 files changed

+111
-8
lines changed

Package.swift

+5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ let package = Package(
4747
// See the "Dependencies" section below.
4848
],
4949
targets: [
50+
.target(
51+
name: "_InstructionCounter"
52+
),
53+
5054
.target(
5155
name: "SwiftFormat",
5256
dependencies: [
@@ -109,6 +113,7 @@ let package = Package(
109113
.executableTarget(
110114
name: "swift-format",
111115
dependencies: [
116+
"_InstructionCounter",
112117
"SwiftFormat",
113118
.product(name: "ArgumentParser", package: "swift-argument-parser"),
114119
.product(name: "SwiftSyntax", package: "swift-syntax"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include <stdint.h>
14+
15+
/// On macOS returns the number of instructions the process has executed since
16+
/// it was launched, on all other platforms returns 0.
17+
uint64_t getInstructionsExecuted();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#if __APPLE__
14+
#include <TargetConditionals.h>
15+
#if TARGET_OS_MAC && !TARGET_OS_IPHONE
16+
#define TARGET_IS_MACOS 1
17+
#endif
18+
#endif
19+
20+
#include "InstructionsExecuted.h"
21+
22+
#ifdef TARGET_IS_MACOS
23+
#include <libproc.h>
24+
#include <sys/resource.h>
25+
#include <unistd.h>
26+
27+
uint64_t getInstructionsExecuted() {
28+
struct rusage_info_v4 ru;
29+
if (proc_pid_rusage(getpid(), RUSAGE_INFO_V4, (rusage_info_t *)&ru) == 0) {
30+
return ru.ri_instructions;
31+
}
32+
return 0;
33+
}
34+
#else
35+
uint64_t getInstructionsExecuted() {
36+
return 0;
37+
}
38+
#endif

Sources/swift-format/Subcommands/Format.swift

+8-3
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,21 @@ extension SwiftFormatCommand {
3030
@OptionGroup()
3131
var formatOptions: LintFormatOptions
3232

33+
@OptionGroup(visibility: .hidden)
34+
var performanceMeasurementOptions: PerformanceMeasurementsOptions
35+
3336
func validate() throws {
3437
if inPlace && formatOptions.paths.isEmpty {
3538
throw ValidationError("'--in-place' is only valid when formatting files")
3639
}
3740
}
3841

3942
func run() throws {
40-
let frontend = FormatFrontend(lintFormatOptions: formatOptions, inPlace: inPlace)
41-
frontend.run()
42-
if frontend.diagnosticsEngine.hasErrors { throw ExitCode.failure }
43+
try performanceMeasurementOptions.countingInstructionsIfRequested {
44+
let frontend = FormatFrontend(lintFormatOptions: formatOptions, inPlace: inPlace)
45+
frontend.run()
46+
if frontend.diagnosticsEngine.hasErrors { throw ExitCode.failure }
47+
}
4348
}
4449
}
4550
}

Sources/swift-format/Subcommands/Lint.swift

+10-5
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,17 @@ extension SwiftFormatCommand {
2828
)
2929
var strict: Bool = false
3030

31-
func run() throws {
32-
let frontend = LintFrontend(lintFormatOptions: lintOptions)
33-
frontend.run()
31+
@OptionGroup(visibility: .hidden)
32+
var performanceMeasurementOptions: PerformanceMeasurementsOptions
3433

35-
if frontend.diagnosticsEngine.hasErrors || strict && frontend.diagnosticsEngine.hasWarnings {
36-
throw ExitCode.failure
34+
func run() throws {
35+
try performanceMeasurementOptions.countingInstructionsIfRequested {
36+
let frontend = LintFrontend(lintFormatOptions: lintOptions)
37+
frontend.run()
38+
39+
if frontend.diagnosticsEngine.hasErrors || strict && frontend.diagnosticsEngine.hasWarnings {
40+
throw ExitCode.failure
41+
}
3742
}
3843
}
3944
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import ArgumentParser
14+
import _InstructionCounter
15+
16+
struct PerformanceMeasurementsOptions: ParsableArguments {
17+
@Flag(help: "Measure number of instructions executed by swift-format")
18+
var measureInstructions = false
19+
20+
/// If `measureInstructions` is set, execute `body` and print the number of instructions
21+
/// executed by it. Otherwise, just execute `body`
22+
func printingInstructionCountIfRequested<T>(_ body: () throws -> T) rethrows -> T {
23+
if !measureInstructions {
24+
return try body()
25+
} else {
26+
let startInstructions = getInstructionsExecuted()
27+
defer {
28+
print("Instructions executed: \(getInstructionsExecuted() - startInstructions)")
29+
}
30+
return try body()
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)