33
33
#include " llvm/Support/FileSystem.h"
34
34
#include " llvm/Support/Path.h"
35
35
#include " llvm/Support/raw_ostream.h"
36
+ #include " llvm/Support/Timer.h"
36
37
#include " llvm/Support/YAMLParser.h"
37
38
38
39
using namespace swift ;
@@ -48,15 +49,17 @@ Compilation::Compilation(DiagnosticEngine &Diags, OutputLevel Level,
48
49
unsigned NumberOfParallelCommands,
49
50
bool EnableIncrementalBuild,
50
51
bool SkipTaskExecution,
51
- bool SaveTemps)
52
+ bool SaveTemps,
53
+ bool ShowDriverTimeCompilation)
52
54
: Diags(Diags), Level(Level), RawInputArgs(std::move(InputArgs)),
53
55
TranslatedArgs(std::move(TranslatedArgs)),
54
56
InputFilesWithTypes(std::move(InputsWithTypes)), ArgsHash(ArgsHash),
55
57
BuildStartTime(StartTime),
56
58
NumberOfParallelCommands(NumberOfParallelCommands),
57
59
SkipTaskExecution(SkipTaskExecution),
58
60
EnableIncrementalBuild(EnableIncrementalBuild),
59
- SaveTemps(SaveTemps) {
61
+ SaveTemps(SaveTemps),
62
+ ShowDriverTimeCompilation(ShowDriverTimeCompilation) {
60
63
};
61
64
62
65
using CommandSet = llvm::SmallPtrSet<const Job *, 16 >;
@@ -421,14 +424,43 @@ int Compilation::performJobsImpl() {
421
424
}
422
425
423
426
int Result = EXIT_SUCCESS;
427
+ llvm::TimerGroup DriverTimerGroup (" Driver Time Compilation" );
428
+ llvm::SmallDenseMap<const Job *, std::unique_ptr<llvm::Timer>, 16 >
429
+ DriverTimers;
424
430
425
431
// Set up a callback which will be called immediately after a task has
426
432
// started. This callback may be used to provide output indicating that the
427
433
// task began.
428
- auto taskBegan = [this ] (ProcessId Pid, void *Context) {
434
+ auto taskBegan = [& ] (ProcessId Pid, void *Context) {
429
435
// TODO: properly handle task began.
430
436
const Job *BeganCmd = (const Job *)Context;
431
437
438
+ if (ShowDriverTimeCompilation) {
439
+ llvm::SmallString<128 > TimerName;
440
+ llvm::raw_svector_ostream OS (TimerName);
441
+
442
+ OS << BeganCmd->getSource ().getClassName ();
443
+ for (auto A : BeganCmd->getSource ().getInputs ()) {
444
+ if (const InputAction *IA = dyn_cast<InputAction>(A)) {
445
+ OS << " " << IA->getInputArg ().getValue ();
446
+ }
447
+ }
448
+ for (auto J : BeganCmd->getInputs ()) {
449
+ for (auto A : J->getSource ().getInputs ()) {
450
+ if (const InputAction *IA = dyn_cast<InputAction>(A)) {
451
+ OS << " " << IA->getInputArg ().getValue ();
452
+ }
453
+ }
454
+ }
455
+
456
+ DriverTimers.insert ({
457
+ BeganCmd,
458
+ std::unique_ptr<llvm::Timer>(
459
+ new llvm::Timer (OS.str (), DriverTimerGroup))
460
+ });
461
+ DriverTimers[BeganCmd]->startTimer ();
462
+ }
463
+
432
464
// For verbose output, print out each command as it begins execution.
433
465
if (Level == OutputLevel::Verbose)
434
466
BeganCmd->printCommandLine (llvm::errs ());
@@ -445,6 +477,10 @@ int Compilation::performJobsImpl() {
445
477
void *Context) -> TaskFinishedResponse {
446
478
const Job *FinishedCmd = (const Job *)Context;
447
479
480
+ if (ShowDriverTimeCompilation) {
481
+ DriverTimers[FinishedCmd]->stopTimer ();
482
+ }
483
+
448
484
if (Level == OutputLevel::Parseable) {
449
485
// Parseable output was requested.
450
486
parseable_output::emitFinishedMessage (llvm::errs (), *FinishedCmd, Pid,
@@ -572,6 +608,10 @@ int Compilation::performJobsImpl() {
572
608
void *Context) -> TaskFinishedResponse {
573
609
const Job *SignalledCmd = (const Job *)Context;
574
610
611
+ if (ShowDriverTimeCompilation) {
612
+ DriverTimers[SignalledCmd]->stopTimer ();
613
+ }
614
+
575
615
if (Level == OutputLevel::Parseable) {
576
616
// Parseable output was requested.
577
617
parseable_output::emitSignalledMessage (llvm::errs (), *SignalledCmd, Pid,
@@ -721,6 +761,7 @@ int Compilation::performJobs() {
721
761
722
762
// If we don't have to do any cleanup work, just exec the subprocess.
723
763
if (Level < OutputLevel::Parseable &&
764
+ !ShowDriverTimeCompilation &&
724
765
(SaveTemps || TempFilePaths.empty ()) &&
725
766
CompilationRecordPath.empty () &&
726
767
Jobs.size () == 1 ) {
0 commit comments