Skip to content

Commit

Permalink
alive double check freeze removal
Browse files Browse the repository at this point in the history
  • Loading branch information
zhengyang92 committed Apr 21, 2020
1 parent 39601e8 commit 7d9e89d
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 18 deletions.
1 change: 1 addition & 0 deletions include/souper/Inst/Inst.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ struct Inst : llvm::FoldingSetNode {
std::vector<llvm::ConstantRange> RangeRefinement;
int nReservedConsts = -1;
int nHoles = -1;
bool IsBorder = false;
};

/// A mapping from an Inst to a replacement. This may either represent a
Expand Down
103 changes: 88 additions & 15 deletions lib/Infer/EnumerativeSynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ using namespace souper;
using namespace llvm;

static const std::vector<Inst::Kind> UnaryOperators = {
Inst::CtPop, Inst::BSwap, Inst::BitReverse, Inst::Cttz, Inst::Ctlz, Inst::Freeze
Inst::CtPop, Inst::BSwap, Inst::BitReverse, Inst::Cttz, Inst::Ctlz
};

static const std::vector<Inst::Kind> BinaryOperators = {
Expand Down Expand Up @@ -207,10 +207,6 @@ bool getGuesses(const std::vector<Inst *> &Inputs,
unaryExclList.push_back(Inst::BitReverse);
}

// disable generating freeze of freeze
if (unaryHoleUsers.size() == 1 && unaryHoleUsers[0]->K == Inst::Freeze)
unaryExclList.push_back(Inst::Freeze);

std::vector<Inst *> PartialGuesses;

std::vector<Inst *> Comps(Inputs.begin(), Inputs.end());
Expand All @@ -231,9 +227,6 @@ bool getGuesses(const std::vector<Inst *> &Inputs,
if (std::find(unaryExclList.begin(), unaryExclList.end(), K) != unaryExclList.end())
continue;

if (K != Inst::Freeze && Width <= 1)
continue;

for (auto Comp : Comps) {
if (K == Inst::BSwap && Width % 16 != 0)
continue;
Expand Down Expand Up @@ -727,6 +720,51 @@ bool isBigQuerySat(SynthesisContext &SC,
return BigQueryIsSat;
}

// if B == NULL, insert freeze to each border, otherwise replace all (freeze B) with B
static Inst *FreezeCopy(Inst *I, InstContext &IC,
std::map<Inst *, Inst *> &InstCache,
std::map<Block *, Block *> &BlockCache,
Inst *B) {

if (InstCache.count(I))
return InstCache.at(I);

std::vector<Inst *> Ops;
for (auto const &Op : I->Ops) {
Ops.push_back(FreezeCopy(Op, IC, InstCache, BlockCache, B));
}

Inst *Copy = 0;
if (!B && I->IsBorder) {
// explicitly forbid cloning the parameter of freeze
Copy = IC.getInst(Inst::Freeze, I->Width, { I }, I->DemandedBits, I->Available);
} else if (I->K == Inst::Freeze) {
if (I->Ops[0] == B) {
Copy = Ops[0];
} else {
// ditto
Copy = IC.getInst(Inst::Freeze, I->Width, { I->Ops[0] }, I->DemandedBits, I->Available);
}
} else if (I->K == Inst::Var) {
Copy = I;
} else if (I->K == Inst::Phi) {
if (!BlockCache.count(I->B)) {
auto BlockCopy = IC.createBlock(I->B->Preds);
BlockCache[I->B] = BlockCopy;
Copy = IC.getPhi(BlockCopy, Ops, I->DemandedBits);
} else {
Copy = IC.getPhi(BlockCache.at(I->B), Ops, I->DemandedBits);
}
} else if (I->K == Inst::Const || I->K == Inst::UntypedConst) {
Copy = I;
} else {
Copy = IC.getInst(I->K, I->Width, Ops, I->DemandedBits, I->Available);
}
assert(Copy);
InstCache[I] = Copy;
return Copy;
}

std::error_code synthesizeWithKLEE(SynthesisContext &SC, std::vector<Inst *> &RHSs,
const std::vector<souper::Inst *> &Guesses) {
std::error_code EC;
Expand Down Expand Up @@ -788,13 +826,48 @@ std::error_code synthesizeWithKLEE(SynthesisContext &SC, std::vector<Inst *> &RH

if (DoubleCheckWithAlive) {
if (!isTransformationValid(SC.LHS, RHS, SC.PCs, SC.IC)) {
llvm::errs() << "Transformation proved wrong by alive.";
ReplacementContext RC;
RC.printInst(SC.LHS, llvm::errs(), /*printNames=*/true);
llvm::errs() << "=>";
ReplacementContext RC2;
RC2.printInst(RHS, llvm::errs(), /*printNames=*/true);
RHS = nullptr;
std::map<Inst *, Inst *> InstCache;
std::map<Block *, Block *> BlockCache;

Inst *F = FreezeCopy(RHS, SC.IC, InstCache, BlockCache, nullptr);

if (!isTransformationValid(SC.LHS, F, SC.PCs, SC.IC)) {
llvm::errs() << "Error: transformation proved wrong by alive, even with freeze inserted in border\n\n";
ReplacementContext RC;
RC.printInst(SC.LHS, llvm::errs(), /*printNames=*/true);
llvm::errs() << "\n=>\n\n";
RC.printInst(RHS, llvm::errs(), /*printNames=*/true);
llvm::errs() << "\n; RHS after inserting freeze \n\n";
RC.printInst(F, llvm::errs(), /*printNames=*/true);
RHS = nullptr;
return EC;
}

// Get border insts
std::set<Inst *> Visited;
std::vector<Inst *> Borders;
std::queue<Inst *> Q;
Q.push(RHS);
while (!Q.empty()) {
Inst *I = Q.front();
Q.pop();
if (I->IsBorder)
Borders.push_back(I);
if (Visited.insert(I).second)
for (auto Op : I->orderedOps())
Q.push(Op);
}
// Remove freezes
for (auto Border : Borders) {
auto I = F;
InstCache.clear();
BlockCache.clear();
F = FreezeCopy(F, SC.IC, InstCache, BlockCache, Border);
if (!isTransformationValid(SC.LHS, F, SC.PCs, SC.IC)) {
F = I;
}
}
RHS = F;
}
}
if (RHS) {
Expand Down
1 change: 1 addition & 0 deletions lib/Inst/Inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,7 @@ void souper::findCands(Inst *Root, std::vector<Inst *> &Guesses,
I->K == Inst::SSubWithOverflow || I->K == Inst::USubWithOverflow ||
I->K == Inst::SMulWithOverflow || I->K == Inst::UMulWithOverflow)
continue;
I->IsBorder = true;
Guesses.emplace_back(I);
if (Guesses.size() >= Max)
return;
Expand Down
15 changes: 15 additions & 0 deletions test/Infer/double-check-freeze-removal-1.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
; REQUIRES: solver, solver-model

; RUN: %souper-check %solver -infer-rhs -souper-infer-iN=false -souper-enumerative-synthesis -souper-double-check %s > %t1
; RUN: %FileCheck %s < %t1

; CHECK: %5:i1 = freeze %3
; CHECK: %6:i1 = or %1, %5


%0:i8 = var ; 0
%1:i1 = eq 0:i8, %0
%2:i8 = var ; 1
%3:i1 = eq 0:i8, %2
%4:i1 = select %1, 1:i1, %3
infer %4
14 changes: 14 additions & 0 deletions test/Infer/double-check-freeze-removal-2.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; REQUIRES: solver, solver-model

; RUN: %souper-check %solver -infer-rhs -souper-infer-iN=false -souper-enumerative-synthesis -souper-double-check %s > %t1
; RUN: %FileCheck %s < %t1

; CHECK: %5:i1 = freeze %1
; CHECK: %6:i1 = or %3, %5

%0:i8 = var ; 0
%1:i1 = eq 0:i8, %0
%2:i8 = var ; 1
%3:i1 = eq 0:i8, %2
%4:i1 = select %3, 1:i1, %1
infer %4
15 changes: 15 additions & 0 deletions test/Infer/double-check-freeze-removal-3.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
; REQUIRES: solver, solver-model

; RUN: %souper-check %solver -infer-rhs -souper-infer-iN=false -souper-enumerative-synthesis -souper-double-check %s > %t1
; RUN: %FileCheck %s < %t1

; CHECK: %6:i1 = freeze %2
; CHECK: %7:i1 = or %4, %6

%0:i1 = var ; 0
%1:i1 = var ; 1
%2:i1 = and %0, %1
%3:i8 = var ; 2
%4:i1 = eq 0:i8, %3
%5:i1 = select %4, 1:i1, %2
infer %5
23 changes: 23 additions & 0 deletions test/Infer/double-check-freeze-removal-4.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; REQUIRES: solver, solver-model, long-duration-synthesis

; RUN: %souper-check %solver -infer-rhs -souper-infer-iN=false -souper-enumerative-synthesis -souper-double-check -souper-enumerative-synthesis-num-instructions=2 -souper-check-all-guesses %s > %t1
; RUN: %FileCheck %s < %t1

; CHECK: %0:i1 = var
; CHECK: %1:i1 = var
; CHECK: %2:i1 = freeze %1
; CHECK: %3:i1 = var
; CHECK: %4:i1 = freeze %3
; CHECK: %5:i1 = and %2, %4
; CHECK: %6:i1 = or %0, %5
; CHECK: result %6

%0:i1 = var
%1:i1 = var
; make cost model happy
%2:i1 = eq %0, 1:i1
%3:i1 = eq %1, 1:i1
%4:i1 = and %2, %3
%5:i1 = var
%6:i1 = select %5, 1:i1, %4
infer %6
2 changes: 0 additions & 2 deletions test/Infer/multiple-rhs1.opt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
; RUN: %FileCheck %s < %t2

; CHECK: result %0
; CHECK: %1:i8 = freeze %0
; CHECK-NEXT: result %1

%0:i8 = var
%1:i8 = add 1:i8, %0
Expand Down
3 changes: 2 additions & 1 deletion test/Infer/syn-double-insts/syn-freeze-or.opt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
; REQUIRES: solver, synthesis
; REQUIRES: solver, synthesis, unsupported
; RUN: %souper-check -infer-rhs -souper-enumerative-synthesis -souper-use-alive -souper-enumerative-synthesis-num-instructions=2 -souper-dataflow-pruning %solver %s > %t1
; RUN: %FileCheck %s < %t1

; No longer supported, freeze synthesis is now handled by alive double-check
; synthesis freeze
; takes about a minute

Expand Down

0 comments on commit 7d9e89d

Please sign in to comment.