Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1306719 > unrolled thread
| Started by | chengang@emindsoft.com.cn |
|---|---|
| First post | 2016-01-11 22:40 +0100 |
| Last post | 2016-01-14 16:40 +0100 |
| Articles | 9 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH] fs: dcache: Use bool return value instead of int chengang@emindsoft.com.cn - 2016-01-11 22:40 +0100
Re: [PATCH] fs: dcache: Use bool return value instead of int Al Viro <viro@ZenIV.linux.org.uk> - 2016-01-12 00:00 +0100
Re: [PATCH] fs: dcache: Use bool return value instead of int David Howells <dhowells@redhat.com> - 2016-01-12 01:40 +0100
Re: [PATCH] fs: dcache: Use bool return value instead of int Al Viro <viro@ZenIV.linux.org.uk> - 2016-01-12 02:10 +0100
Re: [PATCH] fs: dcache: Use bool return value instead of int Chen Gang <chengang@emindsoft.com.cn> - 2016-01-12 22:40 +0100
Re: [PATCH] fs: dcache: Use bool return value instead of int Al Viro <viro@ZenIV.linux.org.uk> - 2016-01-12 23:30 +0100
Re: [PATCH] fs: dcache: Use bool return value instead of int Chen Gang <chengang@emindsoft.com.cn> - 2016-01-13 23:40 +0100
Re: [PATCH] fs: dcache: Use bool return value instead of int Al Viro <viro@ZenIV.linux.org.uk> - 2016-01-14 00:00 +0100
Re: [PATCH] fs: dcache: Use bool return value instead of int Chen Gang <chengang@emindsoft.com.cn> - 2016-01-14 16:40 +0100
| From | chengang@emindsoft.com.cn |
|---|---|
| Date | 2016-01-11 22:40 +0100 |
| Subject | [PATCH] fs: dcache: Use bool return value instead of int |
| Message-ID | <qPSlY-84V-13@gated-at.bofh.it> |
From: Chen Gang <gang.chen.5i5j@gmail.com>
Use bool type for all functions which return boolean value. It will not
only let code clearer, but also sometimes let gcc produce better code.
Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
fs/dcache.c | 8 ++++----
include/linux/dcache.h | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/fs/dcache.c b/fs/dcache.c
index b4539e8..7701479 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1281,9 +1281,9 @@ rename_retry:
static enum d_walk_ret check_mount(void *data, struct dentry *dentry)
{
- int *ret = data;
+ bool *ret = data;
if (d_mountpoint(dentry)) {
- *ret = 1;
+ *ret = true;
return D_WALK_QUIT;
}
return D_WALK_CONTINUE;
@@ -1296,9 +1296,9 @@ static enum d_walk_ret check_mount(void *data, struct dentry *dentry)
* Return true if the parent or its subdirectories contain
* a mount point
*/
-int have_submounts(struct dentry *parent)
+bool have_submounts(struct dentry *parent)
{
- int ret = 0;
+ bool ret = false;
d_walk(parent, &ret, check_mount, NULL);
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 7781ce11..880a41c 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -266,7 +266,7 @@ extern struct dentry *d_find_alias(struct inode *);
extern void d_prune_aliases(struct inode *);
/* test whether we have any submounts in a subdir tree */
-extern int have_submounts(struct dentry *);
+extern bool have_submounts(struct dentry *);
/*
* This adds the entry to the hash queues.
@@ -370,12 +370,12 @@ extern struct dentry *dget_parent(struct dentry *dentry);
* Returns true if the dentry passed is not currently hashed.
*/
-static inline int d_unhashed(const struct dentry *dentry)
+static inline bool d_unhashed(const struct dentry *dentry)
{
return hlist_bl_unhashed(&dentry->d_hash);
}
-static inline int d_unlinked(const struct dentry *dentry)
+static inline bool d_unlinked(const struct dentry *dentry)
{
return d_unhashed(dentry) && !IS_ROOT(dentry);
}
@@ -508,7 +508,7 @@ static inline bool d_really_is_positive(const struct dentry *dentry)
return dentry->d_inode != NULL;
}
-static inline int simple_positive(struct dentry *dentry)
+static inline bool simple_positive(struct dentry *dentry)
{
return d_really_is_positive(dentry) && !d_unhashed(dentry);
}
--
1.9.3
[toc] | [next] | [standalone]
| From | Al Viro <viro@ZenIV.linux.org.uk> |
|---|---|
| Date | 2016-01-12 00:00 +0100 |
| Message-ID | <qPTBo-vZ-25@gated-at.bofh.it> |
| In reply to | #1306719 |
On Tue, Jan 12, 2016 at 05:30:45AM +0800, chengang@emindsoft.com.cn wrote:
> From: Chen Gang <gang.chen.5i5j@gmail.com>
>
> Use bool type for all functions which return boolean value. It will not
> only let code clearer, but also sometimes let gcc produce better code.
What's the point of this chunk?
> static enum d_walk_ret check_mount(void *data, struct dentry *dentry)
> {
> - int *ret = data;
> + bool *ret = data;
> if (d_mountpoint(dentry)) {
> - *ret = 1;
> + *ret = true;
> return D_WALK_QUIT;
> }
> return D_WALK_CONTINUE;
You are replacing a 1-word store with 1-byte store; if anything, that's more
likely to yield _worse_ code, not better one.
> -static inline int d_unhashed(const struct dentry *dentry)
> +static inline bool d_unhashed(const struct dentry *dentry)
> {
> return hlist_bl_unhashed(&dentry->d_hash);
> }
>
> -static inline int d_unlinked(const struct dentry *dentry)
> +static inline bool d_unlinked(const struct dentry *dentry)
> {
> return d_unhashed(dentry) && !IS_ROOT(dentry);
> }
> -static inline int simple_positive(struct dentry *dentry)
> +static inline bool simple_positive(struct dentry *dentry)
> {
> return d_really_is_positive(dentry) && !d_unhashed(dentry);
> }
And these three are harmless, but completely pointless...
[toc] | [prev] | [next] | [standalone]
| From | David Howells <dhowells@redhat.com> |
|---|---|
| Date | 2016-01-12 01:40 +0100 |
| Message-ID | <qPVaa-1En-17@gated-at.bofh.it> |
| In reply to | #1306802 |
Al Viro <viro@ZenIV.linux.org.uk> wrote:
> > -static inline int d_unhashed(const struct dentry *dentry)
> > +static inline bool d_unhashed(const struct dentry *dentry)
> > {
> > return hlist_bl_unhashed(&dentry->d_hash);
> > }
> >
> > -static inline int d_unlinked(const struct dentry *dentry)
> > +static inline bool d_unlinked(const struct dentry *dentry)
> > {
> > return d_unhashed(dentry) && !IS_ROOT(dentry);
> > }
>
> > -static inline int simple_positive(struct dentry *dentry)
> > +static inline bool simple_positive(struct dentry *dentry)
> > {
> > return d_really_is_positive(dentry) && !d_unhashed(dentry);
> > }
>
> And these three are harmless, but completely pointless...
gcc-5 does actually produce slightly smaller code when int returns are
replaced by bools under some circumstances within the kernel.
David
[toc] | [prev] | [next] | [standalone]
| From | Al Viro <viro@ZenIV.linux.org.uk> |
|---|---|
| Date | 2016-01-12 02:10 +0100 |
| Message-ID | <qPVDc-25w-7@gated-at.bofh.it> |
| In reply to | #1306864 |
On Tue, Jan 12, 2016 at 12:33:37AM +0000, David Howells wrote: > gcc-5 does actually produce slightly smaller code when int returns are > replaced by bools under some circumstances within the kernel. For inlines? Are you serious?
[toc] | [prev] | [next] | [standalone]
| From | Chen Gang <chengang@emindsoft.com.cn> |
|---|---|
| Date | 2016-01-12 22:40 +0100 |
| Message-ID | <qQePw-6Hn-5@gated-at.bofh.it> |
| In reply to | #1306802 |
On 1/12/16 06:51, Al Viro wrote:
> On Tue, Jan 12, 2016 at 05:30:45AM +0800, chengang@emindsoft.com.cn wrote:
>> From: Chen Gang <gang.chen.5i5j@gmail.com>
>>
>> Use bool type for all functions which return boolean value. It will not
>> only let code clearer, but also sometimes let gcc produce better code.
>
> What's the point of this chunk?
>
I'll explain it below this mail, please check.
>> static enum d_walk_ret check_mount(void *data, struct dentry *dentry)
>> {
>> - int *ret = data;
>> + bool *ret = data;
>> if (d_mountpoint(dentry)) {
>> - *ret = 1;
>> + *ret = true;
>> return D_WALK_QUIT;
>> }
>> return D_WALK_CONTINUE;
>
> You are replacing a 1-word store with 1-byte store; if anything, that's more
> likely to yield _worse_ code, not better one.
>
For me, it really generates a little better code:
- Both 1-word store and 1-byte store are 1 instruction, normally, they
have the same execution speed (although it is not quite precise).
- But 1-byte store instruction has short length under CISC archs, which
can generate a little better code globally.
- For most of archs, 1-word store can process bytes nonalignment cases,
for check_mount() individually, the parameter data may be not word
alignment, which may cause the 1-word store slower than 1-byte store.
The related objdump is below:
origin:
00000000 <check_mount>:
0: 8b 12 mov (%edx),%edx
2: 81 e2 00 00 01 00 and $0x10000,%edx
8: 74 16 je 20 <check_mount+0x20>
a: c7 00 01 00 00 00 movl $0x1,(%eax)
10: b8 01 00 00 00 mov $0x1,%eax
15: c3 ret
16: 8d 76 00 lea 0x0(%esi),%esi
19: 8d bc 27 00 00 00 00 lea 0x0(%edi,%eiz,1),%edi
20: 31 c0 xor %eax,%eax
22: c3 ret
23: 8d b6 00 00 00 00 lea 0x0(%esi),%esi
29: 8d bc 27 00 00 00 00 lea 0x0(%edi,%eiz,1),%edi
new:
00000000 <check_mount>:
0: 8b 12 mov (%edx),%edx
2: 81 e2 00 00 01 00 and $0x10000,%edx
8: 74 0e je 18 <check_mount+0x18>
a: c6 00 01 movb $0x1,(%eax)
d: b8 01 00 00 00 mov $0x1,%eax
12: c3 ret
13: 90 nop
14: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
18: 31 c0 xor %eax,%eax
1a: c3 ret
1b: 90 nop
1c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
[root@localhost fs]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/6.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-ana/configure
Thread model: posix
gcc version 6.0.0 20151121 (experimental) (GCC)
>> -static inline int d_unhashed(const struct dentry *dentry)
>> +static inline bool d_unhashed(const struct dentry *dentry)
>> {
>> return hlist_bl_unhashed(&dentry->d_hash);
>> }
>>
>> -static inline int d_unlinked(const struct dentry *dentry)
>> +static inline bool d_unlinked(const struct dentry *dentry)
>> {
>> return d_unhashed(dentry) && !IS_ROOT(dentry);
>> }
>
>> -static inline int simple_positive(struct dentry *dentry)
>> +static inline bool simple_positive(struct dentry *dentry)
>> {
>> return d_really_is_positive(dentry) && !d_unhashed(dentry);
>> }
>
> And these three are harmless, but completely pointless...
>
For performance, please check the original reply above this mail.
For me, bool can make the code a little simpler and clearer:
- int can express more things: error code, handler, count ... So if we
really only use one boolean variable, bool type is more clearer (it
is only for boolean).
- The old ANSI C compiler may not support bool type, so we have to use
int type instead of. But if one header/source file has already used
bool type in some part, the whole file need use bool type too.
Thanks.
--
Chen Gang (陈刚)
Open, share, and attitude like air, water, and life which God blessed
[toc] | [prev] | [next] | [standalone]
| From | Al Viro <viro@ZenIV.linux.org.uk> |
|---|---|
| Date | 2016-01-12 23:30 +0100 |
| Message-ID | <qQfBU-7kg-21@gated-at.bofh.it> |
| In reply to | #1307846 |
On Wed, Jan 13, 2016 at 05:42:20AM +0800, Chen Gang wrote: > For me, it really generates a little better code: > > - Both 1-word store and 1-byte store are 1 instruction, normally, they > have the same execution speed (although it is not quite precise). > > - But 1-byte store instruction has short length under CISC archs, which > can generate a little better code globally. > > - For most of archs, 1-word store can process bytes nonalignment cases, > for check_mount() individually, the parameter data may be not word > alignment, which may cause the 1-word store slower than 1-byte store. What the hell do you mean, unaligned? It's given an address of local variable of type int; it _will_ be aligned, or the compiler is FUBAR. As for the inlines... frankly, if gcc generates a different code from having replaced int with bool in those, it's time to do something very nasty to gcc developers.
[toc] | [prev] | [next] | [standalone]
| From | Chen Gang <chengang@emindsoft.com.cn> |
|---|---|
| Date | 2016-01-13 23:40 +0100 |
| Message-ID | <qQCf8-6cl-21@gated-at.bofh.it> |
| In reply to | #1307887 |
On 1/13/16 06:21, Al Viro wrote: > On Wed, Jan 13, 2016 at 05:42:20AM +0800, Chen Gang wrote: > >> For me, it really generates a little better code: >> >> - Both 1-word store and 1-byte store are 1 instruction, normally, they >> have the same execution speed (although it is not quite precise). >> >> - But 1-byte store instruction has short length under CISC archs, which >> can generate a little better code globally. >> >> - For most of archs, 1-word store can process bytes nonalignment cases, >> for check_mount() individually, the parameter data may be not word >> alignment, which may cause the 1-word store slower than 1-byte store. > > What the hell do you mean, unaligned? It's given an address of local > variable of type int; it _will_ be aligned, or the compiler is FUBAR. > I guess you misunderstand my meaning, in our case, it should not happen, so I say "for check_mount() individually". For 32 bits store instruction, we need consider about the byte alignment. > As for the inlines... frankly, if gcc generates a different code from having > replaced int with bool in those, it's time to do something very nasty to > gcc developers. > Could you provide the related proof? Thanks. -- Chen Gang (陈刚) Open, share, and attitude like air, water, and life which God blessed
[toc] | [prev] | [next] | [standalone]
| From | Al Viro <viro@ZenIV.linux.org.uk> |
|---|---|
| Date | 2016-01-14 00:00 +0100 |
| Message-ID | <qQCyu-6kn-5@gated-at.bofh.it> |
| In reply to | #1308881 |
On Thu, Jan 14, 2016 at 06:39:53AM +0800, Chen Gang wrote:
> > As for the inlines... frankly, if gcc generates a different code from having
> > replaced int with bool in those, it's time to do something very nasty to
> > gcc developers.
> >
>
> Could you provide the related proof?
static inline _Bool f(.....)
{
return <int expression>;
}
...
if (f(.....))
should generate the code identical to
if ((_Bool)<int expression>)
which, in turn, should generate the code identical to
if (<int expression> != 0)
and
if (<int expression>)
Neither explicit nor implicit conversion to _Bool (the former by the explicit
cast, the latter - by declaring f() to return _Bool) matters at all when the
damn thing is inlined in a condition context. Conversion to _Bool is
equivalent to comparison with 0, and so is the use in condition of if() and
friends.
For something not inlined you might get different code generated due to a
difference in calling sequences of _Bool(...) and int(...); for inlined
case having one of those variants produce a better code means that compiler
has managed to miss some trivial optimization in all other variants.
And I'm yet to see any proof that gcc *does* fuck up in that fashion. It
might - dumb bugs happen to everyone, but I would not assume that they'd
managed to do something that bogys without experimental evidence.
[toc] | [prev] | [next] | [standalone]
| From | Chen Gang <chengang@emindsoft.com.cn> |
|---|---|
| Date | 2016-01-14 16:40 +0100 |
| Message-ID | <qQSae-yO-37@gated-at.bofh.it> |
| In reply to | #1308889 |
On 1/14/16 06:54, Al Viro wrote:
> On Thu, Jan 14, 2016 at 06:39:53AM +0800, Chen Gang wrote:
>
>>> As for the inlines... frankly, if gcc generates a different code from having
>>> replaced int with bool in those, it's time to do something very nasty to
>>> gcc developers.
>>>
>>
>> Could you provide the related proof?
>
> static inline _Bool f(.....)
> {
> return <int expression>;
> }
>
> ...
> if (f(.....))
>
For me, your case above isn't suitable for using bool. Please check this
patch, there is no any cases like you said above.
- For d_unhashed() which return hlist_bl_unhashed(), it seems like your
case, but in fact hlist_bl_unhashed() also need return bool (which I
shall send another patch for, next).
- And all the other changes of this patch are all for real, pure bool
functions.
Thanks.
> should generate the code identical to
> if ((_Bool)<int expression>)
> which, in turn, should generate the code identical to
> if (<int expression> != 0)
> and
> if (<int expression>)
>
> Neither explicit nor implicit conversion to _Bool (the former by the explicit
> cast, the latter - by declaring f() to return _Bool) matters at all when the
> damn thing is inlined in a condition context. Conversion to _Bool is
> equivalent to comparison with 0, and so is the use in condition of if() and
> friends.
>
> For something not inlined you might get different code generated due to a
> difference in calling sequences of _Bool(...) and int(...); for inlined
> case having one of those variants produce a better code means that compiler
> has managed to miss some trivial optimization in all other variants.
>
> And I'm yet to see any proof that gcc *does* fuck up in that fashion. It
> might - dumb bugs happen to everyone, but I would not assume that they'd
> managed to do something that bogys without experimental evidence.
>
For your cases, what you said sounds OK to me (although I am not quite
sure what you said above whether precise or not).
Thanks.
--
Chen Gang (陈刚)
Open, share, and attitude like air, water, and life which God blessed
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web