bool TransformComponentWithUse(Module& M, ComponentInterfaceTransform& T) { bool modified = false; for (ComponentInterfaceTransform::FMap::const_iterator i = T.rewrites.begin(), e = T.rewrites.end(); i != e; ++i) { errs() << "Looking for calls to " << i->first << "\n"; Function* f = M.getFunction(i->first); if (f == NULL) continue; for (Function::use_iterator ui = f->use_begin(), ue = f->use_end(); ui != ue; ++ui) { Use* use = &(*ui); User* user = ui->getUser(); if (isa<CallInst>(user) || isa<InvokeInst>(user)) { // The instruction is a call site CallSite cs(cast<Instruction>(user)); // If we are not the callee we should bail if( ! cs.isCallee(use)) { continue; } const CallRewrite* const rw = T.lookupRewrite(i->first, cs.arg_begin(), cs.arg_end()); if (rw == NULL) { continue; } #if DUMP BasicBlock* owner = cs.getInstruction()->getParent(); errs() << "Specializing (inter-module) call to '" << cs.getCalledFunction()->getName() << "' in function '" << (owner == NULL ? "??" : owner->getParent()->getName()) << "' on arguments ["; for (unsigned int i = 0, cnt = 0; i < cs.arg_size(); ++i) { if (!vector_in(rw->args, i)) { if (cnt++ != 0) errs() << ","; errs() << i << "=(" << *cs.getArgument(i) << ")"; } } errs() << "]\n"; #endif Instruction* newInst = applyRewriteToCall(M, rw, cs); llvm::ReplaceInstWithInst(cs.getInstruction(), newInst); modified = true; } } } return modified; }
void codeInto<ComponentInterfaceTransform, proto::ComponentInterfaceTransform> ( const ComponentInterfaceTransform& ci, proto::ComponentInterfaceTransform& buf) { for (ComponentInterface::FunctionIterator fi = ci.interface->begin(), fe = ci.interface->end(); fi != fe; ++fi) { for (ComponentInterface::CallIterator c = ci.interface->call_begin(fi), e = ci.interface->call_end(fi); c != e; ++c) { const CallRewrite* rw = ci.lookupRewrite(fi->first(), *c); if (rw != NULL) { proto::CallRewrite* nrw = buf.add_calls(); codeInto<CallRewrite, proto::CallRewrite> (*rw, *nrw); nrw->mutable_call()->set_name(fi->first()); codeInto<CallInfo, proto::CallInfo> (**c, *nrw->mutable_call()); } } } }
/* * Rewrite the given module according to the ComponentInterfaceTransformer. */ bool TransformComponentWithoutUse(Module& M, ComponentInterfaceTransform& T) { assert(T.interface != NULL); bool modified = false; for (Module::iterator f = M.begin(), e = M.end(); f != e; ++f) { for (Function::iterator bb = f->begin(), bbe = f->end(); bb != bbe; ++bb) { for (BasicBlock::iterator I = bb->begin(), E = bb->end(); I != E; ++I) { // TODO: Handle the operands CallSite call; if (CallInst* ci = dyn_cast<CallInst>(&*I)) { if (ci->isInlineAsm()) continue; call = CallSite(ci); } else if (InvokeInst* ci = dyn_cast<InvokeInst>(&*I)) { call = CallSite(ci); } else { // TODO: We need to find all references, including ones stored in variables // we'll be conservative and say that if it is stored in a variable then // we can't optimize it at all continue; } Function* target = call.getCalledFunction(); if (target == NULL || !target->isDeclaration()) { continue; } //iam const CallRewrite* const rw = T.lookupRewrite(target->getNameStr(), call.arg_begin(), call.arg_end()); const CallRewrite* const rw = T.lookupRewrite(target->getName().str(), call.arg_begin(), call.arg_end()); if (rw == NULL) { // There is no rewrite for this function continue; } // Get/Create the function Function* newTarget = M.getFunction(rw->function); if (newTarget == NULL) { // There isn't a function, we need to construct it FunctionType* newType = target->getFunctionType(); std::vector<Type*> argTypes; for (std::vector<unsigned>::const_iterator i = rw->args.begin(), e = rw->args.end(); i != e; ++i) argTypes.push_back(newType->getParamType(*i)); ArrayRef<Type*> params(argTypes); newType = FunctionType::get(target->getReturnType(), params, target->isVarArg()); newTarget = dyn_cast<Function> (M.getOrInsertFunction(rw->function, newType)); } assert(newTarget != NULL); Instruction* newInst = specializeCallSite(I, newTarget, rw->args); llvm::ReplaceInstWithInst(bb->getInstList(), I, newInst); modified = true; } } } return modified; }