Due to the huge and continuously increasing disparity between CPU speeds and disk access latencies, large high-performance applications that exercise disks tend to waste a disproportionate percentage of their execution times waiting for disk requests to complete. This paper presents two compiler-directed approaches to improving the I/O performance of data-intensive applications: code restructuring for disk reuse maximization and adaptive I/O prefetching. The compiler-directed code restructuring improves I/O performance by reducing the number of disk accesses through increasing disk reuse. That is, the data in a given set of disks are reused as much as possible before moving onto other disks. Adaptive I/O prefetching, on the other hand, is motivated by the observation that the effectiveness of compiler-directed I/O prefetching reduces significantly due to harmful prefetches when multiple CPUs share the same set of disks. To reduce intra- and inter-CPU harmful prefetches, our adaptive I/O prefetching scheme obtains inter-thread data sharing patterns through profiling and, based on the extracted sharing patterns, divides the threads into clusters and assigns a dedicated I/O prefetcher thread to each cluster. Our experimental results clearly show that both these approaches improve the I/O performance dramatically over the conventional data locality oriented schemes and compiler-directed I/O prefetching schemes.