コード例 #1
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;
        }
コード例 #2
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;
    }