Skip to content

[flang][Driver] Support -print-supported-cpus and associated aliases #117199

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -5888,12 +5888,24 @@ def target : Joined<["--"], "target=">, Flags<[NoXarchOption]>,
def darwin_target_variant : Separate<["-"], "darwin-target-variant">,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption]>,
HelpText<"Generate code for an additional runtime variant of the deployment target">;

//===----------------------------------------------------------------------===//
// Print CPU info options (clang, clang-cl, flang)
//===----------------------------------------------------------------------===//

let Visibility = [ClangOption, CC1Option, CLOption, FlangOption, FC1Option] in {

def print_supported_cpus : Flag<["-", "--"], "print-supported-cpus">,
Group<CompileOnly_Group>,
Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Print supported cpu models for the given target (if target is not specified,"
" it will print the supported cpus for the default target)">,
HelpText<"Print supported cpu models for the given target (if target is not "
"specified,it will print the supported cpus for the default target)">,
MarshallingInfoFlag<FrontendOpts<"PrintSupportedCPUs">>;

def : Flag<["-"], "mcpu=help">, Alias<print_supported_cpus>;
def : Flag<["-"], "mtune=help">, Alias<print_supported_cpus>;

} // let Visibility = [ClangOption, CC1Option, CLOption, FlangOption, FC1Option]

def print_supported_extensions : Flag<["-", "--"], "print-supported-extensions">,
Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Print supported -march extensions (RISC-V, AArch64 and ARM only)">,
Expand All @@ -5903,8 +5915,6 @@ def print_enabled_extensions : Flag<["-", "--"], "print-enabled-extensions">,
HelpText<"Print the extensions enabled by the given target and -march/-mcpu options."
" (AArch64 and RISC-V only)">,
MarshallingInfoFlag<FrontendOpts<"PrintEnabledExtensions">>;
def : Flag<["-"], "mcpu=help">, Alias<print_supported_cpus>;
def : Flag<["-"], "mtune=help">, Alias<print_supported_cpus>;
def time : Flag<["-"], "time">,
HelpText<"Time individual commands">;
def traditional_cpp : Flag<["-", "--"], "traditional-cpp">,
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4417,7 +4417,8 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,

// Use the -mcpu=? flag as the dummy input to cc1.
Actions.clear();
Action *InputAc = C.MakeAction<InputAction>(*A, types::TY_C);
Action *InputAc = C.MakeAction<InputAction>(
*A, IsFlangMode() ? types::TY_Fortran : types::TY_C);
Comment on lines +4420 to +4421
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually needed.

The -mcpu=help argument is used as a "dummy input" (there is a comment a few lines above that says as much).
The input action created here eventually gets used in ShouldUseFlangCompiler which checks if the input type is accepted by flang. flang does not accept inputs of type TY_C (even if they are "dummies"). If ShouldUseFlangCompiler returns false, a cc1 command line is created - which is, obviously, not correct.

Actions.push_back(
C.MakeAction<PrecompileJobAction>(InputAc, types::TY_Nothing));
for (auto &I : Inputs)
Expand Down Expand Up @@ -6621,8 +6622,8 @@ 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<PrecompileJobAction>(JA) &&
!isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
return false;

return true;
Expand Down
18 changes: 15 additions & 3 deletions clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
}
} else if (isa<AssembleJobAction>(JA)) {
CmdArgs.push_back("-emit-obj");
} else if (isa<PrecompileJobAction>(JA)) {
// The precompile job action is only needed for options such as -mcpu=help.
// Those will already have been handled by the fc1 driver.
} else {
assert(false && "Unexpected action class for Flang tool.");
}
Expand Down Expand Up @@ -911,8 +914,6 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Output.getFilename());
}

assert(Input.isFilename() && "Invalid input.");

if (Args.getLastArg(options::OPT_save_temps_EQ))
Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ);

Expand All @@ -932,7 +933,18 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
}
}

CmdArgs.push_back(Input.getFilename());
// The input could be Ty_Nothing when "querying" options such as -mcpu=help
// are used.
ArrayRef<InputInfo> FrontendInputs = Input;
if (Input.isNothing())
FrontendInputs = {};

for (const InputInfo &Input : FrontendInputs) {
if (Input.isFilename())
CmdArgs.push_back(Input.getFilename());
else
Input.getInputArg().renderAsInput(Args, CmdArgs);
}

const char *Exec = Args.MakeArgString(D.GetProgramPath("flang", TC));
C.addCommand(std::make_unique<Command>(JA, *this,
Expand Down
6 changes: 5 additions & 1 deletion flang/include/flang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ class FrontendInputFile {
struct FrontendOptions {
FrontendOptions()
: showHelp(false), showVersion(false), instrumentedParse(false),
showColors(false), needProvenanceRangeToCharBlockMappings(false) {}
showColors(false), printSupportedCPUs(false),
needProvenanceRangeToCharBlockMappings(false) {}

/// Show the -help text.
unsigned showHelp : 1;
Expand All @@ -250,6 +251,9 @@ struct FrontendOptions {
/// Enable color diagnostics.
unsigned showColors : 1;

/// Print the supported cpus for the current target
unsigned printSupportedCPUs : 1;

/// Enable Provenance to character-stream mapping. Allows e.g. IDEs to find
/// symbols based on source-code location. This is not needed in regular
/// compilation.
Expand Down
2 changes: 2 additions & 0 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,8 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
opts.outputFile = args.getLastArgValue(clang::driver::options::OPT_o);
opts.showHelp = args.hasArg(clang::driver::options::OPT_help);
opts.showVersion = args.hasArg(clang::driver::options::OPT_version);
opts.printSupportedCPUs =
args.hasArg(clang::driver::options::OPT_print_supported_cpus);

// Get the input kind (from the value passed via `-x`)
InputKind dashX(Language::Unknown);
Expand Down
46 changes: 46 additions & 0 deletions flang/test/Driver/print-supported-cpus.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
! Test --print-supported-cpus and associated aliases, -mcpu=help and
! -mtune=help

! RUN: %if x86-registered-target %{ \
! RUN: %flang --target=x86_64-unknown-linux-gnu --print-supported-cpus 2>&1 \
! RUN: | FileCheck %s --check-prefixes=X86,CHECK \
! RUN: %}
! RUN: %if x86-registered-target %{ \
! RUN: %flang --target=x86_64-unknown-linux-gnu -mcpu=help 2>&1 \
! RUN: | FileCheck %s --check-prefixes=X86,CHECK \
! RUN: %}
! RUN: %if x86-registered-target %{ \
! RUN: %flang --target=x86_64-unknown-linux-gnu -mtune=help 2>&1 \
! RUN: | FileCheck %s --check-prefixes=X86,CHECK \
! RUN: %}

! RUN: %if aarch64-registered-target %{ \
! RUN: %flang --target=aarch64-unknown-linux-gnu --print-supported-cpus 2>&1 \
! RUN: | FileCheck %s --check-prefixes=AARCH64,CHECK \
! RUN: %}
! RUN: %if x86-registered-target %{ \
! RUN: %flang --target=aarch64-unknown-linux-gnu -mcpu=help 2>&1 \
! RUN: | FileCheck %s --check-prefixes=AARCH64,CHECK \
! RUN: %}
! RUN: %if x86-registered-target %{ \
! RUN: %flang --target=aarch64-unknown-linux-gnu -mtune=help 2>&1 \
! RUN: | FileCheck %s --check-prefixes=AARCH64,CHECK \
! RUN: %}

! CHECK-NOT: warning: argument unused during compilation

! X86: Target: x86_64-unknown-linux-gnu
! X86: corei7

! AARCH64: Target: aarch64-unknown-linux-gnu
! AARCH64: cortex-a73
! AARCH64: cortex-a75

! The footer displayed contains a reference to clang. This should be changed to
! flang, but that requires a change in llvm/MCSubtargetInfo. When that happens,
! this test will need to be updated and this comment can be removed.

! CHECK: Use -mcpu or -mtune to specify the target's processor.
! CHECK: For example, clang --target=aarch64-unknown-linux-gnu

end program
24 changes: 24 additions & 0 deletions flang/tools/flang-driver/fc1_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,35 @@
#include "flang/Frontend/TextDiagnosticBuffer.h"
#include "flang/FrontendTool/Utils.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"

#include <cstdio>

using namespace Fortran::frontend;

/// Print supported cpus of the given target.
static int printSupportedCPUs(llvm::StringRef triple) {
std::string error;
const llvm::Target *target =
llvm::TargetRegistry::lookupTarget(triple, error);
if (!target) {
llvm::errs() << error;
return 1;
}

// the target machine will handle the mcpu printing
llvm::TargetOptions targetOpts;
std::unique_ptr<llvm::TargetMachine> targetMachine(
target->createTargetMachine(triple, "", "+cpuhelp", targetOpts,
std::nullopt));
return 0;
}

int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
// Create CompilerInstance
std::unique_ptr<CompilerInstance> flang(new CompilerInstance());
Expand Down Expand Up @@ -58,6 +78,10 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmPrinters();

// --print-supported-cpus takes priority over the actual compilation.
if (flang->getFrontendOpts().printSupportedCPUs)
return printSupportedCPUs(flang->getInvocation().getTargetOpts().triple);

diagsBuffer->flushDiagnostics(flang->getDiagnostics());

if (!success)
Expand Down
Loading