// // Copyright (c) rev.ng Srls. See LICENSE.md for details. // #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" #include "llvm/Support/Casting.h" #include "revng/Support/IRHelpers.h" #include "revng-c/MakeEnvNull/MakeEnvNull.h" bool MakeEnvNullPass::runOnFunction(llvm::Function &F) { bool Changed = false; if (not F.getMetadata("revng.func.entry")) return Changed; llvm::Module *M = F.getParent(); llvm::GlobalVariable *Env = M->getGlobalVariable("env", /* AllowInternal */ true); llvm::SmallPtrSet LoadsFromEnvInF; for (llvm::Use &EnvUse : Env->uses()) { if (auto *I = llvm::dyn_cast(EnvUse.getUser())) { if (I->getFunction() != &F) continue; // At this point, all uses of env in a function should be loads LoadsFromEnvInF.insert(llvm::cast(I)); } else if (auto *CE = dyn_cast(EnvUse.getUser())) { if (not CE->isCast()) continue; for (llvm::Use &CEUse : CE->uses()) { if (auto *I = llvm::dyn_cast(CEUse.getUser())) { if (I->getFunction() != &F) continue; // At this point, all uses of env in a function should be loads LoadsFromEnvInF.insert(llvm::cast(I)); } } } } for (llvm::LoadInst *L : LoadsFromEnvInF) { llvm::Type *LoadType = L->getType(); auto *Null = llvm::Constant::getNullValue(LoadType); L->replaceAllUsesWith(Null); } Changed = not LoadsFromEnvInF.empty(); return Changed; } char MakeEnvNullPass::ID = 0; using llvm::RegisterPass; using Pass = MakeEnvNullPass; static RegisterPass RegisterMakeEnvNull("make-env-null", "Pass that substitutes env with " "a null pointer");