This paper investigates a compiler-runtime approach for reducing power consumption in the context of the Network-on-Chip (NoC) based chip multiprocessor (CMP) architectures. Our proposed approach is based on the observation that the same communication patterns across the nodes of a mesh based CMP repeat themselves in successive iterations of a loop nest. The approach collects the link usage statistics during the execution of the first few iterations of a given loop nest and computes the slack (allowable delay) for each communication transaction. This information is subsequently utilized in selecting the most appropriate voltage levels for the communication links (and the corresponding frequencies) in executing the remaining iterations of the loop nest. The results with the benchmarks from the MediaBench suite show that, not only this hybrid approach generates better energy savings than a pure hardware-directed voltage scaling scheme, but it also leads to much less performance degradation than the latter. Specifically, the average energy savings achieved by the pure hardware based scheme and our approach are 24.9% and 38.1%, respectively, and the corresponding performance overhead numbers are 8.3% and 2.1%. Our results also show that the hybrid approach generates much better savings than two recently proposed pure compiler based schemes. In addition, our experimental evaluation indicates that the energy savings obtained through the proposed approach are very close to optimal savings (within 3%) under the same performance bound.