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 : // Declares the ExplodeBasicBlockSubGraphTransform and
16 : // ExplodeBasicBlocksTransform classes. These transforms separate all
17 : // of the basic-blocks in a subgraph or block-graph respectively, into
18 : // individual code and data blocks. This is primarily a test to exercise
19 : // the basic-block motion machinery.
20 :
21 : #ifndef SYZYGY_PE_TRANSFORMS_EXPLODE_BASIC_BLOCKS_TRANSFORM_H_
22 : #define SYZYGY_PE_TRANSFORMS_EXPLODE_BASIC_BLOCKS_TRANSFORM_H_
23 :
24 : #include "syzygy/block_graph/transforms/iterative_transform.h"
25 : #include "syzygy/block_graph/transforms/named_transform.h"
26 :
27 : namespace pe {
28 : namespace transforms {
29 :
30 : // A BasicBlockSubBlockGraph transform that explodes all basic-blocks in a
31 : // basic_block subgraph into individual code or data blocks.
32 : class ExplodeBasicBlockSubGraphTransform
33 : : public block_graph::transforms::NamedBasicBlockSubGraphTransformImpl<
34 : ExplodeBasicBlockSubGraphTransform> {
35 : public:
36 : typedef block_graph::BlockGraph BlockGraph;
37 : typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph;
38 : typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
39 :
40 : // Initialize a new ExplodeBasicBlockSubGraphTransform instance.
41 : explicit ExplodeBasicBlockSubGraphTransform(bool exclude_padding);
42 :
43 : // @name BasicBlockSubGraphTransformInterface methods.
44 : // @{
45 : virtual bool TransformBasicBlockSubGraph(
46 : const TransformPolicyInterface* policy,
47 : BlockGraph* block_graph,
48 : BasicBlockSubGraph* basic_block_subgraph) override;
49 : // @}
50 :
51 : // The transform name.
52 : static const char kTransformName[];
53 :
54 : // @name Accessors.
55 : // @{
56 E : size_t output_code_blocks() const { return output_code_blocks_; }
57 E : size_t output_data_blocks() const { return output_data_blocks_; }
58 : // @}
59 :
60 : protected:
61 : // A flag for whether padding (and dead code) basic-blocks should be excluded
62 : // when reconstituting the exploded blocks.
63 : bool exclude_padding_;
64 : size_t output_code_blocks_;
65 : size_t output_data_blocks_;
66 :
67 : private:
68 : DISALLOW_COPY_AND_ASSIGN(ExplodeBasicBlockSubGraphTransform);
69 : };
70 :
71 : // A BlockGraph transform that, for every code block which is eligible for
72 : // decomposition to basic-blocks, and transforms every basic-blocks in each
73 : // code block into an individual code or data block.
74 : class ExplodeBasicBlocksTransform
75 : : public block_graph::transforms::IterativeTransformImpl<
76 : ExplodeBasicBlocksTransform> {
77 : public:
78 : typedef block_graph::BlockGraph BlockGraph;
79 : typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
80 :
81 : // Initialize a new ExplodeBasicBlocksTransform instance.
82 : ExplodeBasicBlocksTransform();
83 :
84 : // Explodes each basic code block in @p block referenced by into separate
85 : // blocks, then erases @p block from @p block_graph.
86 : // @param policy The policy object restricting how the transform is applied.
87 : // @param block_graph The block graph being modified.
88 : // @param block The block to explode, this must be in @p block_graph.
89 : // @note This method is required by the IterativeTransformImpl parent class.
90 : bool OnBlock(const TransformPolicyInterface* policy,
91 : BlockGraph* block_graph,
92 : BlockGraph::Block* block);
93 :
94 : // Logs metrics about the performed transform.
95 : // @param policy The policy object restricting how the transform is applied.
96 : // @param block_graph The block graph being modified.
97 : // @param header_block The header block associated with the image.
98 : bool PostBlockGraphIteration(const TransformPolicyInterface* policy,
99 : BlockGraph* block_graph,
100 : BlockGraph::Block* header_block);
101 :
102 : // @name Accessors.
103 : // @{
104 : bool exclude_padding() const { return exclude_padding_; }
105 E : void set_exclude_padding(bool value) { exclude_padding_ = value; }
106 : // @}
107 :
108 : // The transform name.
109 : static const char kTransformName[];
110 :
111 : protected:
112 : // Hooks for unit-testing.
113 : virtual bool SkipThisBlock(const BlockGraph::Block* candidate);
114 :
115 : // A flag for whether padding (and dead code) basic-blocks should be excluded
116 : // when reconstituting the exploded blocks.
117 : bool exclude_padding_;
118 :
119 : // Statistics on blocks encountered and generated.
120 : size_t non_decomposable_code_blocks_;
121 : size_t skipped_code_blocks_;
122 : size_t input_code_blocks_;
123 : size_t output_code_blocks_;
124 : size_t output_data_blocks_;
125 :
126 : private:
127 : DISALLOW_COPY_AND_ASSIGN(ExplodeBasicBlocksTransform);
128 : };
129 :
130 : } // namespace transforms
131 : } // namespace pe
132 :
133 : #endif // SYZYGY_PE_TRANSFORMS_EXPLODE_BASIC_BLOCKS_TRANSFORM_H_
|