Skip to content

Commit 23f961b

Browse files
committed
Give the FrontendTool library its own header and allow users
to observe progress through the frontend.
1 parent 39c7ae8 commit 23f961b

File tree

4 files changed

+137
-22
lines changed

4 files changed

+137
-22
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//===--- FrontendTool.h - Frontend control ----------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file provides a high-level API for interacting with the basic
14+
// frontend tool operation.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_FRONTENDTOOL_H
19+
#define SWIFT_FRONTENDTOOL_H
20+
21+
#include "swift/Basic/LLVM.h"
22+
23+
namespace llvm {
24+
class Module;
25+
}
26+
27+
namespace swift {
28+
class CompilerInvocation;
29+
class CompilerInstance;
30+
class SILModule;
31+
32+
/// A simple observer of frontend activity.
33+
///
34+
/// Don't let this interface block enhancements to the frontend pipeline.
35+
class FrontendObserver {
36+
public:
37+
FrontendObserver() = default;
38+
virtual ~FrontendObserver() = default;
39+
40+
/// The frontend has parsed the command line.
41+
virtual void parsedArgs(CompilerInvocation &invocation);
42+
43+
/// The frontend has configured the compiler instance.
44+
virtual void configuredCompiler(CompilerInstance &instance);
45+
46+
/// The frontend has performed semantic analysis.
47+
virtual void performedSemanticAnalysis(CompilerInstance &instance);
48+
49+
/// The frontend has performed basic SIL generation.
50+
/// SIL diagnostic passes have not yet been applied.
51+
virtual void performedSILGeneration(SILModule &module);
52+
53+
/// The frontend has executed the SIL diagnostic passes.
54+
virtual void performedSILDiagnostics(SILModule &module);
55+
56+
/// The frontend has executed the SIL optimization pipeline.
57+
virtual void performedSILOptimization(SILModule &module);
58+
59+
/// The frontend is about to run the program as an immediate script.
60+
virtual void aboutToRunImmediately(CompilerInstance &instance);
61+
62+
// TODO: maybe enhance this interface to hear about IRGen and LLVM
63+
// progress.
64+
};
65+
66+
/// Perform all the operations of the frontend, exactly as if invoked
67+
/// with -frontend.
68+
///
69+
/// \param args the arguments to use as the arguments to the frontend
70+
/// \param argv0 the name used as the frontend executable
71+
/// \param mainAddr an address from the main executable
72+
///
73+
/// \return the exit value of the frontend: 0 or 1 on success unless
74+
/// the frontend executes in immediate mode, in which case this will be
75+
/// the exit value of the script, assuming it exits normally
76+
int performFrontend(ArrayRef<const char *> args,
77+
const char *argv0,
78+
void *mainAddr,
79+
FrontendObserver *observer = nullptr);
80+
81+
82+
} // namespace swift
83+
84+
#endif

include/swift/Subsystems.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,20 +88,6 @@ namespace swift {
8888

8989
/// @}
9090

91-
/// Perform all the operations of the frontend, exactly as if invoked
92-
/// with -frontend.
93-
///
94-
/// \param args the arguments to use as the arguments to the frontend
95-
/// \param argv0 the name used as the frontend executable
96-
/// \param mainAddr an address from the main executable
97-
///
98-
/// \return the exit value of the frontend: 0 or 1 on success unless
99-
/// the frontend executes in immediate mode, in which case this will be
100-
/// the exit value of the script, assuming it exits normally
101-
int performFrontend(ArrayRef<const char *> args,
102-
const char *argv0,
103-
void *mainAddr);
104-
10591
/// \brief Parse a single buffer into the given source file.
10692
///
10793
/// If the source file is the main file, stop parsing after the next

lib/FrontendTool/FrontendTool.cpp

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
///
2121
//===----------------------------------------------------------------------===//
2222

23+
#include "swift/FrontendTool/FrontendTool.h"
24+
2325
#include "swift/Subsystems.h"
2426
#include "swift/AST/DiagnosticsFrontend.h"
2527
#include "swift/AST/DiagnosticsSema.h"
@@ -614,7 +616,8 @@ static void debugFailWithCrash() {
614616
static bool performCompile(CompilerInstance &Instance,
615617
CompilerInvocation &Invocation,
616618
ArrayRef<const char *> Args,
617-
int &ReturnValue) {
619+
int &ReturnValue,
620+
FrontendObserver *observer) {
618621
FrontendOptions opts = Invocation.getFrontendOptions();
619622
FrontendOptions::ActionType Action = opts.RequestedAction;
620623

@@ -669,6 +672,10 @@ static bool performCompile(CompilerInstance &Instance,
669672
else
670673
Instance.performSema();
671674

675+
if (observer) {
676+
observer->performedSemanticAnalysis(Instance);
677+
}
678+
672679
FrontendOptions::DebugCrashMode CrashMode = opts.CrashMode;
673680
if (CrashMode == FrontendOptions::DebugCrashMode::AssertAfterParse)
674681
debugFailWithAssertion();
@@ -759,6 +766,10 @@ static bool performCompile(CompilerInstance &Instance,
759766
}
760767
}
761768

769+
if (observer) {
770+
observer->performedSILGeneration(*SM);
771+
}
772+
762773
// We've been told to emit SIL after SILGen, so write it now.
763774
if (Action == FrontendOptions::EmitSILGen) {
764775
// If we are asked to link all, link all.
@@ -787,9 +798,14 @@ static bool performCompile(CompilerInstance &Instance,
787798
}
788799

789800
// Perform "stable" optimizations that are invariant across compiler versions.
790-
if (!Invocation.getDiagnosticOptions().SkipDiagnosticPasses &&
791-
runSILDiagnosticPasses(*SM))
792-
return true;
801+
if (!Invocation.getDiagnosticOptions().SkipDiagnosticPasses) {
802+
if (runSILDiagnosticPasses(*SM))
803+
return true;
804+
805+
if (observer) {
806+
observer->performedSILDiagnostics(*SM);
807+
}
808+
}
793809

794810
// Now if we are asked to link all, link all.
795811
if (Invocation.getSILOptions().LinkMode == SILOptions::LinkAll)
@@ -818,6 +834,10 @@ static bool performCompile(CompilerInstance &Instance,
818834
}
819835
}
820836

837+
if (observer) {
838+
observer->performedSILOptimization(*SM);
839+
}
840+
821841
{
822842
SharedTimer timer("SIL verification (post-optimization)");
823843
SM->verify();
@@ -915,6 +935,11 @@ static bool performCompile(CompilerInstance &Instance,
915935
const ProcessCmdLine &CmdLine = ProcessCmdLine(opts.ImmediateArgv.begin(),
916936
opts.ImmediateArgv.end());
917937
Instance.setSILModule(std::move(SM));
938+
939+
if (observer) {
940+
observer->aboutToRunImmediately(Instance);
941+
}
942+
918943
ReturnValue =
919944
RunImmediately(Instance, CmdLine, IRGenOpts, Invocation.getSILOptions());
920945
return false;
@@ -997,7 +1022,8 @@ static bool dumpAPI(Module *Mod, StringRef OutDir) {
9971022
}
9981023

9991024
int swift::performFrontend(ArrayRef<const char *> Args,
1000-
const char *Argv0, void *MainAddr) {
1025+
const char *Argv0, void *MainAddr,
1026+
FrontendObserver *observer) {
10011027
llvm::InitializeAllTargets();
10021028
llvm::InitializeAllTargetMCs();
10031029
llvm::InitializeAllAsmPrinters();
@@ -1031,6 +1057,11 @@ int swift::performFrontend(ArrayRef<const char *> Args,
10311057
if (Invocation.getLangOptions().Target.isWindowsCygwinEnvironment())
10321058
IRGenOpts.DWARFVersion = swift::CygwinDWARFVersion;
10331059

1060+
// The compiler invocation is now fully configured; notify our observer.
1061+
if (observer) {
1062+
observer->parsedArgs(Invocation);
1063+
}
1064+
10341065
if (Invocation.getFrontendOptions().PrintHelp ||
10351066
Invocation.getFrontendOptions().PrintHelpHidden) {
10361067
unsigned IncludedFlagsBitmask = options::FrontendOption;
@@ -1125,9 +1156,15 @@ int swift::performFrontend(ArrayRef<const char *> Args,
11251156
return 1;
11261157
}
11271158

1159+
// The compiler instance has been configured; notify our observer.
1160+
if (observer) {
1161+
observer->configuredCompiler(Instance);
1162+
}
1163+
11281164
int ReturnValue = 0;
1129-
bool HadError = performCompile(Instance, Invocation, Args, ReturnValue) ||
1130-
Instance.getASTContext().hadError();
1165+
bool HadError =
1166+
performCompile(Instance, Invocation, Args, ReturnValue, observer) ||
1167+
Instance.getASTContext().hadError();
11311168

11321169
if (!HadError && !Invocation.getFrontendOptions().DumpAPIPath.empty()) {
11331170
HadError = dumpAPI(Instance.getMainModule(),
@@ -1148,3 +1185,11 @@ int swift::performFrontend(ArrayRef<const char *> Args,
11481185

11491186
return (HadError ? 1 : ReturnValue);
11501187
}
1188+
1189+
void FrontendObserver::parsedArgs(CompilerInvocation &invocation) {}
1190+
void FrontendObserver::configuredCompiler(CompilerInstance &instance) {}
1191+
void FrontendObserver::performedSemanticAnalysis(CompilerInstance &instance) {}
1192+
void FrontendObserver::performedSILGeneration(SILModule &module) {}
1193+
void FrontendObserver::performedSILDiagnostics(SILModule &module) {}
1194+
void FrontendObserver::performedSILOptimization(SILModule &module) {}
1195+
void FrontendObserver::aboutToRunImmediately(CompilerInstance &instance) {}

tools/driver/driver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "swift/Driver/Job.h"
2525
#include "swift/Frontend/Frontend.h"
2626
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
27-
#include "swift/Subsystems.h"
27+
#include "swift/FrontendTool/FrontendTool.h"
2828
#include "llvm/ADT/SmallVector.h"
2929
#include "llvm/Support/CommandLine.h"
3030
#include "llvm/Support/Errno.h"

0 commit comments

Comments
 (0)