//===- SimplifyLibCalls.cpp - Optimize specific well-known librayr calls --===// // // The LLVM Compiler Infrastructure // // This file was developed by Reid Spencer group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements a variety of small optimizations for calls to specific // well-known (e.g. runtime library) function calls. For example, a call to the // function "exit(3)" that occurs within the main() function can be transformed // into a simple "return 3" instruction. Many of the ideas for these // optimizations were taken from GCC's "builtins.c" file but their // implementation here is completely knew and LLVM-centric // //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Instructions.h" #include "llvm/ADT/Statistic.h" using namespace llvm; namespace { Statistic<> SimplifiedLibCalls("simplified-lib-calls", "Number of well-known library calls simplified"); /// This class is the base class for a set of small but important /// optimizations of calls to well-known functions, such as those in the c /// library. This class provides the basic infrastructure for handling /// runOnModule. Subclasses register themselves and provide two methods: /// RecognizeCall and OptimizeCall. Whenever this class finds a function call, /// it asks the subclasses to recognize the call. If it is recognized, then /// the OptimizeCall method is called on that subclass instance. In this way /// the subclasses implement the calling conditions on which they trigger and /// the action to perform, making it easy to add new optimizations of this /// form. /// @brief A ModulePass for optimizing well-known function calls struct SimplifyLibCalls : public ModulePass { /// For this pass, process all of the function calls in the module, calling /// RecognizeCall and OptimizeCall as appropriate. virtual bool runOnModule(Module &M); }; RegisterOpt X("simplify-libcalls","Simplify well-known library calls"); struct CallOptimizer { /// @brief Constructor that registers the optimization CallOptimizer(); virtual ~CallOptimizer(); /// The implementations of this function in subclasses is the heart of the /// SimplifyLibCalls algorithm. Sublcasses of this class implement /// OptimizeCall to determine if (a) the conditions are right for optimizing /// the call and (b) to perform the optimization. If an action is taken /// against ci, the subclass is responsible for returning true and ensuring /// that ci is erased from its parent. /// @param ci the call instruction under consideration /// @param f the function that ci calls. /// @brief Optimize a call, if possible. virtual bool OptimizeCall(CallInst* ci, const Function* f) const = 0; }; /// @brief The list of optimizations deriving from CallOptimizer std::vector optlist; CallOptimizer::CallOptimizer() { // Register this call optimizer optlist.push_back(this); } /// Make sure we get our virtual table in this file. CallOptimizer::~CallOptimizer() {} } ModulePass *llvm::createSimplifyLibCallsPass() { return new SimplifyLibCalls(); } bool SimplifyLibCalls::runOnModule(Module &M) { for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) { // All the "well-known" functions are external because they live in a // runtime library somewhere and were (probably) not compiled by LLVM. // So, we only act on external functions that have non-empty uses. if (FI->isExternal() && !FI->use_empty()) { // Loop over each of the uses of the function for (Value::use_iterator UI = FI->use_begin(), UE = FI->use_end(); UI != UE ; ) { CallInst* CI = dyn_cast(*UI); ++UI; // If the use of the function is a call instruction if (CI) { // Loop over each of the registered optimizations and find the one // that can optimize this call. std::vector::iterator OI = optlist.begin(); std::vector::iterator OE = optlist.end(); for ( ; OI != OE ; ++OI) { if ((*OI)->OptimizeCall(CI,&(*FI))) { ++SimplifiedLibCalls; break; } } } } } } return true; } namespace { /// This CallOptimizer will find instances of a call to "exit" that occurs /// within the "main" function and change it to a simple "ret" instruction with /// the same value as passed to the exit function. It assumes that the /// instructions after the call to exit(3) can be deleted since they are /// unreachable anyway. /// @brief Replace calls to exit in main with a simple return struct ExitInMainOptimization : public CallOptimizer { virtual ~ExitInMainOptimization() {} bool OptimizeCall(CallInst* ci, const Function* func) const { // If this isn't the exit function then we don't act if (func->getName() != "exit") return false; // If the call isn't coming from main then we don't act if (const Function* f = ci->getParent()->getParent()) if (f->getName() != "main") return false; // Okay, time to replace it. Get the basic block of the call instruction BasicBlock* bb = ci->getParent(); // Create a return instruction that we'll replace the call with. Note that // the argument of the return is the argument of the call instruction. ReturnInst* ri = new ReturnInst(ci->getOperand(1), ci); // Erase everything from the call instruction to the end of the block. There // really shouldn't be anything other than the call instruction, but just in // case there is we delete it all because its now dead. bb->getInstList().erase(ci, bb->end()); return true; } } ExitInMainOptimizer; }