Coverage for /Syzygy/block_graph/transform.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
88.2%67760.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/block_graph/transform.h"
  16    :  
  17    :  #include "syzygy/block_graph/basic_block_decomposer.h"
  18    :  #include "syzygy/block_graph/block_builder.h"
  19    :  #include "syzygy/block_graph/block_util.h"
  20    :  
  21    :  namespace block_graph {
  22    :  
  23    :  bool ApplyBlockGraphTransform(BlockGraphTransformInterface* transform,
  24    :                                const TransformPolicyInterface* policy,
  25    :                                BlockGraph* block_graph,
  26  E :                                BlockGraph::Block* header_block) {
  27  E :    DCHECK(transform != NULL);
  28  E :    DCHECK(transform->name() != NULL);
  29  E :    DCHECK(policy != NULL);
  30  E :    DCHECK_GT(strlen(transform->name()), 0u);
  31  E :    DCHECK(block_graph != NULL);
  32  E :    DCHECK(header_block != NULL);
  33    :  
  34    :    // Get the ID of the header block. As a sanity check we want to ensure
  35    :    // that it still exists after the transform.
  36  E :    BlockGraph::BlockId header_block_id = header_block->id();
  37    :  
  38  E :    if (!transform->TransformBlockGraph(policy, block_graph, header_block)) {
  39  E :      LOG(ERROR) << "Transform \"" << transform->name() << "\" failed.";
  40  E :      return false;
  41    :    }
  42    :  
  43    :    // Ensure that the header block still exists. If it was changed, it needs
  44    :    // to have been changed in place.
  45  E :    BlockGraph::Block* block = block_graph->GetBlockById(header_block_id);
  46  E :    if (block == NULL) {
  47  E :      LOG(ERROR) << "Header block not found after \"" << transform->name()
  48    :                 << "\" transform.";
  49  E :      return false;
  50    :    }
  51  E :    DCHECK_EQ(header_block, block);
  52    :  
  53  E :    return true;
  54  E :  }
  55    :  
  56    :  bool ApplyBlockGraphTransforms(
  57    :      const std::vector<BlockGraphTransformInterface*>& transforms,
  58    :      const TransformPolicyInterface* policy,
  59    :      BlockGraph* block_graph,
  60  E :      BlockGraph::Block* header_block) {
  61  E :    DCHECK_NE(reinterpret_cast<TransformPolicyInterface*>(NULL), policy);
  62  E :    DCHECK_NE(reinterpret_cast<BlockGraph*>(NULL), block_graph);
  63  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), header_block);
  64    :  
  65    :    // Apply the transforms sequentially.
  66  E :    for (size_t i = 0; i < transforms.size(); ++i) {
  67    :      if (!ApplyBlockGraphTransform(transforms[i],
  68    :                                    policy,
  69    :                                    block_graph,
  70  E :                                    header_block)) {
  71  E :        return false;
  72    :      }
  73  E :    }
  74    :  
  75  E :    return true;
  76  E :  }
  77    :  
  78    :  bool ApplyBasicBlockSubGraphTransform(
  79    :      BasicBlockSubGraphTransformInterface* transform,
  80    :      const TransformPolicyInterface* policy,
  81    :      BlockGraph* block_graph,
  82    :      BlockGraph::Block* block,
  83  E :      BlockVector* new_blocks) {
  84  E :    DCHECK(transform != NULL);
  85  E :    DCHECK(policy != NULL);
  86  E :    DCHECK(block_graph != NULL);
  87  E :    DCHECK(block != NULL);
  88  E :    DCHECK_EQ(BlockGraph::CODE_BLOCK, block->type());
  89  E :    DCHECK(policy->BlockIsSafeToBasicBlockDecompose(block));
  90    :  
  91    :    // Decompose block to basic blocks.
  92  E :    BasicBlockSubGraph subgraph;
  93  E :    BasicBlockDecomposer bb_decomposer(block, &subgraph);
  94  E :    if (!bb_decomposer.Decompose()) {
  95    :      // If the failure is due to unsupported instructions then simply mark the
  96    :      // block as undecomposable so it won't be processed again.
  97  i :      if (bb_decomposer.contains_unsupported_instructions()) {
  98  i :        VLOG(1) << "Block contains unsupported instruction(s): "
  99    :                << BlockInfo(block);
 100  i :        block->set_attribute(BlockGraph::UNSUPPORTED_INSTRUCTIONS);
 101  i :        return true;
 102    :      }
 103    :  
 104  i :      return false;
 105    :    }
 106    :  
 107    :    // Call the transform.
 108  E :    if (!transform->TransformBasicBlockSubGraph(policy, block_graph, &subgraph))
 109  E :      return false;
 110    :  
 111    :    // Update the block-graph post transform.
 112  E :    BlockBuilder builder(block_graph);
 113  E :    if (!builder.Merge(&subgraph))
 114  i :      return false;
 115    :  
 116  E :    if (new_blocks != NULL) {
 117    :      new_blocks->assign(builder.new_blocks().begin(),
 118  E :                         builder.new_blocks().end());
 119    :    }
 120    :  
 121  E :    return true;
 122  E :  }
 123    :  
 124    :  bool ApplyBasicBlockSubGraphTransforms(
 125    :      const std::vector<BasicBlockSubGraphTransformInterface*>& transforms,
 126    :      const TransformPolicyInterface* policy,
 127    :      BlockGraph* block_graph,
 128    :      BlockGraph::Block* block,
 129  E :      BlockVector* new_blocks) {
 130  E :    DCHECK(policy != NULL);
 131  E :    DCHECK(block_graph != NULL);
 132  E :    DCHECK(block != NULL);
 133  E :    DCHECK_EQ(BlockGraph::CODE_BLOCK, block->type());
 134  E :    DCHECK(policy->BlockIsSafeToBasicBlockDecompose(block));
 135    :  
 136    :    // Decompose block to basic blocks.
 137  E :    BasicBlockSubGraph subgraph;
 138  E :    BasicBlockDecomposer bb_decomposer(block, &subgraph);
 139  E :    if (!bb_decomposer.Decompose())
 140  i :      return false;
 141    :  
 142    :    // Call the transforms.
 143    :    std::vector<BasicBlockSubGraphTransformInterface*>::const_iterator it =
 144  E :        transforms.begin();
 145  E :    for (; it != transforms.end(); ++it) {
 146  E :      BasicBlockSubGraphTransformInterface* transform = *it;
 147  E :      DCHECK(transform != NULL);
 148  E :      if (!transform->TransformBasicBlockSubGraph(policy, block_graph, &subgraph))
 149  i :        return false;
 150  E :    }
 151    :  
 152    :    // Update the block-graph post transform.
 153  E :    BlockBuilder builder(block_graph);
 154  E :    if (!builder.Merge(&subgraph))
 155  i :      return false;
 156    :  
 157  E :    if (new_blocks != NULL) {
 158    :      new_blocks->assign(builder.new_blocks().begin(),
 159  E :                         builder.new_blocks().end());
 160    :    }
 161    :  
 162  E :    return true;
 163  E :  }
 164    :  
 165    :  }  // namespace block_graph

Coverage information generated Thu Jan 14 17:40:38 2016.