Beispiel #1
0
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());
       }
     }
   }
 }
Beispiel #3
0
/*
 * 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;
}