Пример #1
0
void TypeAnalysis::genericRelational(CallInst * ci) {
    AType * lhs = state.get(ci->getOperand(0));
    AType * rhs = state.get(ci->getOperand(1));
    if (lhs->isScalar() and rhs->isScalar()) {
        state.update(ci,
                new AType(AType::Kind::R,
                    AType::Kind::DV,
                    AType::Kind::D));
    } else {
        state.update(ci, new AType(AType::Kind::R, AType::Kind::DV));
    }
}
Пример #2
0
void TypeAnalysis::genericGetElement(CallInst * ci) {
    AType * from = state.get(ci->getOperand(0));
    AType * index = state.get(ci->getOperand(1));
    if (from->isDouble()) {
        if (index->isScalar()) {
            state.update(ci,
                    new AType(AType::Kind::R,
                        AType::Kind::DV,
                        AType::Kind::D));
        } else {
            state.update(ci, new AType(AType::Kind::R, AType::Kind::DV));
        }
    } else if (from->isCharacter()) {
        state.update(ci, new AType(AType::Kind::R, AType::Kind::CV));
    } else {
        state.update(ci, new AType(AType::Kind::T));
    }
}
Пример #3
0
 /** Checks that a dot operator result type is correctly set to be double scalar by the type analysis. */
 void project4() {
     char const * source = "function(a, b) { a %*% b }";
     try {
         Environment * env = new Environment(nullptr);
         RVal * actual = eval(env, source);
         llvm::Function * f = actual->f->bitcode;
         // run type analysis on the function
         //auto pm = llvm::legacy::FunctionPassManager(f->getParent());
         TypeAnalysis ta;
         ta.runOnFunction(*f);
         // check the type of the genericDot intrinsic call
         for (auto & b : *f) {
             for (auto & i : b) {
                 if (llvm::CallInst * ci = llvm::dyn_cast<llvm::CallInst>(&i)) {
                     llvm::StringRef s = ci->getCalledFunction()->getName();
                     if (s == "genericDot") {
                         AType * t = ta.state.get(ci);
                         if (t->kind != AType::Kind::R or not t->isScalar())
                             throw "Generic dot does not have correct type";
                         if (ta.state.getLocation(t) != ci)
                             throw "Location attached to the generic dot type is invalid";
                         t = t->payload;
                         if (ta.state.getLocation(t) != nullptr)
                             throw "Generic dot payload cannot have location";
                         t = t->payload;
                         if (ta.state.getLocation(t) != nullptr)
                             throw "Generic dot payload cannot have location";
                         return;
                     }
                 }
             }
         }
         throw "Generic dot not found";
     } catch (char const * e) {
         cout << "ERROR at line " << __LINE__ << " : " << e << endl;
         cout << source << endl << endl;
     } catch (...) {
         cout << "ERROR at line " << __LINE__ << " : " << endl;
         cout << source << endl << endl;
     }
 }