| Reduction of power consumption is an imperative design consideration in chip design across both embedded and high-end systems. More than saving battery power, this has an important consequence on the layout of circuits, and on the cooling/packaging requirements to keep them operating within the thermal constraints. A complete system solution, therefore, requires careful power-efficient design and management of all its components. An optimizing compiler can play important roles in different architectures in terms of power estimation and optimization for different system components. In this thesis, we focus on three types of compiler-assisted optimizations for saving energy.; The first one is a compiler-directed high-level (source level) energy estimation in single issue architectures. We propose a novel energy-aware compilation framework that can estimate the energy consumption of a given code. It allows us to understand energy/performance tradeoffs involving high-level optimizations such as iteration space tiling and other loop and data optimizations.; Our second contribution is an in-depth study of software-based energy saving schemes for multiprocessor systems-on-a-chip (MPSoC). We present an energy saving strategy based on adaptive loop parallelization. Our strategy achieves the potential energy savings when unused processors are shut down or placed into low-power sleep mode during execution of a nested loop. We also integrate a processor pre-activation scheme into our approach based on compile-time analysis of loop nests to eliminate performance overhead due to re-activating powered-down processors. Then, we focus on the constraint-based parallelization problem, and propose an integer linear programming (ILP) technique to select the ideal number of processors to use in parallelizing each loop nest in an application for a given objective function (which may include performance and energy components).; As our third contribution, we propose a strategy for reducing instruction/data Translation Lookaside Buffer (TLB) energy consumption. The main idea is to keep recent translations in a register, thereby eliminating the need to go the main TLB for translation. Our experiments with both instruction and data TLBs and different cache addressing strategies indicate significant savings in energy. Note that this energy-saving strategy can be used in uniprocessors and in on-chip multiprocessors. |