1 /* Execute symbolically all paths of the loop.
2 Copyright (C) 2022-2025 Free Software Foundation, Inc.
3 Contributed by Mariam Arutunian <mariamarutunian@gmail.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef GCC_CRC_VERIFICATION
22 #define GCC_CRC_VERIFICATION
26 #include "coretypes.h"
29 #include "sym-exec/sym-exec-state.h"
31 class crc_symbolic_execution
{
34 /* A vector of states to keep the current state of each executed path. */
35 vec
<state
*> m_states
;
37 /* A vector of final states
38 to keep the returned_value and path conditions. */
39 vec
<state
*> m_final_states
;
41 /* Potential CRC loop, which must be executed symbolically,
42 to check whether it calculates CRC. */
43 class loop
*m_crc_loop
;
45 /* Output CRC from the last block of the loop. */
48 /* Indicates whether the loop execution brought to loop exit.
49 I.e. the condition of the loop is false. */
50 bool m_is_last_iteration
;
52 /* Returns true if the variable is used outside the loop.
53 Otherwise, returns false. */
54 bool is_used_outside_the_loop (tree
);
56 /* Add next basic blocks of the conditional block
57 for the execution path into the stack.
58 If the condition depends on symbolic values, keep both edges.
59 If the condition is true, keep true edge, else - false edge.
60 Returns true if addition succeed. Otherwise - false. */
61 bool add_next_bbs (basic_block
, state
*, auto_vec
<edge
> &);
63 /* Keep conditions depending on symbolic variables in the states. */
64 static bool add_condition (const gcond
*, state
*, state
*);
66 /* The function adds E edge into the STACK if it doesn't have an immediate
69 When loop counter is checked in the if condition,
70 we mustn't continue on real path as we want to stop the execution before
71 the second iteration. */
72 bool add_edge (edge
, auto_vec
<edge
> &);
74 /* Create new state for true and false branch.
75 Keep conditions in new created states. */
76 bool resolve_condition (const gcond
*, auto_vec
<edge
> &);
78 /* If final states are less than two, adds new FINAL_STATE and returns true.
79 Otherwise, returns false.
80 In CRC cases we detect may not occur more than two final states. */
81 bool add_final_state (state
*);
83 /* Keep the state of the executed path in final states. */
86 bool execute_assign_statement (const gassign
*);
88 /* Execute gimple statements of the basic block.
89 Keeping values of variables in the state. */
90 bool execute_bb_gimple_statements (basic_block
, auto_vec
<edge
> &);
92 /* Assign values of phi instruction to its result.
93 Keep updated values in the state. */
94 bool execute_bb_phi_statements (basic_block
, edge
);
96 /* Execute all statements of the basic block.
97 Keeping values of variables in the state. */
98 bool execute_bb_statements (basic_block
, edge
, auto_vec
<edge
> &);
100 /* Create initial state of the loop's header BB variables which have constant
102 If it is the first iteration of the loop, initialise variables with the
103 initial values, otherwise initialise the variable with the value calculated
104 during the previous execution. */
105 state
*create_initial_state (class loop
*);
107 /* Traverse function fun's all paths from the first basic block to the last.
108 Each time iterate loops only once.
109 Symbolically execute statements of each path. */
110 bool traverse_function (function
*);
112 /* Execute the loop, which calculates crc with initial values,
113 to calculate the polynomial. */
114 bool execute_crc_loop (gphi
*, gphi
*, bool);
118 /* Returns calculated polynomial by executing the loop
119 with concrete values.
120 First value of the pair is the tree containing the value of the polynomial,
121 second is the calculated polynomial. The pair may contain nullptr. */
122 std::pair
<tree
, value
*>
123 extract_polynomial (gphi
*, gphi
*, tree
, bool);
125 /* Symbolically execute the CRC loop, doing one iteration. */
126 bool symb_execute_crc_loop ();
128 const vec
<state
*> &get_final_states ()
130 return m_final_states
;
133 bool is_last_iteration ()
135 return m_is_last_iteration
;
138 crc_symbolic_execution (class loop
*loop
, gphi
* output_crc
) :
139 m_crc_loop (loop
), m_output_crc (output_crc
), m_is_last_iteration (false)
141 /* Reserve memory for the vectors of states. */
143 m_states
.create (max_states
);
144 m_final_states
.create (max_states
);
147 ~crc_symbolic_execution ()
150 state::clear_states (&m_states
);
151 state::clear_states (&m_final_states
);
156 /**************************** LFSR MATCHING *********************************/
158 /* Returns true if all states match the LFSR, otherwise - false. */
159 bool all_states_match_lfsr (value
*, bool, tree
, const vec
<state
*> &);
162 #endif //GCC_CRC_VERIFICATION