LLVM equivalent of gcc's __BIGGEST_ALIGNMENT__? - gcc

GCC provides a __BIGGEST_ALIGNMENT__ pre-defined macro which is the largest alignment ever used for any data type on the target machine you are compiling for. I cannot seem to find an LLVM's equivalent for this. Is there any? If not, what is the best way to figure it out (preferably with pre-processor)?

This isn't accessible from the preprocessor, but __attribute__((aligned)) or __attribute__((__aligned__)) (with the alignment value omitted) will give the alignment you want. This is supposed to give the largest alignment of any built-in type, which is 16 on x86 and ARM.
For example:
$ cat align.c
struct foo {
char c;
} __attribute__((aligned)) var;
$ clang align.c -S -o - -emit-llvm
...
#var = global %struct.foo zeroinitializer, align 16
This is used by unwind.h for _Unwind_Exception:
struct _Unwind_Exception
{
_Unwind_Exception_Class exception_class;
_Unwind_Exception_Cleanup_Fn exception_cleanup;
_Unwind_Word private_1;
_Unwind_Word private_2;
/* ### The IA-64 ABI says that this structure must be double-word aligned.
Taking that literally does not make much sense generically. Instead we
provide the maximum alignment required by any type for the machine. */
} __attribute__((__aligned__));

This is in llvm internals as TargetData::PointerABIAlign, but it doesn't appear to be exposed to code. I'd just hard code to 16 bytes, as it seems like it'd be a while before we see any more aligned types or instruction sets.

Related

How to use syscalls correctly in go (different results from Go unsafe.Sizeof vs C sizeof)

Go's unsafe.Sizeof is returning a different result than C's sizeof.
main.go:
package main
import (
"unsafe"
)
type gpioeventdata struct {
Timestamp uint64
ID uint32
}
func main() {
eventdata := gpioeventdata{}
println("Size", unsafe.Sizeof(eventdata))
}
Prints 12 when compiled with env GOOS=linux GOARCH=arm GOARM=6 go build on macOS and run on Raspberry Pi Zero.
gpio.c:
#include <stdio.h>
#include <linux/gpio.h>
int main() {
printf("sizeof gpioevent_data %zu\n", sizeof(struct gpioevent_data));
}
Prints 16 when compiled and run on Raspberry (with gcc).
struct definition in gpio.h:
struct gpioevent_data {
__u64 timestamp;
__u32 id;
};
Edit
I already thought that this is due to alignment, but a lot of people are passing Go structs to syscall.Syscall (e.g. https://github.com/stapelberg/hmgo/blob/master/internal/gpio/reset.go#L49). So that's basically wrong and you should never do that?
If that's wrong, what would be the correct approach calling syscalls with go so that works correctly with different architectures. For example GPIO ioctl calls:
ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
...
struct gpioevent_data event;
ret = read(req.fd, &event, sizeof(event));
The go compiler and the C compiler are handling alignment differently.
In C the structure has been aligned to 16 bytes (adding a 4 bytes slack space after id or before it). The go compiler instead packed the fields without adding any slack space.
Your mistake is thinking that two "structures" in different languages with different compilers should have the same memory layout.
Note that there is no way to "compute" what will be the padding in a C or C++ structure because padding is a choice of the implementer. It's well possible that two different standard-conforming C compilers for the same architecture will generate different paddings (or even the same compiler with different compiling options).
The only way to get the padding correct is to check the specific case, either manually or by writing a script that calls the compiler passing the same compiling options and checks the result (e.g. by output the results of offsetof on all the members) and then generates the needed go source code after parsing that output.
According to https://go101.org/article/memory-layout.html, go generally follows the C rules for structure padding (see https://stackoverflow.com/a/38144117/851737 for details of the C memory alignment rules and here for an algorithm in pseudocode).
However, there is a known bug that go doesn't align 64bit values on 32bit architectures correctly.

Is there a way to tell GCC the range of a parameter?

I have some heavily-used code that I would like GCC to optimize aggressively. But I also want to write clean, reusable code with (inlinable) functions that are called from several places. There are cases where in the inlined function, there is code that I know can be removed because the conditions can never happen.
Let's look at a concrete example:
#include <assert.h>
static inline int foo(int c)
{
if (c < 4)
return c;
else
return 4;
}
int bar(int c)
{
assert(c < 2);
return foo(c);
}
With -DNDEBUG -O3, GCC will still generate the (c < 4) comparison even though I know it is not needed, because a precondition of the bar function is that c is 0 or 1. Without -DNDEBUG, GCC does remove the comparison because it is implied by the asserts - but of course you have the overhead of the asserts then (which is a lot more).
Is there a way to convey the variable range to GCC so it can be used for optimisation?
If CLang can do better on this, I could also consider switching compilers.
You might use __builtin_unreachable (read about other builtins) in a test to tell the compiler, e.g.,
if (x<2 || x>100)
__builtin_unreachable();
// Here the compiler knows that x is between 3 and 99 inclusive
In your case, add this at the start of your bar (probably wrapped in some nice looking macro):
if (c >= 2)
__builtin_unreachable();
If you optimize strongly (e.g., -O2 at least), the compiler knows that x is between 3 and 99 (and recent versions of GCC contain code to do such analysis—at least processing simple constant interval constraints like above—and take advantage of them in later optimization passes).
However, I am not so sure that you should use that! (at least don't use it often and wrap that in some assert-like macro), because it might not worth the trouble, and because the compiler is in practice only able to handle and propagate simple constraints (whose details are compiler version specific).
As far as I know, both recent Clang and GCC accepts that builtin.
Also look into __builtin_trap (which also emits runtime code).

D / DLang / GDC - Alignment of SIMD fields in struct

struct vec_struct {
alias field this;
bool b;
int8 field; // ymm
}
In this code when you look at the generated x64 code output by GDC it seems to be doing a nice job, because it has got the offset right for the 256-bit YMM 'field' correct.
Q: Does D automatically propagate the alignment restrictions on the field to the allocation of static structs or structs on the stack?
In this case -
struct vec_struct {
bool b2;
struct {
alias field this;
bool b;
int8 field; // umm
}
}
it appears that the offset to 'field' is no longer aligned correctly - offset is 40 bytes in GDC. I don't suppose the compiler will use solely unaligned instructions? In any event, I could take the address of field and then pass that to someone expecting to pick up something with guaranteed correct alignment, if I have understood the D docs. Q: Is this correct - a seriously bad problem, or am I being daft?
Please don't bite. I'm both new to D and I hope I have understood the x86 SIMD instructions' docs. (Very experienced professional asm and C programmer, but v out-of-date.)
Noob q: I notice that the GDC opcodes look a bit odd, for example the compiler generates a 256-bit unaligned fetch followed by an aligned binary operation (I think), eg a movdqu followed by a vpaddd r, ymm ptr blah - is the latter aligned-only? Apologies if I have got this wrong, need to read up. Would someone be kind enough to sanity-check me?
Does D automatically propagate the alignment restrictions on the field to the allocation of static structs or structs on the stack?
I think it's supposed to and GDC/LDC should already support proper stack alignment. DMD probably has some bugs in this regard:
https://issues.dlang.org/show_bug.cgi?id=16098
it appears that the offset to 'field' is no longer aligned correctly - offset is 40 bytes in GDC.
As Iain already answered in the D.learn thread this is a bug in the shared DMD/GDC codebase.
Bug report: https://issues.dlang.org/show_bug.cgi?id=17237
DMD bugfix: https://github.com/dlang/dmd/pull/6582
Backport for GDC: https://github.com/D-Programming-GDC/GDC/pull/408

How to force GCC compiler to calculate constant values at compile time?

I have the following code (CPU Atmel AVR ATmega64A):
#define UO_ADC1023 265
#define UREF_180V (1023*180/UO_ADC1023)
....
if(ADC > UREF180) {do_something();}
This should evaluate UREF_180V as 694.87... and than this value should be rounded (better) to 695 or floored (poorer) to 694 to be compared to ADC register.
However I have integer overflow warning at compile. As per this I suppose that compiler generating code which calculates (1023*180/UO_ADC1023) at the run time which is very bad in my case.
I'd like to avoid to calculate those constants by my self (#define UREF_180V 695 in this case I could be sure that they are really literals) to make the code more flexible and readable. I'd like also to be able to check those values after the compiler.
So the questions are:
Is there any possibility to force GCC compiler to calculate such constants at compile time?
How to check this calculated value?
int on AVR is 16-bit. Tell the compiler to use long instead (since 1023 * 180 will overflow).
#define UREF_180V (1023L * 180 / UO_ADC1023)
Macros are inserted at the place of invokation, where their content can later be compiled.
In C++11 you can evaluate expressions at compile time with constexpr, like this:
constexpr auto UREF_180V = 1023*180/UO_ADC1023;
Due to all of the numbers being ints the result of this is 694. To properly round it you would have to change one of the values to a floating point number and create a constexpr rounding function, which can be invoked at compile time.
As for checking the number you could use static_assert(695 == UREF_180V, "");.
To compile C++11 code add -std=c++11 to your compiler options. (You probably have to switch to a C++ project, and I'm not entirely certain AtmelStudio supports C++11, if not I'm sorry)
see the -fmerge-all-constants command, -fgcse, -fsee, or better, see here: https://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/Optimize-Options.html
nonetheless, the integer overflow can be part of an semantic error in your code as welternsturm mentioned

How to print and use constants with gdb (through Xcode)?

I am debugging a Cocoa application using xcode-gdb. I am at a break point and I want view the value of some Cocoa constants (ie NSControlKeyMask) and to do some test with the values in the current stackframe. Specifically I am in - (void) keyDown:(NSEvent *) e , and I have done set $mf = (int)[e modifierFlags] on the gdb prompt. Now I want to do p $mf & NSControlKeyMask and gdb is telling me 'No symbol "NSControlKeyMask" in current context.'
UPDATE:
Xcode has the "Fix and Continue text" feature. So I used Dan M. and n8gray solution with this feature so I don't have to make a proxy of every constant.
If no variables are actually instantiated with a given type, then the debug information for the corresponding symbols doesn't wind up getting generated by gcc. Then, if you ask gdb about such a type, it doesn't know what you are talking about because there is no debug information for that type, and it will give you the "No symbol in current context" error.
A workaround to this problem would normally be to explicitly add a dummy variable, of the type in question, somewhere in the code. Here is a simple example that you can test to see what I'm talking about:
enum an_enum_type {
foo,
bar,
baz
};
int main (int argc, char *argv [])
{
return baz;
}
Save that program to a file named test.cpp and compile it with this command:
g++ -o test -g -O0 test.cpp
Then run it under gdb and type "p /x baz". You will get the "No symbol baz in current context" error.
Now try it with this modified version that has added a dummy variable, of the enum type:
enum an_enum_type {
foo,
bar,
baz
};
an_enum_type dummy;
int main (int argc, char *argv [])
{
return baz;
}
Compile with the same command as before and run under gdb. This time when you type "p /x baz" you'll get "0x2" as the answer, which I think is what you are shooting for in your question.
I've looked into it, and the problem is that the NSEvent.h header file doesn't give a name to the enum that contains NSControlKeyMask -- it's an anonymous enum. So there is no way to create a variable of that type (dummy or otherwise). So, I don't see any way of getting the compiler to generate the debug information for that type. I think you're just going to have to rely on the definition of NSControlKeyMask from the header file.
If you compile with gcc you can use the -g3 switch to get the highest level of debug info. Quoting from the section on -g in the gcc manual:
-glevel
Request debugging information and also use level to specify how much information. The default level is 2.
Level 0 produces no debug information at all. Thus, -g0 negates -g.
Level 1 produces minimal information, enough for making backtraces in parts
of the program that you don't plan to debug. This includes descriptions
of functions and external variables, but no information about local
variables and no line numbers.
Level 3 includes extra information, such as all the macro definitions present
in the program. Some debuggers support macro expansion when you use
-g3.
So if you compile with -g3 you should be able to expand constants and macros in gdb.
As Dan M. discovered, you probably can't get this to work in a straightforward way. Instead, what you could do is put something like this in one of your files:
int myNSControlKeyMask = NSControlKeyMask;
int myNSOptionKeyMask = NSOptionKeyMask;
...
Then at least you can use symbolic names in gdb without having to look up the corresponding values in the .h file.
NSControlKeyMask is most likely a macro and invisible to the debugger. You need to look in the appropriate .h file. Place the cursor over the text NSControlKeyMask in the editor and try command+double-click to jump to its definition.
I seem to be getting the same problem in a bunch of C++ code that is being called from Obj-C in an iPhone app. It's giving me the
No symbol "a" in current context.
error, where a is an int. I tried the -g3 compiler flag with no success. I find it hard to believe gdb doesn't know the type of an int. SDK 3.0, but then again, gdb was printing completely erroneous values when it could find variable in the program.

Resources