Skip to content

Eddi repair#18

Open
AlbertoOcchipinti wants to merge 2 commits intoHEAPLab:masterfrom
AlbertoOcchipinti:eddi-repair
Open

Eddi repair#18
AlbertoOcchipinti wants to merge 2 commits intoHEAPLab:masterfrom
AlbertoOcchipinti:eddi-repair

Conversation

@AlbertoOcchipinti
Copy link
Copy Markdown

PR Title

Add REPAIR-style coarse-grain duplicate scheduling to EDDI

PR Description

Problem

The original EDDI implementation (EDDI_v1) duplicates eligible instructions by inserting each clone immediately after its original instruction. This produces a fine-grain layout such as:

A, A_dup, B, B_dup, C, C_dup

While this preserves the original EDDI duplication flow, it keeps each master instruction and its shadow counterpart very close in the basic block. In this configuration, a transient fault may affect both copies within the same short vulnerability window, reducing the effectiveness of mismatch-based detection. Moreover, the capacity of detecting an illegal branch in the middle of the code is not optimal. These are exactly the kind of limitations that motivated the project goal of integrating a REPAIR-style coarse-grain duplication strategy into ASPIS


Solution

This PR updates the pass by introducing REPAIR in EDDI_v2.

Instead of leaving duplicates interleaved with their originals, the pass now moves cloned instructions toward the end of each basic block, before the terminator, producing a coarse-grain layout of the form:

A, B, C, A_dup, B_dup, C_dup

The goal is to increase the temporal/spatial separation between original and duplicate instructions, reducing the probability that a single transient fault corrupts both copies before consistency checks can expose the mismatch. This is consistent with the REPAIR idea described in the project material and with the broader EDDI discussion on how instruction ordering affects detection behavior


Main changes

1. Tracking duplicated instructions

EDDI_v2 introduces a dedicated container to keep track of cloned instructions:

static std::unordered_set<Instruction *> ClonedInstructions;

This set is populated inside cloneInstr() whenever a duplicated non-alloca instruction is emitted into a basic block. This provides an explicit way to distinguish duplicate instructions from original ones during the subsequent repair/reordering phase

In EDDI_v1, duplicated instructions are inserted but not explicitly tracked for later relocation


2. New basic-block repair phase

EDDI_v2 adds a new function:

void EDDI::repairBasicBlock(
    BasicBlock &BB,
    std::unordered_set<Instruction *> &ClonedInstructions)

This function scans each basic block, collects duplicated instructions in their original relative order, and moves them before the block terminator.

The implementation explicitly avoids moving:

  • PHINodes, because LLVM requires them to stay at the top of the block,
  • AllocaInsts,
  • terminator instructions.

Keeping duplicates in their original relative order is important to avoid unnecessarily perturbing the shadow computation stream

This function is not present in EDDI_v1


3. Reordering is applied after the standard duplication pipeline

After the pass finishes duplicating instructions in a function, EDDI_v2 runs the repair phase on every basic block:

for (BasicBlock &BB : Fn) {
  repairBasicBlock(BB, ClonedInstructions);
}

This means the new workflow is:

  1. duplicate instructions using the existing EDDI logic,
  2. duplicate/remap operands as before,
  3. preserve all existing checking and transformation logic,
  4. finally reorder duplicates into a coarse-grain layout at basic-block level.

By contrast, EDDI_v1 ends after duplication and does not perform any post-processing reorder of the duplicated stream


4. Clone-tracking state reset

Before transforming functions, EDDI_v2 clears the tracking set:

ClonedInstructions.clear();

This prevents stale clone metadata from previous transformations from affecting later blocks/functions within the same pass execution


What remains unchanged

This PR does not redesign the full EDDI pass. It intentionally keeps the existing infrastructure intact, including:

  • operand duplication,
  • consistency-check generation,
  • duplicated function argument handling,
  • duplicated globals,
  • direct/indirect call transformation,
  • error basic block generation.

So the key behavioral difference between EDDI_v1 and EDDI_v2 is not what gets duplicated, but how duplicated instructions are placed in the basic block once they have been generated


Summary

EDDI_v2 extends the original EDDI_v1 by adding a REPAIR reordering phase that:

  • tracks cloned instructions,
  • identifies duplicates inside each basic block,
  • groups originals first and duplicates later,
  • preserves the rest of the EDDI infrastructure unchanged.

AlbertoOcchipinti and others added 2 commits April 15, 2026 19:58
Added a new method to repair basic blocks using cloned instructions and unordered_set.
Reworked the EDDI pass to move duplicated instructions toward a coarse-grain layout inspired by REPAIR, instead of keeping the original fine-grain interleaving. Added basic-block repair logic to collect duplicated instructions and place them near the end of the block before the terminator, while preserving the original duplication pipeline and operand remapping. This change aims to reduce origin/shadow adjacency and better expose the control-flow fault-detection behavior expected from REPAIR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants