Automatic Methods for Hiding Latency in Parallel and Distributed Computation