I was mostly worried if the underlying CL is so dynamic that it would be hard to compile things down cleanly but I'm probably overthinking it.
This reminds me a bit of Emscripten's problem though. Emscripten does "machine code" (I believe LLVM IR) to Javascript translation and in order to get good performance it has to try really hard to rediscover things like switch statements and for loops in the IR, since using those in the JS will lead to good perf.
Anyways, I suppose that the core Lisp semantics are going to be so small that it all works out quite well.
A lot of things you'd do dynamically in Python (with operator overloading or the like) are done statically (with macros, as you allude) in more traditional Lisps like CL and Scheme.
The core Scheme semantics are pretty small. Common Lisp has significantly hairier core semantics.