I know that some CPU architectures don't support unaligned address access(e.g., ARM architectures prior to ARM 4 had no instructions to access half-word objects in memory). And some compiler(e.g., some version of GCC) for that architecture will use a series of memory access when it finds a misaligned address, so that the misaligned access is almost transparent to developers.(Refer to The Definitive Guide to GCC, By William von Hagen)
But I'm wondering how does a compiler know whether an address is aligned or not? After all, what a compiler sees is the virtual address(effective address, EA), if it can see anything. When the program is run, EA could be mapped to any physical address by OS. Even if virtual address is aligned, the resulting physical address could be misaligned, isn't it? The alignment of physical address is what really matters and transfers on CPU address lines.
Because a compiler is not aware of the physical address at all, how can it be smart enough to know if a variable's address is aligned?