Why is pressure advance usually implemented in firmware rather than in slicer
In addition the E axis is no longer controlled directly by the GCode, but it's motion is almost independently determined by the firmware.

This is the case even without linear advance. G-code does not directly control the movement of any of the axes. G-code only specifies the path the axes should travel, but not the acceleration and deceleration associated with following that path. If you are printing a cube, then the G-code might specify that the extruder has to extrude a square. It will specify that the 4 sides of the square should be printed, but it does not specify how the transition from one side to the next should be handled.
The printer cannot instantly transition from extruding one side of the square to extruding the next side, because the direction of the extruder cannot change instantaneously. It needs to smoothly decelerate and accelerate. This is handled by the firmware, which translates the straight line commands from G-code to smooth acceleration and deceleration of the extruder.
This is exactly where linear advance comes in. It is coupled to the acceleration and deceleration. There is no way to &quot;implement&quot; linear advance in G-code, because G-code does not even have any notion of acceleration and deceleration. The G-code (and slicer) has no idea how the firmware is handling the acceleration and deceleration, so therefore it is impossible for the slicer to know what linear advance is required to match.
Then you might ask: &quot;why is acceleration and deceleration not implemented in G-code (rather than in firmware)?&quot; This is simply a design choice. G-code is meant to be a very simple file format, and it simply allows you to specify straight line move commands. Representing smooth acceleration curves would either require breaking them down into many discrete, small steps, but this would greatly increase the file size. You could suggest a more complex G-code specification that would allow a more &quot;compact&quot; representation of acceleration and deceleration curves but then you're just shifting the computation back to the firmware (albeit with a more explicit specification in the G-code).