{'fraction_non_alphanumeric': 0.024868123587038434, 'fraction_numerical': 0.0015071590052750565, 'mean_word_length': 5.7215189873417724, 'pattern_counts': {'":': 0, '<': 0, '<?xml version=': 0, '>': 0, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
Compiler construction of idempotent regions and applications in architecture design

In the field of computer architecture today, out-of-order execution is important to maximize architectural efficiency, the shadow of unreliable hardware is ever-looming, and, with the emergence of mainstream parallel hardware, programmability is once again an important and fundamental challenge. Traditionally, hardware checkpointing and buffering techniques are used to assist with each of these problems. However, these techniques introduce overheads, add complexity to the hardware, and often save more state than necessary. With today's renewed focus on energy efficiency, and with the commercial importance of reduced hardware complexity in today's processor market, the efficacy of these techniques is no longer absolute. 
This thesis develops a novel compiler-based technique to efficiently support a range of hardware features without the need for checkpoints or buffers. The technique breaks programs into idempotent regions—regions that can be freely re-executed—to enable recovery by simple re-execution. The thesis observes that programs can be executed entirely as sequences of {idempotent} regions, develops static analysis and compiler code generation techniques to construct idempotent regions, and demonstrates low overheads and potentially large region sizes for an LLVM-based compiler implementation. Finally, it demonstrates applicability across a range of modern architecture designs in addressing a variety of problems. 
The thesis presents several findings. First, it finds that a compiler, through careful allocation of function-local state, is capable of constructing large idempotent regions in the range of tens to hundreds of instructions. These regions can be sub-divided into smaller regions to optimize for specific constraints. However, code generation of small idempotent regions forces relatively high compiler-induced run-time overheads in the range of 10–20%, while, for larger regions, this overhead quickly approaches zero as region size grows beyond a few tens of instructions. Thus, the compiler-induced costs of constructing small regions are often out-weighed by any benefits, and optimization trade-offs thus generally favor constructing regions that are a few tens of instructions or more. This optimization goal tailors the suitability of idempotence-based recovery to specific architecture domains; this thesis considers specifically architecture design and evaluation for general exception support in GPUs, out-of-order retirement in general-purpose processors, and hardware fault tolerance in emerging processor designs.