[PATCH] pr13012: Support -fpcc-struct-return for x86-32
Arthur O'Dwyer
arthur.j.odwyer at gmail.com
Fri Jun 7 12:07:19 PDT 2013
On Wed, Jun 5, 2013 at 1:23 PM, Arthur O'Dwyer
<arthur.j.odwyer at gmail.com> wrote:
>
> This is my first post to cfe-commits, so my apologies if I get
> something wrong.
> A while back I filed an issue on Bugzilla requesting support for
> -fpcc-struct-return:
> http://llvm.org/bugs/show_bug.cgi?id=13012
>
> Recently I wrote a real patch [...] I believe I don't have the necessary
> credentials to commit the patch anyway, so basically I'm looking for
> a patron to adopt this patch. :)
>
> To observe what the patch does:
> echo "struct S {int i;} foo() {return (struct S){42};}" >foo.c
> clang -m32 -O3 -fomit-frame-pointer foo.c -S -o reg.s
> clang -m32 -O3 -fomit-frame-pointer foo.c -S -o pcc.s -fpcc-struct-return
> diff reg.s pcc.s
Ping? Any takers? Any comments at all?
-Arthur
Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def (revision 183239)
+++ include/clang/Frontend/CodeGenOptions.def (working copy)
@@ -85,6 +85,7 @@
///< enabled.
VALUE_CODEGENOPT(OptimizationLevel, 3, 0) ///< The -O[0-4] option specified.
VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2)
is specified.
+VALUE_CODEGENOPT(PassSmallStructsConvention, 2, 0) /// If
-fpcc-struct-return (==1) or -freg-struct-return (==2) is specified.
CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions.
CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when
-fno-strict-aliasing is enabled.
CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use
struct-path TBAA.
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td (revision 183239)
+++ include/clang/Driver/Options.td (working copy)
@@ -659,6 +659,8 @@
HelpText<"Specify the default maximum struct packing alignment">;
def fpascal_strings : Flag<["-"], "fpascal-strings">, Group<f_Group>,
Flags<[CC1Option]>,
HelpText<"Recognize and construct Pascal-style string literals">;
+def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">,
Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Return small structs on the stack">;
def fpch_preprocess : Flag<["-"], "fpch-preprocess">, Group<f_Group>;
def fpic : Flag<["-"], "fpic">, Group<f_Group>;
def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>;
@@ -668,6 +670,8 @@
def fprofile_generate : Flag<["-"], "fprofile-generate">, Group<f_Group>;
def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>;
def frandom_seed_EQ : Joined<["-"], "frandom-seed=">,
Group<clang_ignored_f_Group>;
+def freg_struct_return : Flag<["-"], "freg-struct-return">,
Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Return small structs in registers">;
def frtti : Flag<["-"], "frtti">, Group<f_Group>;
def fsched_interblock : Flag<["-"], "fsched-interblock">,
Group<clang_ignored_f_Group>;
def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>,
Flags<[CC1Option]>,
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp (revision 183239)
+++ lib/Frontend/CompilerInvocation.cpp (working copy)
@@ -473,6 +473,15 @@
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
}
+ if (Arg *A = Args.getLastArg(OPT_fpcc_struct_return,
OPT_freg_struct_return)) {
+ if (A->getOption().matches(OPT_fpcc_struct_return)) {
+ Opts.PassSmallStructsConvention = 1;
+ } else {
+ assert(A->getOption().matches(OPT_freg_struct_return));
+ Opts.PassSmallStructsConvention = 2;
+ }
+ }
+
return Success;
}
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp (revision 183239)
+++ lib/Driver/Tools.cpp (working copy)
@@ -2160,6 +2160,15 @@
CmdArgs.push_back(A->getValue());
}
+ if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
options::OPT_freg_struct_return)) {
+ if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
+ CmdArgs.push_back("-fpcc-struct-return");
+ } else {
+ assert(A->getOption().matches(options::OPT_freg_struct_return));
+ CmdArgs.push_back("-freg-struct-return");
+ }
+ }
+
if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
CmdArgs.push_back("-mrtd");
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp (revision 183239)
+++ lib/CodeGen/TargetInfo.cpp (working copy)
@@ -4402,7 +4402,26 @@
return ResAddr;
}
+static bool shouldPassSmallStructsInRegsByDefault(const llvm::Triple &Triple) {
+ assert(Triple.getArch() == llvm::Triple::x86);
+ if (Triple.isOSDarwin())
+ return true;
+
+ switch (Triple.getOS()) {
+ case llvm::Triple::Cygwin:
+ case llvm::Triple::MinGW32:
+ case llvm::Triple::AuroraUX:
+ case llvm::Triple::DragonFly:
+ case llvm::Triple::FreeBSD:
+ case llvm::Triple::OpenBSD:
+ case llvm::Triple::Bitrig:
+ return true;
+ default:
+ return false;
+ }
+}
+
ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
@@ -5420,31 +5439,32 @@
return *(TheTargetCodeGenInfo = new TCETargetCodeGenInfo(Types));
case llvm::Triple::x86: {
- if (Triple.isOSDarwin())
- return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, true, true, false,
- CodeGenOpts.NumRegisterParameters));
+ bool IsDarwinVectorABI = Triple.isOSDarwin();
+ bool IsSmallStructInRegABI = shouldPassSmallStructsInRegsByDefault(Triple);
+ bool IsWin32FloatStructABI = (Triple.getOS() == llvm::Triple::Win32);
- switch (Triple.getOS()) {
- case llvm::Triple::Cygwin:
- case llvm::Triple::MinGW32:
- case llvm::Triple::AuroraUX:
- case llvm::Triple::DragonFly:
- case llvm::Triple::FreeBSD:
- case llvm::Triple::OpenBSD:
- case llvm::Triple::Bitrig:
- return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, false, true, false,
- CodeGenOpts.NumRegisterParameters));
+ switch (CodeGenOpts.PassSmallStructsConvention) {
+ case 0: /* use the target's default */
+ break;
+ case 1: /* -fpcc-struct-return */
+ IsSmallStructInRegABI = false;
+ break;
+ case 2: /* -freg-struct-return */
+ IsSmallStructInRegABI = true;
+ break;
+ default:
+ assert(false);
+ }
- case llvm::Triple::Win32:
+ if (Triple.getOS() == llvm::Triple::Win32) {
return *(TheTargetCodeGenInfo =
new WinX86_32TargetCodeGenInfo(Types,
CodeGenOpts.NumRegisterParameters));
-
- default:
+ } else {
return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, false, false, false,
+ new X86_32TargetCodeGenInfo(Types,
+ IsDarwinVectorABI,
IsSmallStructInRegABI,
+ IsWin32FloatStructABI,
CodeGenOpts.NumRegisterParameters));
}
}
More information about the cfe-commits
mailing list