LLVMValueRef gen_expr(compile_t* c, ast_t* ast) { LLVMValueRef ret; bool has_scope = ast_has_scope(ast); if(has_scope) codegen_pushscope(c, ast); switch(ast_id(ast)) { case TK_SEQ: ret = gen_seq(c, ast); break; case TK_FVARREF: case TK_FLETREF: ret = gen_fieldload(c, ast); break; case TK_EMBEDREF: ret = gen_fieldptr(c, ast); break; case TK_PARAMREF: ret = gen_param(c, ast); break; case TK_VAR: case TK_LET: case TK_MATCH_CAPTURE: ret = gen_localdecl(c, ast); break; case TK_VARREF: case TK_LETREF: ret = gen_localload(c, ast); break; case TK_IF: ret = gen_if(c, ast); break; case TK_WHILE: ret = gen_while(c, ast); break; case TK_REPEAT: ret = gen_repeat(c, ast); break; case TK_TRY: case TK_TRY_NO_CHECK: ret = gen_try(c, ast); break; case TK_MATCH: ret = gen_match(c, ast); break; case TK_CALL: ret = gen_call(c, ast); break; case TK_CONSUME: ret = gen_expr(c, ast_childidx(ast, 1)); break; case TK_RECOVER: ret = gen_expr(c, ast_childidx(ast, 1)); break; case TK_BREAK: ret = gen_break(c, ast); break; case TK_CONTINUE: ret = gen_continue(c, ast); break; case TK_RETURN: ret = gen_return(c, ast); break; case TK_ERROR: ret = gen_error(c, ast); break; case TK_IS: ret = gen_is(c, ast); break; case TK_ISNT: ret = gen_isnt(c, ast); break; case TK_ASSIGN: ret = gen_assign(c, ast); break; case TK_THIS: ret = gen_this(c, ast); break; case TK_TRUE: ret = LLVMConstInt(c->i1, 1, false); break; case TK_FALSE: ret = LLVMConstInt(c->i1, 0, false); break; case TK_INT: ret = gen_int(c, ast); break; case TK_FLOAT: ret = gen_float(c, ast); break; case TK_STRING: ret = gen_string(c, ast); break; case TK_TUPLE: ret = gen_tuple(c, ast); break; case TK_FFICALL: ret = gen_ffi(c, ast); break; case TK_ADDRESS: ret = gen_addressof(c, ast); break; case TK_DIGESTOF: ret = gen_digestof(c, ast); break; case TK_DONTCARE: ret = GEN_NOVALUE; break; case TK_COMPILE_INTRINSIC: ast_error(c->opt->check.errors, ast, "unimplemented compile intrinsic"); return NULL; case TK_COMPILE_ERROR: { ast_t* reason_seq = ast_child(ast); ast_t* reason = ast_child(reason_seq); ast_error(c->opt->check.errors, ast, "compile error: %s", ast_name(reason)); return NULL; } default: ast_error(c->opt->check.errors, ast, "not implemented (codegen unknown)"); return NULL; } if(has_scope) codegen_popscope(c); return ret; }
LLVMValueRef gen_expr(compile_t* c, ast_t* ast) { LLVMValueRef ret; bool has_scope = ast_has_scope(ast); bool has_source = codegen_hassource(c); if(has_scope) { codegen_pushscope(c); // Dwarf a new lexical scope, if necessary. if(has_source) dwarf_lexicalscope(&c->dwarf, ast); } switch(ast_id(ast)) { case TK_SEQ: ret = gen_seq(c, ast); break; case TK_FVARREF: case TK_FLETREF: ret = gen_fieldload(c, ast); break; case TK_PARAMREF: ret = gen_param(c, ast); break; case TK_VAR: case TK_LET: ret = gen_localdecl(c, ast); break; case TK_VARREF: case TK_LETREF: ret = gen_localload(c, ast); break; case TK_IF: ret = gen_if(c, ast); break; case TK_WHILE: ret = gen_while(c, ast); break; case TK_REPEAT: ret = gen_repeat(c, ast); break; case TK_TRY: case TK_TRY_NO_CHECK: ret = gen_try(c, ast); break; case TK_MATCH: ret = gen_match(c, ast); break; case TK_CALL: ret = gen_call(c, ast); break; case TK_CONSUME: ret = gen_expr(c, ast_childidx(ast, 1)); break; case TK_RECOVER: ret = gen_expr(c, ast_childidx(ast, 1)); break; case TK_BREAK: ret = gen_break(c, ast); break; case TK_CONTINUE: ret = gen_continue(c, ast); break; case TK_RETURN: ret = gen_return(c, ast); break; case TK_ERROR: ret = gen_error(c, ast); break; case TK_IS: ret = gen_is(c, ast); break; case TK_ISNT: ret = gen_isnt(c, ast); break; case TK_ASSIGN: ret = gen_assign(c, ast); break; case TK_THIS: ret = gen_this(c, ast); break; case TK_TRUE: ret = LLVMConstInt(c->i1, 1, false); break; case TK_FALSE: ret = LLVMConstInt(c->i1, 0, false); break; case TK_INT: ret = gen_int(c, ast); break; case TK_FLOAT: ret = gen_float(c, ast); break; case TK_STRING: ret = gen_string(c, ast); break; case TK_TUPLE: ret = gen_tuple(c, ast); break; case TK_FFICALL: ret = gen_ffi(c, ast); break; case TK_AMP: ret = gen_addressof(c, ast); break; case TK_IDENTITY: ret = gen_identity(c, ast); break; case TK_DONTCARE: ret = GEN_NOVALUE; break; case TK_COMPILER_INTRINSIC: ast_error(ast, "unimplemented compiler intrinsic"); LLVMBuildUnreachable(c->builder); ret = GEN_NOVALUE; break; default: ast_error(ast, "not implemented (codegen unknown)"); return NULL; } if(has_scope) { codegen_popscope(c); if(has_source) dwarf_finish(&c->dwarf); } return ret; }
int main( int argc, char ** argv ) { po::variables_map vm; int ret = config_manager_type::getInstance()->parse_commandline( argc, argv, vm ); if( ret ) return ret; boost::property_tree::ptree config; getSimConfiguration( vm, config ); bool print_config_only = config.empty(); std::string out_path = ""; if( vm.count( log_prefix_option::PREFIX_K ) ) { out_path = vm[ log_prefix_option::PREFIX_K ].as< std::string >(); } log_type conf_child = config.get_child( CONFIG_BLOCK_K, config); const unsigned int nRep = conf_child.get< unsigned int >( REPETITION_K, 1 ); generation_parameter gen_param( conf_child ); qtl_logging_parameter log_param( conf_child ); seed_parameter< > seed_param( conf_child ); std::cout << "Logging period: " << log_param.m_period << std::endl; write_engine_config( out_path ); rng_type rng(seed_param.m_seed); for( unsigned int i = 0; i < nRep; ++i ) { // change the seed value of the random number generator rng.discard( 15 ); const unsigned int tmp_seed = rng(); log_type rep_child_conf = conf_child; rep_child_conf.put( RNG_BLOCK_K + "." + SEED_K, tmp_seed ); simulate_type sim( rep_child_conf ); if( print_config_only ) { fitness_toolkit::getInstance()->tool_configurations( rep_child_conf ); population_growth_toolkit::getInstance()->tool_configurations( rep_child_conf ); log_type tmp; tmp.add_child( CONFIG_BLOCK_K, rep_child_conf ); if( out_path.empty() ) { boost::property_tree::write_json( std::cerr, tmp ); } else { std::ostringstream oss; oss << out_path << "_config.json"; boost::property_tree::write_json( oss.str(), tmp ); } break; } unsigned int log_period = ((gen_param.m_size < log_param.m_period) ? gen_param.m_size : log_param.m_period); log_type sim_times, stat_times; timer_type rep_time; for( unsigned int j = 0; j < gen_param.m_size; ++j ) { timer_type sim_time; sim.simulate(j); sim_time.stop(); clotho::utility::add_value_array( sim_times, sim_time ); sim.reset_parent(); if( !(--log_period) ) { timer_type stat_time; log_type stat_log; sim.computeStats( stat_log ); // combine simulation log and configuration log into single object BOOST_FOREACH( auto& upd, sim.getLog() ) { stat_log.put_child( upd.first, upd.second ); } sim.clearLog(); // BOOST_FOREACH( auto& upd, config ) { // stat_log.put_child(upd.first, upd.second ); // } stat_log.put_child( CONFIG_BLOCK_K, rep_child_conf); log_period = ((j + log_param.m_period < gen_param.m_size) ? log_param.m_period : (gen_param.m_size - j - 1) ); if( !stat_log.empty() ) { if( out_path.empty() ) { boost::property_tree::write_json( std::cout, stat_log ); } else { std::ostringstream oss; oss << out_path << "." << i << "." << j << ".json"; boost::property_tree::write_json( oss.str(), stat_log ); } } stat_time.stop(); clotho::utility::add_value_array( stat_times, stat_time ); } } rep_time.stop(); log_type perform_log; perform_log.add( "performance.runtime", rep_time.elapsed().count() ); perform_log.put_child( "performance.simulate", sim_times ); perform_log.put_child( "performance.stats", stat_times ); if( out_path.empty() ) { boost::property_tree::write_json( std::cout, perform_log ); } else { std::ostringstream oss; oss << out_path << "." << i << ".performance.json"; boost::property_tree::write_json( oss.str(), perform_log ); } }