aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Driver/CC1Options.td2
-rw-r--r--include/clang/Frontend/CodeGenOptions.h6
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp13
-rw-r--r--lib/Frontend/CompilerInvocation.cpp4
4 files changed, 25 insertions, 0 deletions
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 442a3edebd..9d2083258a 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -143,6 +143,8 @@ def femit_coverage_data: Flag<"-femit-coverage-data">,
def coverage_file : Separate<"-coverage-file">,
HelpText<"Emit coverage data to this filename. The extension will be replaced.">;
def coverage_file_EQ : Joined<"-coverage-file=">, Alias<coverage_file>;
+def fuse_register_sized_bitfield_access: Flag<"-fuse-register-sized-bitfield-access">,
+ HelpText<"Use register sized accesses to bit-fields, when possible.">;
def relaxed_aliasing : Flag<"-relaxed-aliasing">,
HelpText<"Turn off Type Based Alias Analysis">;
def masm_verbose : Flag<"-masm-verbose">,
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 83be6f770f..2191980b95 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -91,6 +91,11 @@ public:
unsigned UnrollLoops : 1; /// Control whether loops are unrolled.
unsigned UnsafeFPMath : 1; /// Allow unsafe floating point optzns.
unsigned UnwindTables : 1; /// Emit unwind tables.
+
+ /// Attempt to use register sized accesses to bit-fields in structures, when
+ /// possible.
+ unsigned UseRegisterSizedBitfieldAccess : 1;
+
unsigned VerifyModule : 1; /// Control whether the module should be run
/// through the LLVM Verifier.
@@ -176,6 +181,7 @@ public:
UnrollLoops = 0;
UnsafeFPMath = 0;
UnwindTables = 0;
+ UseRegisterSizedBitfieldAccess = 0;
VerifyModule = 1;
Inlining = NoInlining;
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 0d72f854ba..6daf2ea371 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/RecordLayout.h"
+#include "clang/Frontend/CodeGenOptions.h"
#include "CodeGenTypes.h"
#include "CGCXXABI.h"
#include "llvm/DerivedTypes.h"
@@ -268,6 +269,18 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types,
unsigned AccessedTargetBits = 0; // The number of target bits accessed.
unsigned AccessWidth = TypeSizeInBits; // The current access width to attempt.
+ // If requested, widen the initial bit-field access to be register sized. The
+ // theory is that this is most likely to allow multiple accesses into the same
+ // structure to be coalesced, and that the backend should be smart enough to
+ // narrow the store if no coalescing is ever done.
+ //
+ // The subsequent code will handle align these access to common boundaries and
+ // guaranteeing that we do not access past the end of the structure.
+ if (Types.getCodeGenOpts().UseRegisterSizedBitfieldAccess) {
+ if (AccessWidth < Types.getTarget().getRegisterWidth())
+ AccessWidth = Types.getTarget().getRegisterWidth();
+ }
+
// Round down from the field offset to find the first access position that is
// at an aligned offset of the initial access type.
uint64_t AccessStart = FieldOffset - (FieldOffset % AccessWidth);
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 977f351e42..61887e8eb2 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -133,6 +133,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
Res.push_back("-fno-common");
if (Opts.ForbidGuardVariables)
Res.push_back("-fforbid-guard-variables");
+ if (Opts.UseRegisterSizedBitfieldAccess)
+ Res.push_back("-fuse-register-sized-bitfield-access");
if (Opts.NoImplicitFloat)
Res.push_back("-no-implicit-float");
if (Opts.OmitLeafFramePointer)
@@ -956,6 +958,8 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables);
+ Opts.UseRegisterSizedBitfieldAccess = Args.hasArg(
+ OPT_fuse_register_sized_bitfield_access);
Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing);
Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);
Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants);