Beispiel #1
0
/// 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;
      }
    }
  }
}
Beispiel #2
0
//
// 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;
}