コード例 #1
0
ファイル: const_classes.cpp プロジェクト: UIKit0/pyston
 bool handleBool(LoadInst *li, GlobalVariable *gv) {
     if (VERBOSITY()) {
         llvm::errs() << "Constant-folding this load: " << *li << '\n';
     }
     if (gv->getName() == "True")
         li->replaceAllUsesWith(embedConstantPtr(True, g.llvm_bool_type_ptr));
     else
         li->replaceAllUsesWith(embedConstantPtr(False, g.llvm_bool_type_ptr));
     return true;
 }
コード例 #2
0
ファイル: hooks.cpp プロジェクト: DarrelHsu/pyston
void addRTFunction(CLFunction* cl_f, void* f, ConcreteCompilerType* rtn_type,
                   const std::vector<ConcreteCompilerType*>& arg_types) {
    assert(arg_types.size() == cl_f->numReceivedArgs());
#ifndef NDEBUG
    for (ConcreteCompilerType* t : arg_types)
        assert(t);
#endif

    FunctionSpecialization* spec = new FunctionSpecialization(processType(rtn_type), arg_types);

    std::vector<llvm::Type*> llvm_arg_types;
    int npassed_args = arg_types.size();
    assert(npassed_args == cl_f->numReceivedArgs());
    for (int i = 0; i < npassed_args; i++) {
        if (i == 3) {
            llvm_arg_types.push_back(g.i8_ptr->getPointerTo());
            break;
        }
        llvm_arg_types.push_back(arg_types[i]->llvmType());
    }

    llvm::FunctionType* ft = llvm::FunctionType::get(g.llvm_value_type_ptr, llvm_arg_types, false);

    cl_f->addVersion(new CompiledFunction(NULL, spec, false, f, embedConstantPtr(f, ft->getPointerTo()),
                                          EffortLevel::MAXIMAL, NULL));
}
コード例 #3
0
ファイル: hooks.cpp プロジェクト: science09/pyston
void addRTFunction(CLFunction* cl_f, void* f, ConcreteCompilerType* rtn_type,
                   const std::vector<ConcreteCompilerType*>& arg_types, bool takes_varargs, bool takes_kwargs) {
    FunctionSignature* sig = new FunctionSignature(processType(rtn_type), NULL, 0, takes_varargs, takes_kwargs);

    for (int i = 0; i < arg_types.size(); i++) {
        sig->arg_types.push_back(processType(arg_types[i]));
    }

    std::vector<llvm::Type*> llvm_arg_types;
    int npassed_args = arg_types.size();
    if (takes_varargs)
        npassed_args++;
    if (takes_kwargs)
        npassed_args++;
    for (int i = 0; i < npassed_args; i++) {
        if (i == 3) {
            llvm_arg_types.push_back(g.llvm_value_type_ptr->getPointerTo());
            break;
        }
        llvm_arg_types.push_back(g.llvm_value_type_ptr);
    }

    llvm::FunctionType* ft = llvm::FunctionType::get(g.llvm_value_type_ptr, llvm_arg_types, false);

    cl_f->addVersion(
        new CompiledFunction(NULL, sig, false, f, embedConstantPtr(f, ft->getPointerTo()), EffortLevel::MAXIMAL, NULL));
}
コード例 #4
0
ファイル: hooks.cpp プロジェクト: Bassem450/pyston
void addRTFunction(CLFunction *cl_f, void* f, ConcreteCompilerType* rtn_type, const std::vector<ConcreteCompilerType*> &arg_types, bool is_vararg) {
    FunctionSignature *sig = new FunctionSignature(processType(rtn_type), is_vararg);
    std::vector<llvm::Type*> llvm_arg_types;
    for (int i = 0; i < arg_types.size(); i++) {
        sig->arg_types.push_back(processType(arg_types[i]));
        llvm_arg_types.push_back(g.llvm_value_type_ptr);
    }

    llvm::FunctionType *ft = llvm::FunctionType::get(g.llvm_value_type_ptr, llvm_arg_types, false);

    cl_f->addVersion(new CompiledFunction(NULL, sig, false, f, embedConstantPtr(f, ft->getPointerTo()), EffortLevel::MAXIMAL, NULL));
}
コード例 #5
0
ファイル: util.cpp プロジェクト: 0xcc/pyston
// Returns a llvm::Constant char* to a global string constant
llvm::Constant* getStringConstantPtr(const std::string& str) {
    const char* c;
    if (strings.count(str)) {
        c = strings[str];
    } else {
        char* buf = (char*)malloc(str.size() + 1);
        memcpy(buf, str.c_str(), str.size());
        buf[str.size()] = '\0';

        strings[str] = buf;
        c = buf;
    }
    return embedConstantPtr(c, g.i8->getPointerTo());
}
コード例 #6
0
ファイル: hooks.cpp プロジェクト: DarrelHsu/pyston
static void compileIR(CompiledFunction* cf, EffortLevel::EffortLevel effort) {
    assert(cf);
    assert(cf->func);

    // g.engine->finalizeOBject();
    if (VERBOSITY("irgen") >= 1) {
        printf("Compiling...\n");
        // g.cur_module->dump();
    }

    void* compiled = NULL;
    if (effort > EffortLevel::INTERPRETED) {
        Timer _t("to jit the IR");
#if LLVMREV < 215967
        g.engine->addModule(cf->func->getParent());
#else
        g.engine->addModule(std::unique_ptr<llvm::Module>(cf->func->getParent()));
#endif
        compiled = (void*)g.engine->getFunctionAddress(cf->func->getName());
        assert(compiled);
        cf->llvm_code = embedConstantPtr(compiled, cf->func->getType());

        long us = _t.end();
        static StatCounter us_jitting("us_compiling_jitting");
        us_jitting.log(us);
        static StatCounter num_jits("num_jits");
        num_jits.log();
    } else {
        // HAX just get it for now; this is just to make sure everything works
        //(void*)g.func_registry.getFunctionAddress(cf->func->getName());
    }

    cf->code = compiled;
    if (VERBOSITY("irgen") >= 1) {
        printf("Compiled function to %p\n", compiled);
    }

    StackMap* stackmap = parseStackMap();
    patchpoints::processStackmap(stackmap);
}
コード例 #7
0
ファイル: util.cpp プロジェクト: jmgc/pyston
llvm::Constant* embedRelocatablePtr(const void* addr, llvm::Type* type, llvm::StringRef shared_name) {
    assert(addr);

    if (!ENABLE_JIT_OBJECT_CACHE)
        return embedConstantPtr(addr, type);

    std::string name;
    if (!shared_name.empty()) {
        llvm::GlobalVariable* gv = g.cur_module->getGlobalVariable(shared_name, true);
        if (gv)
            return gv;
        assert(!relocatable_syms.count(name));
        name = shared_name;
    } else {
        name = (llvm::Twine("c") + llvm::Twine(relocatable_syms.size())).str();
    }

    relocatable_syms[name] = addr;

    llvm::Type* var_type = type->getPointerElementType();
    return new llvm::GlobalVariable(*g.cur_module, var_type, true, llvm::GlobalVariable::ExternalLinkage, 0, name);
}
コード例 #8
0
ファイル: const_classes.cpp プロジェクト: UIKit0/pyston
 void replaceUsesWithConstant(llvm::Value* v, uintptr_t val) {
     if (isa<PointerType>(v->getType()))
         v->replaceAllUsesWith(embedConstantPtr((void*)val, v->getType()));
     else
         v->replaceAllUsesWith(getConstantInt(val, v->getType()));
 }
コード例 #9
0
ファイル: const_classes.cpp プロジェクト: UIKit0/pyston
        bool handleCls(LoadInst *li, GlobalVariable *gv) {
            bool changed = true;

            if (VERBOSITY("opt") >= 1) {
                errs() << "\nFound load of class-typed global variable:\n" << *li << '\n';
            }

            BoxedClass *cls = getClassFromGV(gv);
            if (!cls->is_constant) {
                assert(0 && "what globally-resolved classes are not constant??");
                if (VERBOSITY("opt") >= 1) {
                    errs() << gv->getName() << " is not constant; moving on\n";
                }
                return false;
            }

            std::vector<Instruction*> to_remove;
            for (User* user : li->users()) {
                if (CallInst *call = dyn_cast<CallInst>(user)) {
                    if (call->getCalledFunction()->getName() == "_maybeDecrefCls") {
                        errs() << "Found decrefcls call: " << *call << '\n';
                        if (!isUserDefined(cls)) {
                            // Don't delete right away; I think that invalidates the iterator
                            // we're currently iterating over
                            to_remove.push_back(call);
                        }
                    }
                    continue;
                }

                GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(user);
                if (!gep) {
                    //errs() << "Not a gep: " << *user << '\n';
                    continue;
                }

                APInt ap_offset(64, 0, true);
                bool success = gep->accumulateConstantOffset(*g.tm->getDataLayout(), ap_offset);
                assert(success);
                int64_t offset = ap_offset.getSExtValue();

                errs() << "Found a gep at offset " << offset << ": " << *gep << '\n';

                for (User* gep_user : gep->users()) {
                    LoadInst *gep_load = dyn_cast<LoadInst>(gep_user);
                    if (!gep_load) {
                        //errs() << "Not a load: " << *gep_user << '\n';
                        continue;
                    }


                    errs() << "Found a load: " << *gep_load << '\n';

                    if (offset == CLS_DTOR_OFFSET) {
                        errs() << "Dtor; replacing with " << cls->dtor << "\n";
                        replaceUsesWithConstant(gep_load, (uintptr_t)cls->dtor);
                        changed = true;
                    } else if (offset == CLS_HASATTRS_OFFSET) {
                        errs() << "Hasattrs; replacing with " << cls->hasattrs << "\n";
                        replaceUsesWithConstant(gep_load, cls->hasattrs);
                        changed = true;
                    }
                }

            }

            for (int i = 0; i < to_remove.size(); i++) {
                to_remove[i]->eraseFromParent();
                changed = true;
            }

            if (VERBOSITY()) {
                llvm::errs() << "Constant-folding this load: " << *li << '\n';
            }
            li->replaceAllUsesWith(embedConstantPtr(cls, g.llvm_class_type_ptr));

            changed = true;
            return changed;
        }
コード例 #10
0
ファイル: const_classes.cpp プロジェクト: guangwong/pyston
    bool handleCls(LoadInst* li, GlobalVariable* gv) {
        bool changed = true;

        if (VERBOSITY("opt") >= 1) {
            errs() << "\nFound load of class-typed global variable:\n" << *li << '\n';
        }

        BoxedClass* cls = getClassFromGV(gv);
        if (!cls->is_constant) {
            assert(0 && "what globally-resolved classes are not constant??");
            if (VERBOSITY("opt") >= 1) {
                errs() << gv->getName() << " is not constant; moving on\n";
            }
            return false;
        }

        std::vector<Instruction*> to_remove;
        for (User* user : li->users()) {
            if (CallInst* call = dyn_cast<CallInst>(user)) {
                continue;
            }

            GetElementPtrInst* gep = dyn_cast<GetElementPtrInst>(user);
            if (!gep) {
                // errs() << "Not a gep: " << *user << '\n';
                continue;
            }

            APInt ap_offset(64, 0, true);
#if LLVMREV < 214781
            bool success = gep->accumulateConstantOffset(*g.tm->getDataLayout(), ap_offset);
#elif LLVMREV < 227113
            bool success = gep->accumulateConstantOffset(*g.tm->getSubtargetImpl()->getDataLayout(), ap_offset);
#else
            bool success = gep->accumulateConstantOffset(*g.tm->getDataLayout(), ap_offset);
#endif
            assert(success);
            int64_t offset = ap_offset.getSExtValue();

            if (VERBOSITY("opt") >= 1)
                errs() << "Found a gep at offset " << offset << ": " << *gep << '\n';

            for (User* gep_user : gep->users()) {
                LoadInst* gep_load = dyn_cast<LoadInst>(gep_user);
                if (!gep_load) {
                    // errs() << "Not a load: " << *gep_user << '\n';
                    continue;
                }


                if (VERBOSITY("opt") >= 1)
                    errs() << "Found a load: " << *gep_load << '\n';

                if (offset == offsetof(BoxedClass, attrs_offset)) {
                    if (VERBOSITY("opt") >= 1)
                        errs() << "attrs_offset; replacing with " << cls->attrs_offset << "\n";
                    replaceUsesWithConstant(gep_load, cls->attrs_offset);
                    changed = true;
                } else if (offset == offsetof(BoxedClass, tp_basicsize)) {
                    if (VERBOSITY("opt") >= 1)
                        errs() << "tp_basicsize; replacing with " << cls->tp_basicsize << "\n";
                    replaceUsesWithConstant(gep_load, cls->tp_basicsize);
                    changed = true;
                }
            }
        }

        for (int i = 0; i < to_remove.size(); i++) {
            to_remove[i]->eraseFromParent();
            changed = true;
        }

        if (VERBOSITY()) {
            llvm::errs() << "Constant-folding this load: " << *li << '\n';
        }
        li->replaceAllUsesWith(embedConstantPtr(cls, g.llvm_class_type_ptr));

        changed = true;
        return changed;
    }
コード例 #11
0
ファイル: runtime_hooks.cpp プロジェクト: Averroes/pyston
static llvm::Value* addFunc(void* func, llvm::Type* rtn_type, llvm::ArrayRef<llvm::Type*> arg_types,
                            bool varargs = false) {
    llvm::FunctionType* ft = llvm::FunctionType::get(rtn_type, arg_types, varargs);
    return embedConstantPtr(func, ft->getPointerTo());
}
コード例 #12
0
ファイル: runtime_hooks.cpp プロジェクト: Averroes/pyston
static llvm::Value* getFunc(void* func, const char* name) {
    llvm::Function* f = lookupFunction(name);
    ASSERT(f, "%s", name);
    g.func_addr_registry.registerFunction(name, func, 0, f);
    return embedConstantPtr(func, f->getType());
}