-
Notifications
You must be signed in to change notification settings - Fork 683
Replace bit field manipulation functions with macros #913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace bit field manipulation functions with macros #913
Conversation
I have related work in LaszloLango@1223b99 |
This patch achieves quite good code size reduction on arm targets (2-8K on release builds).
Performance on x86_64/linux also improved slightly, especially on the longer running test cases (crypto-md5.js and crypto-sha1.js).
|
* @param width width of the bit-field to be extracted | ||
* @return bit-field's value | ||
*/ | ||
#define jrt_extract_bit_field(container, lsb, width) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use uppercase for name of macros
#define JRT_EXTRACT_BIT_FIELD(container, lsb, width) \
3b18cc1
to
23437c2
Compare
* @return bit-field's value | ||
*/ | ||
uint64_t __attr_const___ | ||
jrt_set_bit_field_value (uint64_t container, /**< container to insert bit-field to */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why could not make this inline (in release mode)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inline declaration in this C file can only have effect if we have LTO. Macros work whatever compiler/linker or setting we use.
Moreover, another issue with the current function-based approach is that it always casts everything to uint64_t
, even if we would like to work with a different type. And then we cast the returned uint64_t
again back to our original type. That cast is not something a compiler can optimize away.
f099c4d
to
a7e8a97
Compare
Rebased and pushed. (Also: found a solution to get rid of not-so-nice type casts that were present in previous versions of this patch.) |
* @return bit-field's value | ||
*/ | ||
#define JRT_EXTRACT_BIT_FIELD(container, lsb, width) \ | ||
(((container) >> lsb) & ((((__typeof__ (container)) 1) << (width)) - 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typeof is std c99?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, that you mention... Interestingly, the build system does not complain about it. I see two ways of dealing with this:
- leave it in the currently proposed form, or
- let the macros have one more argument requiring the type of the container explicitly.
This first approach is a bit less standard-conforming (but seems to be supported by all compiilers out there, at least by clang for sure), while the second one needs more maintenance if the type of the first argument changes (anywhere where the macro is used).
Opinions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer the second, since we want to maintain stdc99 support.
a7e8a97
to
d0eba71
Compare
@zherczeg I've updated the patch as suggested. Does it look better? |
* @return bit-field's value | ||
*/ | ||
#define JRT_EXTRACT_BIT_FIELD(type, container, lsb, width) \ | ||
(((container) >> lsb) & ((((type) 1) << (width)) - 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why did you remove the following asserts?
JERRY_ASSERT (lsb < JERRY_BITSINBYTE * sizeof (uint64_t));
JERRY_ASSERT (width < JERRY_BITSINBYTE * sizeof (uint64_t));
JERRY_ASSERT ((lsb + width) <= JERRY_BITSINBYTE * sizeof (uint64_t));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(((container) >> lsb) & ((((type) 1u) << (width)) - 1u))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had two reasons to remove the asserts:
- I didn't know how to insert them in the macro (which is an expression only, not a block of statements), and
- during the first experiments with the patch the compiler did emit warnings (which were turned to errors) when
lsb
and/orwidth
was 'incompatible' with the type ofcontainer
, and I've considered them as good replacements of the asserts.
As for the 1u
s: in the first case, it is certainly superfluous, since 1
is cast to type
. In the second case, it might also be better to type-cast it instead of using the hard-coded 1u
. IMHO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the do { ... } while (0)
trick could work here too. But if the compiler emit warnings, then it's Ok for me. The debug version of jerry runs really slow, so we should use assertions where they are necessary.
#define JRT_EXTRACT_BIT_FIELD(type, container, lsb, width) \
do \
{ \
JERRY_ASSERT (lsb < JERRY_BITSINBYTE * sizeof (type)); \
JERRY_ASSERT (width < JERRY_BITSINBYTE * sizeof (type)); \
JERRY_ASSERT ((lsb + width) <= JERRY_BITSINBYTE * sizeof (type)); \
(((container) >> lsb) & ((((type) 1) << (width)) - 1)) \
} while (0)
LGTM |
In general functions are easier to debug but I have no strong opinion, because I also use a lot of macros. I did not find the RPi2 results, am I missing something? |
RPi2 results
Binary sizes (bytes): 197,240 -> 193,144 |
LGTM |
JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
d0eba71
to
c9f5950
Compare
JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu