diff --git a/lib/Infer/ExhaustiveSynthesis.cpp b/lib/Infer/ExhaustiveSynthesis.cpp index bf8151e75..3d774b328 100644 --- a/lib/Infer/ExhaustiveSynthesis.cpp +++ b/lib/Infer/ExhaustiveSynthesis.cpp @@ -32,6 +32,9 @@ namespace { "The larger the number is, the more fine-grained debug " "information will be printed"), cl::init(0)); + static cl::opt NoBigQuery("souper-exhaustive-synthesis-no-big-query", + cl::desc("Disable big query in exhaustive synthesis (default=false)"), + cl::init(false)); } // TODO @@ -374,8 +377,10 @@ ExhaustiveSynthesis::synthesize(SMTLIBSolver *SMTSolver, const std::vector &PCs, Inst *LHS, Inst *&RHS, InstContext &IC, unsigned Timeout) { + std::vector Inputs; findCands(LHS, Inputs, /*WidthMustMatch=*/false, /*FilterVars=*/false, MaxLHSCands); + if (DebugLevel > 1) llvm::errs() << "got " << Inputs.size() << " candidates from LHS\n"; @@ -397,7 +402,7 @@ ExhaustiveSynthesis::synthesize(SMTLIBSolver *SMTSolver, // Big Query // TODO: Need to check if big query actually saves us time or just wastes time - { + if (!NoBigQuery) { Inst *Ante = IC.getConst(APInt(1, true)); BlockPCs BPCsCopy; std::vector PCsCopy; @@ -445,6 +450,10 @@ ExhaustiveSynthesis::synthesize(SMTLIBSolver *SMTSolver, // find the valid one int Unsat = 0; int GuessIndex = -1; + + std::vector Vars; + findVars(LHS, Vars); + for (auto I : Guesses) { GuessIndex++; if (DebugLevel > 2) { @@ -478,9 +487,6 @@ ExhaustiveSynthesis::synthesize(SMTLIBSolver *SMTSolver, } } - std::vector Vars; - findVars(LHS, Vars); - std::map ConstMap; { diff --git a/lib/Inst/Inst.cpp b/lib/Inst/Inst.cpp index 39bcdec02..244291bc9 100644 --- a/lib/Inst/Inst.cpp +++ b/lib/Inst/Inst.cpp @@ -783,8 +783,16 @@ void souper::findCands(Inst *Root, std::vector &Guesses, bool WidthMustMatch, bool FilterVars, int Max) { // breadth-first search std::set Visited; - std::queue> Q; - Q.push(std::make_tuple(Root, 0)); + std::queue> Q; + auto Comp = [](const std::pair A, const std::pair B) + { + return A.second < B.second; + }; + std::priority_queue, + std::vector>, + decltype(Comp)> GuessesPQ(Comp); + + Q.push(std::make_pair(Root, 0)); while (!Q.empty()) { Inst *I; int Benefit; @@ -794,7 +802,7 @@ void souper::findCands(Inst *Root, std::vector &Guesses, if (Visited.insert(I).second) { if (I->K != Inst::Phi) { for (auto Op : I->Ops) - Q.push(std::make_tuple(Op, Benefit)); + Q.push(std::make_pair(Op, Benefit)); } if (Benefit > 1 && I->Available && I->K != Inst::Const && I->K != Inst::UntypedConst) { @@ -802,12 +810,16 @@ void souper::findCands(Inst *Root, std::vector &Guesses, continue; if (FilterVars && I->K == Inst::Var) continue; - Guesses.emplace_back(I); - if (Guesses.size() >= Max) - return; + GuessesPQ.push(std::make_pair(I, Benefit)); } } } + unsigned Size = GuessesPQ.size(); + for (unsigned T = 0 ; T < Max && T < Size ; T++) { + Inst *I = GuessesPQ.top().first; + GuessesPQ.pop(); + Guesses.emplace_back(I); + } } Inst *souper::getInstCopy(Inst *I, InstContext &IC, diff --git a/test/Infer/popcount6-syn.opt b/test/Infer/popcount6-syn.opt index a45eb8374..2ac1b650f 100644 --- a/test/Infer/popcount6-syn.opt +++ b/test/Infer/popcount6-syn.opt @@ -1,7 +1,9 @@ ; REQUIRES: solver, solver-model ; RUN: %souper-check %solver -infer-rhs -souper-infer-inst -souper-synthesis-comps=ctpop %s > %t1 +; RUN: %souper-check %solver -infer-rhs -souper-exhaustive-synthesis -souper-exhaustive-synthesis-no-big-query %s > %t2 ; RUN: %FileCheck %s < %t1 +; RUN: %FileCheck %s < %t2 ; CHECK: %21:i32 = ctpop %0 ; CHECK-NEXT: result %21