Example #1
0
/// TestFuncs - Extract all blocks for the miscompiled functions except for the
/// specified blocks.  If the problem still exists, return true.
///
bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs,
                                        std::string &Error) {
    // Test to see if the function is misoptimized if we ONLY run it on the
    // functions listed in Funcs.
    outs() << "Checking to see if the program is misoptimized when all ";
    if (!BBs.empty()) {
        outs() << "but these " << BBs.size() << " blocks are extracted: ";
        for (unsigned i = 0, e = BBs.size() < 10 ? BBs.size() : 10; i != e; ++i)
            outs() << BBs[i]->getName() << " ";
        if (BBs.size() > 10) outs() << "...";
    } else {
        outs() << "blocks are extracted.";
    }
    outs() << '\n';

    // Split the module into the two halves of the program we want.
    ValueToValueMapTy VMap;
    Module *Clone = CloneModule(BD.getProgram(), VMap);
    Module *Orig = BD.swapProgramIn(Clone);
    std::vector<Function*> FuncsOnClone;
    std::vector<BasicBlock*> BBsOnClone;
    for (unsigned i = 0, e = FunctionsBeingTested.size(); i != e; ++i) {
        Function *F = cast<Function>(VMap[FunctionsBeingTested[i]]);
        FuncsOnClone.push_back(F);
    }
    for (unsigned i = 0, e = BBs.size(); i != e; ++i) {
        BasicBlock *BB = cast<BasicBlock>(VMap[BBs[i]]);
        BBsOnClone.push_back(BB);
    }
    VMap.clear();

    Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
    Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
                         FuncsOnClone,
                         VMap);

    // Try the extraction.  If it doesn't work, then the block extractor crashed
    // or something, in which case bugpoint can't chase down this possibility.
    if (std::unique_ptr<Module> New =
                BD.extractMappedBlocksFromModule(BBsOnClone, ToOptimize)) {
        delete ToOptimize;
        // Run the predicate,
        // note that the predicate will delete both input modules.
        bool Ret = TestFn(BD, New.get(), ToNotOptimize, Error);
        delete BD.swapProgramIn(Orig);
        return Ret;
    }
    delete BD.swapProgramIn(Orig);
    delete ToOptimize;
    delete ToNotOptimize;
    return false;
}
Example #2
0
/// TestFuncs - split functions in a Module into two groups: those that are
/// under consideration for miscompilation vs. those that are not, and test
/// accordingly. Each group of functions becomes a separate Module.
///
bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
        std::string &Error) {
    // Test to see if the function is misoptimized if we ONLY run it on the
    // functions listed in Funcs.
    outs() << "Checking to see if the program is misoptimized when "
           << (Funcs.size()==1 ? "this function is" : "these functions are")
           << " run through the pass"
           << (BD.getPassesToRun().size() == 1 ? "" : "es") << ":";
    PrintFunctionList(Funcs);
    outs() << '\n';

    // Create a clone for two reasons:
    // * If the optimization passes delete any function, the deleted function
    //   will be in the clone and Funcs will still point to valid memory
    // * If the optimization passes use interprocedural information to break
    //   a function, we want to continue with the original function. Otherwise
    //   we can conclude that a function triggers the bug when in fact one
    //   needs a larger set of original functions to do so.
    ValueToValueMapTy VMap;
    Module *Clone = CloneModule(BD.getProgram(), VMap);
    Module *Orig = BD.swapProgramIn(Clone);

    std::vector<Function*> FuncsOnClone;
    for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
        Function *F = cast<Function>(VMap[Funcs[i]]);
        FuncsOnClone.push_back(F);
    }

    // Split the module into the two halves of the program we want.
    VMap.clear();
    Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
    Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone,
                         VMap);

    // Run the predicate, note that the predicate will delete both input modules.
    bool Broken = TestFn(BD, ToOptimize, ToNotOptimize, Error);

    delete BD.swapProgramIn(Orig);

    return Broken;
}