GCC will compile one set of files at a time into .o files, and then those are linked together later on, so each "module" (using that term loosely) is compiled separately.
MLton takes in the entire program source, including the standard library, at once. Because of that, there's a ton of information we know, which helps a ton for things like dead code elimination. Because of this, there's a lot of memory required, since we have the entire program's syntax/parse/any other type of tree in memory, and it's not going to be as fast as something like GCC since we're recompiling everything every time in MLton instead of only recompiling the changed modules.
Despite MLton being a bit slower to compile, it's truly an incredible compiler. I had Dr Fluet, the lead maintainer, as my compiler professor in college, and he's a wealth of knowledge. The compiler we wrote in class was in SML and compiled with MLton. The amount of optimizations that occur is insane, it made damn fast executables, and that applies to most big compilers like GCC, Clang, Rustc, etc. The big difference in optimizations is how much information we have at optimization time. Languages like C are a bit looser and thus information may be harder to derive. Rust has a stricter set of rules, so we have more guarantees about a program to base our optimizations around.