@@ -34,7 +34,7 @@ using namespace souper;
3434using namespace llvm ;
3535
3636static const std::vector<Inst::Kind> UnaryOperators = {
37- Inst::CtPop, Inst::BSwap, Inst::BitReverse, Inst::Cttz, Inst::Ctlz, Inst::Freeze
37+ Inst::CtPop, Inst::BSwap, Inst::BitReverse, Inst::Cttz, Inst::Ctlz
3838};
3939
4040static const std::vector<Inst::Kind> BinaryOperators = {
@@ -207,10 +207,6 @@ bool getGuesses(const std::vector<Inst *> &Inputs,
207207 unaryExclList.push_back (Inst::BitReverse);
208208 }
209209
210- // disable generating freeze of freeze
211- if (unaryHoleUsers.size () == 1 && unaryHoleUsers[0 ]->K == Inst::Freeze)
212- unaryExclList.push_back (Inst::Freeze);
213-
214210 std::vector<Inst *> PartialGuesses;
215211
216212 std::vector<Inst *> Comps (Inputs.begin (), Inputs.end ());
@@ -231,9 +227,6 @@ bool getGuesses(const std::vector<Inst *> &Inputs,
231227 if (std::find (unaryExclList.begin (), unaryExclList.end (), K) != unaryExclList.end ())
232228 continue ;
233229
234- if (K != Inst::Freeze && Width <= 1 )
235- continue ;
236-
237230 for (auto Comp : Comps) {
238231 if (K == Inst::BSwap && Width % 16 != 0 )
239232 continue ;
@@ -727,6 +720,51 @@ bool isBigQuerySat(SynthesisContext &SC,
727720 return BigQueryIsSat;
728721}
729722
723+ // if B == NULL, insert freeze to each border, otherwise replace all (freeze B) with B
724+ static Inst *FreezeCopy (Inst *I, InstContext &IC,
725+ std::map<Inst *, Inst *> &InstCache,
726+ std::map<Block *, Block *> &BlockCache,
727+ Inst *B) {
728+
729+ if (InstCache.count (I))
730+ return InstCache.at (I);
731+
732+ std::vector<Inst *> Ops;
733+ for (auto const &Op : I->Ops ) {
734+ Ops.push_back (FreezeCopy (Op, IC, InstCache, BlockCache, B));
735+ }
736+
737+ Inst *Copy = 0 ;
738+ if (!B && I->IsBorder ) {
739+ // explicitly forbid cloning the parameter of freeze
740+ Copy = IC.getInst (Inst::Freeze, I->Width , { I }, I->DemandedBits , I->Available );
741+ } else if (I->K == Inst::Freeze) {
742+ if (I->Ops [0 ] == B) {
743+ Copy = Ops[0 ];
744+ } else {
745+ // ditto
746+ Copy = IC.getInst (Inst::Freeze, I->Width , { I->Ops [0 ] }, I->DemandedBits , I->Available );
747+ }
748+ } else if (I->K == Inst::Var) {
749+ Copy = I;
750+ } else if (I->K == Inst::Phi) {
751+ if (!BlockCache.count (I->B )) {
752+ auto BlockCopy = IC.createBlock (I->B ->Preds );
753+ BlockCache[I->B ] = BlockCopy;
754+ Copy = IC.getPhi (BlockCopy, Ops, I->DemandedBits );
755+ } else {
756+ Copy = IC.getPhi (BlockCache.at (I->B ), Ops, I->DemandedBits );
757+ }
758+ } else if (I->K == Inst::Const || I->K == Inst::UntypedConst) {
759+ Copy = I;
760+ } else {
761+ Copy = IC.getInst (I->K , I->Width , Ops, I->DemandedBits , I->Available );
762+ }
763+ assert (Copy);
764+ InstCache[I] = Copy;
765+ return Copy;
766+ }
767+
730768std::error_code synthesizeWithKLEE (SynthesisContext &SC, std::vector<Inst *> &RHSs,
731769 const std::vector<souper::Inst *> &Guesses) {
732770 std::error_code EC;
@@ -788,13 +826,48 @@ std::error_code synthesizeWithKLEE(SynthesisContext &SC, std::vector<Inst *> &RH
788826
789827 if (DoubleCheckWithAlive) {
790828 if (!isTransformationValid (SC.LHS , RHS, SC.PCs , SC.IC )) {
791- llvm::errs () << " Transformation proved wrong by alive.\n " ;
792- ReplacementContext RC;
793- auto str = RC.printInst (SC.LHS , llvm::errs (), /* printNames=*/ true );
794- llvm::errs () << " infer " << str << " \n " ;
795- str = RC.printInst (RHS, llvm::errs (), /* printNames=*/ true );
796- llvm::errs () << " result " << str << " \n " ;
797- RHS = nullptr ;
829+ std::map<Inst *, Inst *> InstCache;
830+ std::map<Block *, Block *> BlockCache;
831+
832+ Inst *F = FreezeCopy (RHS, SC.IC , InstCache, BlockCache, nullptr );
833+
834+ if (!isTransformationValid (SC.LHS , F, SC.PCs , SC.IC )) {
835+ llvm::errs () << " Error: transformation proved wrong by alive, even with freeze inserted in border\n\n " ;
836+ ReplacementContext RC;
837+ RC.printInst (SC.LHS , llvm::errs (), /* printNames=*/ true );
838+ llvm::errs () << " \n =>\n\n " ;
839+ RC.printInst (RHS, llvm::errs (), /* printNames=*/ true );
840+ llvm::errs () << " \n ; RHS after inserting freeze \n\n " ;
841+ RC.printInst (F, llvm::errs (), /* printNames=*/ true );
842+ RHS = nullptr ;
843+ return EC;
844+ }
845+
846+ // Get border insts
847+ std::set<Inst *> Visited;
848+ std::vector<Inst *> Borders;
849+ std::queue<Inst *> Q;
850+ Q.push (RHS);
851+ while (!Q.empty ()) {
852+ Inst *I = Q.front ();
853+ Q.pop ();
854+ if (I->IsBorder )
855+ Borders.push_back (I);
856+ if (Visited.insert (I).second )
857+ for (auto Op : I->orderedOps ())
858+ Q.push (Op);
859+ }
860+ // Remove freezes
861+ for (auto Border : Borders) {
862+ auto I = F;
863+ InstCache.clear ();
864+ BlockCache.clear ();
865+ F = FreezeCopy (F, SC.IC , InstCache, BlockCache, Border);
866+ if (!isTransformationValid (SC.LHS , F, SC.PCs , SC.IC )) {
867+ F = I;
868+ }
869+ }
870+ RHS = F;
798871 }
799872 }
800873 if (RHS) {
0 commit comments