diff --git a/src/AbsRndNumGenerator.cpp b/src/AbsRndNumGenerator.cpp index 345d01ec9..4c6694929 100644 --- a/src/AbsRndNumGenerator.cpp +++ b/src/AbsRndNumGenerator.cpp @@ -39,7 +39,6 @@ #include "DefaultRndNumGenerator.h" #include "DFSRndNumGenerator.h" -#include "SimpleDeltaRndNumGenerator.h" using namespace std; @@ -80,9 +79,6 @@ AbsRndNumGenerator::make_rndnum_generator(RNDNUM_GENERATOR impl, const unsigned case rDFSRndNumGenerator: rImpl = DFSRndNumGenerator::make_rndnum_generator(); break; - case rSimpleDeltaRndNumGenerator: - rImpl = SimpleDeltaRndNumGenerator::make_rndnum_generator(seed); - break; default: assert(!"unknown random generator"); break; diff --git a/src/AbsRndNumGenerator.h b/src/AbsRndNumGenerator.h index 7ab23fc81..3a4d2ca96 100644 --- a/src/AbsRndNumGenerator.h +++ b/src/AbsRndNumGenerator.h @@ -38,10 +38,9 @@ class Filter; enum RNDNUM_GENERATOR { rDefaultRndNumGenerator = 0, rDFSRndNumGenerator, - rSimpleDeltaRndNumGenerator, }; -#define MAX_RNDNUM_GENERATOR (rSimpleDeltaRndNumGenerator+1) +#define MAX_RNDNUM_GENERATOR (rDFSRndNumGenerator+1) // I could make AbsRndNumGenerator not pure, but want to force each subclass implement // it's own member functions, in case of forgetting something. diff --git a/src/ArrayVariable.cpp b/src/ArrayVariable.cpp index 9d934b244..4c153608f 100644 --- a/src/ArrayVariable.cpp +++ b/src/ArrayVariable.cpp @@ -448,7 +448,6 @@ bool ArrayVariable::no_loop_initializer(void) const { // don't use loop initializer if we are doing test case reduction - // if (CGOptions::get_reducer()) return true; // can not use loop initializer if either array member are structs, or they are constants, or it has > 1 initial values return type->eType==eStruct || type->eType==eUnion || is_const() || is_global() || (init_values.size() > 0); } diff --git a/src/CGOptions.cpp b/src/CGOptions.cpp index 6c9d3dcad..51e04a293 100644 --- a/src/CGOptions.cpp +++ b/src/CGOptions.cpp @@ -43,13 +43,11 @@ #include "Bookkeeper.h" #include "CompatibleChecker.h" #include "PartialExpander.h" -#include "DeltaMonitor.h" #include "Probabilities.h" #include "OutputMgr.h" #include "StringUtils.h" using namespace std; -Reducer* CGOptions::reducer_ = NULL; vector CGOptions::safe_math_wrapper_ids_; map CGOptions::enabled_builtin_kinds_; int CGOptions::int_size_ = 0; @@ -114,9 +112,7 @@ DEFINE_GETTER_SETTER_BOOL(dfs_exhaustive) DEFINE_GETTER_SETTER_STRING_REF(dfs_debug_sequence) DEFINE_GETTER_SETTER_INT (max_exhaustive_depth) DEFINE_GETTER_SETTER_BOOL(compact_output) -DEFINE_GETTER_SETTER_BOOL(msp) DEFINE_GETTER_SETTER_INT(func1_max_params) -DEFINE_GETTER_SETTER_BOOL(splat) DEFINE_GETTER_SETTER_BOOL(klee) DEFINE_GETTER_SETTER_BOOL(crest) DEFINE_GETTER_SETTER_BOOL(ccomp) @@ -240,9 +236,7 @@ CGOptions::set_default_settings(void) use_struct(true); use_union(true); compact_output(false); - msp(false); func1_max_params(CGOPTIONS_DEFAULT_FUNC1_MAX_PARAMS); - splat(false); klee(false); crest(false); ccomp(false); @@ -451,7 +445,7 @@ bool CGOptions::resolve_exhaustive_options() } if (CGOptions::has_extension_support()) { - conflict_msg_ = "exhaustive mode doesn't support splat|klee|crest|coverage-test extension"; + conflict_msg_ = "exhaustive mode doesn't support klee|crest|coverage-test extension"; return true; } // For effeciency reason, we fix the size of struct fields @@ -476,9 +470,6 @@ bool CGOptions::has_extension_conflict() { int count = 0; - - if (CGOptions::splat()) - count++; if (CGOptions::klee()) count++; if (CGOptions::crest()) @@ -487,7 +478,7 @@ CGOptions::has_extension_conflict() count++; if (count > 1) { - conflict_msg_ = "You could only specify --splat or --klee or --crest or --coverage-test"; + conflict_msg_ = "You could only specify --klee or --crest or --coverage-test"; return true; } return false; @@ -496,7 +487,7 @@ CGOptions::has_extension_conflict() bool CGOptions::has_extension_support() { - return (CGOptions::splat() || CGOptions::klee() + return (CGOptions::klee() || CGOptions::crest() || CGOptions::coverage_test()); } @@ -559,23 +550,6 @@ CGOptions::has_conflict(void) } } - if (!CGOptions::delta_monitor().empty()) { - string msg; - if (!DeltaMonitor::init(msg, CGOptions::delta_monitor(), CGOptions::delta_output())) { - conflict_msg_ = msg; - return true; - } - } - - if (!CGOptions::go_delta().empty()) { - string msg; - if (!DeltaMonitor::init_for_running(msg, CGOptions::go_delta(), CGOptions::delta_output(), - CGOptions::delta_input(), CGOptions::no_delta_reduction())) { - conflict_msg_ = msg; - return true; - } - } - if (!CGOptions::lang_cpp() && CGOptions::cpp11()) { conflict_msg_ = "--cpp11 option makes sense only with --lang-cpp option enabled."; return true; diff --git a/src/CGOptions.h b/src/CGOptions.h index ee7bb5ee4..38a1ffbd7 100644 --- a/src/CGOptions.h +++ b/src/CGOptions.h @@ -33,7 +33,6 @@ #include #include #include -#include "Reducer.h" using namespace std; /////////////////////////////////////////////////////////////////////////////// @@ -178,15 +177,9 @@ class CGOptions { static bool compact_output(void); static bool compact_output(bool p); - static bool msp(void); - static bool msp(bool p); - static int func1_max_params(void); static int func1_max_params(int p); - static bool splat(void); - static bool splat(bool p); - static bool klee(void); static bool klee(bool p); @@ -382,9 +375,6 @@ class CGOptions { static int max_array_num_in_loop(); static int max_array_num_in_loop(int p); - static void init_reducer(std::string fname) { reducer_ = new Reducer(fname);} - static Reducer* get_reducer(void) { return reducer_; } - static bool x86_64(); static bool identify_wrappers(void); @@ -523,9 +513,7 @@ class CGOptions { static std::string dfs_debug_sequence_; static int max_exhaustive_depth_; static bool compact_output_; - static bool msp_; static int func1_max_params_; - static bool splat_; static bool klee_; static bool crest_; static bool ccomp_; @@ -610,7 +598,6 @@ class CGOptions { static bool take_union_field_addr_; static bool vol_struct_union_fields_; static bool const_struct_union_fields_; - static Reducer* reducer_; static bool fast_execution_; // flag to indicate language diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 78ab884d5..ffe7cfd2a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -87,8 +87,6 @@ set(csmith_SOURCES DefaultProgramGenerator.h DefaultRndNumGenerator.cpp DefaultRndNumGenerator.h - DeltaMonitor.cpp - DeltaMonitor.h DepthSpec.cpp DepthSpec.h Effect.cpp @@ -138,8 +136,6 @@ set(csmith_SOURCES Lhs.h LinearSequence.cpp LinearSequence.h - MspFilters.cpp - MspFilters.h OutputMgr.cpp OutputMgr.h PartialExpander.cpp @@ -150,10 +146,6 @@ set(csmith_SOURCES RandomNumber.cpp RandomNumber.h RandomProgramGenerator.cpp - Reducer.cpp - Reducer.h - ReducerOutputMgr.cpp - ReducerOutputMgr.h SafeOpFlags.cpp SafeOpFlags.h Sequence.cpp @@ -161,12 +153,6 @@ set(csmith_SOURCES SequenceFactory.cpp SequenceFactory.h SequenceLineParser.h - SimpleDeltaRndNumGenerator.cpp - SimpleDeltaRndNumGenerator.h - SimpleDeltaSequence.cpp - SimpleDeltaSequence.h - SplatExtension.cpp - SplatExtension.h Statement.cpp Statement.h StatementArrayOp.cpp diff --git a/src/DefaultOutputMgr.cpp b/src/DefaultOutputMgr.cpp index c0a364fca..a1c64032b 100644 --- a/src/DefaultOutputMgr.cpp +++ b/src/DefaultOutputMgr.cpp @@ -45,7 +45,6 @@ #include "VariableSelector.h" #include "Type.h" #include "random.h" -#include "DeltaMonitor.h" #include "Error.h" static std::string filename_prefix = "rnd_output"; @@ -201,9 +200,6 @@ void DefaultOutputMgr::Output() { std::ostream &out = get_main_out(); - if (DeltaMonitor::is_running() && (Error::get_error() != SUCCESS)) { - out << "Delta reduction error!\n"; - } if (is_split()) { OutputGlobals(); OutputAllHeaders(); @@ -223,7 +219,6 @@ DefaultOutputMgr::Output() if (!CGOptions::nomain()) OutputMain(out); OutputTail(out); - DeltaMonitor::Output(out); } std::ostream & diff --git a/src/DefaultProgramGenerator.cpp b/src/DefaultProgramGenerator.cpp index f355e9c08..c9c9eb90f 100644 --- a/src/DefaultProgramGenerator.cpp +++ b/src/DefaultProgramGenerator.cpp @@ -37,11 +37,9 @@ #include "RandomNumber.h" #include "AbsRndNumGenerator.h" #include "DefaultOutputMgr.h" -#include "ReducerOutputMgr.h" #include "Finalization.h" #include "Function.h" #include "Type.h" -#include "DeltaMonitor.h" #include "CGOptions.h" #include "SafeOpFlags.h" #include "ExtensionMgr.h" @@ -64,17 +62,8 @@ DefaultProgramGenerator::~DefaultProgramGenerator() void DefaultProgramGenerator::initialize() { - if (DeltaMonitor::is_delta()) { - DeltaMonitor::CreateRndNumInstance(seed_); - } - else { - RandomNumber::CreateInstance(rDefaultRndNumGenerator, seed_); - } - if (CGOptions::get_reducer()) { - output_mgr_ = new ReducerOutputMgr(); - } else { - output_mgr_ = DefaultOutputMgr::CreateInstance(); - } + RandomNumber::CreateInstance(rDefaultRndNumGenerator, seed_); + output_mgr_ = DefaultOutputMgr::CreateInstance(); assert(output_mgr_); ExtensionMgr::CreateExtension(); diff --git a/src/DefaultRndNumGenerator.cpp b/src/DefaultRndNumGenerator.cpp index 8afad6df8..de06e18d0 100644 --- a/src/DefaultRndNumGenerator.cpp +++ b/src/DefaultRndNumGenerator.cpp @@ -43,7 +43,6 @@ #include "SequenceFactory.h" #include "Sequence.h" #include "CGOptions.h" -#include "DeltaMonitor.h" DefaultRndNumGenerator *DefaultRndNumGenerator::impl_ = 0; @@ -104,8 +103,6 @@ DefaultRndNumGenerator::get_prefixed_name(const std::string &name) void DefaultRndNumGenerator::add_number(int v, int bound, int k) { - if (DeltaMonitor::is_running()) - seq_->add_number(v, bound, k); } /* diff --git a/src/DeltaMonitor.cpp b/src/DeltaMonitor.cpp deleted file mode 100644 index ec63b67bb..000000000 --- a/src/DeltaMonitor.cpp +++ /dev/null @@ -1,210 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2015, 2017 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#if HAVE_CONFIG_H -# include -#endif - -#ifdef WIN32 -#pragma warning(disable : 4786) /* Disable annoying warning messages */ -#endif - -#include "DeltaMonitor.h" -#include -#include -#include "SequenceFactory.h" -#include "SimpleDeltaSequence.h" -#include "SimpleDeltaRndNumGenerator.h" -#include "random.h" -#include "RandomNumber.h" - -using namespace std; - -DELTA_TYPE DeltaMonitor::delta_type_ = MAX_DELTA_TYPE; - -std::string DeltaMonitor::output_file_ = ""; - -std::string DeltaMonitor::input_file_ = ""; - -bool DeltaMonitor::is_running_ = false; - -bool DeltaMonitor::is_delta_ = false; - -bool DeltaMonitor::no_delta_reduction_ = false; - -Sequence *DeltaMonitor::seq_ = NULL; - -DeltaMonitor::DeltaMonitor() -{ - -} - -DeltaMonitor::~DeltaMonitor() -{ - -} - -Sequence * -DeltaMonitor::GetSequence() -{ - assert(delta_type_ != MAX_DELTA_TYPE); - - switch (DeltaMonitor::delta_type_) { - case dSimpleDelta: - DeltaMonitor::seq_ = SimpleDeltaSequence::CreateInstance(SimpleDeltaSequence::default_sep_char); - break; - default: - assert("DeltaMonitor GetSequence error" && 0); - break; - } - assert(DeltaMonitor::seq_); - return DeltaMonitor::seq_; -} - -char -DeltaMonitor::GetSepChar() -{ - return SimpleDeltaSequence::default_sep_char; -} - -void -DeltaMonitor::CreateRndNumInstance(const unsigned long seed) -{ - assert(!DeltaMonitor::input_file_.empty()); - switch (DeltaMonitor::delta_type_) { - case dSimpleDelta: - RandomNumber::CreateInstance(rSimpleDeltaRndNumGenerator, seed); - break; - default: - assert("DeltaMonitor CreateRndNumInstance error" && 0); - break; - } -} - -bool -DeltaMonitor::set_delta_type(std::string &msg, const std::string &monitor_type) -{ - if (!monitor_type.compare("simple")) { - DeltaMonitor::delta_type_ = dSimpleDelta; - } - else { - msg = "not supported monitor type!"; - return false; - } - DeltaMonitor::is_running_ = true; - return true; -} - -bool -DeltaMonitor::init(std::string &msg, const std::string &monitor_type, const std::string &o_file) -{ - assert(!monitor_type.empty()); - - if (o_file.empty()) { - msg = "please specify the file for delta output by --delta-output [file]"; - return false; - } - DeltaMonitor::output_file_ = o_file; - - if (!DeltaMonitor::set_delta_type(msg, monitor_type)) { - return false; - } - - return true; -} - -bool -DeltaMonitor::init_for_running(std::string &msg, const std::string &monitor_type, - const std::string &o_file, const std::string &i_file, bool no_delta) -{ - assert(!monitor_type.empty()); - - if (i_file.empty()) { - msg = "please specify the file for delta input by --delta-input [file]"; - return false; - } - if (o_file.empty()) { - DeltaMonitor::output_file_ = i_file; - } - else { - DeltaMonitor::output_file_ = o_file; - } - DeltaMonitor::input_file_ = i_file; - - if (!DeltaMonitor::set_delta_type(msg, monitor_type)) { - return false; - } - - DeltaMonitor::is_delta_ = true; - DeltaMonitor::no_delta_reduction_ = no_delta; - return true; -} - -void -DeltaMonitor::OutputStatistics(ostream &out) -{ - switch (DeltaMonitor::delta_type_) { - case dSimpleDelta: - SimpleDeltaRndNumGenerator::OutputStatistics(out); - break; - default: - assert(0); - break; - } -} - -void -DeltaMonitor::Output(ostream &out) -{ - if (!DeltaMonitor::is_running_) - return; - - if (is_delta_) - DeltaMonitor::OutputStatistics(out); - - assert(!output_file_.empty()); - std::string s; - - get_sequence(s); - ofstream ofile(output_file_.c_str()); - ofile << s; -} - -const std::string & -DeltaMonitor::get_input() -{ - return DeltaMonitor::input_file_; -} - -const std::string & -DeltaMonitor::get_output() -{ - return DeltaMonitor::output_file_; -} - diff --git a/src/DeltaMonitor.h b/src/DeltaMonitor.h deleted file mode 100644 index ad0c50e6c..000000000 --- a/src/DeltaMonitor.h +++ /dev/null @@ -1,94 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2015 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef DELTA_MONITOR_H -#define DELTA_MONITOR_H - -#include -#include - -class SequenceFactory; -class Sequence; - -enum DELTA_TYPE { - dSimpleDelta, -}; - -#define MAX_DELTA_TYPE ((DELTA_TYPE) (dSimpleDelta+1)) - -class DeltaMonitor { -public: - static Sequence *GetSequence(); - - static char GetSepChar(); - - static void CreateRndNumInstance(const unsigned long seed); - - static bool is_running() { return is_running_; } - - static bool is_delta() { return is_delta_; } - - static bool no_delta_reduction() { return no_delta_reduction_; } - - static bool init(std::string &msg, const std::string &monitor_type, const std::string &o_file); - - static bool init_for_running(std::string &msg, const std::string &monitor_type, - const std::string &o_file, const std::string &i_file, bool no_delta); - - static bool set_delta_type(std::string &msg, const std::string &monitor_type); - - static void Output(std::ostream &out); - - static const std::string &get_input(); - - static const std::string &get_output(); - -private: - DeltaMonitor(); - - ~DeltaMonitor(); - - static void OutputStatistics(std::ostream &out); - - static DELTA_TYPE delta_type_; - - static std::string output_file_; - - static std::string input_file_; - - static bool is_running_; - - static bool is_delta_; - - static bool no_delta_reduction_; - - static Sequence *seq_; -}; - -#endif diff --git a/src/ExpressionAssign.cpp b/src/ExpressionAssign.cpp index 73f925dfc..ef6701d83 100644 --- a/src/ExpressionAssign.cpp +++ b/src/ExpressionAssign.cpp @@ -134,10 +134,6 @@ void ExpressionAssign::Output(std::ostream &out) const { output_cast(out); - Reducer* reducer = CGOptions::get_reducer(); - if (reducer && reducer->output_expr(this, out)) { - return; - } out << "("; assign->OutputAsExpr(out); out << ")"; diff --git a/src/ExpressionComma.cpp b/src/ExpressionComma.cpp index c0cfc7455..e518e6463 100644 --- a/src/ExpressionComma.cpp +++ b/src/ExpressionComma.cpp @@ -36,7 +36,6 @@ #include "Common.h" #include "CGContext.h" #include "CGOptions.h" -#include "Reducer.h" #include "Type.h" #include "util.h" @@ -121,10 +120,6 @@ void ExpressionComma::Output(std::ostream &out) const { output_cast(out); - Reducer* reducer = CGOptions::get_reducer(); - if (reducer && reducer->output_expr(this, out)) { - return; - } out << "("; lhs.Output(out); out << " , "; diff --git a/src/ExpressionFuncall.cpp b/src/ExpressionFuncall.cpp index 66be0ccf4..9d3f07688 100644 --- a/src/ExpressionFuncall.cpp +++ b/src/ExpressionFuncall.cpp @@ -47,7 +47,6 @@ #include "Error.h" #include "Bookkeeper.h" #include "StringUtils.h" -#include "Reducer.h" #include "Block.h" #include "random.h" @@ -246,10 +245,6 @@ void ExpressionFuncall::Output(std::ostream &out) const { output_cast(out); - Reducer* reducer = CGOptions::get_reducer(); - if (reducer && reducer->output_expr(this, out)) { - return; - } invoke.Output(out); } diff --git a/src/ExpressionVariable.cpp b/src/ExpressionVariable.cpp index 01dabcc19..d215586ac 100644 --- a/src/ExpressionVariable.cpp +++ b/src/ExpressionVariable.cpp @@ -206,10 +206,6 @@ void ExpressionVariable::Output(std::ostream &out) const { output_cast(out); - Reducer* reducer = CGOptions::get_reducer(); - if (reducer && reducer->output_expr(this, out)) { - return; - } int i; int indirect_level = get_indirect_level(); if (indirect_level > 0) { diff --git a/src/ExtensionMgr.cpp b/src/ExtensionMgr.cpp index a337e484a..f49ce8a28 100644 --- a/src/ExtensionMgr.cpp +++ b/src/ExtensionMgr.cpp @@ -35,7 +35,6 @@ #include #include #include "CGOptions.h" -#include "SplatExtension.h" #include "KleeExtension.h" #include "CrestExtension.h" #include "CoverageTestExtension.h" @@ -52,10 +51,7 @@ void ExtensionMgr::CreateExtension() { int params_size = CGOptions::func1_max_params(); - if (CGOptions::splat()) { - extension_ = dynamic_cast(new SplatExtension()); - } - else if (CGOptions::klee()) { + if (CGOptions::klee()) { extension_ = dynamic_cast(new KleeExtension()); } else if (CGOptions::crest()) { diff --git a/src/MspFilters.cpp b/src/MspFilters.cpp deleted file mode 100644 index 65c007c6d..000000000 --- a/src/MspFilters.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2017 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#if HAVE_CONFIG_H -# include -#endif - -#include -#include "MspFilters.h" -#include "SafeOpFlags.h" - -MspBinaryFilter::MspBinaryFilter() -{ - -} - -MspBinaryFilter::~MspBinaryFilter() -{ - -} - -bool -MspBinaryFilter::filter(int v) const -{ - assert(v >= 0); - eBinaryOps op = static_cast(v); - if ((op == eDiv || op == eMod)) - return true; - else - return false; -} - -///////////////////////////////////////////////////////// - -MspSafeOpSizeFilter::MspSafeOpSizeFilter(eBinaryOps op) - : bin_op_(op) -{ - -} - -MspSafeOpSizeFilter::~MspSafeOpSizeFilter() -{ - -} - -bool -MspSafeOpSizeFilter::filter(int v) const -{ - assert(v >= 0); - SafeOpSize op_size = static_cast(v); - switch(bin_op_) { - case eMul: //fall-through - case eRShift: //fall-through - case eLShift: - if ((op_size == sInt32 || op_size == sInt64)) - return true; - else - return false; - break; - default: - return false; - } -} - diff --git a/src/MspFilters.h b/src/MspFilters.h deleted file mode 100644 index 94acfd469..000000000 --- a/src/MspFilters.h +++ /dev/null @@ -1,58 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2015 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef MSP_FILTERS_H -#define MSP_FILTERS_H - -#include "Filter.h" -#include "FunctionInvocation.h" - -class MspBinaryFilter : public Filter -{ -public: - MspBinaryFilter(); - - virtual ~MspBinaryFilter(); - - virtual bool filter(int v) const; -}; - -class MspSafeOpSizeFilter : public Filter -{ -public: - MspSafeOpSizeFilter(eBinaryOps op); - - virtual ~MspSafeOpSizeFilter(); - - virtual bool filter(int v) const; -private: - eBinaryOps bin_op_; -}; - -#endif //MSP_FILTERS_H diff --git a/src/Probabilities.cpp b/src/Probabilities.cpp index beea8416a..76d884f31 100644 --- a/src/Probabilities.cpp +++ b/src/Probabilities.cpp @@ -45,7 +45,6 @@ #include "Type.h" #include "SafeOpFlags.h" #include "CGOptions.h" -#include "MspFilters.h" #include "VectorFilter.h" #include "random.h" @@ -863,15 +862,6 @@ Probabilities::unregister_extra_filter(ProbName pname, Filter *filter) void Probabilities::set_extra_filters(ProbName pname) { - if (CGOptions::msp()) { - switch(pname) { - case pBinaryOpsProb: - extra_filters_[pname] = new MspBinaryFilter(); - break; - default: - break; - } - } } bool diff --git a/src/RandomProgramGenerator.cpp b/src/RandomProgramGenerator.cpp index a8eb615b1..6968b7a25 100644 --- a/src/RandomProgramGenerator.cpp +++ b/src/RandomProgramGenerator.cpp @@ -242,11 +242,9 @@ static void print_advanced_help() cout << "Only works in the exhaustive mode." << endl << endl; // target platforms - cout << " --msp: enable certain msp related features " << endl << endl; cout << " --ccomp: generate compcert-compatible code" << endl << endl; // symblic excutions - cout << " --splat: enable splat extension" << endl << endl; cout << " --klee: enable klee extension" << endl << endl; cout << " --crest: enable crest extension" << endl << endl; @@ -256,7 +254,7 @@ static void print_advanced_help() cout << "Can only be used with --coverage-test." << endl << endl; cout << " --func1_max_params : specify the number of symbolic variables passed to func_1 (default 3). "; - cout << "Only used when --splat | --crest | --klee | --coverage-test is enabled." << endl << endl; + cout << "Only used when --crest | --klee | --coverage-test is enabled." << endl << endl; // struct/union related options cout << " --fixed-struct-fields: fix the size of struct fields to max-struct-fields (default 10)." << endl << endl; @@ -414,11 +412,6 @@ main(int argc, char **argv) continue; } - if (strcmp (argv[i], "--splat") == 0) { - CGOptions::splat(true); - continue; - } - if (strcmp (argv[i], "--klee") == 0) { CGOptions::klee(true); continue; @@ -482,11 +475,6 @@ main(int argc, char **argv) continue; } - if (strcmp (argv[i], "--msp") == 0) { - CGOptions::msp(true); - continue; - } - if (strcmp (argv[i], "--packed-struct") == 0) { CGOptions::packed_struct(true); continue; @@ -1403,23 +1391,6 @@ main(int argc, char **argv) continue; } - if (strcmp (argv[i], "--reduce") == 0) { - string filename; - i++; - arg_check(argc, i); - if (!parse_string_arg(argv[i], filename)) { - cout<< "please specify reduction directive file!" << std::endl; - exit(-1); - } - ifstream conf(filename.c_str()); - if (conf.fail()) { - cout<< "can't read reduction directive file " << filename << "!" << std::endl; - exit(-1); - } - CGOptions::init_reducer(filename); - continue; - } - if (strcmp(argv[i], "--fast-execution") == 0) { CGOptions::lang_cpp(true); // jumps can easily cause infinite loops. Just disable them diff --git a/src/Reducer.cpp b/src/Reducer.cpp deleted file mode 100644 index 3e0012abd..000000000 --- a/src/Reducer.cpp +++ /dev/null @@ -1,1417 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2015, 2017 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#if HAVE_CONFIG_H -# include -#endif - -#ifdef WIN32 -#pragma warning(disable : 4786) /* Disable annoying warning messages */ -#endif - -#include "Reducer.h" -#include -#include -#include -#include -#include "StringUtils.h" -#include "Function.h" -#include "FunctionInvocationUser.h" -#include "FunctionInvocationBinary.h" -#include "Block.h" -#include "Statement.h" -#include "StatementExpr.h" -#include "StatementIf.h" -#include "StatementFor.h" -#include "StatementGoto.h" -#include "StatementArrayOp.h" -#include "StatementReturn.h" -#include "Lhs.h" -#include "Variable.h" -#include "VariableSelector.h" -#include "ArrayVariable.h" -#include "Expression.h" -#include "ExpressionVariable.h" -#include "ExpressionFuncall.h" -#include "ExpressionAssign.h" -#include "ExpressionComma.h" -#include "Constant.h" -#include "CVQualifiers.h" -#include "FactMgr.h" - -Reducer::Reducer(string fname) -: dump_block_entry(false), - dump_all_block_info(false), - dump_monitored_var(false), - dump_dropped_params(false), - drop_params(false), - rewrite_calls_inside(NULL), - reduce_binaries(false), - output_if_ids(false), - monitored_var(NULL), - monitored_func(NULL), - monitored_call_id(""), - dump_stms_in_blocks(NULL), - configured(false), - fname_(fname) -{ - // nothing else to do -} - -Reducer::~Reducer(void) -{ -} - -void -Reducer::configure(void) -{ - ifstream conf(fname_.c_str()); - std::string line; - // default: use the first function as mian - main = GetFirstFunction(); - while(!conf.eof()) { - getline(conf, line); - if (StringUtils::empty_line(line)) - continue; - if (dump_dropped_params) { - // if "dropped parameters" is not the last setting, means we are done with parameter dropping - dump_dropped_params = false; - } - // find the variable that caused diff. checksums - if (line.find("focus variable") == 0) { - getline(conf, line); - StringUtils::chop(line); - // make sure the focus var is marked as used var - const Variable* key = VariableSelector::find_var_by_name(line); - if (key == NULL) { - // it's possible an array variable that is not specifically itemized in the - // program that is the focus var. we manually itemize it here - vector strs; - StringUtils::split_string(line, strs, "[]"); - const Variable* ary = VariableSelector::find_var_by_name(strs[0]); - assert(ary && ary->isArray); - const ArrayVariable* av = (const ArrayVariable*)ary; - vector indices; - for (size_t k=0; kget_dimension(); k++) { - assert(k + 1 < strs.size()); - indices.push_back(StringUtils::str2int(strs[k+1])); - } - av->itemize(indices); - } - key = VariableSelector::find_var_by_name(line); - assert(key); - monitored_var = key; - used_vars.push_back(key->get_named_var()); - } - // find the line that crashed a compiler - else if (line.find("crc lines") == 0) { - getline(conf, line); - StringUtils::chop(line); - // find the global variables in CRC statements, and mark them as used - vector strs; - StringUtils::split_string(line, strs, "(),[."); - for (size_t i=0; i vnames; - StringUtils::split_string(line, vnames, ", "); - for (size_t i=0; i::const_iterator iter; - for(iter = map_active_blks.begin(); iter != map_active_blks.end(); ++iter) { - const Block* b = iter->first; - for (j=0; jstms.size(); j++) { - if (b->stms[j]->stm_id == stm_id) { - return b->stms[j]; - } - } - } - return NULL; -} - -bool -Reducer::is_ptr_written_in_stm(const Statement* stm) -{ - size_t i; - FactMgr* fm = get_fact_mgr_for_func(stm->func); - const vector& write_vars = fm->map_stm_effect[stm].get_write_vars(); - for (i=0; iis_pointer()) { - const Block* blk = (stm->eType == eBlock) ? (const Block*)stm : stm->parent; - if (wvar->is_visible(blk) && is_var_used(wvar)) { - return true; - } - } - } - return false; -} - -bool -Reducer::is_exp_replaced(const Expression* e) -{ - if (e->term_type == eVariable || e->term_type == eLhs) { - return map_reduced_vars.find(e) != map_reduced_vars.end(); - } - if (e->term_type == eFunction) { - const FunctionInvocation* fi = e->get_invoke(); - assert(fi); - return map_reduced_invocations.find(fi) != map_reduced_invocations.end(); - } - return false; -} - -bool -Reducer::is_var_init_reduced(const Variable* v) -{ - return map_reduced_var_inits.find(v) != map_reduced_var_inits.end(); -} - -bool -Reducer::is_label_used(const string l) -{ - if (l == "") return false; - return std::find(used_labels.begin(), used_labels.end(), l) != used_labels.end(); -} - -string -Reducer::find_jump_label(const Statement* stm) -{ - string label = stm->find_jump_label(); - return (is_label_used(label)) ? label : ""; -} - -int -Reducer::find_required_labels(const Statement* stm, vector& labels) -{ - string label = find_jump_label(stm); - if (label != "") { - labels.push_back(label); - } - - vector blks; - size_t i, j; - stm->get_blocks(blks); - for (i=0; istms.size(); j++) { - const Statement* s = blks[i]->stms[j]; - find_required_labels(s, labels); - } - } - } - return labels.size(); -} - -int -Reducer::find_missing_labels(const Statement* stm, const Statement* alt_stm, vector& labels) -{ - labels.clear(); - vector labels1, labels2; - stm->find_contained_labels(labels1); - if (alt_stm) { - alt_stm->find_contained_labels(labels2); - } - size_t i; - for (i=0; i& work_blks, vector& work_funcs, std::ostream& out) -{ - size_t i, j; - vector blks; - vector funcalls; - vector uniq_funcs; - out << "****** block: " << blk->stm_id << " ******" << endl; - for (i=0; istms.size(); i++) { - const Statement* stm = blk->stms[i]; - funcalls.clear(); - uniq_funcs.clear(); - stm->get_called_funcs(funcalls); - stm->get_blocks(blks); - out << stm->stm_id; - if (funcalls.size() > 0) { - // find the unique functions that was called - for (j=0; jget_func(); - if (find_function_in_set(uniq_funcs, f) == -1) { - uniq_funcs.push_back(f); - } - } - // print the unique functions, add them to work list if necessary - out << "("; - for (j=0; j 0) { - out << ", "; - } - const Function* f = uniq_funcs[j]; - if (find_function_in_set(work_funcs, f) == -1) { - work_funcs.push_back(f); - } - out << f->name; - } - out << ")"; - } - if (blks.size() > 0) { - out << "{"; - for (j=0; j 0) { - out << ", "; - } - work_blks.push_back(blks[j]); - out << blks[j]->stm_id; - } - out << "}"; - } - out << endl; - } -} - -bool -Reducer::is_blk_deleted(const Block* b) const -{ - // if active_blks is not initialized, we assume all functions are to be kept - if (map_active_blks.size() == 0) return false; - return map_active_blks.find(b) == map_active_blks.end(); -} - -bool -Reducer::is_stm_deleted(const Statement* stm) const -{ - const Statement* s = stm; - while (s && replaced_stms.find(s) == replaced_stms.end() && !is_blk_deleted(s->parent)) { - s = s->find_container_stm(); - } - // s = NULL means the statement is not reduced - return !(s == NULL); -} - -bool -Reducer::is_param_dropped(const Function* f, int i) -{ - // assume all parameters are not dropped during configuration - if (!drop_params || !configured) return false; - return !is_var_used(f->param[i]); -} - -void -Reducer::replace_stm(const Statement* stm, const Statement* new_stm, string pre_stm) -{ - replaced_stms[stm] = new_stm; - if (!pre_stm.empty()) { - map_pre_stm_assigns[stm] = pre_stm; - map_str_effects[pre_stm] = find_used_vars(pre_stm); - } -} - -void -Reducer::delete_stms_after(const Statement* stm, bool include_parent_blks) -{ - const Block* parent = stm->parent; - size_t i, j; - bool begin_delete = false; - const Statement* return_stm = stm->func->body->get_last_stm(); - assert(return_stm); - for (i=0; istms.size(); i++) { - const Statement* s = parent->stms[i]; - vector labels; - - if (begin_delete) { - if (find_required_labels(s, labels)==0 && s != return_stm) { - // don't delete statements that contains add-back blocks (those has 0 count in map_active_blks) - vector blks; - s->get_blocks(blks); - bool must_dump = false; - for (j=0; jfind_container_stm(); - if (s) { - delete_stms_after(s, include_parent_blks); - } - } -} - -// find local variables that have to be lifted to global, most likely because -// they are used via pointer in a callee function at the bottom of a call chain -int -Reducer::find_local_vars_to_lift(vector& vars) -{ - size_t i; - vars.clear(); - if (monitored_func) { - for (i=0; ifeffect.is_read(v) || monitored_func->feffect.is_written(v)) { - // if there is a variable that is read by the function externally, - // but is neither a global or a parameter, this must be a local variable - // of one of the functions in the call chain - - // Note this can not handle parameters not belong to monitored function, - // so taking address of parameters and passing into a function call is forbidden - // see ExpressionVariable::make_random - if (!v->is_global() && !v->is_argument()) { - vars.push_back(v); - break; - } - } - } - } - return vars.size(); -} - -void -Reducer::expand_used_vars(void) -{ - size_t i, j; - for (i=0; i init_values; - if (v->isArray) { - const ArrayVariable* av = dynamic_cast(v); - init_values = av->get_init_values(); - } - init_values.push_back(v->init); - - for (j=0; jterm_type == eVariable) { - const ExpressionVariable* ev = (const ExpressionVariable*)(init); - if (ev->get_indirect_level() < 0) { - string dummy; - const Variable* addr_var = ev->get_var()->get_array(dummy); - // if not an array ... - if (addr_var == 0) { - addr_var = ev->get_var(); - } - // if addr_var is a field, get the container var - addr_var = addr_var->get_named_var(); - if (!is_var_used(addr_var)) { - used_vars.push_back(addr_var); - } - } - } - } - } -} - -bool -Reducer::is_replaced_var(const ExpressionVariable* ev, string& str_out) -{ - if (map_reduced_vars.find(ev) != map_reduced_vars.end()) { - str_out = map_reduced_vars[ev]; - return true; - } - return false; -} - -const Expression* -Reducer::get_replaced_invocation(const FunctionInvocation* fi) -{ - if (map_reduced_invocations.find(fi) != map_reduced_invocations.end()) { - return map_reduced_invocations[fi]; - } - return NULL; -} - -void -Reducer::get_used_vars_and_funcs_and_labels(const FunctionInvocation* fi, vector& vars, vector& funcs, vector& labels) -{ - const Expression* replace = get_replaced_invocation(fi); - bool must_visit = std::find(must_use_var_invocations.begin(), must_use_var_invocations.end(), fi) != must_use_var_invocations.end(); - if (replace != NULL && !must_visit) { - get_used_vars_and_funcs_and_labels(replace, vars, funcs, labels); - return; - } - size_t i; - if (fi->invoke_type == eFuncCall) { - const FunctionInvocationUser* call = (const FunctionInvocationUser*)(fi); - if (find_function_in_set(funcs, call->get_func()) == -1) { - // special case: if the body of function is never entered, means this - // function is never invoked, mostly due to a && or || shortcut, we - // replace the function call with a constant 0. In fact it's not evaluated - // anyway, so which constant we use doesn't matter - if (is_blk_deleted(call->get_func()->body)) { - if (call->get_type().is_aggregate()) { - // it's not a real constant, but we don't want to go through the trouble - // of creating an ExpressionVariable - string vname = add_artificial_globals(&call->get_type()); - map_reduced_invocations[fi] = new Constant(&call->get_type(), vname); - } - else { - map_reduced_invocations[fi] = new Constant(&fi->get_type(), "0"); - } - return; - } - // recursively find used vars and functions - const Function* f = call->get_func(); - - get_used_vars_and_funcs_and_labels(f->body, vars, funcs, labels); - funcs.push_back(f); - // remember the parameters we dropped - for (i=0; iparam.size(); i++) { - if (is_param_dropped(f, i)) { - dropped_params.push_back(f->param[i]); - } - } - } - // only visit the parameters that are not dropped - for (i=0; iparam_value.size(); i++) { - if (!is_param_dropped(call->get_func(), i)) { - get_used_vars_and_funcs_and_labels(fi->param_value[i], vars, funcs, labels); - } - } - } - else { - for (i=0; iparam_value.size(); i++) { - get_used_vars_and_funcs_and_labels(fi->param_value[i], vars, funcs, labels); - } - } -} - -void -Reducer::get_used_vars_and_funcs_and_labels(const Expression* e, vector& vars, vector& funcs, vector& labels) -{ - string tmp; - switch (e->term_type) { - case eLhs: { - const Lhs* lhs = (const Lhs*)e; - add_variable_to_set(vars, lhs->get_var()->get_named_var()); - break; - } - case eConstant: { - const Constant* cst = (const Constant*)e; - const Variable* v = find_addressed_var(cst->get_value()); - if (v) { - add_variable_to_set(vars, v); - } - break; - } - // check if the variable is replaced by a constant - case eVariable: { - const ExpressionVariable* ev = (const ExpressionVariable*)e; - if (!is_replaced_var(ev, tmp) && !ev->get_var()->is_tmp_var()) { - add_variable_to_set(vars, ev->get_var()->get_named_var()); - } - break; - } - // check if invocation is replaced by a variable or constant - case eFunction: { - const ExpressionFuncall* funcall = (const ExpressionFuncall*)e; - get_used_vars_and_funcs_and_labels(funcall->get_invoke(), vars, funcs, labels); - break; - } - case eAssignment: { - const ExpressionAssign* ea = (const ExpressionAssign*)e; - get_used_vars_and_funcs_and_labels(ea->get_lhs(), vars, funcs, labels); - get_used_vars_and_funcs_and_labels(ea->get_rhs(), vars, funcs, labels); - break; - } - case eCommaExpr: { - const ExpressionComma* ec = (const ExpressionComma*)e; - get_used_vars_and_funcs_and_labels(ec->get_lhs(), vars, funcs, labels); - get_used_vars_and_funcs_and_labels(ec->get_rhs(), vars, funcs, labels); - break; - } - default: break; - } -} - -void -Reducer::find_called_funcs(const FunctionInvocation* fi, string id, vector& funcs, vector& ids) -{ - // analyze reduced expression instead if there is one - if (map_reduced_invocations.find(fi) != map_reduced_invocations.end()) { - const Expression* e = map_reduced_invocations[fi]; - const FunctionInvocation* invoke = e->get_invoke(); - if (invoke) { - find_called_funcs(invoke, id, funcs, ids); - } - return; - } - - const FunctionInvocationUser* func_call = NULL; - if (fi->invoke_type == eFuncCall) { - func_call = (const FunctionInvocationUser*)fi; - funcs.push_back(func_call); - ids.push_back(id); - } - // find calls in parameters, skip dropped parameters - for (size_t i=0; iparam_value.size(); i++) { - const Expression* value = fi->param_value[i]; - if (func_call==NULL || !is_param_dropped(func_call->get_func(), i)) { - const FunctionInvocation* fi = value->get_invoke(); - if (fi) { - find_called_funcs(fi, id + "_" + StringUtils::int2str(i), funcs, ids); - } - } - } -} - -int -Reducer::reduce_const_binary_op(const FunctionInvocationBinary* fib) -{ - const Expression* op1 = fib->param_value[0]; - const Expression* op2 = fib->param_value[1]; - if (op1->get_invoke() != NULL && map_reduced_invocations.find(op1->get_invoke()) != map_reduced_invocations.end()) { - op1 = map_reduced_invocations[op1->get_invoke()]; - } - if (op2->get_invoke() != NULL && map_reduced_invocations.find(op2->get_invoke()) != map_reduced_invocations.end()) { - op2 = map_reduced_invocations[op2->get_invoke()]; - } - if (op1->term_type == eConstant || map_reduced_vars.find(op1) != map_reduced_vars.end()) { - string str1 = (op1->term_type == eConstant) ? ((const Constant*)op1)->get_value() : map_reduced_vars[op1]; - if (op2->term_type == eConstant || map_reduced_vars.find(op2) != map_reduced_vars.end()) { - string str2 = (op2->term_type == eConstant) ? ((const Constant*)op2)->get_value() : map_reduced_vars[op2]; - INT64 result = 0; - INT64 v1 = StringUtils::str2longlong(str1); - INT64 v2 = StringUtils::str2longlong(str2); - switch (fib->get_operation()) { - case eAdd: result = v1 + v2; break; - case eSub: result = v1 - v2; break; - case eMul: result = v1 * v2; break; - case eDiv: result = v2 ? v1 / v2 : v1; break; - case eMod: result = v2 ? v1 % v2 : v1; break; - case eCmpGt: result = v1 > v2; break; - case eCmpLt: result = v1 < v2; break; - case eCmpGe: result = v1 >= v2; break; - case eCmpLe: result = v1 <= v2; break; - case eCmpEq: result = v1 == v2; break; - case eCmpNe: result = v1 != v2; break; - case eAnd: result = v1 && v2; break; - case eOr: result = v1 || v2; break; - case eBitXor: result = v1 ^ v2; break; - case eBitAnd: result = v1 & v2; break; - case eBitOr: result = v1 | v2; break; - case eRShift: result = (v2 > 0) ? v1 >> v2 : v1; break; - case eLShift: result = (v2 > 0) ? v1 << v2 : v1; break; - } - Constant* cst = new Constant(&fib->get_type(), StringUtils::longlong2str(result)); - map_reduced_invocations[fib] = cst; - return 1; - } - } - return 0; -} - -void -Reducer::reduce_const_binary_ops(vector& ops) -{ - size_t i; - size_t len = ops.size(); - for (i=0; i& ops, vector& ids, bool no_ptr_cmp) -{ - int cnt = 0; - vector exprs; - stm->get_exprs(exprs); - for (size_t i=0; i& ops, vector& ids, bool no_ptr_cmp) -{ - const FunctionInvocation* fi = exp->get_invoke(); - if (fi) { - // analyze reduced expression instead if there is one - if (map_reduced_invocations.find(fi) != map_reduced_invocations.end()) { - return find_binary_operations(map_reduced_invocations[fi], ops, ids, no_ptr_cmp); - } - - if (fi->invoke_type == eBinaryPrim) { - const FunctionInvocationBinary* fib = (const FunctionInvocationBinary*)fi; - if (!reduce_const_binary_op(fib)) { - if (!no_ptr_cmp || !fib->ptr_cmp) { - ops.push_back(fib); - ids.push_back(exp->expr_id); - } - } - } - const FunctionInvocationUser* func_call = NULL; - if (fi->invoke_type == eFuncCall) { - func_call = (const FunctionInvocationUser*)fi; - } - // find binary operations in parameters, skip dropped parameters - for (size_t i=0; iparam_value.size(); i++) { - const Expression* param = fi->param_value[i]; - if (func_call==NULL || !is_param_dropped(func_call->get_func(), i)) { - find_binary_operations(param, ops, ids, no_ptr_cmp); - } - } - } - return ops.size(); -} - -const FunctionInvocation* -Reducer::find_invoke_by_eid(const Statement* s, int id) const -{ - size_t i; - vector exprs; - s->get_exprs(exprs); - for (i=0; iget_invoke(); - if (e->expr_id == id) { - return fi; - } - if (fi) { - for (size_t i=0; iparam_value.size(); i++) { - const Expression* param = fi->param_value[i]; - const FunctionInvocation* tmp = find_invoke_by_eid(param, id); - if (tmp) { - return tmp; - } - } - } - return NULL; -} - -void -Reducer::build_left_right_binary_trees(vector& ops, vector& left_trees, vector& right_trees) -{ - size_t i, j, k; - vector sub_ops; - vector dummy, covered; - left_trees.clear(); - right_trees.clear(); - for (i=0; iparam_value[0], sub_ops, dummy, true); - for (j=0; jparam_value[1], sub_ops, dummy, true); - for (j=0; j& vars, vector& funcs, vector& labels) -{ - if (stm == NULL) return; - // for if statements with both branches deleted - if (stm->eType == eIfElse) { - const StatementIf* si = (const StatementIf*)stm; - if (is_blk_deleted(si->get_true_branch()) && is_blk_deleted(si->get_false_branch())) { - replace_stm(si, NULL, ""); - delete_stms_after(si, false); - } - } - // for goto statement whose target is deleted - else if (stm->eType == eGoto) { - const StatementGoto* sg = (const StatementGoto*)stm; - if (is_blk_deleted(sg->dest->parent)) { - bool keep = false; - // special case: if goto jump into a for-loop that use the monitored variable as - // induction variable, we keep the jump, for seed 355297830 - const Statement* s = sg->dest->find_container_stm(); - if (s && s->eType == eFor) { - const StatementFor* sf = (const StatementFor*)s; - if (sf->get_init()->get_lhs()->get_var() == this->monitored_var) { - keep = true; - if (std::find(labels.begin(), labels.end(), sg->label) == labels.end()) { - labels.push_back(sg->label); - } - } - } - if (!keep) { - replace_stm(sg, NULL, ""); - } - } else { - if (std::find(labels.begin(), labels.end(), sg->label) == labels.end()) { - labels.push_back(sg->label); - } - } - } - // include used variables from pre-statement assignments - if (map_pre_stm_assigns.find(stm) != map_pre_stm_assigns.end()) { - const string& assigns = map_pre_stm_assigns[stm]; - add_variables_to_set(vars, map_str_effects[assigns]); - } - // used replacement for replaced statements - bool must_visit = std::find(must_use_var_stms.begin(), must_use_var_stms.end(), stm) != must_use_var_stms.end(); - if (!must_visit && replaced_stms.find(stm) != replaced_stms.end()) { - get_used_vars_and_funcs_and_labels(replaced_stms[stm], vars, funcs, labels); - return; - } - - string label = stm->find_jump_label(); - if (!label.empty()) { - labels.push_back(label); - } - size_t i, j; - //stm->Output(cout); - vector exps; - stm->get_exprs(exps); - for (i=0; ieType == eArrayOp) { - const StatementArrayOp* sa = (const StatementArrayOp*)stm; - for (i=0; ictrl_vars.size(); i++) { - add_variable_to_set(vars, sa->ctrl_vars[i]->get_named_var()); - } - // JYTODO: detect the case when initializer is not invoked - if (sa->init_value) { - add_variable_to_set(vars, sa->array_var->get_named_var()); - } - } - vector blks; - stm->get_blocks(blks); - for (i=0; istms.size(); j++) { - const Statement* s = blks[i]->stms[j]; - get_used_vars_and_funcs_and_labels(s, vars, funcs, labels); - } - if (std::find(all_blks.begin(), all_blks.end(), blks[i]->stm_id) == all_blks.end()) { - all_blks.push_back(blks[i]->stm_id); - } - } -} - -int -Reducer::configure_diff_active_blks(string line, int first_bid) -{ - vector ids; - StringUtils::split_int_string(line, ids, ",()"); - size_t i; - assert(!ids.empty()); - const Block* one_branch = find_block_by_id(first_bid); - assert(one_branch); - const Statement* stm = one_branch->find_container_stm(); - if (stm && stm->eType == eIfElse) { - for (i=0; iget_false_branch()) ? si->get_true_branch() : si->get_false_branch(); - map_active_blks[other_branch] = map_active_blks[one_branch]; - assert(!used_vars.empty()); - - // replace both branches with direct conflicting assignments - string vname = monitored_var->name; - string assign1 = vname + " = 0;"; - string assign2 = vname + " = 1;"; - replace_stm(one_branch, NULL, assign1); - replace_stm(other_branch, NULL, assign2); - - // delete all statement following this if-else statement - delete_stms_after(si, true); - return 1; - } - else return 0; -} - -void -Reducer::config_active_blks(string cmd) -{ - size_t i; - vector tmp_strs; - if (cmd == "poll") { - dump_block_entry = true; - } else if (cmd == "blind poll") { - dump_all_block_info = true; - } - else { - tmp_strs.clear(); - bool take_diff_branch = false; - if (cmd.find("||") != string::npos) { - StringUtils::split_string(cmd, tmp_strs, "|"); - assert(tmp_strs.size() == 2); - cmd = tmp_strs[0]; - int blkid = StringUtils::str2int(tmp_strs[1]); - take_diff_branch = configure_diff_active_blks(cmd, blkid); - } - if (!take_diff_branch) { - StringUtils::split_string(cmd, tmp_strs, ",()"); - for (i=0; iparent; b != NULL; b = b->parent) { - if (map_active_blks.find(b) != map_active_blks.end()) { - break; - } - map_active_blks[b] = 0; - } - } - } - } - } -} - -void -Reducer::config_call_chain_shortcut(string cmd) -{ - if (cmd == "poll") { - dump_monitored_var = true; - add_artificial_globals(get_int_type(), "global_call_id"); - } - else { - vector strs; - StringUtils::split_string(cmd, strs, ":"); - assert(strs.size() == 2 || strs.size() == 3); - if (strs.size() == 2) { - dump_monitored_var = true; - add_artificial_globals(get_int_type(), "global_call_id"); - monitored_func = find_function_by_name(strs[0]); - assert(monitored_func); - monitored_call_id = strs[1]; - } - else { - main = find_function_by_name(strs[0]); - assert(main); - main_str = strs[2]; - } - } -} - -void -Reducer::config_stm_reduction(string cmd) -{ - size_t i, j; - if (cmd.find(":") == string::npos) { - size_t pos = cmd.find(" blind"); - if (pos != string::npos) { - cmd = cmd.substr(0, pos); - if (cmd == "main") cmd = "func_1"; - const Function* f = find_function_by_name(cmd); - assert(f); - dump_stms_in_blocks = f; - } - else { - // the reducer treats func_1 as main - if (cmd == "main") cmd = "func_1"; - const Function* f = find_function_by_name(cmd); - assert(f); - for (i=0; iblocks.size(); i++) { - const Block* b = f->blocks[i]; - if (!is_blk_deleted(b) && map_active_blks[b] == 1) { - for (j=0; jstms.size(); j++) { - const Statement* s = b->stms[j]; - if (!s->must_jump()) { - dump_value_before.push_back(s); - dump_value_after.push_back(s); - } - } - } - } - } - } - else { - vector strs; - StringUtils::split_string(cmd, strs, ":"); - assert(strs.size() == 2 || strs.size() == 3); - string assigns = strs.size()==3 ? strs[2] : ""; - reduce_stms_with_assigns(StringUtils::str2int(strs[0]), StringUtils::str2int(strs[1]), assigns); - } -} - -void -Reducer::config_expr_reduction(string cmd) -{ - if (cmd.find(":") == string::npos) { - // the reducer treats func_1 as main - if (cmd == "main") cmd = "func_1"; - const Function* f = find_function_by_name(cmd); - assert(f); - rewrite_calls_inside = f; - } - else { - vector strs; - StringUtils::split_string(cmd, strs, ":"); - assert(strs.size() == 2 || strs.size() == 3); - string assigns = strs.size()==3 ? strs[2] : ""; - reduce_call_with_assigns(strs[0], strs[1], assigns); - } -} - -void -Reducer::config_binary_reduction(string cmd) -{ - if (cmd.find(":") == string::npos) { - // the reducer treats func_1 as main - reduce_binaries = (cmd == "all"); - } - else { - size_t i; - // for rollback, ignore this reduction if ends with a '-', keep vars as used_vars if ends with '+' - char last = cmd[cmd.length()-1]; - if (last == '-') return; - if (last == '+') { - cmd = cmd.substr(0, cmd.length()-1); - } - vector ints; - StringUtils::split_int_string(cmd, ints, "[:]"); - assert(ints.size() >= 2); - const Statement* stm = find_stm_by_id(ints[0]); - assert(stm); - ints.erase(ints.begin()); - // must be pairs of ":" where choice is 1 (select left) or 2 (select right) - assert(ints.size() % 2 == 0); - - for (i = 0; i < ints.size(); i += 2) { - // special case: reduce if (...) to if (1) - if (ints[i] == 0) { - assert(ints[i+1] == -1); - assert(stm->eType == eIfElse); - const FunctionInvocation* fi = stm->get_direct_invocation(); - assert(fi); - map_reduced_invocations[fi] = new Constant(&fi->get_type(), "1"); - break; - } - const FunctionInvocation* fi = find_invoke_by_eid(stm, ints[i]); - assert(fi && fi->invoke_type == eBinaryPrim); - int choice = ints[i+1] - 1; - assert(choice == 0 || choice == 1); - const Expression* op = fi->param_value[choice]; - if (last == '+') { - must_use_var_invocations.push_back(fi); - } - map_reduced_invocations[fi] = op; - } - } -} - -void -Reducer::config_if_reduction(string cmd) -{ - if (cmd.find(",") == string::npos) { - // the reducer treats func_1 as main - output_if_ids = (cmd == "poll"); - } - else { - size_t i; - vector strs; - StringUtils::split_string(cmd, strs, ","); - for (i=0; ieType == eIfElse); - const StatementIf* si = (const StatementIf*)stm; - if (is_blk_deleted(si->get_false_branch())) { - replace_stm(si, si->get_true_branch(), ""); - } - else if (is_blk_deleted(si->get_true_branch())) { - replace_stm(si, si->get_false_branch(), ""); - } - // at least one branch should be deleted - else assert(0); - - if (rollback) { - must_use_var_stms.push_back(stm); - } - } - } -} - -void -Reducer::config_var_init_reduction(string cmd) -{ - vector strs; - StringUtils::split_string(cmd, strs, ":"); - assert(strs.size() == 2); - - const Variable* v = VariableSelector::find_var_by_name(strs[0]); - assert(v); - map_reduced_var_inits[v] = strs[1]; -} - -string -Reducer::add_artificial_globals(const Type* t, string name) -{ - static int cnt = 0; - ostringstream oss; - t->Output(oss); - if (name == "") { - name = "tmp_" + StringUtils::int2str(cnt++); - } - artificial_globals.push_back(oss.str() + " " + name); - return name; -} - -const Variable* -Reducer::find_addressed_var(string addr) -{ - if (addr.find("&") == 0) { - string addr_var = addr.substr(1); - size_t dotbracket = StringUtils::find_any_char(addr_var, 0, "[."); - if (dotbracket != string::npos) { - addr_var = addr_var.substr(0, dotbracket); - } - const Variable* addr_v = VariableSelector::find_var_by_name(addr_var); - assert(addr_v); - return addr_v; - } - return NULL; -} - -vector -Reducer::find_used_vars(string assigns) -{ - size_t i; - vector vars; - vector vnames, values; - StringUtils::breakup_assigns(assigns, vnames, values); - - // parse the assignment string - for (i=0; ieType == eIfElse) { - const Block* if_true = ((const StatementIf*)stm)->get_true_branch(); - const Block* if_false = ((const StatementIf*)stm)->get_false_branch(); - const Block* b = is_blk_deleted(if_true) ? if_false : if_true; - assert(b); - replace_stm(stm, b, ""); - } else { - replace_stm(stm, NULL, ""); - } - return 0; - } - - // find invocation based on id - vector calls; - vector ids; - const FunctionInvocation* invoke = NULL; - const FunctionInvocation* fi = stm->get_direct_invocation(); - assert(fi); - find_called_funcs(fi, tmp_name.substr(0, dash), calls, ids); - size_t i; - for (i=0; iget_type()); - Constant* cst = new Constant(type, value); - // record this reduction - map_reduced_invocations[invoke] = cst; //tmp_ev; - if (!extra_assigns.empty()) { - map_pre_stm_assigns[stm] = extra_assigns; - map_str_effects[extra_assigns] = find_used_vars(extra_assigns); - } - return 0; -} - -int -Reducer::reduce_stms_with_assigns(int id1, int id2, const string& assigns) -{ - const Statement* stm = find_stm_by_id(id1); - assert(stm); - const Block* blk = stm->parent; - assert(blk); - - size_t i; - int begin = -1; - int end = -1; - for (i=0; istms.size(); i++) { - const Statement* s = blk->stms[i]; - if (s == stm) { - begin = i; - end = i; - } - if (s->stm_id == id2) { - assert(begin != -1); - end = i; - break; - } - } - - if (begin != -1 && end != -1) { - for (int i=begin+1; i<=end; i++) { - replace_stm(blk->stms[i], NULL, ""); - } - replace_stm(blk->stms[begin], NULL, assigns); - } - return 0; -} - -int -Reducer::output_expr(const Expression* e, std::ostream &out) -{ - string tmp; - if (e->term_type == eVariable) { - const ExpressionVariable* ev = (const ExpressionVariable*)e; - if (is_replaced_var(ev, tmp)) { - out << tmp; - return 1; - } - } - // check if invocation is replaced by a variable or constant - else if (e->term_type == eFunction) { - const ExpressionFuncall* funcall = (const ExpressionFuncall*)e; - const FunctionInvocation* invoke = funcall->get_invoke(); - const Expression* exp = get_replaced_invocation(invoke); - if (exp) { - exp->Output(out); - return 1; - } else { - if (invoke->invoke_type == eFuncCall) { - const FunctionInvocationUser* call = (const FunctionInvocationUser*)(invoke); - const Function* func = call->get_func(); - out << func->name << "("; - size_t i; - bool first = true; - for (i=0; iparam.size(); i++) { - if (!is_param_dropped(func, i)) { - if (!first) { - out << ", "; - } - call->param_value[i]->Output(out); - first = false; - } - } - out << ")"; - return 1; - } - } - } - else if (e->term_type == eAssignment) { - const ExpressionAssign* ea = dynamic_cast(e); - ostringstream oss; - // if RHS can be simplified, print the simplified version - if (output_expr(ea->get_rhs(), oss)) { - out << "("; - ea->get_lhs()->Output(out); - out << " "; - ea->get_stm_assign()->output_op(out); - out << " "; - out << oss.str(); - out << ")"; - return 1; - } - } - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// - -// Local Variables: -// c-basic-offset: 4 -// tab-width: 4 -// End: - -// End of file. diff --git a/src/Reducer.h b/src/Reducer.h deleted file mode 100644 index e96462471..000000000 --- a/src/Reducer.h +++ /dev/null @@ -1,172 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2015 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef REDUCER_H -#define REDUCER_H - -#include -#include -#include -#include -#include "Effect.h" -#include "util.h" -using namespace std; - -class Function; -class Block; -class Statement; -class Variable; -class Expression; -class ExpressionVariable; -class FactMgr; -class Type; -class FunctionInvocation; -class FunctionInvocationUser; -class FunctionInvocationBinary; - -/* - * - */ -class Reducer -{ -public: - Reducer(string fname); - virtual ~Reducer(void); - void configure(void); - - bool is_blk_deleted(const Block* b) const; - bool is_stm_deleted(const Statement* stm) const; - bool is_var_used(const Variable* v); - bool is_param_dropped(const Function* f, int i); - bool is_replaced_var(const ExpressionVariable* ev, string& str_out); - const Expression* get_replaced_invocation(const FunctionInvocation* fi); - bool is_ptr_written_in_stm(const Statement* stm); - bool is_exp_replaced(const Expression* e); - bool is_label_used(const string l); - bool is_var_init_reduced(const Variable* v); - string find_jump_label(const Statement* stm); - int find_required_labels(const Statement* stm, vector& labels); - int find_missing_labels(const Statement* stm, const Statement* alt_stm, vector& labels); - - // for effect analysis and variable dropping - vector find_used_vars(string assigns); - const Variable* find_addressed_var(string addr); - void find_called_funcs(const FunctionInvocation* fi, string id, vector& funcs, vector& ids); - void get_used_vars_and_funcs_and_labels(const FunctionInvocation* fi, vector& vars, vector& funcs, vector& labels); - void get_used_vars_and_funcs_and_labels(const Expression* e, vector& vars, vector& funcs, vector& labels); - void get_used_vars_and_funcs_and_labels(const Statement* stm, vector& vars, vector& funcs, vector& labels); - void expand_used_vars(void); - const FunctionInvocation* find_invoke_by_eid(const Statement* s, int id) const; - const FunctionInvocation* find_invoke_by_eid(const Expression* e, int id) const; - int find_binary_operations(const Statement* stm, vector& ops, vector& ids, bool no_ptr_cmp=false); - int find_binary_operations(const Expression* exp, vector& ops, vector& ids, bool no_ptr_cmp=false); - void build_left_right_binary_trees(vector& ops, vector& left_trees, vector& right_trees); - int reduce_const_binary_op(const FunctionInvocationBinary* fib); - void reduce_const_binary_ops(vector& ops); - - // for function dropping - int reduce_call_with_assigns(const string& tmp_name, const string& value, const string& extra_assigns); - - // for statement reduction - void replace_stm(const Statement* stm, const Statement* new_stm, string pre_stm); - void delete_stms_after(const Statement* stm, bool include_parent_blks); - int reduce_stms_with_assigns(int id1, int id2, const string& assigns); - - string add_artificial_globals(const Type* t, string name=""); - - // for outputing - void output_block_skeleton(const Block* blk, vector& work_blks, vector& work_funcs, std::ostream& out); - int output_expr(const Expression* e, std::ostream &out); - - // for interaction with reduction config file - void config_active_blks(string cmd); - int configure_diff_active_blks(string line, int first_bid); - void config_call_chain_shortcut(string cmd); - void config_stm_reduction(string cmd); - void config_expr_reduction(string cmd); - void config_binary_reduction(string cmd); - void config_if_reduction(string cmd); - void config_var_init_reduction(string cmd); - - bool dump_block_entry; - bool dump_all_block_info; - bool dump_monitored_var; - bool dump_dropped_params; - bool drop_params; - const Function* rewrite_calls_inside; - bool reduce_binaries; - bool output_if_ids; - const Variable* monitored_var; - const Function* monitored_func; - string monitored_call_id; - string crc_lines; - - std::map map_active_blks; - vector all_blks; - vector dropped_params; - - // for statement reduction - std::map replaced_stms; - std::vector dump_value_before; - std::vector dump_value_after; - std::map > map_str_effects; - const Function* dump_stms_in_blocks; - - // for expression reduction - std::map map_reduced_vars; - std::map map_reduced_invocations; - std::map map_pre_stm_assigns; - std::map map_reduced_var_inits; - std::vector must_use_var_invocations; - std::vector must_use_var_stms; - - vector used_funcs; - vector used_vars; - vector used_labels; - vector artificial_globals; - const Function* main; - string main_str; - bool configured; - -private: - string fname_; - const Statement* find_stm_by_id(int stm_id); - int find_local_vars_to_lift(vector& vars); -}; - -/////////////////////////////////////////////////////////////////////////////// - -#endif // REDUCER_H - -// Local Variables: -// c-basic-offset: 4 -// tab-width: 4 -// End: - -// End of file. diff --git a/src/ReducerOutputMgr.cpp b/src/ReducerOutputMgr.cpp deleted file mode 100644 index f76017bce..000000000 --- a/src/ReducerOutputMgr.cpp +++ /dev/null @@ -1,1021 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2013, 2015, 2017 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#if HAVE_CONFIG_H -# include -#endif - -#include "ReducerOutputMgr.h" - -#include -#include -#include "Common.h" -#include "CGOptions.h" -#include "platform.h" -#include "Bookkeeper.h" -#include "Function.h" -#include "FunctionInvocation.h" -#include "FunctionInvocationUser.h" -#include "ExpressionFuncall.h" -#include "ExpressionVariable.h" -#include "CGContext.h" -#include "ArrayVariable.h" -#include "VariableSelector.h" -#include "Type.h" -#include "random.h" -#include "DeltaMonitor.h" -#include "Error.h" -#include "Reducer.h" -#include "Block.h" -#include "Statement.h" -#include "StatementIf.h" -#include "StatementFor.h" -#include "StatementArrayOp.h" -#include "StatementGoto.h" -#include "StringUtils.h" -#include "FactMgr.h" - -using namespace std; - -#define BINARY_REDUCTION_LIMIT 18 - -struct binary_reduced_stm { - string cmd; - string stm; - int len; -}; - -std::ostream & -ReducerOutputMgr::get_main_out() -{ - if (ofile_) return *ofile_; - if (!CGOptions::output_file().empty()) { - ofile_ = new ofstream(CGOptions::output_file().c_str()); - return *ofile_; - } - else { - return std::cout; - } -} - -ReducerOutputMgr::ReducerOutputMgr() -: ofile_(NULL) -{ - reducer = CGOptions::get_reducer(); - assert(reducer); -} - -ReducerOutputMgr::~ReducerOutputMgr() -{ - if (ofile_) { - ofile_->close(); - delete ofile_; - } -} - -void -ReducerOutputMgr::OutputHeader(int argc, char *argv[], unsigned long /*seed*/) -{ - // output shortened header: csmith options + random_inc.h include - ostream& out = get_main_out(); - out << "// Options: "; - if (argc <= 1) { - out << " (none)"; - } else { - for (int i = 1; i < argc; ++i) { - out << " " << argv[i]; - } - } - out << endl; - out << "#include \"csmith.h\"" << endl << endl; -} - -void -ReducerOutputMgr::output_var(const Variable* v, std::ostream &out, int indent) -{ - if (!reducer->is_var_init_reduced(v)) { - v->OutputDef(out, indent); - } - else { - string init = reducer->map_reduced_var_inits[v]; - output_tab(out, indent); - v->OutputDecl(out); - out << " = " << init << ";" << endl; - } -} - -void -ReducerOutputMgr::output_vars(const vector &vars, std::ostream &out, int indent) -{ - size_t i; - int dimen = 0; - vector avs; - // print used vars, and find the max dimension of all array variables - for (i=0; iis_var_used(v)) continue; - output_var((const ArrayVariable*)v, out, indent); - if (v->isArray) { - const ArrayVariable* av = (const ArrayVariable*)(v); - if (!av->no_loop_initializer()) { - if (av->get_dimension() > (size_t)dimen) { - dimen = av->get_dimension(); - } - avs.push_back(av); - } - } - } - // output array initializers - if (dimen > 0) { - vector &ctrl_vars = Variable::get_new_ctrl_vars(); - OutputArrayCtrlVars(ctrl_vars, out, dimen, indent); - for (i=0; ioutput_init(out, av->init, ctrl_vars, indent); - } - } -} - -int -ReducerOutputMgr::output_block(const Block* blk, std::ostream& out, int indent, bool no_bracelet) -{ - size_t i; - if (reducer->is_blk_deleted(blk)) { - output_tab(out, indent + 1); - out << ";" << endl; - return 0; - } - // see Reducer::config_diff_active_blks - if (reducer->replaced_stms.find(blk) != reducer->replaced_stms.end() && reducer->replaced_stms[blk] == NULL) { - output_tab(out, indent + 1); - out << reducer->map_pre_stm_assigns[blk] << endl; - return 0; - } - - if (!no_bracelet) { - output_open_encloser("{", out, indent); - } - // add support for "--math-notmp" - if (CGOptions::math_notmp()) { - blk->OutputTmpVariableList(out, indent); - } - output_vars(blk->local_vars, out, indent); - - // dump global state for top level block if necessary - if (blk->parent == NULL) { - output_global_state_for_func(blk->func, out, indent); - } - // dump "entering block ..." information - output_block_entry_msg(blk, out, indent); - if (reducer->dump_stms_in_blocks == blk->func) { - string fname = blk->func->name; - if (fname == "func_1") fname = "main"; - string s = "// " + fname + " block " + StringUtils::int2str(blk->stm_id) + " ["; - for (i=0; istms.size(); i++) { - if (i > 0) { - s += ":"; - } - s += StringUtils::int2str(blk->stms[i]->stm_id); - } - s += "]"; - output_tab(out, indent); - out << s << endl; - } - - FactMgr* fm = get_fact_mgr_for_func(blk->func); - for (i=0; istms.size(); i++) { - const Statement* stm = blk->stms[i]; - output_stm(stm, out, fm, indent); - } - - if (!no_bracelet) { - output_close_encloser("}", out, indent, true); - } - outputln(out); - return 0; -} - -int -ReducerOutputMgr::output_func_header(const Function* f, std::ostream& out) -{ - // output function header - out << "static "; - f->rv->qfer.output_qualified_type(f->return_type, out); - out << " " << f->name << "("; - size_t i; - bool first = true; - for (i=0; iparam.size(); i++) { - const Variable* var = f->param[i]; - if (!reducer->is_param_dropped(f, i)) { - if (!first) { - out << ", "; - } - var->output_qualified_type(out); - out << " " << var->name; - first = false; - } - } - out << ")"; - return 0; -} - -void -ReducerOutputMgr::output_crc_lines(std::ostream& out) -{ - // declare loop variables if they are used in crc lines - for (char c = 'i'; c <= 'z'; c++) { - string pattern = string("; ") + c + "++)"; - if (reducer->crc_lines.find(pattern) != string::npos) { - output_tab(out, 1); - out << "int " << c << " = 0;" << endl; - } - } - if (reducer->crc_lines.find("print_hash_value") != string::npos) { - output_tab(out, 1); - out << "int print_hash_value = 0;" << endl; - } - // print the real CRC lines - output_tab(out, 1); - out << reducer->crc_lines << endl; -} - -int -ReducerOutputMgr::output_main_func(std::ostream& out) -{ - size_t i; - const Function* f = reducer->main; - if (f->param.size() == 0 && (reducer->main_str == "" || reducer->main_str.find("func_")==0)) { - out << "int main(void)" << endl; - if (reducer->is_blk_deleted(f->body)) { - out << "{" << endl; - if (!reducer->crc_lines.empty()) { - output_crc_lines(out); - } - output_tab(out, 1); - out << "return 0;" << endl; - out << "}" << endl; - } - else { - output_block(f->body, out, 0); - } - } - else { - output_func(f, out); - out << endl << "int main(void) {" << endl; - output_tab(out, 1); - // break up function call and parameters, and skip parameters that are reduced - vector strs; - StringUtils::split_string(reducer->main_str, strs, "();"); - assert(strs.size() == 2 || strs.size() == 1); - string func_name = strs[0]; - out << func_name << "("; - if (strs.size() == 2) { - const Function* f = find_function_by_name(func_name); - assert(f); - string params = strs[1]; - strs.clear(); - StringUtils::split_string(params, strs, ","); - bool first = true; - for (i=0; iis_param_dropped(f, i)) { - if (!first) { - out << ", "; - } - out << strs[i]; - first = false; - } - } - } - out << ");" << endl; - output_tab(out, 1); - out << "return 0;" << endl << "}"; - outputln(out); - } - return 0; -} -int -ReducerOutputMgr::output_func(const Function* f, std::ostream& out) -{ - output_func_header(f, out); - out << endl; - output_block(f->body, out, 0); - return 0; -} - -void -ReducerOutputMgr::output_pre_stm_assigns(const Statement* stm, std::ostream &out, int indent) -{ - if (reducer->map_pre_stm_assigns.find(stm) != reducer->map_pre_stm_assigns.end()) { - string assigns = reducer->map_pre_stm_assigns[stm]; - output_tab(out, indent); - out << assigns; - outputln(out); - } -} - -void -ReducerOutputMgr::output_block_entry_msg(const Block* blk, std::ostream &out, int indent) -{ - if (reducer->dump_block_entry) { - const Statement* s = blk->find_container_stm(); - if (s && s->eType == eFor) { - output_tab(out, indent); - out << "static int cnt = 0;" << endl; - output_tab(out, indent++); - out << "if (cnt++ < 1000) {" << endl; - } - string msg = "entering " + blk->func->name + "@" + StringUtils::int2str(blk->stm_id) + "\\n"; - output_print_str(out, msg, "", indent); - outputln(out); - if (s && s->eType == eFor) { - output_tab(out, --indent); - out << "}" << endl; - } - } -} - -void -ReducerOutputMgr::output_pre_stm_values(const Statement* stm, std::ostream &out, FactMgr* fm, int indent) -{ - if (find_stm_in_set(reducer->dump_value_before, stm) != -1) { - assert(stm->parent); - string blkid = StringUtils::int2str(stm->parent->stm_id); - string id = StringUtils::int2str(stm->stm_id); - out << "/* replacing " << blkid << " " << id << " before" << endl; - output_write_var_values("values before " + id + "...\\n", stm, out, fm, indent, true); - out << "*/" << endl; - } -} - -void -ReducerOutputMgr::output_post_stm_values(const Statement* stm, std::ostream &out, FactMgr* fm, int indent) -{ - // print value of variables that may have been written by the statement - if (find_stm_in_set(reducer->dump_value_after, stm) != -1) { - assert(stm->parent); - string blkid = StringUtils::int2str(stm->parent->stm_id); - string id = StringUtils::int2str(stm->stm_id); - out << "/* replacing " << blkid << " " << id << " after" << endl; - output_write_var_values("values after " + id + "...\\n", stm, out, fm, indent, true); - output_memory_addrs(stm, out, indent); - out << "*/" << endl; - } -} - -/* - * compute the real "meaningful" length of statement or expression - * anything not affecting the program complexity is ignored - */ -int real_length(string exp) -{ - int len = 0; - size_t i; - for (i=1; i= '0' && exp[i] <= '9') { - len -= 1; - } - if (((exp[i-1] >= '0' && exp[i-1] <= '9') || (exp[i-1] >= 'A' && exp[i-1] <= 'F')) && - ((exp[i] >= '0' && exp[i] <= '9') || (exp[i] >= 'A' && exp[i] <= 'F'))) { - len -= 1; - } - len++; - } - return len; -} - -/* - * insert an output for a binary reduced statement into the ordered array - */ -void insert_alt_stm_cmd(vector& stms, const string& cmd, const string& stm) -{ - int len = real_length(stm); - struct binary_reduced_stm alt = {cmd, stm, len}; - for (size_t i=0; i& binarys, vector& ids) -{ - int s; - while (binarys.size() > BINARY_REDUCTION_LIMIT) { - for (s = binarys.size() - 1; s>=0; s--) { - const FunctionInvocationBinary* fib = binarys[s]; - vector dummy1; - vector dummy2; - if (reducer->find_binary_operations(fib->param_value[0], dummy1, dummy2, true) == 0 && - reducer->find_binary_operations(fib->param_value[1], dummy1, dummy2, true) == 0) { - binarys.erase(binarys.begin() + s); - ids.erase(ids.begin() + s); - break; - } - } - } - // if still more than limit, delete the last few binary operations - if (binarys.size() > BINARY_REDUCTION_LIMIT) { - int extra = binarys.size() - BINARY_REDUCTION_LIMIT; - for (s=0; sreduce_binaries || stm->get_direct_invocation() == NULL) return; - vector binarys; - vector ids; - reducer->find_binary_operations(stm, binarys, ids, true); - assert(ids.size() == binarys.size()); - - // reduce runtime by limiting the number of binary operations we try to reduce - limit_binarys(binarys, ids); - vector combinations; - vector left_trees, right_trees; - - reducer->build_left_right_binary_trees(binarys, left_trees, right_trees); - assert(binarys.size() == left_trees.size() && binarys.size() == right_trees.size()); - - // special case: output "if (1)" for if conditions - if (stm->eType == eIfElse) { - output_tab(out, indent); - out << "// [" << StringUtils::int2str(stm->stm_id) << ":0:-1] " << "if (1)" << endl; - } - // output the selections at single points - for (i=0; istm_id); - const Expression* op = fi->param_value[j]; - reducer->map_reduced_invocations[fi] = op; - out << ":" + StringUtils::int2str(ids[i]) << ":" << StringUtils::int2str(j+1) << "] "; - stm->eType == eIfElse ? ((const StatementIf*)stm)->output_condition(out, 0, 0) : stm->Output(out, 0, 0); - reducer->map_reduced_invocations.erase(fi); - } - } - if (binarys.size()) { - output_tab(out, indent); - out << "// end of single choices" << endl; - } - intvec orig; - for (i=0; i alt_stms; - for (i=1; istm_id); - vector reduced_invokes; - for (j=0; jparam_value[choice - 1]; - reducer->map_reduced_invocations[fi] = op; - cmd += ":" + StringUtils::int2str(ids[j]) + ":" + StringUtils::int2str(choice); - reduced_invokes.push_back(fi); - } - } - cmd += "]"; - ostringstream oss; - stm->eType == eIfElse ? ((const StatementIf*)stm)->output_condition(oss, 0, 0) : stm->Output(oss, 0, 0); - insert_alt_stm_cmd(alt_stms, cmd, oss.str()); - // impose an artificial upper limit on number of alternatives so reducer can finish quicker - if (alt_stms.size() >= 10000) { - break; - } - - for (j=0; jmap_reduced_invocations.erase(reduced_invokes[j]); - } - } - for (i=0; iis_blk_deleted(si->get_true_branch()) && reducer->is_blk_deleted(si->get_false_branch())) { - assert(0); // should have been taken care in get_used_vars_and_funcs_and_labels - } - else if (reducer->is_blk_deleted(si->get_false_branch())) { - if (reducer->replaced_stms.find(si) != reducer->replaced_stms.end() && reducer->replaced_stms[si] == si->get_true_branch()) { - output_block(si->get_true_branch(), out, indent, true); - } else { - if (reducer->output_if_ids) { - out << "/* if reduction candidate: " << StringUtils::int2str(si->stm_id) << " */" << endl; - } - si->output_condition(out, 0, indent); - output_block(si->get_true_branch(), out, indent); - } - } - else if (reducer->is_blk_deleted(si->get_true_branch())) { - if (reducer->replaced_stms.find(si) != reducer->replaced_stms.end() && reducer->replaced_stms[si] == si->get_false_branch()) { - output_block(si->get_false_branch(), out, indent, true); - } else { - if (reducer->output_if_ids) { - out << "/* if reduction candidate: " << StringUtils::int2str(si->stm_id) << " */" << endl; - } - // special case: if condition is replaced, don't flip it by outputting "!" - if (reducer->is_exp_replaced(si->get_test())) { - si->output_condition(out, 0, indent); - } - else { - output_tab(out, indent); - out << "if (!("; - si->get_test()->Output(out); - out << "))" << endl; - } - output_block(si->get_false_branch(), out, indent); - } - } - else { - si->output_condition(out, 0, indent); - output_block(si->get_true_branch(), out, indent); - output_tab(out, indent); - out << "else" << endl; - output_block(si->get_false_branch(), out, indent); - } - } - -void -ReducerOutputMgr::output_reduced_stm(const Statement* stm, std::ostream &out, int indent) -{ - vector blks; - stm->get_blocks(blks); - if (blks.empty()) { - // insert printing value for focus variable - if (stm->eType == eReturn) { - // output value(s) of monitor variable(s) before return - if (reducer->dump_monitored_var && stm->func->feffect.is_written_partially(reducer->monitored_var)) { - output_tab(out, indent); - string vname = reducer->monitored_var->name; - out <<"printf(\" " << vname << " = %d\", " << vname <<");"; - outputln(out); - output_tab(out, indent); - out << "printf(\" before leaving " << stm->func->name << ":%d\\n\", call_id);"; - outputln(out); - } - // output value of key variable for the main function before return - else if (stm->func == reducer->main) { - if (reducer->monitored_var) { - ostringstream oss; - const Variable* key = reducer->monitored_var; - oss << "checksum " << key->get_actual_name() << " = "; - key->output_runtime_value(out, oss.str(), "\\n", indent, 0); - outputln(out); - } - } - if (stm->func == GetFirstFunction()) { - // output crc lines if they are required - if (!reducer->crc_lines.empty()) { - output_crc_lines(out); - } - output_tab(out, indent); - out << "return 0;" << endl; - return; - } - } - else if (stm->eType == eGoto && reducer->dump_block_entry) { - const StatementGoto* sg = (const StatementGoto*)stm; - output_tab(out, indent); - out << "if ("; - sg->test.Output(out); - out << ")" << endl; - output_open_encloser("{", out, indent); - output_block_entry_msg(sg->dest->parent, out, indent); - output_tab(out, indent); - out << "goto " << sg->label << ";" << endl; - output_close_encloser("}", out, indent); - return; - } - stm->Output(out, 0, indent); - return; - } - - switch (stm->eType) { - case eIfElse: - output_if_stm((const StatementIf*)stm, out, indent); - break; - case eFor: { - const StatementFor* sf = (const StatementFor*)stm; - if (reducer->is_blk_deleted(sf->get_body())) { - bool keep_body = false; - const Variable* cv = sf->get_init()->get_lhs()->get_var(); - if (cv == reducer->monitored_var) { - vector labels, req_labels; - if (sf->get_body()->find_contained_labels(labels)) { - size_t i; - for (i=0; iis_label_used(labels[i])) { - req_labels.push_back(labels[i]); - } - } - if (req_labels.size() > 0) { - sf->output_header(out, indent); - for (i=0; iget_init()->Output(out, 0, indent); - } - } - else { - sf->output_header(out, indent); - output_block(sf->get_body(), out, indent); - } - break; - } - case eArrayOp: { - const StatementArrayOp* sa = (const StatementArrayOp*)stm; - if (reducer->is_blk_deleted(sa->body)) { - break; - } - sa->output_header(out, indent); - output_block(sa->body, out, indent); - break; - } - default: break; - } -} -void -ReducerOutputMgr::output_stm(const Statement* stm, std::ostream &out, FactMgr* fm, int indent) -{ - string str_out; - // print pre-statement assignments - output_pre_stm_assigns(stm, out, indent); - output_pre_stm_values(stm, out, fm, indent); - - if (reducer->replaced_stms.find(stm) != reducer->replaced_stms.end()) { - const Statement* alt_stm = reducer->replaced_stms[stm]; - vector labels; - // special case for goto target: if the jump source is still around, we have to keep the label somehow - if (reducer->find_missing_labels(stm, alt_stm, labels)) { - for (size_t i=0; ieType == eBlock) { - output_block((const Block*)alt_stm, out, indent, true); - } else if (alt_stm) { - output_stm(reducer->replaced_stms[stm], out, fm, indent); - } - return; - } - - if (stm->func == reducer->rewrite_calls_inside) { - rewrite_func_calls(stm, out, indent); - } - // print lable for jump detination - string label = reducer->find_jump_label(stm); - label.empty() ? (out << "") : (out << label << ":" << endl); - - output_alt_exprs(stm, out, indent); - - output_reduced_stm(stm, out, indent); - - output_post_stm_values(stm, out, fm, indent); -} - -void -ReducerOutputMgr::rewrite_func_call(const Statement* stm, const FunctionInvocation* invoke, string tmp_id, std::ostream& out, int indent) -{ - // output pre-values - FactMgr* fm = get_fact_mgr_for_func(stm->func); - output_write_var_values("begin of values before rewrite...\\n", stm, out, fm, indent); - // output " t1 = " - const Type* type = &(invoke->get_type());; - Expression* tmp_call = new ExpressionFuncall(*(invoke->clone())); - CVQualifiers qfer = CVQualifiers::random_qualifiers(type, 0, 0); - Variable* tmp_var = Variable::CreateVariable(tmp_id, type, tmp_call, &qfer); - tmp_var->OutputDef(out, indent); - - // output the value of the tmp variable - ostringstream oss; - oss << "<" << tmp_id << " = "; - tmp_var->output_runtime_value(out, oss.str(), ">\\n", indent); - outputln(out); - - // output post values - output_write_var_values("begin of values after rewrite...\\n", stm, out, fm, indent); - if (reducer->is_ptr_written_in_stm(stm)) { - output_memory_addrs(stm, out, indent); - } - ExpressionVariable* tmp_ev = new ExpressionVariable(*tmp_var); - reducer->map_reduced_invocations[invoke] = tmp_ev; - // output stm with call replaced with tmp_id - (stm->eType == eIfElse) ? ((const StatementIf*)stm)->output_condition(out, 0, indent) : stm->Output(out, 0, indent); - - // clean up - reducer->map_reduced_invocations.erase(invoke); - delete tmp_ev; - delete tmp_var; -} - -int -ReducerOutputMgr::rewrite_func_calls(const Statement* stm, std::ostream &out, int indent) -{ - vector calls; - const FunctionInvocation* fi = stm->get_direct_invocation(); - if (fi) { - vector ids; - string init_name = "t" + StringUtils::int2str(stm->stm_id); - reducer->find_called_funcs(fi, init_name, calls, ids); - if (!calls.empty()) { - size_t i; - for (i=0; iget_type().is_aggregate()) { - continue; - } - output_tab(out, indent); - out << "/* " << "replacing " << ids[i] << endl; - rewrite_func_call(stm, calls[i], ids[i], out, indent); - output_tab(out, indent); - out << "*/" << endl; - } - } - } - return calls.size(); -} - -/* - * dumping global states at the function entry point for path shortcutting purpose - */ -void -ReducerOutputMgr::output_global_state_for_func(const Function* f, std::ostream &out, int indent) -{ - if (!reducer->dump_monitored_var) return; - size_t i; - if (reducer->monitored_func && f == reducer->main) { - output_global_values("values before main\\n", out, indent); - } - // output statement to increment call counter for delta purpose - if (f->feffect.is_written(reducer->monitored_var)) { - output_tab(out, indent); - out <<"int call_id = ++global_call_id;"; - outputln(out); - - // output global state if we are interested in this particular function call - if (f == reducer->monitored_func) { - assert(reducer->monitored_call_id != ""); - output_tab(out, indent); - out << "if (call_id == " << reducer->monitored_call_id << ")" << endl; - output_open_encloser("{", out, indent); - - // dump addresses of global variables - output_memory_addrs(f->body, out, indent); - - // dump global state at the beginning of this call - output_global_values("values after main and before " + f->name + "\\n", out, indent); - - // output parameter values for this call - output_print_str(out, "\\n", "", indent); - output_print_str(out, f->name + "(", "", indent); - bool first = true; - for (i=0; iparam.size(); i++) { - const Variable* v = f->param[i]; - if (reducer->is_var_used(v)) { - if (!first) { - output_print_str(out, ", ", "", 0); - } - v->output_runtime_value(out, "", "", 0); - first = false; - } - } - output_print_str(out, ");\\n", "", indent); - output_close_encloser("}", out, indent); - outputln(out); - } - } -} - -void -ReducerOutputMgr::output_write_var_values(string title, const Statement* stm, std::ostream &out, FactMgr* fm, int indent, bool cover_block_writes) -{ - output_print_str(out, title, "", indent); - outputln(out); - size_t i; - const Statement* s = stm; - if (cover_block_writes) { - s = stm->parent; - assert(s); - } - const vector& write_vars = fm->map_stm_effect[s].get_write_vars(); - for (i=0; iis_visible(stm->parent) && reducer->is_var_used(wvar)) { - // output printf statements to record the type of the variable - ostringstream oss; - //wvar->OutputDecl(oss); - string dimen = StringUtils::int2str(wvar->get_dimension()); - oss << "<" << wvar->get_actual_name() << "(" << dimen << ")" << " = "; - wvar->output_runtime_value(out, oss.str(), ">\\n", indent); - outputln(out); - } - } - output_print_str(out, "end of values\\n", "", indent); - outputln(out); -} - -void -ReducerOutputMgr::output_memory_addrs(const Statement* stm, std::ostream& out, int indent) -{ - size_t i; - vector all_vars = VariableSelector::find_all_visible_vars(stm->parent); - //combine_variable_sets(beffect.get_read_vars(), beffect.get_write_vars(), all_vars); - //remove_field_vars(all_vars); - output_print_str(out, "begin memory dump \\n", "", indent); - outputln(out); - for (i=0; iis_var_used(v)) { - v->output_addressable_name(out, indent); - } - } - output_print_str(out, "end memory dump \\n", "", indent); - outputln(out); -} - -void -ReducerOutputMgr::output_global_values(string header, std::ostream& out, int indent) -{ - size_t i; - // dump values of global variables - // "begin global vars entering main \\n" - output_print_str(out, header, "", indent); - outputln(out); - for (i=0; iused_vars.size(); i++) { - const Variable* v = reducer->used_vars[i]; - if (v->is_global()) { - ostringstream oss; - string dimen = StringUtils::int2str(v->get_dimension()); - oss << "<" << v->get_actual_name() << "(" << dimen << ")" << " = "; - v->output_runtime_value(out, oss.str(), ">\\n", indent); - outputln(out); - } - } - output_print_str(out, "end of values\\n", "", indent); - outputln(out); -} - -void -ReducerOutputMgr::OutputStructUnions(ostream& out) -{ - size_t i; - for (i=0; iused_vars.size(); i++) { - const Type* t = reducer->used_vars[i]->type; - if (t->is_aggregate()) { - Type* type = Type::find_type(t); - assert(type); - OutputStructUnion(type, out); - } - } -} - -void -ReducerOutputMgr::output_artificial_globals(ostream& out) -{ - for (size_t i=0; iartificial_globals.size(); i++) { - out << reducer->artificial_globals[i] << ";" << endl; - } -} - -void -ReducerOutputMgr::output_tail(ostream& out) -{ - size_t i; - if (reducer->dump_block_entry || reducer->dump_all_block_info) { - out << "// all blocks: "; - // print from backward so the leaf blocks will be printed last - for (i=reducer->all_blks.size(); i>0; i--) { - out << StringUtils::int2str(reducer->all_blks[i-1]) << ", "; - } - out << endl; - } - if (reducer->drop_params && reducer->dump_dropped_params) { - out << "// all dropped parameters: "; - for (i=0; idropped_params.size(); i++) { - out << reducer->dropped_params[i]->name << ", "; - } - out << endl; - } -} - -void -ReducerOutputMgr::Output() -{ - // configure reducer - reducer->configure(); - - // find all the functions and variables that are used after reductions - const Function* main = reducer->main; - reducer->get_used_vars_and_funcs_and_labels(main->body, reducer->used_vars, reducer->used_funcs, reducer->used_labels); - reducer->expand_used_vars(); - - std::ostream &out = get_main_out(); - OutputStructUnions(out); - output_vars(*VariableSelector::GetGlobalVariables(), out, 0); - output_artificial_globals(out); - size_t i; - for (i=0; iused_funcs.size(); i++) { - output_func_header(reducer->used_funcs[i], out); - out << ";" << endl; - } - for (int j=reducer->used_funcs.size(); j>0; j--) { - const Function* f = reducer->used_funcs[j-1]; - outputln(out); - output_func(f, out); - outputln(out); - } - outputln(out); - output_main_func(out); - output_tail(out); -} - diff --git a/src/ReducerOutputMgr.h b/src/ReducerOutputMgr.h deleted file mode 100644 index 516e8e66c..000000000 --- a/src/ReducerOutputMgr.h +++ /dev/null @@ -1,98 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2015 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef REDUCER_OUTPUT_MGR_H -#define REDUCER_OUTPUT_MGR_H - -#include -#include -#include -#include -#include "OutputMgr.h" -#include "util.h" - -class Reducer; -class FactMgr; -class Block; -class Function; -class Statement; -class StatementIf; -class Expression; -class FunctionInvocation; -class FunctionInvocationBinary; - -using namespace std; - -class ReducerOutputMgr : public OutputMgr { -public: - ReducerOutputMgr(); - virtual ~ReducerOutputMgr(); - virtual void OutputHeader(int argc, char *argv[], unsigned long seed); - virtual void Output(); - - virtual std::ostream &get_main_out(); - - void rewrite_func_call(const Statement* stm, const FunctionInvocation* invoke, string id, std::ostream& out, int indent); - int rewrite_func_calls(const Statement* stm, std::ostream &out, int indent); - void output_alt_exprs(const Statement* stm, std::ostream &out, int indent); - - void output_write_var_values(string title, const Statement* stm, std::ostream &out, FactMgr* fm, int indent, bool cover_block_writes=false); - void output_memory_addrs(const Statement* stm, std::ostream& out, int indent); - void output_global_values(string header, std::ostream& out, int indent); - void output_tail(ostream& out); - void output_crc_lines(std::ostream& out); - - void output_vars(const vector &vars, std::ostream &out, int indent); - void output_var(const Variable* v, std::ostream &out, int indent); - int output_func_header(const Function* f, std::ostream& out); - int output_main_func(std::ostream& out); - int output_func(const Function* f, std::ostream& out); - int output_funcs(std::ostream& out); - int output_block(const Block* blk, std::ostream& out, int indent, bool no_bracelet=false); - void output_if_stm(const StatementIf* si, std::ostream &out, int indent); - void output_reduced_stm(const Statement* stm, std::ostream &out, int indent); - void output_stm(const Statement* stm, std::ostream &out, FactMgr* fm, int indent); - void output_pre_stm_assigns(const Statement* stm, std::ostream &out, int indent); - void output_block_entry_msg(const Block* blk, std::ostream &out, int indent); - void output_pre_stm_values(const Statement* stm, std::ostream &out, FactMgr* fm, int indent); - void output_post_stm_values(const Statement* stm, std::ostream &out, FactMgr* fm, int indent); - void output_global_state_for_func(const Function* f, std::ostream &out, int indent); - void output_artificial_globals(ostream& out); - - virtual void OutputStructUnions(ostream& out); - void OutputGlobals(ostream& out); - -private: - void OutputGlobals(); - void limit_binarys(vector& binarys, vector& ids); - std::ofstream *ofile_; - Reducer* reducer; -}; - -#endif // REDUCER_OUTPUT_MGR_H diff --git a/src/SafeOpFlags.cpp b/src/SafeOpFlags.cpp index 5f5111f4e..05d45b6e2 100644 --- a/src/SafeOpFlags.cpp +++ b/src/SafeOpFlags.cpp @@ -41,7 +41,6 @@ #include "Error.h" #include "Probabilities.h" #include "DepthSpec.h" -#include "MspFilters.h" #include "CGOptions.h" using namespace std; @@ -169,9 +168,6 @@ SafeOpFlags::make_random_unary(const Type *rv_type, const Type *op1_type, eUnary // ISSUE: in the old code, is_func is always true // Probably need to be fixed later. flags->is_func_ = true; - - MspSafeOpSizeFilter *filter = new MspSafeOpSizeFilter(MAX_BINARY_OP); - Probabilities::register_extra_filter(pSafeOpsSizeProb, filter); if (rv_is_float) { assert(CGOptions::enable_float()); flags->op_size_ = sFloat; @@ -179,9 +175,6 @@ SafeOpFlags::make_random_unary(const Type *rv_type, const Type *op1_type, eUnary else { flags->op_size_ = (SafeOpSize)rnd_upto(MAX_SAFE_OP_SIZE-1, SAFE_OPS_SIZE_PROB_FILTER); } - Probabilities::unregister_extra_filter(pSafeOpsSizeProb, filter); - - delete filter; return flags; } @@ -221,9 +214,6 @@ SafeOpFlags::make_random_binary(const Type *rv_type, const Type *op1_type, const // Probably need to be fixed later. flags->is_func_ = true; - MspSafeOpSizeFilter *filter = new MspSafeOpSizeFilter(bop); - Probabilities::register_extra_filter(pSafeOpsSizeProb, filter); - if (rv_is_float) { assert(CGOptions::enable_float()); flags->op_size_ = sFloat; @@ -231,11 +221,6 @@ SafeOpFlags::make_random_binary(const Type *rv_type, const Type *op1_type, const else { flags->op_size_ = (SafeOpSize)rnd_upto(MAX_SAFE_OP_SIZE-1, SAFE_OPS_SIZE_PROB_FILTER); } - Probabilities::unregister_extra_filter(pSafeOpsSizeProb, filter); - ERROR_GUARD_AND_DEL2(NULL, flags, filter); - - //Probabilities::unregister_extra_filter(pSafeOpsSizeProb, filter); - delete filter; return flags; } diff --git a/src/SequenceFactory.cpp b/src/SequenceFactory.cpp index 4ffd3336a..a8e710737 100644 --- a/src/SequenceFactory.cpp +++ b/src/SequenceFactory.cpp @@ -37,8 +37,6 @@ #include #include #include "LinearSequence.h" -#include "SimpleDeltaSequence.h" -#include "DeltaMonitor.h" std::set SequenceFactory::seqs_; @@ -48,15 +46,8 @@ Sequence* SequenceFactory::make_sequence() { Sequence *seq = NULL; - - if (DeltaMonitor::is_running()) { - seq = DeltaMonitor::GetSequence(); - current_sep_char_ = DeltaMonitor::GetSepChar(); - } - else { - seq = new LinearSequence(LinearSequence::default_sep_char); - current_sep_char_ = LinearSequence::default_sep_char; - } + seq = new LinearSequence(LinearSequence::default_sep_char); + current_sep_char_ = LinearSequence::default_sep_char; assert(seq); seqs_.insert(seq); diff --git a/src/SimpleDeltaRndNumGenerator.cpp b/src/SimpleDeltaRndNumGenerator.cpp deleted file mode 100644 index 07662a892..000000000 --- a/src/SimpleDeltaRndNumGenerator.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2015, 2017 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#if HAVE_CONFIG_H -# include -#endif - -#ifdef WIN32 -#pragma warning(disable : 4786) /* Disable annoying warning messages */ -#endif -#include "SimpleDeltaRndNumGenerator.h" - -#include -#include -#include - -#include "CGOptions.h" -#include "Filter.h" -#include "SequenceFactory.h" -#include "Sequence.h" -#include "Error.h" -#include "RandomNumber.h" -#include "DefaultRndNumGenerator.h" -#include "DeltaMonitor.h" - -SimpleDeltaRndNumGenerator *SimpleDeltaRndNumGenerator::impl_ = 0; - -SimpleDeltaRndNumGenerator::SimpleDeltaRndNumGenerator(Sequence *concrete_seq) - : rand_depth_(0), - random_point_(0), - filter_depth_(0), - trace_string_(""), - seq_(concrete_seq) -{ - -} - -SimpleDeltaRndNumGenerator::~SimpleDeltaRndNumGenerator() -{ - SequenceFactory::destroy_sequences(); -} - -/* - * Singleton - */ -SimpleDeltaRndNumGenerator* -SimpleDeltaRndNumGenerator::make_rndnum_generator(const unsigned long /*seed*/) -{ - if (impl_) - return impl_; - - Sequence *seq = SequenceFactory::make_sequence(); - - seq->init_sequence(); - - impl_ = new SimpleDeltaRndNumGenerator(seq); - - impl_->random_point_ = SimpleDeltaRndNumGenerator::pure_rnd_upto(seq->sequence_length()); - - assert(impl_); - - return impl_; -} - -int -SimpleDeltaRndNumGenerator::random_choice (int bound, const Filter *f, const string *) -{ - assert(seq_); - - int rv = seq_->get_number(bound); - ++rand_depth_; - - if (rv == -1) { - Error::set_error(INVALID_SIMPLE_DELTA_SEQUENCE); - return -1; - } - - if (f) { - ++filter_depth_; - if (f->filter(rv)) { - Error::set_error(FILTER_ERROR); - return -1; - } - --filter_depth_; - } - switch_to_default_generator(); - return rv; -} - -/* - * - */ -void -SimpleDeltaRndNumGenerator::get_sequence(std::string &sequence) -{ - std::ostringstream ss; - seq_->get_sequence(ss); - sequence = ss.str(); -} - -std::string -SimpleDeltaRndNumGenerator::get_prefixed_name(const std::string &name) -{ - return name; -} - -/* - * Print the tracing information for debugging. - */ -std::string & -SimpleDeltaRndNumGenerator::trace_depth() -{ - return trace_string_; -} - -unsigned int -SimpleDeltaRndNumGenerator::rnd_upto(const unsigned int n, const Filter *f, const std::string *where) -{ - int x = random_choice(n, f, where); - assert(x == -1 || (x >= 0 && x < static_cast(n))); - return x; -} - -bool -SimpleDeltaRndNumGenerator::rnd_flipcoin(const unsigned int, const Filter *f, const std::string *where) -{ - int y = random_choice(2, f, where); - assert(y == -1 || (y >= 0 && y < 2)); - return y; -} - -unsigned long -SimpleDeltaRndNumGenerator::genrand(void) -{ - return AbsRndNumGenerator::genrand(); -} - -std::string -SimpleDeltaRndNumGenerator::RandomHexDigits( int num ) -{ - std::string str; - const char* hex1 = AbsRndNumGenerator::get_hex1(); - while (num--) { - int x = random_choice(16, NULL, NULL); - str += hex1[x]; - } - return str; -} - -std::string -SimpleDeltaRndNumGenerator::RandomDigits( int num ) -{ - std::string str; - const char* dec1 = AbsRndNumGenerator::get_dec1(); - while ( num-- ) - { - int x = random_choice(10, NULL, NULL); - str += dec1[x]; - } - - return str; -} - -unsigned int -SimpleDeltaRndNumGenerator::pure_rnd_upto(const unsigned int bound) -{ - assert(impl_); - return impl_->genrand() % bound; -} - -bool -SimpleDeltaRndNumGenerator::pure_rnd_flipcoin(const unsigned int p) -{ - assert(impl_); - bool rv = (impl_->genrand() % 100) < p; - return rv; -} - -void -SimpleDeltaRndNumGenerator::switch_to_default_generator() -{ - if (DeltaMonitor::no_delta_reduction() || rand_depth_ < impl_->random_point_ || impl_->filter_depth_ != 0) - return; - - //RNDNUM_GENERATOR old; - //old = RandomNumber::SwitchRndNumGenerator(rDefaultRndNumGenerator); - RandomNumber::SwitchRndNumGenerator(rDefaultRndNumGenerator); - DefaultRndNumGenerator *generator = dynamic_cast(RandomNumber::GetRndNumGenerator()); - generator->set_rand_depth(impl_->rand_depth_); -} - -void -SimpleDeltaRndNumGenerator::OutputStatistics(ostream &out) -{ - assert(impl_); - assert(impl_->seq_); - out << "/*" << std::endl; - out << "** This program was reduced by the simple delta reduction algorithm" << std::endl; -#ifdef WIN32 - out << "** at a random point " << (unsigned int)impl_->random_point_ << " with the sequence of length " << (unsigned int)impl_->seq_->sequence_length() << "." << std::endl; -#else - out << "** at a random point " << impl_->random_point_ << " with the sequence of length " << impl_->seq_->sequence_length() << "." << std::endl; -#endif - out << "*/" << std::endl; -} diff --git a/src/SimpleDeltaRndNumGenerator.h b/src/SimpleDeltaRndNumGenerator.h deleted file mode 100644 index 9e1b9eba7..000000000 --- a/src/SimpleDeltaRndNumGenerator.h +++ /dev/null @@ -1,99 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef SIMPLE_DELTA_RNDNUM_GENERATOR_H -#define SIMPLE_DELTA_RNDNUM_GENERATOR_H - -#include -#include - -#include "Common.h" -#include "CommonMacros.h" -#include "AbsRndNumGenerator.h" - -class Sequence; -class Filter; - -class SimpleDeltaRndNumGenerator : public AbsRndNumGenerator -{ -public: - virtual ~SimpleDeltaRndNumGenerator(); - - static SimpleDeltaRndNumGenerator *make_rndnum_generator(const unsigned long seed); - - static void OutputStatistics(ostream &out); - - virtual std::string get_prefixed_name(const std::string &name); - - virtual std::string& trace_depth(); - - virtual void get_sequence(std::string &sequence); - - virtual unsigned int rnd_upto(const unsigned int n, const Filter *f = NULL, const std::string *where = NULL); - - virtual bool rnd_flipcoin(const unsigned int p, const Filter *f = NULL, const std::string *where = NULL); - - virtual std::string RandomHexDigits( int num ); - - virtual std::string RandomDigits( int num ); - - virtual enum RNDNUM_GENERATOR kind() { return rSimpleDeltaRndNumGenerator; } - -private: - // ------------------------------------------------------------------------------------------ - SimpleDeltaRndNumGenerator(Sequence *concrete_seq); - - virtual unsigned long genrand(void); - - int random_choice(int bound, const Filter *f = NULL, const std::string *where = NULL); - - static unsigned int pure_rnd_upto(const unsigned int bound); - - static bool pure_rnd_flipcoin(const unsigned int p); - - void switch_to_default_generator(); - - // ---------------------------------------------------------------------------------------- - static SimpleDeltaRndNumGenerator *impl_; - - unsigned INT64 rand_depth_; - - unsigned INT64 random_point_; - - unsigned int filter_depth_; - - std::string trace_string_; - - Sequence *seq_; - - // disallow copy and assignment constructors - DISALLOW_COPY_AND_ASSIGN(SimpleDeltaRndNumGenerator); -}; - -#endif //SIMPLE_DELTA_RNDNUM_GENERATOR_H diff --git a/src/SimpleDeltaSequence.cpp b/src/SimpleDeltaSequence.cpp deleted file mode 100644 index 2194d803c..000000000 --- a/src/SimpleDeltaSequence.cpp +++ /dev/null @@ -1,218 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2015, 2017 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#if HAVE_CONFIG_H -# include -#endif - -#include "SimpleDeltaSequence.h" - -#include -#include -#include -#include -#include "SequenceLineParser.h" -#include "DeltaMonitor.h" -#include "CGOptions.h" - -using namespace std; - -// Represent the pair -class SimpleDeltaSequence::ValuePair -{ -public: - ValuePair(int value, int bound); - - ~ValuePair(); - - int get_value() const { return value_; } - - int get_bound() const { return bound_; } - - void set_value(int value) { value_ = value; } - - void set_bound(int bound) { bound_ = bound; } - - void set_value_bound(int value, int bound) { - value_ = value; - bound_ = bound; - } - -private: - int value_; - - int bound_; -}; - -SimpleDeltaSequence::ValuePair::ValuePair(int value, int bound) - : value_(value), - bound_(bound) -{ - -} - -SimpleDeltaSequence::ValuePair::~ValuePair( ) -{ - -} - -/////////////////////////////////////////////////////////////////// -const char SimpleDeltaSequence::default_sep_char = ','; - -SimpleDeltaSequence *SimpleDeltaSequence::impl_ = NULL; - -SimpleDeltaSequence::SimpleDeltaSequence(const char sep_char) - : sep_char_(sep_char), - current_pos_(0) -{ - // Nothing to do -} - -SimpleDeltaSequence::~SimpleDeltaSequence() -{ - // Nothing to do -} - -/* - * Create singleton instance. - */ -SimpleDeltaSequence* -SimpleDeltaSequence::CreateInstance(const char sep_char) -{ - if (impl_) - return impl_; - - impl_ = new SimpleDeltaSequence(sep_char); - assert(impl_); - - return impl_; -} - -/* - * - */ -bool -SimpleDeltaSequence::empty_line(const std::string &line) -{ - if (line.empty()) - return true; - size_t found = line.find_first_not_of("\t\n "); - return (found == string::npos); -} - -void -SimpleDeltaSequence::init_sequence() -{ - const std::string &fname = DeltaMonitor::get_input(); - assert(!fname.empty()); - - std::string line; - ifstream seqf(fname.c_str()); - assert("fail to open simple delta input file!" && seqf.is_open()); - - int i = 0; - while (!seqf.eof()) { - getline(seqf, line); - if (empty_line(line)) - continue; - std::vector v; - if(!SequenceLineParser >::parse_sequence(v, line, sep_char_)) - assert("bad simple delta input sequence!" && 0); - assert(v.size() == 2); - SimpleDeltaSequence::ValuePair *p = new SimpleDeltaSequence::ValuePair(v[0], v[1]); - sequence_[i] = p; - i++; - } - seqf.close(); -} - -void -SimpleDeltaSequence::add_number(int v, int bound, int k) -{ - SimpleDeltaSequence::ValuePair *p = new SimpleDeltaSequence::ValuePair(v, bound); - seq_map_[k] = p; -} - -int -SimpleDeltaSequence::get_number_by_pos(int /*pos*/) -{ - assert(0); - return 0; -} - -int -SimpleDeltaSequence::get_number(int bound) -{ - - SimpleDeltaSequence::ValuePair *p = sequence_[current_pos_]; - assert("SimpleDeltaSequence: get_number p is NULL!" && p); - int b = p->get_bound(); - assert("SimpleDeltaSequence: bound doesn't match!" && bound == b); - seq_map_[current_pos_] = p; - ++current_pos_; - return p->get_value(); -} - -void -SimpleDeltaSequence::clear() -{ - std::map::iterator i; - for (i = seq_map_.begin(); i != seq_map_.end(); ++i) { - assert((*i).second); - delete ((*i).second); - } - seq_map_.clear(); -} - -void SimpleDeltaSequence::output_one(ostream &out, - const SimpleDeltaSequence::ValuePair *p) -{ - assert(p); - int value = p->get_value(); - int bound = p->get_bound(); - out << value << sep_char_ << bound; - out << std::endl; -} - -void -SimpleDeltaSequence::get_sequence(ostream &out) -{ - assert(!seq_map_.empty()); - - std::map::iterator i; - for (i = seq_map_.begin(); i != seq_map_.end(); ++i) { - output_one(out, (*i).second); - } -} - -unsigned INT64 -SimpleDeltaSequence::sequence_length() -{ - return sequence_.size(); -} diff --git a/src/SimpleDeltaSequence.h b/src/SimpleDeltaSequence.h deleted file mode 100644 index d0ccc84ca..000000000 --- a/src/SimpleDeltaSequence.h +++ /dev/null @@ -1,84 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef SIMPLE_DELTA_SEQUENCE_H -#define SIMPLE_DELTA_SEQUENCE_H - -#include -#include -#include -#include -#include "Common.h" -#include "Sequence.h" - -class SimpleDeltaSequence : public Sequence { -public: - static SimpleDeltaSequence *CreateInstance(const char sep_char); - - virtual ~SimpleDeltaSequence(); - - virtual void init_sequence(); - - virtual unsigned INT64 sequence_length(); - - virtual void add_number(int v, int bound, int k); - - virtual int get_number(int bound); - - virtual int get_number_by_pos(int pos); - - virtual void clear(); - - virtual void get_sequence(std::ostream &); - - virtual char get_sep_char() const { return sep_char_; } - - static const char default_sep_char; - -private: - class ValuePair; - - explicit SimpleDeltaSequence(const char sep_char); - - bool empty_line(const std::string &line); - - void output_one(std::ostream &out, const ValuePair *p); - - std::map seq_map_; - - std::map sequence_; - - static SimpleDeltaSequence *impl_; - - const char sep_char_; - - unsigned INT64 current_pos_; -}; - -#endif // SIMPLE_DELTA_SEQUENCE_H diff --git a/src/SplatExtension.cpp b/src/SplatExtension.cpp deleted file mode 100644 index 96c795358..000000000 --- a/src/SplatExtension.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2008, 2009, 2010, 2011, 2015, 2017 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#if HAVE_CONFIG_H -# include -#endif - -#include "SplatExtension.h" -#include -#include "Type.h" -#include "Constant.h" -#include "ExtensionValue.h" - -using namespace std; - -SplatExtension::SplatExtension() -{ - -} - -SplatExtension::~SplatExtension() -{ - std::vector::iterator i; - for (i = values_.begin(); i != values_.end(); ++i) { - delete (*i); - } - values_.clear(); -} - -void -SplatExtension::GenerateValues() -{ - vector::iterator i; - for (i = values_.begin(); i != values_.end(); ++i) { - const Type *type = (*i)->get_type(); - Constant *c = Constant::make_random(type); - (*i)->set_value(c); - } -} - -void -SplatExtension::output_symbolics(ostream &out) -{ - std::vector::iterator i; - out << "#ifdef __SPLAT__" << endl; - for (i = values_.begin(); i != values_.end(); ++i) { - assert(*i); - out << AbsExtension::tab_; - int bits = (*i)->get_type()->SizeInBytes() * 8; - out << "setInput(&" << (*i)->get_name() << ", " << bits << ", "; - Constant *value = (*i)->get_value(); - assert(value); - value->Output(out); - out << ");" << endl; - } - out << "#endif" << endl << endl; -} - -void -SplatExtension::OutputHeader(std::ostream &out) -{ - out << "#ifdef __SPLAT__" << endl; - out << "#include \"../includes/instrument.h\"" << endl; - out << "#endif" << endl; -} - -void -SplatExtension::OutputTail(std::ostream &out) -{ - out << "#ifdef __SPLAT__" << endl; - out << AbsExtension::tab_ << "__splat_exit(ExitNoBug);" << endl; - out << "#else" << endl; - out << AbsExtension::tab_ << "return 0;" << endl; - out << "#endif" << endl; -} - -void -SplatExtension::OutputInit(std::ostream &out) -{ - out << "#ifdef __SPLAT__" << endl; - out << "void __splat_instrumentedCode()" << endl; - out << "#else" << endl; - out << "int main(void)" << endl; - out << "#endif" << endl; - out << "{" << endl; - AbsExtension::default_output_definitions(out, values_, true); - output_symbolics(out); -} - -void -SplatExtension::OutputFirstFunInvocation(std::ostream &out, FunctionInvocation *invoke) -{ - AbsExtension::OutputFirstFunInvocation(out, invoke); -} - diff --git a/src/SplatExtension.h b/src/SplatExtension.h deleted file mode 100644 index e34e92d07..000000000 --- a/src/SplatExtension.h +++ /dev/null @@ -1,67 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef SPLAT_EXTENSION_H -#define SPLAT_EXTENSION_H - -#include -#include -#include -#include "AbsExtension.h" -#include "CVQualifiers.h" - -class ExtensionValue; - -class SplatExtension : public AbsExtension { - friend class ExtensionMgr; -public: - virtual void GenerateValues(); - - virtual void OutputInit(std::ostream &out); - - virtual void OutputFirstFunInvocation(std::ostream &out, FunctionInvocation *invoke); - - virtual void OutputHeader(std::ostream &out); - - virtual void OutputTail(std::ostream &out); - - virtual std::vector &get_values() { return values_; } - -private: - - void output_symbolics(std::ostream &out); - - std::vector values_; - - SplatExtension(); - - ~SplatExtension(); -}; - -#endif // SPLAT_EXTENSION_H diff --git a/src/Variable.cpp b/src/Variable.cpp index c42d96cab..2d3356fd9 100644 --- a/src/Variable.cpp +++ b/src/Variable.cpp @@ -72,7 +72,6 @@ using namespace std; -// Yang: I changed the definition of ctrl_vars, and ReducerMgr might be affected std::vector< std::vector* > Variable::ctrl_vars_vectors; unsigned long Variable::ctrl_vars_count;