Пример #1
0
CFG *Add_target(CFG *cfg,int target,string checkstr){
    check = trim(checkstr);
    CFG *cfg1=new CFG();
    cfg1=cfg;
    int len=check.length();
    char x[len];
    int numCheck=1;//count of equations
    for(int i=0;i<len;i++){
        x[i]=check.at(i);
        if(x[i]=='&')
            numCheck++;
    }
    State *old_target=cfg->searchState(target);
    string funcName = old_target->funcName;
    State *new_target=new State(false,-1,"q1",funcName);
    new_target->transList.clear();
    new_target->consList.clear();
    Transition *temp=new Transition(-2,"p1");
    temp->fromState=old_target;
    temp->fromName=cfg->getNodeName(target);
    temp->level=temp->fromState->level+1;
    temp->toState=new_target;
    new_target->level = temp->level;
    temp->toName="q1";
    temp->guardList.clear();
    int a[numCheck+1];
    int k=0;
    a[k++]=0;
    for(int i=0;i<len;i++)
        if(x[i]=='&')
            a[k++]=i+1;
    a[numCheck]=len+1;
    string b[numCheck];
    for(int i=0;i<numCheck;i++)
        b[i]=check.substr(a[i],a[i+1]-a[i]-1);

    Constraint cTemp;
    for(int i=0;i<numCheck;i++){
	cTemp = StringToConstraints(b[i], funcName);
	temp->guardList.push_back(cTemp);
    }

    cfg1->stateList.push_back(*new_target);
    cfg1->transitionList.push_back(*temp);
    return cfg1;
}
Пример #2
0
int main(int argc, char *argv[])
{
    cl::SetVersionPrinter(&versionPrinter);
    cl::ParseCommandLineOptions(argc, argv, "llvm2kittel\n");

    if (boundedIntegers && divisionConstraintType == Exact) {
        std::cerr << "Cannot use \"-division-constraint=exact\" in combination with \"-bounded-integers\"" << std::endl;
        return 333;
    }
    if (!boundedIntegers && unsignedEncoding) {
        std::cerr << "Cannot use \"-unsigned-encoding\" without \"-bounded-integers\"" << std::endl;
        return 333;
    }
    if (!boundedIntegers && bitwiseConditions) {
        std::cerr << "Cannot use \"-bitwise-conditions\" without \"-bounded-integers\"" << std::endl;
        return 333;
    }
    if (numInlines != 0 && eagerInline) {
        std::cerr << "Cannot use \"-inline\" in combination with \"-eager-inline\"" << std::endl;
        return 333;
    }

#if LLVM_VERSION < VERSION(3, 5)
    llvm::OwningPtr<llvm::MemoryBuffer> owningBuffer;
    llvm::MemoryBuffer::getFileOrSTDIN(filename, owningBuffer);
    llvm::MemoryBuffer *buffer = owningBuffer.get();
#else
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> owningBuffer = llvm::MemoryBuffer::getFileOrSTDIN(filename);
    llvm::MemoryBuffer *buffer = NULL;
    if (!owningBuffer.getError()) {
        buffer = owningBuffer->get();
    }
#endif

    if (buffer == NULL) {
        std::cerr << "LLVM bitcode file \"" << filename << "\" does not exist or cannot be read." << std::endl;
        return 1;
    }

    llvm::LLVMContext context;
    std::string errMsg;
#if LLVM_VERSION < VERSION(3, 5)
    llvm::Module *module = llvm::ParseBitcodeFile(buffer, context, &errMsg);
#elif LLVM_VERSION == VERSION(3, 5)
    llvm::Module *module = NULL;
    llvm::ErrorOr<llvm::Module*> moduleOrError = llvm::parseBitcodeFile(buffer, context);
    std::error_code ec = moduleOrError.getError();
    if (ec) {
        errMsg = ec.message();
    } else {
        module = moduleOrError.get();
    }
#elif LLVM_VERSION == VERSION(3, 6)
    llvm::Module *module = NULL;
    llvm::ErrorOr<llvm::Module*> moduleOrError = llvm::parseBitcodeFile(buffer->getMemBufferRef(), context);
    std::error_code ec = moduleOrError.getError();
    if (ec) {
        errMsg = ec.message();
    } else {
        module = moduleOrError.get();
    }
#else
    llvm::Module *module = NULL;
    llvm::ErrorOr<std::unique_ptr<llvm::Module>> moduleOrError = llvm::parseBitcodeFile(buffer->getMemBufferRef(), context);
    std::error_code ec = moduleOrError.getError();
    if (ec) {
        errMsg = ec.message();
    } else {
        module = moduleOrError->get();
    }
#endif

    // check if the file is a proper bitcode file and contains a module
    if (module == NULL) {
        std::cerr << "LLVM bitcode file doesn't contain a valid module." << std::endl;
        return 2;
    }

    llvm::Function *function = NULL;
    llvm::Function *firstFunction = NULL;
    unsigned int numFunctions = 0;
    std::list<std::string> functionNames;

    for (llvm::Module::iterator i = module->begin(), e = module->end(); i != e; ++i) {
        if (i->getName() == functionname) {
            function = &*i;
            break;
        } else if (functionname.empty() && i->getName() == "main") {
            function = &*i;
            break;
        } else if (!i->isDeclaration()) {
            ++numFunctions;
            functionNames.push_back(i->getName());
            if (firstFunction == NULL) {
                firstFunction = &*i;
            }
        }
    }

    if (function == NULL) {
        if (numFunctions == 0) {
            std::cerr << "Module does not contain any function." << std::endl;
            return 3;
        }
        if (functionname.empty()) {
            if (numFunctions == 1) {
                function = firstFunction;
            } else {
                std::cerr << "LLVM module contains more than one function:" << std::endl;
                for (std::list<std::string>::iterator i = functionNames.begin(), e = functionNames.end(); i != e; ++i) {
                    std::cerr << "    " << *i << std::endl;
                }
                std::cerr << "Please specify which function should be used." << std::endl;
                return 4;
            }
        } else  {
            std::cerr << "Specified function not found." << std::endl;
            std::cerr << "Candidates are:" << std::endl;
            for (std::list<std::string>::iterator i = functionNames.begin(), e = functionNames.end(); i != e; ++i) {
                std::cerr << "    " << *i << std::endl;
            }
            return 5;
        }
    }

    // check for cyclic call hierarchies
    HierarchyBuilder checkHierarchy;
    checkHierarchy.computeHierarchy(module);
    if (eagerInline && checkHierarchy.isCyclic()) {
        std::cerr << "Cannot use \"-eager-inline\" with a cyclic call hierarchy!" << std::endl;
        return 7;
    }

    // transform!
    NondefFactory ndf(module);
    transformModule(module, function, ndf);

    // name them!
    InstNamer namer;
    namer.visit(module);

    // check them!
    const llvm::Type *boolType = llvm::Type::getInt1Ty(context);
    const llvm::Type *floatType = llvm::Type::getFloatTy(context);
    const llvm::Type *doubleType = llvm::Type::getDoubleTy(context);
    InstChecker checker(boolType, floatType, doubleType);
    checker.visit(module);

    // print it!
    if (debug) {
#if LLVM_VERSION < VERSION(3, 5)
        llvm::PassManager printPass;
        printPass.add(llvm::createPrintModulePass(&llvm::outs()));
        printPass.run(*module);
#else
        llvm::outs() << *module << '\n';
#endif
    }
    if (dumpLL) {
        std::string outFile = filename.substr(0, filename.length() - 3) + ".ll";
#if LLVM_VERSION < VERSION(3, 5)
        std::string errorInfo;
        llvm::raw_fd_ostream stream(outFile.data(), errorInfo);
        if (errorInfo.empty()) {
            llvm::PassManager dumpPass;
            dumpPass.add(llvm::createPrintModulePass(&stream));
            dumpPass.run(*module);
            stream.close();
        }
#elif LLVM_VERSION == VERSION(3, 5)
        std::string errorInfo;
        llvm::raw_fd_ostream stream(outFile.data(), errorInfo, llvm::sys::fs::F_Text);
        if (errorInfo.empty()) {
            stream << *module << '\n';
            stream.close();
        }
#else
        std::error_code errorCode;
        llvm::raw_fd_ostream stream(outFile.data(), errorCode, llvm::sys::fs::F_Text);
        if (!errorCode) {
            stream << *module << '\n';
            stream.close();
        }
#endif
    }

    // check for junk
    std::list<llvm::Instruction*> unsuitable = checker.getUnsuitableInsts();
    if (!unsuitable.empty()) {
        std::cerr << "Unsuitable instructions detected:" << std::endl;
        for (std::list<llvm::Instruction*>::iterator i = unsuitable.begin(), e = unsuitable.end(); i != e; ++i) {
            (*i)->dump();
        }
        return 6;
    }

    // compute recursion hierarchy
    HierarchyBuilder hierarchy;
    hierarchy.computeHierarchy(module);
    std::list<std::list<llvm::Function*> > sccs = hierarchy.getSccs();

    std::map<llvm::Function*, std::list<llvm::Function*> > funToScc;
    for (std::list<std::list<llvm::Function*> >::iterator i = sccs.begin(), e = sccs.end(); i != e; ++i) {
        std::list<llvm::Function*> scc = *i;
        for (std::list<llvm::Function*>::iterator si = scc.begin(), se = scc.end(); si != se; ++si) {
            funToScc.insert(std::make_pair(*si, scc));
        }
    }
    std::list<llvm::Function*> dependsOnList = hierarchy.getTransitivelyCalledFunctions(function);
    std::set<llvm::Function*> dependsOn;
    dependsOn.insert(dependsOnList.begin(), dependsOnList.end());
    dependsOn.insert(function);
    std::list<std::list<llvm::Function*> > dependsOnSccs;
    for (std::list<std::list<llvm::Function*> >::iterator i = sccs.begin(), e = sccs.end(); i != e; ++i) {
        std::list<llvm::Function*> scc = *i;
        for (std::list<llvm::Function*>::iterator fi = scc.begin(), fe = scc.end(); fi != fe; ++fi) {
            llvm::Function *f = *fi;
            if (dependsOn.find(f) != dependsOn.end()) {
                dependsOnSccs.push_back(scc);
                break;
            }
        }
    }

    // compute may/must info, propagated conditions, and compute loop exiting blocks for all functions
    std::map<llvm::Function*, MayMustMap> mmMap;
    std::map<llvm::Function*, std::set<llvm::GlobalVariable*> > funcMayZapDirect;
    std::map<llvm::Function*, TrueFalseMap> tfMap;
    std::map<llvm::Function*, std::set<llvm::BasicBlock*> > lebMap;
    std::map<llvm::Function*, ConditionMap> elcMap;
    for (std::set<llvm::Function*>::iterator df = dependsOn.begin(), dfe = dependsOn.end(); df != dfe; ++df) {
        llvm::Function *func = *df;
        std::pair<MayMustMap, std::set<llvm::GlobalVariable*> > tmp = getMayMustMap(func);
        mmMap.insert(std::make_pair(func, tmp.first));
        funcMayZapDirect.insert(std::make_pair(func, tmp.second));
        std::set<llvm::BasicBlock*> lcbs;
        if (onlyLoopConditions) {
            lcbs = getLoopConditionBlocks(func);
            lebMap.insert(std::make_pair(func, lcbs));
        }
        if (propagateConditions) {
            tfMap.insert(std::make_pair(func, getConditionPropagationMap(func, lcbs)));
        }
        if (explicitizeLoopConditions) {
            elcMap.insert(std::make_pair(func, getExplicitizedLoopConditionMap(func)));
        }
    }

    // transitively close funcMayZapDirect
    std::map<llvm::Function*, std::set<llvm::GlobalVariable*> > funcMayZap;
    for (std::set<llvm::Function*>::iterator df = dependsOn.begin(), dfe = dependsOn.end(); df != dfe; ++df) {
        llvm::Function *func = *df;
        std::set<llvm::GlobalVariable*> funcTransZap;
        std::list<llvm::Function*> funcDependsOnList = hierarchy.getTransitivelyCalledFunctions(func);
        std::set<llvm::Function*> funcDependsOn;
        funcDependsOn.insert(funcDependsOnList.begin(), funcDependsOnList.end());
        funcDependsOn.insert(func);
        for (std::set<llvm::Function*>::iterator depfi = funcDependsOn.begin(), depfe = funcDependsOn.end(); depfi != depfe; ++depfi) {
            llvm::Function *depf = *depfi;
            std::map<llvm::Function*, std::set<llvm::GlobalVariable*> >::iterator depfZap = funcMayZapDirect.find(depf);
            if (depfZap == funcMayZapDirect.end()) {
                std::cerr << "Could not find alias information (" << __FILE__ << ":" << __LINE__ << ")!" << std::endl;
                exit(9876);
            }
            funcTransZap.insert(depfZap->second.begin(), depfZap->second.end());
        }
        funcMayZap.insert(std::make_pair(func, funcTransZap));
    }

    // convert sccs separately
    unsigned int num = static_cast<unsigned int>(dependsOnSccs.size());
    unsigned int currNum = 0;
    for (std::list<std::list<llvm::Function*> >::iterator scci = dependsOnSccs.begin(), scce = dependsOnSccs.end(); scci != scce; ++scci) {
        std::list<llvm::Function*> scc = *scci;
        std::list<ref<Rule> > allRules;
        std::list<ref<Rule> > allCondensedRules;
        std::list<ref<Rule> > allKittelizedRules;
        std::list<ref<Rule> > allSlicedRules;
        if (debug) {
            std::cout << "========================================" << std::endl;
        }
        if ((!complexityTuples && !uniformComplexityTuples) || debug) {
            std::cout << "///*** " << getPartNumber(++currNum, num) << '_' << getSccName(scc) << " ***///" << std::endl;
        }
        std::set<llvm::Function*> sccSet;
        sccSet.insert(scc.begin(), scc.end());

        std::set<std::string> complexityLHSs;

        for (std::list<llvm::Function*>::iterator fi = scc.begin(), fe = scc.end(); fi != fe; ++fi) {
            llvm::Function *curr = *fi;
            Converter converter(boolType, assumeIsControl, selectIsControl, onlyMultiPredIsControl, boundedIntegers, unsignedEncoding, onlyLoopConditions, divisionConstraintType, bitwiseConditions, complexityTuples || uniformComplexityTuples);
            std::map<llvm::Function*, MayMustMap>::iterator tmp1 = mmMap.find(curr);
            if (tmp1 == mmMap.end()) {
                std::cerr << "Could not find alias information (" << __FILE__ << ":" << __LINE__ << ")!" << std::endl;
                exit(9876);
            }
            MayMustMap curr_mmMap = tmp1->second;
            std::map<llvm::Function*, TrueFalseMap>::iterator tmp2 = tfMap.find(curr);
            TrueFalseMap curr_tfMap;
            if (tmp2 != tfMap.end()) {
                curr_tfMap = tmp2->second;
            }
            std::map<llvm::Function*, std::set<llvm::BasicBlock*> >::iterator tmp3 = lebMap.find(curr);
            std::set<llvm::BasicBlock*> curr_leb;
            if (tmp3 != lebMap.end()) {
                curr_leb = tmp3->second;
            }
            std::map<llvm::Function*, ConditionMap>::iterator tmp4 = elcMap.find(curr);
            ConditionMap curr_elcMap;
            if (tmp4 != elcMap.end()) {
                curr_elcMap = tmp4->second;
            }
            converter.phase1(curr, sccSet, curr_mmMap, funcMayZap, curr_tfMap, curr_leb, curr_elcMap);
            converter.phase2(curr, sccSet, curr_mmMap, funcMayZap, curr_tfMap, curr_leb, curr_elcMap);
            std::list<ref<Rule> > rules = converter.getRules();
            std::list<ref<Rule> > condensedRules = converter.getCondensedRules();
            std::list<ref<Rule> > kittelizedRules = kittelize(condensedRules, smtSolver);
            Slicer slicer(curr, converter.getPhiVariables());
            std::list<ref<Rule> > slicedRules;
            if (noSlicing) {
                slicedRules = kittelizedRules;
            } else {
                slicedRules = slicer.sliceUsage(kittelizedRules);
                slicedRules = slicer.sliceConstraint(slicedRules);
                slicedRules = slicer.sliceDefined(slicedRules);
                slicedRules = slicer.sliceStillUsed(slicedRules, conservativeSlicing);
                slicedRules = slicer.sliceTrivialNondefConstraints(slicedRules);
                slicedRules = slicer.sliceDuplicates(slicedRules);
            }
            if (boundedIntegers) {
                slicedRules = kittelize(addBoundConstraints(slicedRules, converter.getBitwidthMap(), unsignedEncoding), smtSolver);
            }
            if (debug) {
                allRules.insert(allRules.end(), rules.begin(), rules.end());
                allCondensedRules.insert(allCondensedRules.end(), condensedRules.begin(), condensedRules.end());
                allKittelizedRules.insert(allKittelizedRules.end(), kittelizedRules.begin(), kittelizedRules.end());
            }
            if (simplifyConds) {
                slicedRules = simplifyConstraints(slicedRules);
            }
            allSlicedRules.insert(allSlicedRules.end(), slicedRules.begin(), slicedRules.end());

            if (complexityTuples || uniformComplexityTuples) {
                std::set<std::string> tmpLHSs = converter.getComplexityLHSs();
                complexityLHSs.insert(tmpLHSs.begin(), tmpLHSs.end());
            }
        }
        if (debug) {
            std::cout << "========================================" << std::endl;
            for (std::list<ref<Rule> >::iterator i = allRules.begin(), e = allRules.end(); i != e; ++i) {
                ref<Rule> tmp = *i;
                std::cout << tmp->toString() << std::endl;
            }
            std::cout << "========================================" << std::endl;
            for (std::list<ref<Rule> >::iterator i = allCondensedRules.begin(), e = allCondensedRules.end(); i != e; ++i) {
                ref<Rule> tmp = *i;
                std::cout << tmp->toString() << std::endl;
            }
            std::cout << "========================================" << std::endl;
            for (std::list<ref<Rule> >::iterator i = allKittelizedRules.begin(), e = allKittelizedRules.end(); i != e; ++i) {
                ref<Rule> tmp = *i;
                std::cout << tmp->toString() << std::endl;
            }
            std::cout << "========================================" << std::endl;
        }
        if (complexityTuples) {
            printComplexityTuples(allSlicedRules, complexityLHSs, std::cout);
        } else if (uniformComplexityTuples) {
            std::ostringstream startfun;
            startfun << "eval_" << getSccName(scc) << "_start";
            std::string name = startfun.str();
            printUniformComplexityTuples(allSlicedRules, complexityLHSs, name, std::cout);
        } else if (t2output) {
            std::string startFun = "eval_" + getSccName(scc) + "_start";
            printT2System(allSlicedRules, startFun, std::cout);
        } else {
            for (std::list<ref<Rule> >::iterator i = allSlicedRules.begin(), e = allSlicedRules.end(); i != e; ++i) {
                ref<Rule> tmp = *i;
                std::cout << tmp->toKittelString() << std::endl;
            }
        }
    }

    return 0;
}