[clang] ec94f37 - [LTO][clang] Teaching Clang to Pass Plugin Options to the AIX Linker
Qiongsi Wu via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 12 12:59:15 PDT 2022
Author: Qiongsi Wu
Date: 2022-10-12T15:57:46-04:00
New Revision: ec94f372d1c13b40029519a50184258d4de24a13
URL: https://github.com/llvm/llvm-project/commit/ec94f372d1c13b40029519a50184258d4de24a13
DIFF: https://github.com/llvm/llvm-project/commit/ec94f372d1c13b40029519a50184258d4de24a13.diff
LOG: [LTO][clang] Teaching Clang to Pass Plugin Options to the AIX Linker
This patch teaches `clang` to use the prefix `-bplugin_opt:` (instead of `-plugin-opt`) on AIX, when passing plugin options to the linker. This patch follows https://reviews.llvm.org/D134668.
We put the code that decides what plugin option prefix to use at the top of the function `tools::addLTOOptions`. The plugin option prefix, the mcpu prefix, and the opt level prefix are different on AIX. We thought about choosing the strings in a function that reads the linker name and the target triple, or we could push the logic into different derived `ToolChain` classes. But this logic would not be used anywhere else, so these alternatives looked too complicated for what they did. Therefore we are doing it the current way. That said, I am all ears for suggestions to improve this code!
Subsequent code uses the `PluginOptPrefix` variable consistently instead of the hardcoded `-plugin-opt`.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D134820
Added:
clang/test/Driver/lto-aix.c
Modified:
clang/lib/Driver/ToolChains/AIX.cpp
clang/lib/Driver/ToolChains/AIX.h
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/CommonArgs.h
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp
index 653fbeaffbd4e..748b6a3590053 100644
--- a/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/clang/lib/Driver/ToolChains/AIX.cpp
@@ -191,6 +191,12 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// Specify linker input file(s).
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+ if (D.isUsingLTO()) {
+ assert(!Inputs.empty() && "Must have at least one input.");
+ addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0],
+ D.getLTOMode() == LTOK_Thin);
+ }
+
if (Args.hasArg(options::OPT_shared) && !hasExportListLinkerOpts(CmdArgs)) {
const char *CreateExportListExec = Args.MakeArgString(
diff --git a/clang/lib/Driver/ToolChains/AIX.h b/clang/lib/Driver/ToolChains/AIX.h
index e7ec3a5ece4dc..c9948a65b89ab 100644
--- a/clang/lib/Driver/ToolChains/AIX.h
+++ b/clang/lib/Driver/ToolChains/AIX.h
@@ -67,6 +67,7 @@ class LLVM_LIBRARY_VISIBILITY AIX : public ToolChain {
return false;
}
bool isPICDefaultForced() const override { return true; }
+ bool HasNativeLLVMSupport() const override { return true; }
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 7d4efaa88405d..21ad9c8b836b2 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -65,24 +65,26 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
-static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs) {
+static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs,
+ const StringRef PluginOptPrefix) {
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
- CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=-pass-remarks=") +
- A->getValue()));
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "-pass-remarks=" + A->getValue()));
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
CmdArgs.push_back(Args.MakeArgString(
- Twine("-plugin-opt=-pass-remarks-missed=") + A->getValue()));
+ Twine(PluginOptPrefix) + "-pass-remarks-missed=" + A->getValue()));
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
CmdArgs.push_back(Args.MakeArgString(
- Twine("-plugin-opt=-pass-remarks-analysis=") + A->getValue()));
+ Twine(PluginOptPrefix) + "-pass-remarks-analysis=" + A->getValue()));
}
static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
const llvm::Triple &Triple,
const InputInfo &Input,
- const InputInfo &Output) {
+ const InputInfo &Output,
+ const StringRef PluginOptPrefix) {
StringRef Format = "yaml";
if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
Format = A->getValue();
@@ -96,29 +98,32 @@ static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
assert(!F.empty() && "Cannot determine remarks output name.");
// Append "opt.ld.<format>" to the end of the file name.
- CmdArgs.push_back(
- Args.MakeArgString(Twine("-plugin-opt=opt-remarks-filename=") + F +
- Twine(".opt.ld.") + Format));
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "opt-remarks-filename=" + F +
+ ".opt.ld." + Format));
if (const Arg *A =
Args.getLastArg(options::OPT_foptimization_record_passes_EQ))
CmdArgs.push_back(Args.MakeArgString(
- Twine("-plugin-opt=opt-remarks-passes=") + A->getValue()));
+ Twine(PluginOptPrefix) + "opt-remarks-passes=" + A->getValue()));
- CmdArgs.push_back(Args.MakeArgString(
- Twine("-plugin-opt=opt-remarks-format=") + Format.data()));
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "opt-remarks-format=" + Format.data()));
}
static void renderRemarksHotnessOptions(const ArgList &Args,
- ArgStringList &CmdArgs) {
+ ArgStringList &CmdArgs,
+ const StringRef PluginOptPrefix) {
if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness,
options::OPT_fno_diagnostics_show_hotness, false))
- CmdArgs.push_back("-plugin-opt=opt-remarks-with-hotness");
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "opt-remarks-with-hotness"));
if (const Arg *A =
Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ))
- CmdArgs.push_back(Args.MakeArgString(
- Twine("-plugin-opt=opt-remarks-hotness-threshold=") + A->getValue()));
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) +
+ "opt-remarks-hotness-threshold=" + A->getValue()));
}
void tools::addPathIfExists(const Driver &D, const Twine &Path,
@@ -484,14 +489,19 @@ bool tools::isUseSeparateSections(const llvm::Triple &Triple) {
void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
ArgStringList &CmdArgs, const InputInfo &Output,
const InputInfo &Input, bool IsThinLTO) {
+ const bool IsOSAIX = ToolChain.getTriple().isOSAIX();
const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
const Driver &D = ToolChain.getDriver();
if (llvm::sys::path::filename(Linker) != "ld.lld" &&
llvm::sys::path::stem(Linker) != "ld.lld") {
// Tell the linker to load the plugin. This has to come before
- // AddLinkerInputs as gold requires -plugin to come before any -plugin-opt
- // that -Wl might forward.
- CmdArgs.push_back("-plugin");
+ // AddLinkerInputs as gold requires -plugin and AIX ld requires -bplugin to
+ // come before any -plugin-opt/-bplugin_opt that -Wl might forward.
+ const char *PluginPrefix = IsOSAIX ? "-bplugin:" : "";
+ const char *PluginName = IsOSAIX ? "/libLTO" : "/LLVMgold";
+
+ if (!IsOSAIX)
+ CmdArgs.push_back("-plugin");
#if defined(_WIN32)
const char *Suffix = ".dll";
@@ -502,19 +512,23 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
#endif
SmallString<1024> Plugin;
- llvm::sys::path::native(
- Twine(D.Dir) + "/../" CLANG_INSTALL_LIBDIR_BASENAME "/LLVMgold" +
- Suffix,
- Plugin);
- CmdArgs.push_back(Args.MakeArgString(Plugin));
+ llvm::sys::path::native(Twine(D.Dir) +
+ "/../" CLANG_INSTALL_LIBDIR_BASENAME +
+ PluginName + Suffix,
+ Plugin);
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginPrefix) + Plugin));
}
+ const char *PluginOptPrefix = IsOSAIX ? "-bplugin_opt:" : "-plugin-opt=";
+ const char *mcpuOptPrefix = IsOSAIX ? "-mcpu=" : "mcpu=";
+ const char *OptLevelPrefix = IsOSAIX ? "-O" : "O";
+
// Note, this solution is far from perfect, better to encode it into IR
// metadata, but this may not be worth it, since it looks like aranges is on
// the way out.
if (Args.hasArg(options::OPT_gdwarf_aranges)) {
- CmdArgs.push_back(
- Args.MakeArgString("-plugin-opt=-generate-arange-section"));
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "-generate-arange-section"));
}
// Try to pass driver level flags relevant to LTO code generation down to
@@ -523,7 +537,8 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
// Handle flags for selecting CPU variants.
std::string CPU = getCPUName(D, Args, ToolChain.getTriple());
if (!CPU.empty())
- CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU));
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + mcpuOptPrefix + CPU));
if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
// The optimization level matches
@@ -541,34 +556,37 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
} else if (A->getOption().matches(options::OPT_O0))
OOpt = "0";
if (!OOpt.empty())
- CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=O") + OOpt));
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + OptLevelPrefix + OOpt));
}
- if (Args.hasArg(options::OPT_gsplit_dwarf)) {
- CmdArgs.push_back(
- Args.MakeArgString(Twine("-plugin-opt=dwo_dir=") +
- Output.getFilename() + "_dwo"));
- }
+ if (Args.hasArg(options::OPT_gsplit_dwarf))
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine(PluginOptPrefix) + "dwo_dir=" + Output.getFilename() + "_dwo"));
if (IsThinLTO)
- CmdArgs.push_back("-plugin-opt=thinlto");
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + "thinlto"));
StringRef Parallelism = getLTOParallelism(Args, D);
if (!Parallelism.empty())
CmdArgs.push_back(
- Args.MakeArgString("-plugin-opt=jobs=" + Twine(Parallelism)));
+ Args.MakeArgString(Twine(PluginOptPrefix) + "jobs=" + Parallelism));
// If an explicit debugger tuning argument appeared, pass it along.
- if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
- options::OPT_ggdbN_Group)) {
+ if (Arg *A =
+ Args.getLastArg(options::OPT_gTune_Group, options::OPT_ggdbN_Group)) {
if (A->getOption().matches(options::OPT_glldb))
- CmdArgs.push_back("-plugin-opt=-debugger-tune=lldb");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=lldb"));
else if (A->getOption().matches(options::OPT_gsce))
- CmdArgs.push_back("-plugin-opt=-debugger-tune=sce");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=sce"));
else if (A->getOption().matches(options::OPT_gdbx))
- CmdArgs.push_back("-plugin-opt=-debugger-tune=dbx");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=dbx"));
else
- CmdArgs.push_back("-plugin-opt=-debugger-tune=gdb");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "-debugger-tune=gdb"));
}
bool UseSeparateSections =
@@ -576,21 +594,26 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
if (Args.hasFlag(options::OPT_ffunction_sections,
options::OPT_fno_function_sections, UseSeparateSections))
- CmdArgs.push_back("-plugin-opt=-function-sections=1");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "-function-sections=1"));
else if (Args.hasArg(options::OPT_fno_function_sections))
- CmdArgs.push_back("-plugin-opt=-function-sections=0");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "-function-sections=0"));
if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
UseSeparateSections))
- CmdArgs.push_back("-plugin-opt=-data-sections=1");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "-data-sections=1"));
else if (Args.hasArg(options::OPT_fno_data_sections))
- CmdArgs.push_back("-plugin-opt=-data-sections=0");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "-data-sections=0"));
// Pass an option to enable split machine functions.
if (auto *A = Args.getLastArg(options::OPT_fsplit_machine_functions,
options::OPT_fno_split_machine_functions)) {
if (A->getOption().matches(options::OPT_fsplit_machine_functions))
- CmdArgs.push_back("-plugin-opt=-split-machine-functions");
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "-split-machine-functions"));
}
if (Arg *A = getLastProfileSampleUseArg(Args)) {
@@ -598,8 +621,8 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
if (!llvm::sys::fs::exists(FName))
D.Diag(diag::err_drv_no_such_file) << FName;
else
- CmdArgs.push_back(
- Args.MakeArgString(Twine("-plugin-opt=sample-profile=") + FName));
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "sample-profile=" + FName));
}
auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate,
@@ -612,29 +635,31 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
auto *ProfileUseArg = getLastProfileUseArg(Args);
if (CSPGOGenerateArg) {
- CmdArgs.push_back(Args.MakeArgString("-plugin-opt=cs-profile-generate"));
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "cs-profile-generate"));
if (CSPGOGenerateArg->getOption().matches(
options::OPT_fcs_profile_generate_EQ)) {
SmallString<128> Path(CSPGOGenerateArg->getValue());
llvm::sys::path::append(Path, "default_%m.profraw");
- CmdArgs.push_back(
- Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") + Path));
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "cs-profile-path=" + Path));
} else
- CmdArgs.push_back(
- Args.MakeArgString("-plugin-opt=cs-profile-path=default_%m.profraw"));
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine(PluginOptPrefix) + "cs-profile-path=default_%m.profraw"));
} else if (ProfileUseArg) {
SmallString<128> Path(
ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
if (Path.empty() || llvm::sys::fs::is_directory(Path))
llvm::sys::path::append(Path, "default.profdata");
- CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") +
- Path));
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine(PluginOptPrefix) + "cs-profile-path=" + Path));
}
// This controls whether or not we perform JustMyCode instrumentation.
if (Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false)) {
if (ToolChain.getEffectiveTriple().isOSBinFormatELF())
- CmdArgs.push_back("-plugin-opt=-enable-jmc-instrument");
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "-enable-jmc-instrument"));
else
D.Diag(clang::diag::warn_drv_fjmc_for_elf_only);
}
@@ -643,29 +668,29 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
if (!StatsFile.empty())
CmdArgs.push_back(
- Args.MakeArgString(Twine("-plugin-opt=stats-file=") + StatsFile));
+ Args.MakeArgString(Twine(PluginOptPrefix) + "stats-file=" + StatsFile));
// Setup crash diagnostics dir.
if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir))
CmdArgs.push_back(Args.MakeArgString(
- Twine("-plugin-opt=-crash-diagnostics-dir=") + A->getValue()));
+ Twine(PluginOptPrefix) + "-crash-diagnostics-dir=" + A->getValue()));
- addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true);
+ addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true, PluginOptPrefix);
// Handle remark diagnostics on screen options: '-Rpass-*'.
- renderRpassOptions(Args, CmdArgs);
+ renderRpassOptions(Args, CmdArgs, PluginOptPrefix);
// Handle serialized remarks options: '-fsave-optimization-record'
// and '-foptimization-record-*'.
if (willEmitRemarks(Args))
renderRemarksOptions(Args, CmdArgs, ToolChain.getEffectiveTriple(), Input,
- Output);
+ Output, PluginOptPrefix);
// Handle remarks hotness/threshold related options.
- renderRemarksHotnessOptions(Args, CmdArgs);
+ renderRemarksHotnessOptions(Args, CmdArgs, PluginOptPrefix);
addMachineOutlinerArgs(D, Args, CmdArgs, ToolChain.getEffectiveTriple(),
- /*IsLTO=*/true);
+ /*IsLTO=*/true, PluginOptPrefix);
}
void tools::addOpenMPRuntimeSpecificRPath(const ToolChain &TC,
@@ -1669,10 +1694,12 @@ void tools::addMultilibFlag(bool Enabled, const char *const Flag,
}
void tools::addX86AlignBranchArgs(const Driver &D, const ArgList &Args,
- ArgStringList &CmdArgs, bool IsLTO) {
+ ArgStringList &CmdArgs, bool IsLTO,
+ const StringRef PluginOptPrefix) {
auto addArg = [&, IsLTO](const Twine &Arg) {
if (IsLTO) {
- CmdArgs.push_back(Args.MakeArgString("-plugin-opt=" + Arg));
+ assert(!PluginOptPrefix.empty() && "Cannot have empty PluginOptPrefix!");
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + Arg));
} else {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back(Args.MakeArgString(Arg));
@@ -2106,10 +2133,12 @@ bool tools::haveAMDGPUCodeObjectVersionArgument(
void tools::addMachineOutlinerArgs(const Driver &D,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs,
- const llvm::Triple &Triple, bool IsLTO) {
+ const llvm::Triple &Triple, bool IsLTO,
+ const StringRef PluginOptPrefix) {
auto addArg = [&, IsLTO](const Twine &Arg) {
if (IsLTO) {
- CmdArgs.push_back(Args.MakeArgString("-plugin-opt=" + Arg));
+ assert(!PluginOptPrefix.empty() && "Cannot have empty PluginOptPrefix!");
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + Arg));
} else {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back(Args.MakeArgString(Arg));
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 326141c3f926e..57b820e6349b3 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -190,7 +190,8 @@ void addMultilibFlag(bool Enabled, const char *const Flag,
Multilib::flags_list &Flags);
void addX86AlignBranchArgs(const Driver &D, const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CmdArgs, bool IsLTO);
+ llvm::opt::ArgStringList &CmdArgs, bool IsLTO,
+ const StringRef PluginOptPrefix = "");
void checkAMDGPUCodeObjectVersion(const Driver &D,
const llvm::opt::ArgList &Args);
@@ -203,7 +204,8 @@ bool haveAMDGPUCodeObjectVersionArgument(const Driver &D,
void addMachineOutlinerArgs(const Driver &D, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs,
- const llvm::Triple &Triple, bool IsLTO);
+ const llvm::Triple &Triple, bool IsLTO,
+ const StringRef PluginOptPrefix = "");
void addOpenMPDeviceRTL(const Driver &D, const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
diff --git a/clang/test/Driver/lto-aix.c b/clang/test/Driver/lto-aix.c
new file mode 100644
index 0000000000000..89b5d5aeb8ef5
--- /dev/null
+++ b/clang/test/Driver/lto-aix.c
@@ -0,0 +1,6 @@
+// Test LTO path, mcpu and opt level options
+// RUN: %clang --target=powerpc-ibm-aix -### %s -flto -fuse-ld=ld -O3 2>&1 \
+// RUN: | FileCheck -check-prefixes=LTOPATH,MCPUOPTLEVEL %s
+//
+// LTOPATH: "-bplugin:{{.*}}libLTO.{{so|dll|dylib}}"
+// MCPUOPTLEVEL: "-bplugin_opt:-mcpu={{.*}}" "-bplugin_opt:-O3"
More information about the cfe-commits
mailing list