示例#1
0
void Executor::start(Function *f, VariablesPtr vals, LocalVariables *lv) {

    assert(f && "Expecting a function!");
    assert((vals && lv) && "Expecting variables!");
    assert((status==INIT || status==IDLE) &&
           "Wrong status for Executor (!=INIT/IDLE)!");
    TargetFun = f;
    if (!DisabledSymbolicExe) {
        // Create a new context and a new
        // formula to hold the next path
        PathContext = new Context(lv);
        PathEncoder = new Encoder(PathContext);
        PathFormula = new Formula();
        // Reset symbolic path
        Path->clear();
    }
    // Create a program trace 
    Trace = new ProgramTrace(f);
    // Initialize the input symbols for the main function
    // TODO : Function of type main(argc,argv)
    // Function of type foo(arg1,...,argn)
    // Retrieve all main function arguments
    std::vector<InputVarTracePtr> valsVec = vals->getVector();
    unsigned i = 0;
    const FunctionType *FTy = f->getFunctionType();
    Function::arg_iterator ait;
    for (ait = f->arg_begin(); ait != f->arg_end(); ++ait) {
        // Check the type of the argument
        const unsigned argNo = ait->getArgNo();
        const Type *argTy = FTy->getParamType(argNo);
        assert(argTy->isIntegerTy(32) && "Unsuported function arg type!");
        if (!DisabledSymbolicExe) {
            SMAP->addInput(ait);
        }
        assert(i<valsVec.size() && "Function arg!");
        Trace->addProgramInput(valsVec[i++]);
    }
    status = START;
}
示例#2
0
//
// Method: runOnModule()
//
// Description:
//  Entry point for this LLVM pass.
//  Clone functions that take GEPs as arguments
//
// 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 GEPExprArgs::runOnModule(Module& M) {
  bool changed;
  do {
    changed = false;
    for (Module::iterator F = M.begin(); F != M.end(); ++F){
      for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
        for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
          CallInst *CI = dyn_cast<CallInst>(I++);
          if(!CI)
            continue;

          if(CI->hasByValArgument())
            continue;
          // if the GEP calls a function, that is externally defined,
          // or might be changed, ignore this call site.
          Function *F = CI->getCalledFunction();

          if (!F || (F->isDeclaration() || F->mayBeOverridden())) 
            continue;
          if(F->hasStructRetAttr())
            continue;
          if(F->isVarArg())
            continue;

          // find the argument we must replace
          Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
          unsigned argNum = 1;
          for(; argNum < CI->getNumOperands();argNum++, ++ai) {
            if(ai->use_empty())
              continue;
            if (isa<GEPOperator>(CI->getOperand(argNum)))
              break;
          }

          // if no argument was a GEP operator to be changed 
          if(ai == ae)
            continue;

          GEPOperator *GEP = dyn_cast<GEPOperator>(CI->getOperand(argNum));
          if(!GEP->hasAllConstantIndices())
            continue;

          // Construct the new Type
          // Appends the struct Type at the beginning
          std::vector<Type*>TP;
          TP.push_back(GEP->getPointerOperand()->getType());
          for(unsigned c = 1; c < CI->getNumOperands();c++) {
            TP.push_back(CI->getOperand(c)->getType());
          }

          //return type is same as that of original instruction
          FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
          Function *NewF;
          numSimplified++;
          if(numSimplified > 800) 
            return true;

          NewF = Function::Create(NewFTy,
                                  GlobalValue::InternalLinkage,
                                  F->getName().str() + ".TEST",
                                  &M);

          Function::arg_iterator NI = NewF->arg_begin();
          NI->setName("GEParg");
          ++NI;

          ValueToValueMapTy ValueMap;

          for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) {
            ValueMap[II] = NI;
            NI->setName(II->getName());
            NI->addAttr(F->getAttributes().getParamAttributes(II->getArgNo() + 1));
          }
          NewF->setAttributes(NewF->getAttributes().addAttr(
              0, F->getAttributes().getRetAttributes()));
          // Perform the cloning.
          SmallVector<ReturnInst*,100> Returns;
          CloneFunctionInto(NewF, F, ValueMap, false, Returns);
          std::vector<Value*> fargs;
          for(Function::arg_iterator ai = NewF->arg_begin(), 
              ae= NewF->arg_end(); ai != ae; ++ai) {
            fargs.push_back(ai);
          }

          NewF->setAttributes(NewF->getAttributes().addAttr(
              ~0, F->getAttributes().getFnAttributes()));
          //Get the point to insert the GEP instr.
          SmallVector<Value*, 8> Ops(CI->op_begin()+1, CI->op_end());
          Instruction *InsertPoint;
          for (BasicBlock::iterator insrt = NewF->front().begin(); 
               isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}

          NI = NewF->arg_begin();
          SmallVector<Value*, 8> Indices;
          Indices.append(GEP->op_begin()+1, GEP->op_end());
          GetElementPtrInst *GEP_new = GetElementPtrInst::Create(cast<Value>(NI),
                                                                 Indices, 
                                                                 "", InsertPoint);
          fargs.at(argNum)->replaceAllUsesWith(GEP_new);
          unsigned j = argNum + 1;
          for(; j < CI->getNumOperands();j++) {
            if(CI->getOperand(j) == GEP)
              fargs.at(j)->replaceAllUsesWith(GEP_new);
          }

          SmallVector<AttributeWithIndex, 8> AttributesVec;

          // Get the initial attributes of the call
          AttrListPtr CallPAL = CI->getAttributes();
          Attributes RAttrs = CallPAL.getRetAttributes();
          Attributes FnAttrs = CallPAL.getFnAttributes();
          if (RAttrs)
            AttributesVec.push_back(AttributeWithIndex::get(0, RAttrs));

          SmallVector<Value*, 8> Args;
          Args.push_back(GEP->getPointerOperand());
          for(unsigned j =1;j<CI->getNumOperands();j++) {
            Args.push_back(CI->getOperand(j));
            // position in the AttributesVec
            if (Attributes Attrs = CallPAL.getParamAttributes(j))
              AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
          }
          // Create the new attributes vec.
          if (FnAttrs != Attribute::None)
            AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));

          AttrListPtr NewCallPAL = AttrListPtr::get(AttributesVec.begin(),
                                                    AttributesVec.end());

          CallInst *CallI = CallInst::Create(NewF,Args,"", CI);
          CallI->setCallingConv(CI->getCallingConv());
          CallI->setAttributes(NewCallPAL);
          CI->replaceAllUsesWith(CallI);
          CI->eraseFromParent();
          changed = true;
        }
      }
    }
  } while(changed);
  return true;
}
示例#3
0
/// Deduce nocapture attributes for the SCC.
static bool addArgumentAttrs(const SCCNodeSet &SCCNodes) {
    bool Changed = false;

    ArgumentGraph AG;

    AttrBuilder B;
    B.addAttribute(Attribute::NoCapture);

    // Check each function in turn, determining which pointer arguments are not
    // captured.
    for (Function *F : SCCNodes) {
        // Definitions with weak linkage may be overridden at linktime with
        // something that captures pointers, so treat them like declarations.
        if (F->isDeclaration() || F->mayBeOverridden())
            continue;

        // Functions that are readonly (or readnone) and nounwind and don't return
        // a value can't capture arguments. Don't analyze them.
        if (F->onlyReadsMemory() && F->doesNotThrow() &&
                F->getReturnType()->isVoidTy()) {
            for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A != E;
                    ++A) {
                if (A->getType()->isPointerTy() && !A->hasNoCaptureAttr()) {
                    A->addAttr(AttributeSet::get(F->getContext(), A->getArgNo() + 1, B));
                    ++NumNoCapture;
                    Changed = true;
                }
            }
            continue;
        }

        for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A != E;
                ++A) {
            if (!A->getType()->isPointerTy())
                continue;
            bool HasNonLocalUses = false;
            if (!A->hasNoCaptureAttr()) {
                ArgumentUsesTracker Tracker(SCCNodes);
                PointerMayBeCaptured(&*A, &Tracker);
                if (!Tracker.Captured) {
                    if (Tracker.Uses.empty()) {
                        // If it's trivially not captured, mark it nocapture now.
                        A->addAttr(
                            AttributeSet::get(F->getContext(), A->getArgNo() + 1, B));
                        ++NumNoCapture;
                        Changed = true;
                    } else {
                        // If it's not trivially captured and not trivially not captured,
                        // then it must be calling into another function in our SCC. Save
                        // its particulars for Argument-SCC analysis later.
                        ArgumentGraphNode *Node = AG[&*A];
                        for (SmallVectorImpl<Argument *>::iterator
                                UI = Tracker.Uses.begin(),
                                UE = Tracker.Uses.end();
                                UI != UE; ++UI) {
                            Node->Uses.push_back(AG[*UI]);
                            if (*UI != A)
                                HasNonLocalUses = true;
                        }
                    }
                }
                // Otherwise, it's captured. Don't bother doing SCC analysis on it.
            }
            if (!HasNonLocalUses && !A->onlyReadsMemory()) {
                // Can we determine that it's readonly/readnone without doing an SCC?
                // Note that we don't allow any calls at all here, or else our result
                // will be dependent on the iteration order through the functions in the
                // SCC.
                SmallPtrSet<Argument *, 8> Self;
                Self.insert(&*A);
                Attribute::AttrKind R = determinePointerReadAttrs(&*A, Self);
                if (R != Attribute::None) {
                    AttrBuilder B;
                    B.addAttribute(R);
                    A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B));
                    Changed = true;
                    R == Attribute::ReadOnly ? ++NumReadOnlyArg : ++NumReadNoneArg;
                }
            }
        }
    }

    // The graph we've collected is partial because we stopped scanning for
    // argument uses once we solved the argument trivially. These partial nodes
    // show up as ArgumentGraphNode objects with an empty Uses list, and for
    // these nodes the final decision about whether they capture has already been
    // made.  If the definition doesn't have a 'nocapture' attribute by now, it
    // captures.

    for (scc_iterator<ArgumentGraph *> I = scc_begin(&AG); !I.isAtEnd(); ++I) {
        const std::vector<ArgumentGraphNode *> &ArgumentSCC = *I;
        if (ArgumentSCC.size() == 1) {
            if (!ArgumentSCC[0]->Definition)
                continue; // synthetic root node

            // eg. "void f(int* x) { if (...) f(x); }"
            if (ArgumentSCC[0]->Uses.size() == 1 &&
                    ArgumentSCC[0]->Uses[0] == ArgumentSCC[0]) {
                Argument *A = ArgumentSCC[0]->Definition;
                A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B));
                ++NumNoCapture;
                Changed = true;
            }
            continue;
        }

        bool SCCCaptured = false;
        for (auto I = ArgumentSCC.begin(), E = ArgumentSCC.end();
                I != E && !SCCCaptured; ++I) {
            ArgumentGraphNode *Node = *I;
            if (Node->Uses.empty()) {
                if (!Node->Definition->hasNoCaptureAttr())
                    SCCCaptured = true;
            }
        }
        if (SCCCaptured)
            continue;

        SmallPtrSet<Argument *, 8> ArgumentSCCNodes;
        // Fill ArgumentSCCNodes with the elements of the ArgumentSCC.  Used for
        // quickly looking up whether a given Argument is in this ArgumentSCC.
        for (auto I = ArgumentSCC.begin(), E = ArgumentSCC.end(); I != E; ++I) {
            ArgumentSCCNodes.insert((*I)->Definition);
        }

        for (auto I = ArgumentSCC.begin(), E = ArgumentSCC.end();
                I != E && !SCCCaptured; ++I) {
            ArgumentGraphNode *N = *I;
            for (SmallVectorImpl<ArgumentGraphNode *>::iterator UI = N->Uses.begin(),
                    UE = N->Uses.end();
                    UI != UE; ++UI) {
                Argument *A = (*UI)->Definition;
                if (A->hasNoCaptureAttr() || ArgumentSCCNodes.count(A))
                    continue;
                SCCCaptured = true;
                break;
            }
        }
        if (SCCCaptured)
            continue;

        for (unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
            Argument *A = ArgumentSCC[i]->Definition;
            A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B));
            ++NumNoCapture;
            Changed = true;
        }

        // We also want to compute readonly/readnone. With a small number of false
        // negatives, we can assume that any pointer which is captured isn't going
        // to be provably readonly or readnone, since by definition we can't
        // analyze all uses of a captured pointer.
        //
        // The false negatives happen when the pointer is captured by a function
        // that promises readonly/readnone behaviour on the pointer, then the
        // pointer's lifetime ends before anything that writes to arbitrary memory.
        // Also, a readonly/readnone pointer may be returned, but returning a
        // pointer is capturing it.

        Attribute::AttrKind ReadAttr = Attribute::ReadNone;
        for (unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
            Argument *A = ArgumentSCC[i]->Definition;
            Attribute::AttrKind K = determinePointerReadAttrs(A, ArgumentSCCNodes);
            if (K == Attribute::ReadNone)
                continue;
            if (K == Attribute::ReadOnly) {
                ReadAttr = Attribute::ReadOnly;
                continue;
            }
            ReadAttr = K;
            break;
        }

        if (ReadAttr != Attribute::None) {
            AttrBuilder B, R;
            B.addAttribute(ReadAttr);
            R.addAttribute(Attribute::ReadOnly).addAttribute(Attribute::ReadNone);
            for (unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
                Argument *A = ArgumentSCC[i]->Definition;
                // Clear out existing readonly/readnone attributes
                A->removeAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, R));
                A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B));
                ReadAttr == Attribute::ReadOnly ? ++NumReadOnlyArg : ++NumReadNoneArg;
                Changed = true;
            }
        }
    }

    return Changed;
}
示例#4
0
//
// Method: runOnModule()
//
// Description:
//  Entry point for this LLVM pass.
//  Clone functions that take LoadInsts as arguments
//
// 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 LoadArgs::runOnModule(Module& M) {
  std::map<std::pair<Function*, const Type * > , Function* > fnCache;
  bool changed;
  do { 
    changed = false;
    for (Module::iterator Func = M.begin(); Func != M.end(); ++Func) {
      for (Function::iterator B = Func->begin(), FE = Func->end(); B != FE; ++B) {
        for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
          CallInst *CI = dyn_cast<CallInst>(I++);
          if(!CI)
            continue;

          if(CI->hasByValArgument())
            continue;
          // if the CallInst calls a function, that is externally defined,
          // or might be changed, ignore this call site.
          Function *F = CI->getCalledFunction();
          if (!F || (F->isDeclaration() || F->mayBeOverridden())) 
            continue;
          if(F->hasStructRetAttr())
            continue;
          if(F->isVarArg())
            continue;

          // find the argument we must replace
          Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
          unsigned argNum = 0;
          for(; argNum < CI->getNumArgOperands();argNum++, ++ai) {
            // do not care about dead arguments
            if(ai->use_empty())
              continue;
            if(F->getAttributes().getParamAttributes(argNum).hasAttrSomewhere(Attribute::SExt) ||
               F->getAttributes().getParamAttributes(argNum).hasAttrSomewhere(Attribute::ZExt))
              continue;
            if (isa<LoadInst>(CI->getArgOperand(argNum)))
              break;
          }

          // if no argument was a GEP operator to be changed 
          if(ai == ae)
            continue;

          LoadInst *LI = dyn_cast<LoadInst>(CI->getArgOperand(argNum));
          Instruction * InsertPt = &(Func->getEntryBlock().front());
          AllocaInst *NewVal = new AllocaInst(LI->getType(), "",InsertPt);

          StoreInst *Copy = new StoreInst(LI, NewVal);
          Copy->insertAfter(LI);
          /*if(LI->getParent() != CI->getParent())
            continue;
          // Also check that there is no store after the load.
          // TODO: Check if the load/store do not alias.
          BasicBlock::iterator bii = LI->getParent()->begin();
          Instruction *BII = bii;
          while(BII != LI) {
            ++bii;
            BII = bii;
          }
          while(BII != CI) {
            if(isa<StoreInst>(BII))
              break;
            ++bii;
            BII = bii;
          }
          if(isa<StoreInst>(bii)){
            continue;
          }*/

          // Construct the new Type
          // Appends the struct Type at the beginning
          std::vector<Type*>TP;
          for(unsigned c = 0; c < CI->getNumArgOperands();c++) {
            if(c == argNum)
              TP.push_back(LI->getPointerOperand()->getType());
            TP.push_back(CI->getArgOperand(c)->getType());
          }

          //return type is same as that of original instruction
          FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
          numSimplified++;
          //if(numSimplified > 1000)
          //return true;

          Function *NewF;
          std::map<std::pair<Function*, const Type* > , Function* >::iterator Test;
          Test = fnCache.find(std::make_pair(F, NewFTy));
          if(Test != fnCache.end()) {
            NewF = Test->second;
          } else {
            NewF = Function::Create(NewFTy,
                                    GlobalValue::InternalLinkage,
                                    F->getName().str() + ".TEST",
                                    &M);

            fnCache[std::make_pair(F, NewFTy)] = NewF;
            Function::arg_iterator NI = NewF->arg_begin();

            ValueToValueMapTy ValueMap;

            unsigned count = 0;
            for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++count, ++NI) {
              if(count == argNum) {
                NI->setName("LDarg");
                continue;
              }
              ValueMap[II] = NI;
              NI->setName(II->getName());
              NI->addAttr(F->getAttributes().getParamAttributes(II->getArgNo() + 1));
              ++II;
            }
            // Perform the cloning.
            SmallVector<ReturnInst*,100> Returns;
            CloneFunctionInto(NewF, F, ValueMap, false, Returns);
            std::vector<Value*> fargs;
            for(Function::arg_iterator ai = NewF->arg_begin(), 
                ae= NewF->arg_end(); ai != ae; ++ai) {
              fargs.push_back(ai);
            }

            NewF->setAttributes(NewF->getAttributes().addAttributes(
                F->getContext(), 0, F->getAttributes().getRetAttributes()));
            NewF->setAttributes(NewF->getAttributes().addAttributes(
                F->getContext(), ~0, F->getAttributes().getFnAttributes()));
            //Get the point to insert the GEP instr.
            Instruction *InsertPoint;
            for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}
            LoadInst *LI_new = new LoadInst(fargs.at(argNum), "", InsertPoint);
            fargs.at(argNum+1)->replaceAllUsesWith(LI_new);
          }
          
          //this does not seem to be a good idea
          AttributeSet NewCallPAL=AttributeSet();
	  
          // Get the initial attributes of the call
          AttributeSet CallPAL = CI->getAttributes();
          AttributeSet RAttrs = CallPAL.getRetAttributes();
          AttributeSet FnAttrs = CallPAL.getFnAttributes();
          if (!RAttrs.isEmpty())
            NewCallPAL=NewCallPAL.addAttributes(F->getContext(),0, RAttrs);

          SmallVector<Value*, 8> Args;
          for(unsigned j =0;j<CI->getNumArgOperands();j++) {
            if(j == argNum) {
              Args.push_back(NewVal);
            }
            Args.push_back(CI->getArgOperand(j));
            // position in the NewCallPAL
            AttributeSet Attrs = CallPAL.getParamAttributes(j+1);
            if (!Attrs.isEmpty())
              NewCallPAL=NewCallPAL.addAttributes(F->getContext(),Args.size(), Attrs);
          }
          // Create the new attributes vec.
          if (!FnAttrs.isEmpty())
            NewCallPAL=NewCallPAL.addAttributes(F->getContext(),~0, FnAttrs);

          CallInst *CallI = CallInst::Create(NewF,Args,"", CI);
          CallI->setCallingConv(CI->getCallingConv());
          CallI->setAttributes(NewCallPAL);
          CI->replaceAllUsesWith(CallI);
          CI->eraseFromParent();
          changed = true;
        }
      }
    }
  } while(changed);
  return true;
}
//
// Method: runOnModule()
//
// Description:
//  Entry point for this LLVM pass.
//  If a function returns a struct, make it return
//  a pointer to the struct.
//
// 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 StructRet::runOnModule(Module& M) {
  const llvm::DataLayout targetData(&M);

  std::vector<Function*> worklist;
  for (Module::iterator I = M.begin(); I != M.end(); ++I)
    if (!I->mayBeOverridden()) {
      if(I->hasAddressTaken())
        continue;
      if(I->getReturnType()->isStructTy()) {
        worklist.push_back(I);
      }
    }

  while(!worklist.empty()) {
    Function *F = worklist.back();
    worklist.pop_back();
    Type *NewArgType = F->getReturnType()->getPointerTo();

    // Construct the new Type
    std::vector<Type*>TP;
    TP.push_back(NewArgType);
    for (Function::arg_iterator ii = F->arg_begin(), ee = F->arg_end();
         ii != ee; ++ii) {
      TP.push_back(ii->getType());
    }

    FunctionType *NFTy = FunctionType::get(F->getReturnType(), TP, F->isVarArg());

    // Create the new function body and insert it into the module.
    Function *NF = Function::Create(NFTy, 
                                    F->getLinkage(),
                                    F->getName(), &M);
    ValueToValueMapTy ValueMap;
    Function::arg_iterator NI = NF->arg_begin();
    NI->setName("ret");
    ++NI;
    for (Function::arg_iterator II = F->arg_begin(); II != F->arg_end(); ++II, ++NI) {
      ValueMap[II] = NI;
      NI->setName(II->getName());
      AttributeSet attrs = F->getAttributes().getParamAttributes(II->getArgNo() + 1);
      if (!attrs.isEmpty())
        NI->addAttr(attrs);
    }
    // Perform the cloning.
    SmallVector<ReturnInst*,100> Returns;
    if (!F->isDeclaration())
      CloneFunctionInto(NF, F, ValueMap, false, Returns);
    std::vector<Value*> fargs;
    for(Function::arg_iterator ai = NF->arg_begin(), 
        ae= NF->arg_end(); ai != ae; ++ai) {
      fargs.push_back(ai);
    }
    NF->setAttributes(NF->getAttributes().addAttributes(
        M.getContext(), 0, F->getAttributes().getRetAttributes()));
    NF->setAttributes(NF->getAttributes().addAttributes(
        M.getContext(), ~0, F->getAttributes().getFnAttributes()));
    
    for (Function::iterator B = NF->begin(), FE = NF->end(); B != FE; ++B) {      
      for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
        ReturnInst * RI = dyn_cast<ReturnInst>(I++);
        if(!RI)
          continue;
        LoadInst *LI = dyn_cast<LoadInst>(RI->getOperand(0));
        assert(LI && "Return should be preceded by a load instruction");
        IRBuilder<> Builder(RI);
        Builder.CreateMemCpy(fargs.at(0),
            LI->getPointerOperand(),
            targetData.getTypeStoreSize(LI->getType()),
            targetData.getPrefTypeAlignment(LI->getType()));
      }
    }

    for(Value::use_iterator ui = F->use_begin(), ue = F->use_end();
        ui != ue; ) {
      CallInst *CI = dyn_cast<CallInst>(*ui++);
      if(!CI)
        continue;
      if(CI->getCalledFunction() != F)
        continue;
      if(CI->hasByValArgument())
        continue;
      AllocaInst *AllocaNew = new AllocaInst(F->getReturnType(), 0, "", CI);
      SmallVector<Value*, 8> Args;

      //this should probably be done in a different manner
      AttributeSet NewCallPAL=AttributeSet();
      
      // Get the initial attributes of the call
      AttributeSet CallPAL = CI->getAttributes();
      AttributeSet RAttrs = CallPAL.getRetAttributes();
      AttributeSet FnAttrs = CallPAL.getFnAttributes();
      
      if (!RAttrs.isEmpty())
        NewCallPAL=NewCallPAL.addAttributes(F->getContext(),0, RAttrs);

      Args.push_back(AllocaNew);
      for(unsigned j = 0; j < CI->getNumOperands()-1; j++) {
        Args.push_back(CI->getOperand(j));
        // position in the NewCallPAL
        AttributeSet Attrs = CallPAL.getParamAttributes(j);
        if (!Attrs.isEmpty())
          NewCallPAL=NewCallPAL.addAttributes(F->getContext(),Args.size(), Attrs);
      }
      // Create the new attributes vec.
      if (!FnAttrs.isEmpty())
        NewCallPAL=NewCallPAL.addAttributes(F->getContext(),~0, FnAttrs);

      CallInst *CallI = CallInst::Create(NF, Args, "", CI);
      CallI->setCallingConv(CI->getCallingConv());
      CallI->setAttributes(NewCallPAL);
      LoadInst *LI = new LoadInst(AllocaNew, "", CI);
      CI->replaceAllUsesWith(LI);
      CI->eraseFromParent();
    }
    if(F->use_empty())
      F->eraseFromParent();
  }
  return true;
}