blob: 2c376c66ebfc522dccb4f7f19c725f32128d8d42 [file] [log] [blame]
//===- GlobalRegisterOpt.cpp ---------------------------------------------- --//
//
// The SAFECode Compiler
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass eliminates unnessary pool_register_global() calls in the code.
//
//===----------------------------------------------------------------------===//
#include <iostream>
#define DEBUG_TYPE "poolreg-global-elim"
#include "safecode/OptimizeChecks.h"
#include "safecode/Utility.h"
#include "llvm/ADT/Statistic.h"
// Pass Statistics
namespace {
STATISTIC (RemovedRegistration,
"Number of object registrations/deregistrations removed");
}
char GlobalRegisterOpt::ID = 0;
static RegisterPass<GlobalRegisterOpt>
X ("poolreg-global-elim", "Global Variable Register Eliminiation");
//
// Method: findSafeGlobals()
//
// Description:
// Find global variables that do not escape into memory or external code.
//
template<typename insert_iterator>
static void
findSafeGlobals (Module & M, insert_iterator InsertPt) {
for (Module::global_iterator GV = M.global_begin();
GV != M.global_end();
++GV) {
if (!escapesToMemory (GV))
InsertPt = GV;
}
return;
}
//
// Method: isSafeToRemove()
//
// Description:
// Determine whether the registration for the specified pointer value can be
// safely removed.
//
// Inputs:
// Ptr - The pointer value that is registered.
// SafeValues - The values that do not need registration.
//
// Return value:
// true - The registration of this value can be safely removed.
// false - The registration of this value may not be safely removed.
//
bool
isSafeToRemove (Value * Ptr, std::set<Value *> & SafeValues) {
//
// We can remove registrations on global variables that don't escape to
// memory.
//
if (GlobalVariable * GV = dyn_cast<GlobalVariable>(Ptr->stripPointerCasts()))
if (SafeValues.count (GV))
return true;
return false;
}
//
// Method: removeUnusedRegistration()
//
// Description:
// This method take a registration function and removes all
// registrations made with that function for pointers that are never checked.
//
// Inputs:
// F - The registration function.
// SafeValues - The set of values that are never checked.
//
void
removeUnusedRegistrations (Function * F, std::set<Value *> & SafeValues) {
//
// If the function does not exist, do nothing.
//
if (!F)
return;
//
// Scan through all uses of each registration function and see if it can be
// safely removed. If so, schedule it for removal.
//
std::vector<Instruction *> toBeRemoved;
//
// Look for and record all registrations that can be deleted.
//
for (Value::use_iterator UI=F->use_begin(), UE=F->use_end();
UI != UE;
++UI) {
CallSite CS (cast<CallInst>(*UI));
if (CS.getInstruction()) {
if (isSafeToRemove (CS.getArgument (2), SafeValues)) {
toBeRemoved.push_back(CS.getInstruction());
}
}
}
//
// Update the statistics.
//
if (toBeRemoved.size())
RemovedRegistration += toBeRemoved.size();
std::cerr << "Removing " << toBeRemoved.size() << " Globals!" << std::endl;
//
// Remove the unnecesary registrations.
//
std::vector<Instruction *>::iterator it, end;
for (it = toBeRemoved.begin(), end = toBeRemoved.end(); it != end; ++it) {
(*it)->eraseFromParent();
}
return;
}
namespace llvm {
//
// Method: runOnModule()
//
// Description:
// Entry point for this pass. Find calls to pool_register_global() that are
// unneeded and eliminate them.
//
bool
GlobalRegisterOpt::runOnModule(Module & M) {
//
// Get the pool registration function. If it doesn't exist or if it has no
// uses, do nothing.
//
Function * RegisterGlobal = M.getFunction ("pool_register_global");
Function * RegisterGlobalDebug = M.getFunction ("pool_register_global_debug");
if (!RegisterGlobal && !RegisterGlobalDebug)
return false;
//
// Find the set of globals that do not need to be registered.
//
std::set<Value *> SafeGlobals;
findSafeGlobals (M, std::inserter (SafeGlobals, SafeGlobals.begin()));
//
// Remove all unused registrations.
//
removeUnusedRegistrations (RegisterGlobal, SafeGlobals);
removeUnusedRegistrations (RegisterGlobalDebug, SafeGlobals);
return true;
}
}