2019-01-06 18:11:49 -06:00
/*
* yosys - - Yosys Open SYnthesis Suite
*
* Copyright ( C ) 2018 whitequark < whitequark @ whitequark . org >
*
* Permission to use , copy , modify , and / or distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
*
* THE SOFTWARE IS PROVIDED " AS IS " AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS . IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL , DIRECT , INDIRECT , OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE , DATA OR PROFITS , WHETHER IN AN
* ACTION OF CONTRACT , NEGLIGENCE OR OTHER TORTIOUS ACTION , ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE .
*
*/
# include "kernel/yosys.h"
2020-08-26 12:29:32 -05:00
# include "backends/rtlil/rtlil_backend.h"
2019-01-06 18:11:49 -06:00
USING_YOSYS_NAMESPACE
2020-08-26 12:29:32 -05:00
using namespace RTLIL_BACKEND ;
2019-01-06 18:11:49 -06:00
PRIVATE_NAMESPACE_BEGIN
struct BugpointPass : public Pass {
BugpointPass ( ) : Pass ( " bugpoint " , " minimize testcases " ) { }
2020-06-18 18:34:52 -05:00
void help ( ) override
2019-01-06 18:11:49 -06:00
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log ( " \n " ) ;
2020-12-07 02:42:45 -06:00
log ( " bugpoint [options] [-script <filename> | -command \" <command> \" ] \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " \n " ) ;
2020-04-23 14:16:55 -05:00
log ( " This command minimizes the current design that is known to crash Yosys with the \n " ) ;
log ( " given script into a smaller testcase. It does this by removing an arbitrary part \n " ) ;
log ( " of the design and recursively invokes a new Yosys process with this modified design \n " ) ;
log ( " and the same script, repeating these steps while it can find a smaller design that \n " ) ;
log ( " still causes a crash. Once this command finishes, it replaces the current design \n " ) ;
log ( " with the smallest testcase it was able to produce. \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " \n " ) ;
2020-12-07 02:42:45 -06:00
log ( " -script <filename> | -command \" <command> \" \n " ) ;
log ( " use this script file or command to crash Yosys. required. \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " \n " ) ;
log ( " -yosys <filename> \n " ) ;
log ( " use this Yosys binary. if not specified, `yosys` is used. \n " ) ;
log ( " \n " ) ;
2020-12-07 02:23:32 -06:00
log ( " -grep \" <string> \" \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " only consider crashes that place this string in the log file. \n " ) ;
log ( " \n " ) ;
log ( " -fast \n " ) ;
2019-07-09 04:08:38 -05:00
log ( " run `proc_clean; clean -purge` after each minimization step. converges \n " ) ;
log ( " faster, but produces larger testcases, and may fail to produce any \n " ) ;
log ( " testcase at all if the crash is related to dangling wires. \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " \n " ) ;
log ( " -clean \n " ) ;
2019-07-09 04:08:38 -05:00
log ( " run `proc_clean; clean -purge` before checking testcase and after \n " ) ;
log ( " finishing. produces smaller and more useful testcases, but may fail to \n " ) ;
log ( " produce any testcase at all if the crash is related to dangling wires. \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " \n " ) ;
2020-04-23 14:16:55 -05:00
log ( " It is possible to constrain which parts of the design will be considered for \n " ) ;
log ( " removal. Unless one or more of the following options are specified, all parts \n " ) ;
log ( " will be considered. \n " ) ;
log ( " \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " -modules \n " ) ;
2020-04-24 15:26:04 -05:00
log ( " try to remove modules. modules with a (* bugpoint_keep *) attribute \n " ) ;
log ( " will be skipped. \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " \n " ) ;
log ( " -ports \n " ) ;
2020-04-24 15:26:04 -05:00
log ( " try to remove module ports. ports with a (* bugpoint_keep *) attribute \n " ) ;
log ( " will be skipped (useful for clocks, resets, etc.) \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " \n " ) ;
log ( " -cells \n " ) ;
2020-04-24 15:26:04 -05:00
log ( " try to remove cells. cells with a (* bugpoint_keep *) attribute will \n " ) ;
log ( " be skipped. \n " ) ;
2019-01-06 18:11:49 -06:00
log ( " \n " ) ;
log ( " -connections \n " ) ;
log ( " try to reconnect ports to 'x. \n " ) ;
log ( " \n " ) ;
2020-12-07 02:27:25 -06:00
log ( " -processes \n " ) ;
log ( " try to remove processes. processes with a (* bugpoint_keep *) attribute \n " ) ;
log ( " will be skipped. \n " ) ;
log ( " \n " ) ;
2019-07-09 04:08:38 -05:00
log ( " -assigns \n " ) ;
log ( " try to remove process assigns from cases. \n " ) ;
log ( " \n " ) ;
log ( " -updates \n " ) ;
log ( " try to remove process updates from syncs. \n " ) ;
log ( " \n " ) ;
2019-01-06 18:11:49 -06:00
}
2020-12-07 02:42:45 -06:00
bool run_yosys ( RTLIL : : Design * design , string yosys_cmd , string yosys_arg )
2019-01-06 18:11:49 -06:00
{
design - > sort ( ) ;
std : : ofstream f ( " bugpoint-case.il " ) ;
2020-08-26 12:29:32 -05:00
RTLIL_BACKEND : : dump_design ( f , design , /*only_selected=*/ false , /*flag_m=*/ true , /*flag_n=*/ false ) ;
2019-01-06 18:11:49 -06:00
f . close ( ) ;
2020-12-07 02:42:45 -06:00
string yosys_cmdline = stringf ( " %s -qq -L bugpoint-case.log %s bugpoint-case.il " , yosys_cmd . c_str ( ) , yosys_arg . c_str ( ) ) ;
2019-01-07 02:45:21 -06:00
return run_command ( yosys_cmdline ) = = 0 ;
2019-01-06 18:11:49 -06:00
}
bool check_logfile ( string grep )
{
if ( grep . empty ( ) )
return true ;
2020-12-07 02:23:32 -06:00
if ( grep . size ( ) > 2 & & grep . front ( ) = = ' " ' & & grep . back ( ) = = ' " ' )
grep = grep . substr ( 1 , grep . size ( ) - 2 ) ;
2019-01-06 18:11:49 -06:00
std : : ifstream f ( " bugpoint-case.log " ) ;
while ( ! f . eof ( ) )
{
string line ;
getline ( f , line ) ;
if ( line . find ( grep ) ! = std : : string : : npos )
return true ;
}
return false ;
}
RTLIL : : Design * clean_design ( RTLIL : : Design * design , bool do_clean = true , bool do_delete = false )
{
if ( ! do_clean )
return design ;
RTLIL : : Design * design_copy = new RTLIL : : Design ;
2020-04-06 03:35:09 -05:00
for ( auto module : design - > modules ( ) )
design_copy - > add ( module - > clone ( ) ) ;
2019-07-09 04:08:38 -05:00
Pass : : call ( design_copy , " proc_clean -quiet " ) ;
2019-01-06 18:11:49 -06:00
Pass : : call ( design_copy , " clean -purge " ) ;
if ( do_delete )
delete design ;
return design_copy ;
}
2020-12-07 03:24:35 -06:00
RTLIL : : Design * simplify_something ( RTLIL : : Design * design , int & seed , bool stage2 , bool modules , bool ports , bool cells , bool connections , bool processes , bool assigns , bool updates , bool wires )
2019-01-06 18:11:49 -06:00
{
RTLIL : : Design * design_copy = new RTLIL : : Design ;
2020-04-06 03:35:09 -05:00
for ( auto module : design - > modules ( ) )
design_copy - > add ( module - > clone ( ) ) ;
2019-01-06 18:11:49 -06:00
int index = 0 ;
if ( modules )
{
2020-04-21 12:56:28 -05:00
Module * removed_module = nullptr ;
2020-04-06 03:35:09 -05:00
for ( auto module : design_copy - > modules ( ) )
2019-01-06 18:11:49 -06:00
{
2020-04-06 03:35:09 -05:00
if ( module - > get_blackbox_attribute ( ) )
2019-01-06 18:11:49 -06:00
continue ;
2020-04-24 15:26:04 -05:00
if ( module - > get_bool_attribute ( ID : : bugpoint_keep ) )
continue ;
2019-01-06 18:11:49 -06:00
if ( index + + = = seed )
{
2020-04-24 15:41:19 -05:00
log_header ( design , " Trying to remove module %s. \n " , log_id ( module ) ) ;
2020-04-21 12:56:28 -05:00
removed_module = module ;
break ;
2019-01-06 18:11:49 -06:00
}
}
2020-04-21 12:56:28 -05:00
if ( removed_module ) {
design_copy - > remove ( removed_module ) ;
return design_copy ;
}
2019-01-06 18:11:49 -06:00
}
if ( ports )
{
for ( auto mod : design_copy - > modules ( ) )
{
2019-04-18 10:42:12 -05:00
if ( mod - > get_blackbox_attribute ( ) )
2019-01-06 18:11:49 -06:00
continue ;
for ( auto wire : mod - > wires ( ) )
{
2020-04-24 13:17:09 -05:00
if ( ! wire - > port_id )
continue ;
2020-04-02 11:51:32 -05:00
if ( ! stage2 & & wire - > get_bool_attribute ( ID ( $ bugpoint ) ) )
2019-01-06 18:11:49 -06:00
continue ;
2020-04-24 15:26:04 -05:00
if ( wire - > get_bool_attribute ( ID : : bugpoint_keep ) )
2020-04-24 13:17:09 -05:00
continue ;
if ( index + + = = seed )
2019-01-06 18:11:49 -06:00
{
2020-04-24 15:41:19 -05:00
log_header ( design , " Trying to remove module port %s. \n " , log_id ( wire ) ) ;
2020-04-24 13:17:09 -05:00
wire - > port_input = wire - > port_output = false ;
mod - > fixup_ports ( ) ;
return design_copy ;
2019-01-06 18:11:49 -06:00
}
}
}
}
if ( cells )
{
for ( auto mod : design_copy - > modules ( ) )
{
2019-04-18 10:42:12 -05:00
if ( mod - > get_blackbox_attribute ( ) )
2019-01-06 18:11:49 -06:00
continue ;
2020-04-21 12:56:28 -05:00
Cell * removed_cell = nullptr ;
2020-04-06 03:35:09 -05:00
for ( auto cell : mod - > cells ( ) )
2019-01-06 18:11:49 -06:00
{
2020-04-24 15:26:04 -05:00
if ( cell - > get_bool_attribute ( ID : : bugpoint_keep ) )
continue ;
2019-01-06 18:11:49 -06:00
if ( index + + = = seed )
{
2020-04-24 15:41:19 -05:00
log_header ( design , " Trying to remove cell %s.%s. \n " , log_id ( mod ) , log_id ( cell ) ) ;
2020-04-21 12:56:28 -05:00
removed_cell = cell ;
break ;
2019-01-06 18:11:49 -06:00
}
}
2020-04-21 12:56:28 -05:00
if ( removed_cell ) {
mod - > remove ( removed_cell ) ;
return design_copy ;
}
2019-01-06 18:11:49 -06:00
}
}
if ( connections )
{
for ( auto mod : design_copy - > modules ( ) )
{
2019-04-18 10:42:12 -05:00
if ( mod - > get_blackbox_attribute ( ) )
2019-01-06 18:11:49 -06:00
continue ;
for ( auto cell : mod - > cells ( ) )
{
for ( auto it : cell - > connections_ )
{
RTLIL : : SigSpec port = cell - > getPort ( it . first ) ;
bool is_undef = port . is_fully_undef ( ) ;
bool is_port = port . is_wire ( ) & & ( port . as_wire ( ) - > port_input | | port . as_wire ( ) - > port_output ) ;
if ( is_undef | | ( ! stage2 & & is_port ) )
continue ;
if ( index + + = = seed )
{
2020-04-24 15:41:19 -05:00
log_header ( design , " Trying to remove cell port %s.%s.%s. \n " , log_id ( mod ) , log_id ( cell ) , log_id ( it . first ) ) ;
2019-01-06 18:11:49 -06:00
RTLIL : : SigSpec port_x ( State : : Sx , port . size ( ) ) ;
cell - > unsetPort ( it . first ) ;
cell - > setPort ( it . first , port_x ) ;
return design_copy ;
}
if ( ! stage2 & & ( cell - > input ( it . first ) | | cell - > output ( it . first ) ) & & index + + = = seed )
{
2020-04-24 15:41:19 -05:00
log_header ( design , " Trying to expose cell port %s.%s.%s as module port. \n " , log_id ( mod ) , log_id ( cell ) , log_id ( it . first ) ) ;
2019-01-06 18:11:49 -06:00
RTLIL : : Wire * wire = mod - > addWire ( NEW_ID , port . size ( ) ) ;
2020-04-02 11:51:32 -05:00
wire - > set_bool_attribute ( ID ( $ bugpoint ) ) ;
2019-01-06 18:11:49 -06:00
wire - > port_input = cell - > input ( it . first ) ;
wire - > port_output = cell - > output ( it . first ) ;
cell - > unsetPort ( it . first ) ;
cell - > setPort ( it . first , wire ) ;
mod - > fixup_ports ( ) ;
return design_copy ;
}
}
}
}
}
2020-12-07 02:27:25 -06:00
if ( processes )
{
for ( auto mod : design_copy - > modules ( ) )
{
if ( mod - > get_blackbox_attribute ( ) )
continue ;
RTLIL : : IdString removed_process ;
for ( auto process : mod - > processes )
{
if ( process . second - > get_bool_attribute ( ID : : bugpoint_keep ) )
continue ;
if ( index + + = = seed )
{
log_header ( design , " Trying to remove process %s.%s. \n " , log_id ( mod ) , log_id ( process . first ) ) ;
removed_process = process . first ;
break ;
}
}
if ( ! removed_process . empty ( ) ) {
delete mod - > processes [ removed_process ] ;
mod - > processes . erase ( removed_process ) ;
return design_copy ;
}
}
}
2019-07-09 04:08:38 -05:00
if ( assigns )
{
for ( auto mod : design_copy - > modules ( ) )
{
if ( mod - > get_blackbox_attribute ( ) )
continue ;
for ( auto & pr : mod - > processes )
{
vector < RTLIL : : CaseRule * > cases = { & pr . second - > root_case } ;
while ( ! cases . empty ( ) )
{
RTLIL : : CaseRule * cs = cases [ 0 ] ;
cases . erase ( cases . begin ( ) ) ;
for ( auto it = cs - > actions . begin ( ) ; it ! = cs - > actions . end ( ) ; + + it )
{
if ( index + + = = seed )
{
2020-04-24 15:41:19 -05:00
log_header ( design , " Trying to remove assign %s %s in %s.%s. \n " , log_signal ( it - > first ) , log_signal ( it - > second ) , log_id ( mod ) , log_id ( pr . first ) ) ;
2019-07-09 04:08:38 -05:00
cs - > actions . erase ( it ) ;
return design_copy ;
}
}
for ( auto & sw : cs - > switches )
cases . insert ( cases . end ( ) , sw - > cases . begin ( ) , sw - > cases . end ( ) ) ;
}
}
}
}
if ( updates )
{
for ( auto mod : design_copy - > modules ( ) )
{
if ( mod - > get_blackbox_attribute ( ) )
continue ;
for ( auto & pr : mod - > processes )
{
for ( auto & sy : pr . second - > syncs )
{
for ( auto it = sy - > actions . begin ( ) ; it ! = sy - > actions . end ( ) ; + + it )
{
if ( index + + = = seed )
{
2020-04-24 15:41:19 -05:00
log_header ( design , " Trying to remove sync %s update %s %s in %s.%s. \n " , log_signal ( sy - > signal ) , log_signal ( it - > first ) , log_signal ( it - > second ) , log_id ( mod ) , log_id ( pr . first ) ) ;
2019-07-09 04:08:38 -05:00
sy - > actions . erase ( it ) ;
return design_copy ;
}
}
2021-02-22 17:21:46 -06:00
int i = 0 ;
for ( auto it = sy - > mem_write_actions . begin ( ) ; it ! = sy - > mem_write_actions . end ( ) ; + + it , + + i )
{
if ( index + + = = seed )
{
log_header ( design , " Trying to remove sync %s memwr %s %s %s %s in %s.%s. \n " , log_signal ( sy - > signal ) , log_id ( it - > memid ) , log_signal ( it - > address ) , log_signal ( it - > data ) , log_signal ( it - > enable ) , log_id ( mod ) , log_id ( pr . first ) ) ;
sy - > mem_write_actions . erase ( it ) ;
// Remove the bit for removed action from other actions' priority masks.
for ( auto it2 = sy - > mem_write_actions . begin ( ) ; it2 ! = sy - > mem_write_actions . end ( ) ; + + it2 ) {
auto & mask = it2 - > priority_mask ;
if ( GetSize ( mask ) > i ) {
mask . bits . erase ( mask . bits . begin ( ) + i ) ;
}
}
return design_copy ;
}
}
2019-07-09 04:08:38 -05:00
}
}
}
}
2020-12-07 03:24:35 -06:00
if ( wires )
{
for ( auto mod : design_copy - > modules ( ) )
{
if ( mod - > get_blackbox_attribute ( ) )
continue ;
Wire * removed_wire = nullptr ;
for ( auto wire : mod - > wires ( ) )
{
if ( wire - > get_bool_attribute ( ID : : bugpoint_keep ) )
continue ;
if ( wire - > name . begins_with ( " $delete_wire " ) )
continue ;
if ( index + + = = seed )
{
log_header ( design , " Trying to remove wire %s.%s. \n " , log_id ( mod ) , log_id ( wire ) ) ;
removed_wire = wire ;
break ;
}
}
if ( removed_wire ) {
mod - > remove ( { removed_wire } ) ;
return design_copy ;
}
}
}
2020-04-06 03:35:09 -05:00
return nullptr ;
2019-01-06 18:11:49 -06:00
}
2020-06-18 18:34:52 -05:00
void execute ( std : : vector < std : : string > args , RTLIL : : Design * design ) override
2019-01-06 18:11:49 -06:00
{
2020-12-07 02:42:45 -06:00
string yosys_cmd = " yosys " , yosys_arg , grep ;
2019-01-06 18:11:49 -06:00
bool fast = false , clean = false ;
2020-12-07 03:24:35 -06:00
bool modules = false , ports = false , cells = false , connections = false , processes = false , assigns = false , updates = false , wires = false , has_part = false ;
2019-01-06 18:11:49 -06:00
2020-04-24 13:17:09 -05:00
log_header ( design , " Executing BUGPOINT pass (minimize testcases). \n " ) ;
log_push ( ) ;
2019-01-06 18:11:49 -06:00
size_t argidx ;
for ( argidx = 1 ; argidx < args . size ( ) ; argidx + + )
{
if ( args [ argidx ] = = " -yosys " & & argidx + 1 < args . size ( ) ) {
yosys_cmd = args [ + + argidx ] ;
continue ;
}
if ( args [ argidx ] = = " -script " & & argidx + 1 < args . size ( ) ) {
2020-12-07 02:42:45 -06:00
if ( ! yosys_arg . empty ( ) )
log_cmd_error ( " A -script or -command option can be only provided once! \n " ) ;
yosys_arg = stringf ( " -s %s " , args [ + + argidx ] . c_str ( ) ) ;
continue ;
}
if ( args [ argidx ] = = " -command " & & argidx + 1 < args . size ( ) ) {
if ( ! yosys_arg . empty ( ) )
log_cmd_error ( " A -script or -command option can be only provided once! \n " ) ;
yosys_arg = stringf ( " -p %s " , args [ + + argidx ] . c_str ( ) ) ;
2019-01-06 18:11:49 -06:00
continue ;
}
if ( args [ argidx ] = = " -grep " & & argidx + 1 < args . size ( ) ) {
grep = args [ + + argidx ] ;
continue ;
}
if ( args [ argidx ] = = " -fast " ) {
fast = true ;
continue ;
}
if ( args [ argidx ] = = " -clean " ) {
clean = true ;
continue ;
}
if ( args [ argidx ] = = " -modules " ) {
modules = true ;
has_part = true ;
continue ;
}
if ( args [ argidx ] = = " -ports " ) {
ports = true ;
has_part = true ;
continue ;
}
if ( args [ argidx ] = = " -cells " ) {
cells = true ;
has_part = true ;
continue ;
}
if ( args [ argidx ] = = " -connections " ) {
connections = true ;
has_part = true ;
continue ;
}
2020-12-07 02:27:25 -06:00
if ( args [ argidx ] = = " -processes " ) {
processes = true ;
has_part = true ;
continue ;
}
2019-07-09 04:08:38 -05:00
if ( args [ argidx ] = = " -assigns " ) {
assigns = true ;
has_part = true ;
continue ;
}
if ( args [ argidx ] = = " -updates " ) {
updates = true ;
has_part = true ;
continue ;
}
2020-12-07 03:24:35 -06:00
if ( args [ argidx ] = = " -wires " ) {
wires = true ;
has_part = true ;
continue ;
}
2019-01-06 18:11:49 -06:00
break ;
}
extra_args ( args , argidx , design ) ;
2020-12-07 02:42:45 -06:00
if ( yosys_arg . empty ( ) )
log_cmd_error ( " Missing -script or -command option. \n " ) ;
2019-05-13 11:55:15 -05:00
2019-01-06 18:11:49 -06:00
if ( ! has_part )
{
modules = true ;
ports = true ;
cells = true ;
connections = true ;
2020-12-07 02:27:25 -06:00
processes = true ;
2019-07-09 04:08:38 -05:00
assigns = true ;
updates = true ;
2020-12-07 03:24:35 -06:00
wires = true ;
2019-01-06 18:11:49 -06:00
}
if ( ! design - > full_selection ( ) )
log_cmd_error ( " This command only operates on fully selected designs! \n " ) ;
RTLIL : : Design * crashing_design = clean_design ( design , clean ) ;
2020-12-07 02:42:45 -06:00
if ( run_yosys ( crashing_design , yosys_cmd , yosys_arg ) )
log_cmd_error ( " The provided script file or command and Yosys binary do not crash on this design! \n " ) ;
2019-01-06 18:11:49 -06:00
if ( ! check_logfile ( grep ) )
log_cmd_error ( " The provided grep string is not found in the log file! \n " ) ;
2019-05-05 03:00:27 -05:00
int seed = 0 ;
2019-01-06 18:11:49 -06:00
bool found_something = false , stage2 = false ;
while ( true )
{
2020-12-07 03:24:35 -06:00
if ( RTLIL : : Design * simplified = simplify_something ( crashing_design , seed , stage2 , modules , ports , cells , connections , processes , assigns , updates , wires ) )
2019-01-06 18:11:49 -06:00
{
simplified = clean_design ( simplified , fast , /*do_delete=*/ true ) ;
bool crashes ;
if ( clean )
{
RTLIL : : Design * testcase = clean_design ( simplified ) ;
2020-12-07 02:42:45 -06:00
crashes = ! run_yosys ( testcase , yosys_cmd , yosys_arg ) ;
2019-01-06 18:11:49 -06:00
delete testcase ;
}
else
{
2020-12-07 02:42:45 -06:00
crashes = ! run_yosys ( simplified , yosys_cmd , yosys_arg ) ;
2019-01-06 18:11:49 -06:00
}
if ( crashes & & check_logfile ( grep ) )
{
log ( " Testcase crashes. \n " ) ;
if ( crashing_design ! = design )
delete crashing_design ;
crashing_design = simplified ;
found_something = true ;
}
else
{
log ( " Testcase does not crash. \n " ) ;
delete simplified ;
seed + + ;
}
}
else
{
seed = 0 ;
if ( found_something )
found_something = false ;
else
{
if ( ! stage2 )
{
log ( " Demoting introduced module ports. \n " ) ;
stage2 = true ;
}
else
{
log ( " Simplifications exhausted. \n " ) ;
break ;
}
}
}
}
if ( crashing_design ! = design )
{
Pass : : call ( design , " design -reset " ) ;
crashing_design = clean_design ( crashing_design , clean , /*do_delete=*/ true ) ;
2020-04-06 03:35:09 -05:00
for ( auto module : crashing_design - > modules ( ) )
design - > add ( module - > clone ( ) ) ;
2019-01-06 18:11:49 -06:00
delete crashing_design ;
}
2020-04-24 13:17:09 -05:00
log_pop ( ) ;
2019-01-06 18:11:49 -06:00
}
} BugpointPass ;
PRIVATE_NAMESPACE_END