Skip to content

Commit b40313f

Browse files
author
EmilioCorigliano
committed
feat(REPAIR): add REPAIR coarse-grained duplication
1 parent 401278a commit b40313f

2 files changed

Lines changed: 62 additions & 1 deletion

File tree

passes/ASPIS.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "Utils/Utils.h"
99
#include <map>
1010
#include <set>
11+
#include <unordered_set>
1112

1213
using namespace llvm;
1314

@@ -40,6 +41,7 @@ class EDDI : public PassInfoMixin<EDDI> {
4041
std::set<Function*> toHardenFunctions;
4142
std::set<Value*> toHardenVariables;
4243
std::set<Value*> DuplicatedCalls;
44+
std::unordered_set<Instruction *> ClonedInstructions;
4345

4446
std::string entryPoint;
4547

@@ -68,8 +70,8 @@ class EDDI : public PassInfoMixin<EDDI> {
6870
Function *duplicateFnArgs(Function &Fn, Module &Md, std::map<Value *, Value *> &DuplicatedInstructionMap);
6971
void CreateErrBB(Module &Md, Function &Fn, BasicBlock *ErrBB);
7072
bool temporaryArgumentDuplication(Module &Md, llvm::Value *value, IRBuilder<> &B, std::map<llvm::Value *, llvm::Value *> &InstructionMap);
71-
7273
void fixGlobalCtors(Module &M);
74+
void repairBasicBlock(BasicBlock &BB);
7375
public:
7476
explicit EDDI(bool duplicateAll, bool MultipleErrBBEnabled = false, std::string entryPoint = "main") : duplicateAll(duplicateAll), MultipleErrBBEnabled(MultipleErrBBEnabled), entryPoint(entryPoint) {}
7577

passes/EDDI.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ EDDI::cloneInstr(Instruction &I,
585585
} // else place it right after the instruction we are working on
586586
else {
587587
IClone->insertAfter(&I);
588+
ClonedInstructions.insert(IClone);
588589
}
589590
DuplicatedInstructionMap.insert(
590591
std::pair<Instruction *, Instruction *>(&I, IClone));
@@ -1567,6 +1568,7 @@ PreservedAnalyses EDDI::run(Module &Md, ModuleAnalysisManager &AM) {
15671568

15681569
// list of duplicated instructions to remove since they are equal to the original
15691570
std::set<CallBase *> GrayAreaCallsToFix;
1571+
ClonedInstructions.clear();
15701572
int iFn = 1;
15711573
LLVM_DEBUG(dbgs() << "Iterating over the functions...\n");
15721574

@@ -2055,6 +2057,63 @@ void EDDI::fixGlobalCtors(Module &M) {
20552057
NewGlobalCtors->setSection(Section);
20562058
}
20572059

2060+
/**
2061+
* REPAIR groups all original instructions first, followed by all their
2062+
* duplicates, producing the coarse-grain order:
2063+
* A, B, C, A_dup, B_dup, C_dup
2064+
*
2065+
* This layout increases the temporal and spatial distance between a MI/SI
2066+
* pair. As a result, a single transient fault (SEU) is less likely to
2067+
* corrupt both the original and its duplicate before a consistency check
2068+
* can detect the mismatch (improving error-detection coverage for
2069+
* spatially-correlated faults)
2070+
*
2071+
* The function is called after the EDDI duplication phase has already
2072+
* cloned every eligible instruction and wired up operands. It only moves
2073+
* instructions;
2074+
*
2075+
* @param BB The basic block whose instructions are to be
2076+
* reordered
2077+
*/
2078+
void EDDI::repairBasicBlock(BasicBlock &BB) {
2079+
2080+
// Collect all duplicated instructions in this BB,
2081+
// preserving their relative order so that data-flow dependencies
2082+
// among duplicates remain satisfied after the move
2083+
std::vector<Instruction *> DupsInOrder;
2084+
2085+
for (Instruction &I : BB) {
2086+
// PHINodes must stay at the top of the block (LLVM invariant).
2087+
// AllocaInsts are kept in the entry block's alloca region.
2088+
// Terminators (br, ret, switch, …) must remain last.
2089+
// None of these should be relocated
2090+
2091+
if (I.isTerminator() || isa<CallBase>(I)) {
2092+
// If there are no duplicates in this block, nothing to reorder
2093+
if (DupsInOrder.empty())
2094+
return;
2095+
2096+
// Move every duplicate just before the terminator, in their
2097+
// original relative order
2098+
for (Instruction *Dup : DupsInOrder) {
2099+
if(isa<PHINode>(Dup)){
2100+
Dup->moveBefore(BB.getFirstNonPHI());
2101+
}
2102+
else{
2103+
Dup->moveBefore(&I);
2104+
}
2105+
}
2106+
DupsInOrder.clear();
2107+
continue;
2108+
} else if (ClonedInstructions.find(&I) != ClonedInstructions.end()) {
2109+
// If this instruction belongs to the cloned set, it is a duplicate
2110+
// that needs to be sunk to the bottom of the block
2111+
DupsInOrder.push_back(&I);
2112+
}
2113+
}
2114+
}
2115+
2116+
20582117
//-----------------------------------------------------------------------------
20592118
// New PM Registration
20602119
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)