diff --git a/lib/Decompiler/ASTBuildAnalysis.cpp b/lib/Decompiler/ASTBuildAnalysis.cpp index d9b5c840c..917bdf6e2 100644 --- a/lib/Decompiler/ASTBuildAnalysis.cpp +++ b/lib/Decompiler/ASTBuildAnalysis.cpp @@ -647,10 +647,22 @@ void StmtBuilder::createAST(llvm::Function &F, clang::FunctionDecl &FDecl) { for (Instruction &I : *BB) { // Skip calls to `revng_scev_barrier_*` + // FIXME: calls to revng_scev_barrier_* should eventually be removed after + // using them and before actually generating C code for them. if (auto *Call = dyn_cast(&I)) { - llvm::StringRef CalleeName = Call->getCalledFunction()->getName(); - if (CalleeName.startswith("revng_scev_barrier_")) - continue; + if (Call->getType()->isIntOrPtrTy()) { + + const llvm::Type *BarrierTy = Call->getType(); + const std::string BarrierName = makeSCEVBarrierName(BarrierTy); + const llvm::Function *SCEVBarrier = Call->getCalledFunction(); + + if (SCEVBarrier->getName().str() == BarrierName) { + revng_assert(SCEVBarrier->arg_size() == 1); + InstrStmts[&I] = getExprForValue(Call->getArgOperand(0)); + + continue; + } + } } // We don't build clang's AST expressions for PHINodes nor for diff --git a/lib/Decompiler/AddSCEVBarrierPass.cpp b/lib/Decompiler/AddSCEVBarrierPass.cpp index a761a663d..1a5538f5a 100644 --- a/lib/Decompiler/AddSCEVBarrierPass.cpp +++ b/lib/Decompiler/AddSCEVBarrierPass.cpp @@ -22,7 +22,7 @@ struct AddSCEVBarrierPass : public llvm::FunctionPass { void getAnalysisUsage(llvm::AnalysisUsage &AU) const override { AU.addUsedIfAvailable(); - AU.setPreservesCFG(); // Only the CFG is preserved, because we insert calls. + AU.setPreservesAll(); // Only the CFG is preserved, because we insert calls. } }; diff --git a/lib/Decompiler/MarkForSerialization.cpp b/lib/Decompiler/MarkForSerialization.cpp index 3adced901..746609995 100644 --- a/lib/Decompiler/MarkForSerialization.cpp +++ b/lib/Decompiler/MarkForSerialization.cpp @@ -102,9 +102,20 @@ Analysis::InterruptType Analysis::transfer(const llvm::BasicBlock *BB) { // StoreInst and CallInst that are not pure always have side effects. ToSerialize[&I].set(HasSideEffects); revng_log(MarkLog, "Instr HasSideEffects"); + + // Also, force calls to revng_init_local_sp to behave like if they had + // many uses, so that they generate a local variable. + if (auto *Call = dyn_cast(&I)) { + llvm::StringRef CalleeName = Call->getCalledFunction()->getName(); + if (CalleeName == "revng_init_local_sp") { + ToSerialize[&I].set(HasManyUses); + revng_log(MarkLog, "Instr HasManyUses"); + } + } } switch (I.getNumUses()) { + case 1: { User *U = I.uses().begin()->getUser(); Instruction *UserI = cast(U); @@ -113,8 +124,6 @@ Analysis::InterruptType Analysis::transfer(const llvm::BasicBlock *BB) { if (NBBDuplicates < UserNDuplicates) { ToSerialize[&I].set(HasDuplicatedUses); revng_log(MarkLog, "Instr HasDuplicatedUses"); - } else { - Pending.insert(&I); } } break;