/// scanForInterest - This function decides which arguments would be worth /// specializing on. void PartSpec::scanForInterest(Function& F, InterestingArgVector& args) { for(Function::arg_iterator ii = F.arg_begin(), ee = F.arg_end(); ii != ee; ++ii) { for(Value::use_iterator ui = ii->use_begin(), ue = ii->use_end(); ui != ue; ++ui) { bool interesting = false; User *U = *ui; if (isa<CmpInst>(U)) interesting = true; else if (isa<CallInst>(U)) interesting = ui->getOperand(0) == ii; else if (isa<InvokeInst>(U)) interesting = ui->getOperand(0) == ii; else if (isa<SwitchInst>(U)) interesting = true; else if (isa<BranchInst>(U)) interesting = true; if (interesting) { args.push_back(std::distance(F.arg_begin(), ii)); break; } } } }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. Search for functions which could be called // indirectly and create clones for them which are only called by direct // calls. // // Inputs: // M - A reference to the LLVM module to transform. // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool IndClone::runOnModule(Module& M) { // Set of functions to clone std::vector<Function*> toClone; // // Check all of the functions in the module. If the function could be called // by an indirect function call, add it to our worklist of functions to // clone. // for (Module::iterator I = M.begin(); I != M.end(); ++I) { // Flag whether the function should be cloned bool pleaseCloneTheFunction = false; // // Only clone functions which are defined and cannot be replaced by another // function by the linker. // if (!I->isDeclaration() && !I->mayBeOverridden()) { for (Value::use_iterator ui = I->use_begin(), ue = I->use_end(); ui != ue; ++ui) { if (!isa<CallInst>(*ui) && !isa<InvokeInst>(*ui)) { if(!ui->use_empty()) // // If this function is used for anything other than a direct function // call, then we want to clone it. // pleaseCloneTheFunction = true; } else { // // This is a call instruction, but hold up ranger! We need to make // sure that the function isn't passed as an argument to *another* // function. That would make the function usable in an indirect // function call. // for (unsigned index = 1; index < ui->getNumOperands(); ++index) { if (ui->getOperand(index)->stripPointerCasts() == I) { pleaseCloneTheFunction = true; break; } } } // // If we've discovered that the function could be used by an indirect // call site, schedule it for cloning. // if (pleaseCloneTheFunction) { toClone.push_back(I); break; } } } } // // Update the statistics on the number of functions we'll be cloning. // We only update the statistic if we want to clone one or more functions; // due to the magic of how statistics work, avoiding assignment prevents it // from needlessly showing up. // if (toClone.size()) numCloned += toClone.size(); // // Go through the worklist and clone each function. After cloning a // function, change all direct calls to use the clone instead of using the // original function. // for (unsigned index = 0; index < toClone.size(); ++index) { // // Clone the function and give it a name indicating that it is a clone to // be used for direct function calls. // Function * Original = toClone[index]; Function* DirectF = CloneFunction(Original); DirectF->setName(Original->getName() + "_DIRECT"); // // Make the clone internal; external code can use the original function. // DirectF->setLinkage(GlobalValue::InternalLinkage); // // Link the cloned function into the set of functions belonging to the // module. // Original->getParent()->getFunctionList().push_back(DirectF); // // Find all uses of the function that use it as a direct call. Change // them to use the clone. // for (Value::use_iterator ui = Original->use_begin(), ue = Original->use_end(); ui != ue; ) { CallInst *CI = dyn_cast<CallInst>(*ui); ui++; if (CI) { if (CI->getCalledFunction() == Original) { ++numReplaced; CI->setCalledFunction(DirectF); } } } } // // Assume that we've cloned at least one function. // return true; }