blob: ef183507018b5709b59b243ed7c3d1a937f1e839 [file] [log] [blame]
//===-- IndClonder.cpp - Clone Indirect Called Functions ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "indclone"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/Statistic.h"
#include <set>
using namespace llvm;
STATISTIC(numCloned, "Number of Functions Cloned");
STATISTIC(numReplaced, "Number of Calls Replaced");
namespace {
class IndClone : public ModulePass {
public:
static char ID;
IndClone() : ModulePass(&ID) {}
bool runOnModule(Module& M) {
std::set<Function*> toClone;
for (Module::iterator I = M.begin(); I != M.end(); ++I)
if (!I->isDeclaration() && !I->mayBeOverridden())
for(Value::use_iterator ui = I->use_begin(), ue = I->use_end();
ui != ue; ++ui)
if (!isa<CallInst>(ui)) {
toClone.insert(I);
}
numCloned += toClone.size();
for (std::set<Function*>::iterator I = toClone.begin(),
E = toClone.end(); I != E; ++I) {
Function* DirectF = CloneFunction(*I);
DirectF->setName((*I)->getName() + "_DIRECT");
DirectF->setLinkage(GlobalValue::InternalLinkage);
(*I)->getParent()->getFunctionList().push_back(DirectF);
for(Value::use_iterator ui = (*I)->use_begin(), ue = (*I)->use_end();
ui != ue; ++ui)
if (CallInst* CI = dyn_cast<CallInst>(ui))
if (CI->getOperand(0) == *I) {
++numReplaced;
CI->setOperand(0, DirectF);
}
}
return true;
}
};
}
char IndClone::ID = 0;
static RegisterPass<IndClone>
X("indclone", "Indirect call cloning");