Skip to content

Commit

Permalink
Reduce downstream delta
Browse files Browse the repository at this point in the history
This commit is motivated by reducing the merge burden by shrinking the
diff between llvm upstream and classic-flang-llvm-project.

Outside of Flang, Fortran code is fed through the Compile phase, and
the appropriate tooling is picked up through ToolChain::SelectTool.

Classic Flang introduced a FortranFrontend, but these days this seems
unnecessary. Fortran can go through the same machinery as everything else.

* Use the Preprocess phase to preprocess Fortran code. This phase is
  always combined with the Compile phase.

* Use the Compile phase to lower Fortran code to LLVM IR, and use the
  Backend phase to compile and optimize the IR. These phases are never
  combined.

* Remove FortranFrontendJobClass.

* Remove FortranFrontend tool (instead it's just the Flang tool, which
  in Classic Flang mode is Classic Flang).

* Update tests which inspect the output of the Classic Flang tooling,
  and ensures that the driver does the right thing for various types of
  inputs.

Based on a patch from Peter Waller <[email protected]>.
  • Loading branch information
bryanpkc committed Sep 25, 2024
1 parent bea6f6d commit 4d1a0c9
Show file tree
Hide file tree
Showing 15 changed files with 125 additions and 102 deletions.
11 changes: 0 additions & 11 deletions clang/include/clang/Driver/Action.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ class Action {
AnalyzeJobClass,
MigrateJobClass,
CompileJobClass,
FortranFrontendJobClass,
BackendJobClass,
AssembleJobClass,
LinkJobClass,
Expand Down Expand Up @@ -471,16 +470,6 @@ class MigrateJobAction : public JobAction {
}
};

class FortranFrontendJobAction : public JobAction {
void anchor() override;
public:
FortranFrontendJobAction(Action *Input, types::ID OutputType);

static bool classof(const Action *A) {
return A->getKind() == FortranFrontendJobClass;
}
};

class CompileJobAction : public JobAction {
void anchor() override;

Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Driver/Phases.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ namespace phases {
enum ID {
Preprocess,
Precompile,
FortranFrontend,
Compile,
Backend,
Assemble,
Expand Down
2 changes: 0 additions & 2 deletions clang/include/clang/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ class ToolChain {

mutable std::unique_ptr<Tool> Clang;
mutable std::unique_ptr<Tool> Flang;
mutable std::unique_ptr<Tool> FortranFrontend;
mutable std::unique_ptr<Tool> Assemble;
mutable std::unique_ptr<Tool> Link;
mutable std::unique_ptr<Tool> StaticLibTool;
Expand All @@ -170,7 +169,6 @@ class ToolChain {

Tool *getClang() const;
Tool *getFlang() const;
Tool *getFortranFrontend() const;
Tool *getAssemble() const;
Tool *getLink() const;
Tool *getStaticLibTool() const;
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/Driver/Types.def
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ TYPE("ada", Ada, INVALID, nullptr, phases
TYPE("assembler", PP_Asm, INVALID, "s", phases::Assemble, phases::Link)
TYPE("assembler-with-cpp", Asm, PP_Asm, "S", phases::Preprocess, phases::Assemble, phases::Link)
#ifdef ENABLE_CLASSIC_FLANG
TYPE("f77", PP_F_FixedForm, INVALID, "f", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link)
TYPE("f77-cpp-input", F_FixedForm, PP_F_FixedForm, "F", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link)
TYPE("f95", PP_F_FreeForm, INVALID, "f95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link)
TYPE("f95-cpp-input", F_FreeForm, PP_F_FreeForm, "F95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link)
TYPE("f77", PP_F_FixedForm, INVALID, "f", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("f77-cpp-input", F_FixedForm, PP_F_FixedForm, "F", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("f95", PP_F_FreeForm, INVALID, "f95", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("f95-cpp-input", F_FreeForm, PP_F_FreeForm, "F95", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
#else
TYPE("f95", PP_Fortran, INVALID, "i", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
Expand Down
7 changes: 0 additions & 7 deletions clang/lib/Driver/Action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ const char *Action::getClassName(ActionClass AC) {
return "api-extractor";
case AnalyzeJobClass: return "analyzer";
case MigrateJobClass: return "migrator";
case FortranFrontendJobClass: return "fortran-frontend";
case CompileJobClass: return "compiler";
case BackendJobClass: return "backend";
case AssembleJobClass: return "assembler";
Expand Down Expand Up @@ -373,12 +372,6 @@ void MigrateJobAction::anchor() {}
MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
: JobAction(MigrateJobClass, Input, OutputType) {}

void FortranFrontendJobAction::anchor() {}

FortranFrontendJobAction::FortranFrontendJobAction(Action *Input,
types::ID OutputType)
: JobAction(FortranFrontendJobClass, Input, OutputType) {}

void CompileJobAction::anchor() {}

CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
Expand Down
50 changes: 20 additions & 30 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,27 +346,15 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,

// -{E,EP,P,M,MM} only run the preprocessor.
if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
#ifdef ENABLE_CLASSIC_FLANG
(PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
#endif
(PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
(PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
(PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
CCGenDiagnostics) {
#ifdef ENABLE_CLASSIC_FLANG
// -fsyntax-only or -E stops Fortran compilation after FortranFrontend
if (IsFlangMode() && (DAL.getLastArg(options::OPT_E) ||
DAL.getLastArg(options::OPT_fsyntax_only))) {
FinalPhase = phases::FortranFrontend;

// if not Fortran, fsyntax_only implies 'Compile' is the FinalPhase
} else if (DAL.getLastArg(options::OPT_fsyntax_only)) {
if (IsFlangMode())
FinalPhase = phases::Compile;

// everything else has 'Preprocess' as its FinalPhase
} else {
else
FinalPhase = phases::Preprocess;
}
#else
FinalPhase = phases::Preprocess;
#endif
Expand All @@ -380,14 +368,9 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
options::OPT_fmodule_header_EQ))) {
FinalPhase = phases::Precompile;

#ifdef ENABLE_CLASSIC_FLANG
// -{analyze,emit-ast} only run up to the compiler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
#else
// -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
(PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
#endif
(PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
(PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
(PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
Expand Down Expand Up @@ -4076,10 +4059,13 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
if (InputArg->isClaimed())
continue;

// Fortran input is preprocessed using the frontend.
if (InitialPhase == phases::FortranFrontend &&
#ifdef ENABLE_CLASSIC_FLANG
// If the input is detected as already preprocessed (e.g. has the .f95
// extension), and the user specifies -E, preprocess the file anyway.
if (IsFlangMode() && InitialPhase == phases::Compile &&
FinalPhase == phases::Preprocess)
continue;
#endif

// Claim here to avoid the more general unused warning.
InputArg->claim();
Expand Down Expand Up @@ -4854,13 +4840,6 @@ Action *Driver::ConstructPhaseAction(

return C.MakeAction<PrecompileJobAction>(Input, OutputTy);
}
case phases::FortranFrontend: {
if (Args.hasArg(options::OPT_fsyntax_only))
return C.MakeAction<FortranFrontendJobAction>(Input,
types::TY_Nothing);
return C.MakeAction<FortranFrontendJobAction>(Input,
types::TY_LLVM_IR);
}
case phases::Compile: {
if (Args.hasArg(options::OPT_fsyntax_only))
return C.MakeAction<CompileJobAction>(Input, types::TY_Nothing);
Expand All @@ -4883,6 +4862,10 @@ Action *Driver::ConstructPhaseAction(
return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing);
if (Args.hasArg(options::OPT_extract_api))
return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
#ifdef ENABLE_CLASSIC_FLANG
if (IsFlangMode())
return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_IR);
#endif
return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC);
}
case phases::Backend: {
Expand Down Expand Up @@ -5349,6 +5332,10 @@ class ToolSelector final {
if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR()))
return nullptr;

// Classic Flang is not integrated with the backend.
if (C.getDriver().IsFlangMode() && !T->hasIntegratedAssembler())
return nullptr;

if (T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode))
return nullptr;

Expand Down Expand Up @@ -6620,8 +6607,11 @@ bool Driver::ShouldUseFlangCompiler(const JobAction &JA) const {
return false;

// And say "no" if this is not a kind of action flang understands.
if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) &&
!isa<BackendJobAction>(JA))
if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA)
#ifndef ENABLE_CLASSIC_FLANG
&& !isa<BackendJobAction>(JA)
#endif
)
return false;

return true;
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Driver/Phases.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const char *phases::getPhaseName(ID Id) {
switch (Id) {
case Preprocess: return "preprocessor";
case Precompile: return "precompiler";
case FortranFrontend: return "fortran-frontend";
case Compile: return "compiler";
case Backend: return "backend";
case Assemble: return "assembler";
Expand Down
21 changes: 4 additions & 17 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,13 +467,13 @@ Tool *ToolChain::getClang() const {
}

Tool *ToolChain::getFlang() const {
#ifndef ENABLE_CLASSIC_FLANG
if (!Flang)
Flang.reset(new tools::Flang(*this));
return Flang.get();
#ifdef ENABLE_CLASSIC_FLANG
Flang.reset(new tools::ClassicFlang(*this));
#else
llvm_unreachable("Flang is not supported by this toolchain");
Flang.reset(new tools::Flang(*this));
#endif
return Flang.get();
}

Tool *ToolChain::buildAssembler() const {
Expand All @@ -494,16 +494,6 @@ Tool *ToolChain::getAssemble() const {
return Assemble.get();
}

Tool *ToolChain::getFortranFrontend() const {
#ifdef ENABLE_CLASSIC_FLANG
if (!FortranFrontend)
FortranFrontend.reset(new tools::ClassicFlang(*this));
return FortranFrontend.get();
#else
llvm_unreachable("Fortran is not supported by this toolchain");
#endif
}

Tool *ToolChain::getClangAs() const {
if (!Assemble)
Assemble.reset(new tools::ClangAs(*this));
Expand Down Expand Up @@ -587,9 +577,6 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const {
return getOffloadPackager();
case Action::LinkerWrapperJobClass:
return getLinkerWrapper();

case Action::FortranFrontendJobClass:
return getFortranFrontend();
}

llvm_unreachable("Invalid tool kind.");
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/ClassicFlang.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class LLVM_LIBRARY_VISIBILITY ClassicFlang : public Tool {

bool hasGoodDiagnostics() const override { return true; }
bool hasIntegratedAssembler() const override { return false; }
bool hasIntegratedCPP() const override { return false; }
bool hasIntegratedCPP() const override { return true; }

void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
Expand Down
12 changes: 12 additions & 0 deletions clang/test/Driver/flang/classic-flang-must-preprocess.F
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
! REQUIRES: classic_flang

! Check that the driver invokes flang1 correctly for fixed-form Fortran code
! which requires preprocessing.

! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \
! RUN: | FileCheck %s
! CHECK: "flang1"
! CHECK-SAME: "-preprocess"
! CHECK-SAME: "-nofreeform"
! CHECK-NEXT: "flang2"
! CHECK-NEXT: {{clang.* "-cc1"}}
12 changes: 12 additions & 0 deletions clang/test/Driver/flang/classic-flang-must-preprocess.F95
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
! REQUIRES: classic_flang

! Check that the driver invokes flang1 correctly for free-form Fortran code
! which requires preprocessing.

! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \
! RUN: | FileCheck %s
! CHECK: "flang1"
! CHECK-SAME: "-preprocess"
! CHECK-SAME: "-freeform"
! CHECK-NEXT: "flang2"
! CHECK-NEXT: {{clang.* "-cc1"}}
26 changes: 26 additions & 0 deletions clang/test/Driver/flang/classic-flang.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
! REQUIRES: classic_flang

! Check that the driver invokes flang1 correctly for preprocessed fixed-form
! Fortran code.

! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \
! RUN: | FileCheck %s
! CHECK: "flang1"
! CHECK-NOT: "-preprocess"
! CHECK-SAME: "-nofreeform"
! CHECK-NEXT: "flang2"
! CHECK-NEXT: {{clang.* "-cc1"}}

! Check that the driver invokes flang1 correctly when preprocessing is
! explicitly requested.

! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -E %s -### 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-PREPROCESS %s
! CHECK-PREPROCESS: "flang1"
! CHECK-PREPROCESS-SAME: "-preprocess"
! CHECK-PREPROCESS-SAME: "-es"
! CHECK-PREPROCESS-SAME: "-pp"
! CHECK-PREPROCESS-NOT: "flang1"
! CHECK-PREPROCESS-NOT: "flang2"
! CHECK-PREPROCESS-NOT: {{clang.* "-cc1"}}
! CHECK-PREPROCESS-NOT: {{clang.* "-cc1as"}}
43 changes: 43 additions & 0 deletions clang/test/Driver/flang/classic-flang.f95
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
! REQUIRES: classic_flang

! Check that the driver invokes flang1 correctly for preprocessed free-form
! Fortran code. Also check that the backend is invoked correctly.

! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s
! CHECK-OBJECT: "flang1"
! CHECK-OBJECT-NOT: "-preprocess"
! CHECK-OBJECT-SAME: "-freeform"
! CHECK-OBJECT-NEXT: "flang2"
! CHECK-OBJECT-SAME: "-asm" [[LLFILE:.*.ll]]
! CHECK-OBJECT-NEXT: {{clang.* "-cc1"}}
! CHECK-OBJECT-SAME: "-o" "classic-flang.o"
! CHECK-OBJECT-SAME: "-x" "ir"
! CHECK-OBJECT-SAME: [[LLFILE]]

! Check that the driver invokes flang1 correctly when preprocessing is
! explicitly requested.

! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -E %s -### 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-PREPROCESS %s
! CHECK-PREPROCESS: "flang1"
! CHECK-PREPROCESS-SAME: "-preprocess"
! CHECK-PREPROCESS-SAME: "-es"
! CHECK-PREPROCESS-SAME: "-pp"
! CHECK-PREPROCESS-NOT: "flang1"
! CHECK-PREPROCESS-NOT: "flang2"
! CHECK-PREPROCESS-NOT: {{clang.* "-cc1"}}
! CHECK-PREPROCESS-NOT: {{clang.* "-cc1as"}}

! Check that the backend job (clang -cc1) is not combined into the compile job
! (flang2) even if -integrated-as is specified.

! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-ASM %s
! CHECK-ASM: "flang1"
! CHECK-ASM-NEXT: "flang2"
! CHECK-ASM-SAME: "-asm" [[LLFILE:.*.ll]]
! CHECK-ASM-NEXT: {{clang.* "-cc1"}}
! CHECK-ASM-SAME: "-o" "classic-flang.s"
! CHECK-ASM-SAME: "-x" "ir"
! CHECK-ASM-SAME: [[LLFILE]]
28 changes: 0 additions & 28 deletions clang/test/Driver/flang/classic_flang.f95

This file was deleted.

3 changes: 3 additions & 0 deletions clang/test/Driver/lit.local.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ config.suffixes = [
".f90",
".F90",
".f95",
'.F95',
'.f',
'.F',
".cu",
".rs",
".cl",
Expand Down

0 comments on commit 4d1a0c9

Please sign in to comment.