void CLProgramGenerator::goGenerator() {
  // Initialise probabilies.
  CLExpression::InitProbabilityTable();
  CLStatement::InitProbabilityTable();
  // Create vector types.
  Vector::GenerateVectorTypes();
  // Initialise function tables.
  FunctionInvocationBuiltIn::InitTables();
  // Initialise Variable objects used for thread identifiers.
  ExpressionID::Initialise();
  // Initialize runtime parameters;
  InitRuntimeParameters();
  // Initalize atomic parameters
  if (CLOptions::atomics())
    ExpressionAtomic::InitAtomics();
  // Initialise buffers used for inter-thread communication.
  StatementComm::InitBuffers();
  // Initialise Message Passing data.
  MessagePassing::Initialise();

  // Expects argc, argv and seed. These vars should really be in the output_mgr.
  output_mgr_->OutputHeader(0, NULL, seed_);

  // This creates the random program, the rest handles post-processing and
  // outputting the program.
  GenerateAllTypes();
  GenerateFunctions();

  // If tracking divergence is set, perform the tracking now.
  std::unique_ptr<Divergence> div;
  if (CLOptions::track_divergence()) {
    div.reset(new Divergence());
    div->ProcessEntryFunction(GetFirstFunction());
  }

  // If EMI block generation is set, prune them.
  if (CLOptions::emi())
    EMIController::GetEMIController()->PruneEMISections();

  // If atomic blocks are generated, add operations for the special values
  if (CLOptions::atomics())
    StatementAtomicResult::GenSpecialVals();

  // If atomic reductions are generated, add the hash buffer
  if (CLOptions::atomic_reductions())
    StatementAtomicReduction::RecordBuffer();

  // If Message Passing is enabled, create orderings and message updates.
  if (CLOptions::message_passing())
    MessagePassing::CreateMessageOrderings();

  // At this point, all the global variables that have been created throughout
  // program generation should have been created. Any global variables added to
  // VariableSelector's global list after this point must be added to globals
  // manually, or the name will not be prepended with the global struct.
  Globals *globals = Globals::GetGlobals();

  // Once the global struct is created, we add the global memory buffers.
  // Adding global memory buffers to do with atomic expressions.
  if (CLOptions::atomics()) {
    ExpressionAtomic::AddVarsToGlobals(globals);
  }

  // Add the reduction variables for atomic reductions to the global struct
  if (CLOptions::atomic_reductions())
    StatementAtomicReduction::AddVarsToGlobals(globals);

  // Now add the input data for EMI sections if specified.
  if (CLOptions::emi())
    for (MemoryBuffer *mb :
        *EMIController::GetEMIController()->GetItemisedEMIInput())
      globals->AddGlobalMemoryBuffer(mb);

  // Add the 9 variables used for the identifiers.
  if (CLOptions::fake_divergence())
    ExpressionID::AddVarsToGlobals(globals);

  // Add buffers used for inter-thread comm.
  if (CLOptions::inter_thread_comm())
    StatementComm::AddVarsToGlobals(globals);

  // Add messages for message passing.
  if (CLOptions::message_passing())
    MessagePassing::AddMessageVarsToGlobals(globals);

  // If barriers have been set, use the divergence information to place them.
  if (CLOptions::barriers()) {
    if (CLOptions::divergence()) GenerateBarriers(div.get(), globals);
    else { /*TODO Non-div barriers*/ }
  }

  if (CLOptions::small())
    CLSmith::CLVariable::ParseUnusedVars();

  // Output the whole program.
  output_mgr_->Output();

  // Release any singleton instances used.
  Globals::ReleaseGlobals();
  EMIController::ReleaseEMIController();
}
Exemple #2
0
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<string> 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<int> indices;
				for (size_t k=0; k<av->get_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<string> strs;
			StringUtils::split_string(line, strs, "(),[.");
			for (size_t i=0; i<strs.size(); i++) {
				if (strs[i].find("g_") == 0) {
					const Variable* v = VariableSelector::find_var_by_name(strs[i]);
					assert(v);
					add_variable_to_set(used_vars, v);
				}
			}
			crc_lines = line;
		}
		else if (line.find("keep variable") == 0) {
			getline(conf, line);
			StringUtils::chop(line);
			// make sure the focus var is marked as used var
			vector<string> vnames;
			StringUtils::split_string(line, vnames, ", ");
			for (size_t i=0; i<vnames.size(); i++) {
				const Variable* v = VariableSelector::find_var_by_name(vnames[i]);
				assert(v);
				used_vars.push_back(v);
			}
		}
		else if (line.find("drop parameters") == 0) {
			getline(conf, line);
			StringUtils::chop(line);
			if (line == "all") {
				drop_params = true;
				dump_dropped_params = true;
			}
		}
		// find the active blocks
		else if (line.find("active blocks") == 0) {
			getline(conf, line);
			config_active_blks(line);
		}
		else if (line.find("call chain shortcut") == 0) {
			getline(conf, line);
			config_call_chain_shortcut(line);
		}
		else if (line.find("replace statement") == 0) {
			getline(conf, line);
			config_stm_reduction(line);
		}
		else if (line.find("replace calls") == 0) {
			getline(conf, line);
			config_expr_reduction(line);
		}
		else if (line.find("replace binary") == 0) {
			getline(conf, line);
			config_binary_reduction(line);
		}
		else if (line.find("replace if") == 0) {
			getline(conf, line);
			config_if_reduction(line);
		}
		else if (line.find("replace array initializer") == 0) {
			getline(conf, line);
			config_var_init_reduction(line);
		}
	}
	conf.close();
	configured = true;
}