blob: 74fc3fa718e0b821243ddf3ea43b45301fb4d488 [file] [log] [blame]
//===- OptimizeChecks.cpp - Optimize SAFECode Checks ---------------------- --//
//
// 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 unused checks.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "opt-safecode"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "safecode/OptimizeChecks.h"
#include "SCUtils.h"
#include "dsa/DSSupport.h"
#include <iostream>
#include <set>
namespace {
struct DeleteItself {
void operator()(llvm::CallInst * CI) {
CI->eraseFromParent();
}
};
}
NAMESPACE_SC_BEGIN
char UnusedCheckElimination::ID = 0;
namespace {
// Pass Statistics
STATISTIC (Removed, "Number of checks on unused pointers removed");
}
static RegisterPass<UnusedCheckElimination>
X ("unused-check-elim", "Unused Check elimination");
bool
UnusedCheckElimination::runOnModule (Module & M) {
//
// Get prerequisite analysis results.
//
unusedChecks.clear();
intrinsic = &getAnalysis<InsertSCIntrinsic>();
//
// Scan through the use/def chains of all the run-time checks. If the
// pointer being checked is never used, then eliminate the check.
//
InsertSCIntrinsic::intrinsic_const_iterator i = intrinsic->intrinsic_begin();
InsertSCIntrinsic::intrinsic_const_iterator e = intrinsic->intrinsic_end();
for (; i != e; ++i) {
if (i->flag & (InsertSCIntrinsic::SC_INTRINSIC_CHECK |
InsertSCIntrinsic::SC_INTRINSIC_OOB)) {
for (Value::use_iterator I = i->F->use_begin(), E = i->F->use_end();
I != E;
++I) {
//
// Get the pointer that the run-time check is checking. Strip off the
// casts because the cast may have no uses but the pointer it comes
// from may have uses (other than the casts).
//
CallInst * CI = cast<CallInst>(*I);
if (Value * CheckedPointer = intrinsic->getValuePointer(CI)) {
CheckedPointer = CheckedPointer->stripPointerCasts();
//
// If the checked pointer has no uses, schedule the run-time check for
// deletion.
//
if (CheckedPointer->use_empty()) unusedChecks.push_back(CI);
}
}
}
}
//
// Delete all unneeded run-time checks.
//
DeleteItself op;
std::for_each(unusedChecks.begin(), unusedChecks.end(), op);
//
// Record whether we modified the program and update the statistics. Note
// that we update the statistics because this pass could be run multipe
// times, and we want the total number of eliminated checks.
//
bool modified = unusedChecks.size() > 0;
Removed += unusedChecks.size();
//
// Free memory and finish the pass.
//
unusedChecks.clear();
return modified;
}
NAMESPACE_SC_END