Some obvious stack-related ideas that are worth exploring IMHO are (1) using the stack pointer to guide the prefetcher, to run ahead of cache misses when you return from subroutines and go up the stack; and (2) having an instruction that helps avoid unneeded cache misses when going down the stack; for example, a dedicated instruction for decrementing the stack pointer which zeros entire cache lines directly in L1 without loading them. Or perhaps, for more generality, an instruction for marking any arbitrary address range in this way.
Who knows, at least the first one might already be in use in some microarchitectures!