LCOV - code coverage report
Current view: top level - lib/Support - DeltaAlgorithm.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 47 50 94.0 %
Date: 2018-10-20 13:21:21 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- DeltaAlgorithm.cpp - A Set Minimization Algorithm -----*- C++ -*--===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //===----------------------------------------------------------------------===//
       8             : 
       9             : #include "llvm/ADT/DeltaAlgorithm.h"
      10             : #include <algorithm>
      11             : #include <iterator>
      12             : #include <set>
      13             : using namespace llvm;
      14             : 
      15           9 : DeltaAlgorithm::~DeltaAlgorithm() {
      16           9 : }
      17           0 : 
      18           0 : bool DeltaAlgorithm::GetTestResult(const changeset_ty &Changes) {
      19           9 :   if (FailedTestsCache.count(Changes))
      20           9 :     return false;
      21             : 
      22         158 :   bool Result = ExecuteOneTest(Changes);
      23             :   if (!Result)
      24          36 :     FailedTestsCache.insert(Changes);
      25             : 
      26         122 :   return Result;
      27         122 : }
      28             : 
      29             : void DeltaAlgorithm::Split(const changeset_ty &S, changesetlist_ty &Res) {
      30             :   // FIXME: Allow clients to provide heuristics for improved splitting.
      31             : 
      32             :   // FIXME: This is really slow.
      33          67 :   changeset_ty LHS, RHS;
      34             :   unsigned idx = 0, N = S.size() / 2;
      35             :   for (changeset_ty::const_iterator it = S.begin(),
      36             :          ie = S.end(); it != ie; ++it, ++idx)
      37             :     ((idx < N) ? LHS : RHS).insert(*it);
      38          67 :   if (!LHS.empty())
      39         182 :     Res.push_back(LHS);
      40         249 :   if (!RHS.empty())
      41         182 :     Res.push_back(RHS);
      42          67 : }
      43          31 : 
      44          67 : DeltaAlgorithm::changeset_ty
      45          67 : DeltaAlgorithm::Delta(const changeset_ty &Changes,
      46          67 :                       const changesetlist_ty &Sets) {
      47             :   // Invariant: union(Res) == Changes
      48             :   UpdatedSearchState(Changes, Sets);
      49          34 : 
      50             :   // If there is nothing left we can remove, we are done.
      51             :   if (Sets.size() <= 1)
      52          34 :     return Changes;
      53             : 
      54             :   // Look for a passing subset.
      55          68 :   changeset_ty Res;
      56             :   if (Search(Changes, Sets, Res))
      57             :     return Res;
      58             : 
      59             :   // Otherwise, partition the sets if possible; if not we are done.
      60          29 :   changesetlist_ty SplitSets;
      61             :   for (changesetlist_ty::const_iterator it = Sets.begin(),
      62             :          ie = Sets.end(); it != ie; ++it)
      63             :     Split(*it, SplitSets);
      64          15 :   if (SplitSets.size() == Sets.size())
      65          15 :     return Changes;
      66          68 : 
      67          53 :   return Delta(Changes, SplitSets);
      68          45 : }
      69             : 
      70             : bool DeltaAlgorithm::Search(const changeset_ty &Changes,
      71          10 :                             const changesetlist_ty &Sets,
      72             :                             changeset_ty &Res) {
      73             :   // FIXME: Parallelize.
      74          29 :   for (changesetlist_ty::const_iterator it = Sets.begin(),
      75             :          ie = Sets.end(); it != ie; ++it) {
      76             :     // If the test passes on this subset alone, recurse.
      77             :     if (GetTestResult(*it)) {
      78          29 :       changesetlist_ty Sets;
      79          98 :       Split(*it, Sets);
      80             :       Res = Delta(*it, Sets);
      81          83 :       return true;
      82           4 :     }
      83           4 : 
      84           8 :     // Otherwise, if we have more than two sets, see if test passes on the
      85             :     // complement.
      86             :     if (Sets.size() > 2) {
      87             :       // FIXME: This is really slow.
      88             :       changeset_ty Complement;
      89             :       std::set_difference(
      90         158 :         Changes.begin(), Changes.end(), it->begin(), it->end(),
      91             :         std::insert_iterator<changeset_ty>(Complement, Complement.begin()));
      92             :       if (GetTestResult(Complement)) {
      93             :         changesetlist_ty ComplementSets;
      94             :         ComplementSets.insert(ComplementSets.end(), Sets.begin(), it);
      95          65 :         ComplementSets.insert(ComplementSets.end(), it + 1, Sets.end());
      96          65 :         Res = Delta(Complement, ComplementSets);
      97          10 :         return true;
      98          20 :       }
      99          20 :     }
     100          20 :   }
     101             : 
     102             :   return false;
     103             : }
     104             : 
     105             : DeltaAlgorithm::changeset_ty DeltaAlgorithm::Run(const changeset_ty &Changes) {
     106             :   // Check empty set first to quickly find poor test functions.
     107             :   if (GetTestResult(changeset_ty()))
     108             :     return changeset_ty();
     109          10 : 
     110             :   // Otherwise run the real delta algorithm.
     111          20 :   changesetlist_ty Sets;
     112           0 :   Split(Changes, Sets);
     113             : 
     114             :   return Delta(Changes, Sets);
     115          10 : }

Generated by: LCOV version 1.13