Exemple #1
0
bool Unboxing::runOnFunction(llvm::Function & f) {
    //std::cout << "running Unboxing optimization..." << std::endl;
    m = reinterpret_cast<RiftModule*>(f.getParent());
    ta = &getAnalysis<TypeAnalysis>();
    for (auto & b : f) {
        auto i = b.begin();
        while (i != b.end()) {
            ins = i;
            bool erase = false;
            if (CallInst * ci = dyn_cast<CallInst>(ins)) {
                StringRef s = ci->getCalledFunction()->getName();
                if (s == "genericAdd") {
                    erase = genericArithmetic(Instruction::FAdd);
                } else if (s == "genericSub") {
                    erase = genericArithmetic(Instruction::FSub);
                } else if (s == "genericMul") {
                    erase = genericArithmetic(Instruction::FMul);
                } else if (s == "genericDiv") {
                    erase = genericArithmetic(Instruction::FDiv);
                } else if (s == "genericLt") {
                    erase = genericRelational(FCmpInst::FCMP_OLT);
                } else if (s == "genericGt") {
                    erase = genericRelational(FCmpInst::FCMP_OGT);
                } else if (s == "genericEq") {
                    erase = genericRelational(FCmpInst::FCMP_OEQ);
                } else if (s == "genericNeq") {
                    erase = genericRelational(FCmpInst::FCMP_ONE);
                } else if (s == "genericGetElement") {
                    erase = genericGetElement();
                }
            }
            if (erase) {
                llvm::Instruction * v = i;
                ++i;
                state().erase(v);
                v->eraseFromParent();
            } else {
                ++i;
            }
        }
    }
    if (DEBUG) {
        cout << "After unboxing optimization: --------------------------------" << endl;
        f.dump();
        state().print(cout);
    }
    return false;
}
Exemple #2
0
bool TypeAnalysis::runOnFunction(llvm::Function & f) {
    state.clear();
    if (DEBUG) std::cout << "runnning TypeAnalysis..." << std::endl;
    // for all basic blocks, for all instructions
    do {
        // cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl;
        state.iterationStart();
        for (auto & b : f) {
            for (auto & i : b) {
                if (CallInst * ci = dyn_cast<CallInst>(&i)) {
                    StringRef s = ci->getCalledFunction()->getName();
                    if (s == "doubleVectorLiteral") {
                        // when creating literal from a double, it is
                        // always double scalar
                        llvm::Value * op = ci->getOperand(0);
                        AType * t = new AType(AType::Kind::D);
                        state.update(op, t);
                        state.update(ci, new AType(AType::Kind::DV, t));
                    } else if (s == "characterVectorLiteral") {
                        state.update(ci, new AType(AType::Kind::CV));
                    } else if (s == "fromDoubleVector") {
                        state.update(ci,
                                new AType(AType::Kind::R,
                                    state.get(ci->getOperand(0))));
                    } else if (s == "fromCharacterVector") {
                        state.update(ci,
                                new AType(AType::Kind::R,
                                    state.get(ci->getOperand(0))));
                    } else if (s == "fromFunction") {
                        state.update(ci,
                                new AType(AType::Kind::R,
                                    state.get(ci->getOperand(0))));
                    } else if (s == "genericGetElement") {
                        genericGetElement(ci);
                    } else if (s == "genericSetElement") {
                        // don't do anything for set element as it does not
                        // produce any new value
                    } else if (s == "genericAdd") {
                        genericArithmetic(ci);
                    } else if (s == "genericSub") {
                        genericArithmetic(ci);
                    } else if (s == "genericMul") {
                        genericArithmetic(ci);
                    } else if (s == "genericDiv") {
                        genericArithmetic(ci);
                    } else if (s == "genericEq") {
                        genericRelational(ci);
                    } else if (s == "genericNeq") {
                        genericRelational(ci);
                    } else if (s == "genericLt") {
                        genericRelational(ci);
                    } else if (s == "genericGt") {
                        genericRelational(ci);
                    } else if (s == "length") {
                        // result of length operation is always 
                        // double scalar
                        state.update(ci, new AType(AType::Kind::D));
                    } else if (s == "type") {
                        // result of type operation is always 
                        // character vector
                        state.update(ci, new AType(AType::Kind::CV));
                    } else if (s == "c") {
                        // make sure the types to c are correct
                        AType * t1 = state.get(ci->getArgOperand(1));
                        for (unsigned i = 2; i < ci->getNumArgOperands(); ++i)
                            t1 = t1->merge(state.get(ci->getArgOperand(i)));
                        if (t1->isScalar())
                            // concatenation of scalars is a vector
                            t1 = new AType(AType::Kind::R, AType::Kind::DV);
                        state.update(ci, t1);
                    } else if (s == "genericEval") {
                        state.update(ci, new AType(AType::Kind::R));
                    } else if (s == "envGet") {
                        state.update(ci, new AType(AType::Kind::R));
                    }
                } else if (PHINode * phi = dyn_cast<PHINode>(&i)) {
                    AType * first = state.get(phi->getOperand(0));
                    AType * second = state.get(phi->getOperand(1));
                    AType * result = first->merge(second);
                    state.update(phi, result);
                }
            }
        }
    } while (!state.hasReachedFixpoint());
    if (DEBUG) {
        f.dump();
        cout << state << endl;
    }
    return false;
}