aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2011-06-21 18:54:46 +0000
committerDaniel Dunbar <daniel@zuster.org>2011-06-21 18:54:46 +0000
commite26bdb91b7e3912ffe895b78a446db94471a59dd (patch)
treea455cb228d6d1a1021bd56774d9f27d95088c44c /lib
parent08737c49bd98f73b50fe90fd19f97c41cd29e3d1 (diff)
IRgen: Add a -fuse-register-sized-bitfield-access option, for testing.
- Changes bit-field access policy to try to use (aligned) register sized accesses. The idea here is that by using larger accesses we expose more coalescing potential to the backend when we have situations like adjacent bit-fields in the same structure (which is common), and that the backend should be smart enough to narrow the accesses down when no coalescing is done or when it is shown not to be profitable. -- $ clang -m32 -O3 -S -o - t.c _f0: ## @f0 pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movb (%eax), %cl andb $-128, %cl orb $1, %cl movb %cl, (%eax) movb 1(%eax), %cl andb $-128, %cl orb $1, %cl movb %cl, 1(%eax) movb 2(%eax), %cl andb $-128, %cl orb $1, %cl movb %cl, 2(%eax) movb 3(%eax), %cl andb $-128, %cl orb $1, %cl movb %cl, 3(%eax) popl %ebp ret $ clang -m32 -O3 -S -o - t.c -Xclang -fuse-register-sized-bitfield-access _f0: ## @f0 pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl $-2139062144, %ecx ## imm = 0xFFFFFFFF80808080 andl (%eax), %ecx orl $16843009, %ecx ## imm = 0x1010101 movl %ecx, (%eax) popl %ebp ret -- git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133532 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp13
-rw-r--r--lib/Frontend/CompilerInvocation.cpp4
2 files changed, 17 insertions, 0 deletions
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);