void LLVMAddFunctionAttr2(LLVMValueRef Fn, uint64_t PA) { Function *Func = unwrap<Function>(Fn); const AttributeSet PAL = Func->getAttributes(); AttrBuilder B(PA); const AttributeSet PALnew = PAL.addAttributes(Func->getContext(), AttributeSet::FunctionIndex, AttributeSet::get(Func->getContext(), AttributeSet::FunctionIndex, B)); Func->setAttributes(PALnew); }
// MakeFunctionClone - If the specified function needs to be modified for pool // allocation support, make a clone of it, adding additional arguments as // necessary, and return it. If not, just return null. // Function* RTAssociate::MakeFunctionClone(Function &F, FuncInfo& FI, DSGraph* G) { if (G->node_begin() == G->node_end()) return 0; if (FI.ArgNodes.empty()) return 0; // No need to clone if no pools need to be passed in! // Update statistics.. NumArgsAdded += FI.ArgNodes.size(); if (MaxArgsAdded < FI.ArgNodes.size()) MaxArgsAdded = FI.ArgNodes.size(); ++NumCloned; // Figure out what the arguments are to be for the new version of the // function FunctionType *OldFuncTy = F.getFunctionType(); std::vector<Type*> ArgTys(FI.ArgNodes.size(), PoolDescPtrTy); ArgTys.reserve(OldFuncTy->getNumParams() + FI.ArgNodes.size()); ArgTys.insert(ArgTys.end(), OldFuncTy->param_begin(), OldFuncTy->param_end()); // Create the new function prototype FunctionType *FuncTy = FunctionType::get(OldFuncTy->getReturnType(), ArgTys, OldFuncTy->isVarArg()); // Create the new function... Function *New = Function::Create(FuncTy, Function::InternalLinkage, F.getName()); New->copyAttributesFrom(&F); F.getParent()->getFunctionList().insert(&F, New); // Set the rest of the new arguments names to be PDa<n> and add entries to the // pool descriptors map Function::arg_iterator NI = New->arg_begin(); for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) { FI.PoolDescriptors[FI.ArgNodes[i]] = CreateArgPool(FI.ArgNodes[i], NI); NI->setName("PDa"); } // Map the existing arguments of the old function to the corresponding // arguments of the new function, and copy over the names. ValueToValueMapTy ValueMap; for (Function::arg_iterator I = F.arg_begin(); NI != New->arg_end(); ++I, ++NI) { ValueMap[I] = NI; NI->setName(I->getName()); } // Perform the cloning. SmallVector<ReturnInst*,100> Returns; // TODO: review the boolean flag here CloneFunctionInto(New, &F, ValueMap, true, Returns); // // The CloneFunctionInto() function will copy the parameter attributes // verbatim. This is incorrect; each attribute should be shifted one so // that the pool descriptor has no attributes. // const AttributeSet OldAttrs = New->getAttributes(); if (!OldAttrs.isEmpty()) { AttributeSet NewAttrs; for (unsigned index = 0; index < OldAttrs.getNumSlots(); ++index) { const AttributeSet & PAWI = OldAttrs.getSlotAttributes(index); unsigned argIndex = OldAttrs.getSlotIndex(index); // If it's not the return value, move the attribute to the next // parameter. if (argIndex) ++argIndex; // Add the parameter to the new list. NewAttrs = NewAttrs.addAttributes(F.getContext(), argIndex, PAWI); } // Assign the new attributes to the function clone New->setAttributes(NewAttrs); } for (ValueToValueMapTy::iterator I = ValueMap.begin(), E = ValueMap.end(); I != E; ++I) FI.NewToOldValueMap.insert(std::make_pair(I->second, const_cast<Value*>(I->first))); return FI.Clone = New; }