int main() { uv_idle_t idler; uv_idle_init(get_loop(), &idler); uv_idle_start(&idler, wait_for_a_while); printf("Now quitting.\n"); uv_run(get_loop(), UV_RUN_DEFAULT); return 0; }
//------------------------------register_new_node------------------------------ void PhaseIdealLoop::register_new_node( Node *n, Node *blk ) { _igvn.register_new_node_with_optimizer(n); set_ctrl(n, blk); IdealLoopTree *loop = get_loop(blk); if( !loop->_child ) loop->_body.push(n); }
//------------------------------split_thru_region------------------------------ // Split Node 'n' through merge point. Node *PhaseIdealLoop::split_thru_region( Node *n, Node *region ) { uint wins = 0; assert( n->is_CFG(), "" ); assert( region->is_Region(), "" ); Node *r = new (C, region->req()) RegionNode( region->req() ); IdealLoopTree *loop = get_loop( n ); for( uint i = 1; i < region->req(); i++ ) { Node *x = n->clone(); Node *in0 = n->in(0); if( in0->in(0) == region ) x->set_req( 0, in0->in(i) ); for( uint j = 1; j < n->req(); j++ ) { Node *in = n->in(j); if( get_ctrl(in) == region ) x->set_req( j, in->in(i) ); } _igvn.register_new_node_with_optimizer(x); set_loop(x, loop); set_idom(x, x->in(0), dom_depth(x->in(0))+1); r->init_req(i, x); } // Record region r->set_req(0,region); // Not a TRUE RegionNode _igvn.register_new_node_with_optimizer(r); set_loop(r, loop); if( !loop->_child ) loop->_body.push(r); return r; }
tree reset_evolution_in_loop (unsigned loop_num, tree chrec, tree new_evol) { struct loop *loop = get_loop (cfun, loop_num); if (POINTER_TYPE_P (chrec_type (chrec))) gcc_assert (ptrofftype_p (chrec_type (new_evol))); else gcc_assert (chrec_type (chrec) == chrec_type (new_evol)); if (TREE_CODE (chrec) == POLYNOMIAL_CHREC && flow_loop_nested_p (loop, get_chrec_loop (chrec))) { tree left = reset_evolution_in_loop (loop_num, CHREC_LEFT (chrec), new_evol); tree right = reset_evolution_in_loop (loop_num, CHREC_RIGHT (chrec), new_evol); return build3 (POLYNOMIAL_CHREC, TREE_TYPE (left), CHREC_VAR (chrec), left, right); } while (TREE_CODE (chrec) == POLYNOMIAL_CHREC && CHREC_VARIABLE (chrec) == loop_num) chrec = CHREC_LEFT (chrec); return build_polynomial_chrec (loop_num, chrec, new_evol); }
tree hide_evolution_in_other_loops_than_loop (tree chrec, unsigned loop_num) { struct loop *loop = get_loop (cfun, loop_num), *chloop; if (automatically_generated_chrec_p (chrec)) return chrec; switch (TREE_CODE (chrec)) { case POLYNOMIAL_CHREC: chloop = get_chrec_loop (chrec); if (chloop == loop) return build_polynomial_chrec (loop_num, hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec), loop_num), CHREC_RIGHT (chrec)); else if (flow_loop_nested_p (chloop, loop)) /* There is no evolution in this loop. */ return initial_condition (chrec); else { gcc_assert (flow_loop_nested_p (loop, chloop)); return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec), loop_num); } default: return chrec; } }
static tree chrec_evaluate (unsigned var, tree chrec, tree n, unsigned int k) { tree arg0, arg1, binomial_n_k; tree type = TREE_TYPE (chrec); struct loop *var_loop = get_loop (cfun, var); while (TREE_CODE (chrec) == POLYNOMIAL_CHREC && flow_loop_nested_p (var_loop, get_chrec_loop (chrec))) chrec = CHREC_LEFT (chrec); if (TREE_CODE (chrec) == POLYNOMIAL_CHREC && CHREC_VARIABLE (chrec) == var) { arg1 = chrec_evaluate (var, CHREC_RIGHT (chrec), n, k + 1); if (arg1 == chrec_dont_know) return chrec_dont_know; binomial_n_k = tree_fold_binomial (type, n, k); if (!binomial_n_k) return chrec_dont_know; arg0 = fold_build2 (MULT_EXPR, type, CHREC_LEFT (chrec), binomial_n_k); return chrec_fold_plus (type, arg0, arg1); } binomial_n_k = tree_fold_binomial (type, n, k); if (!binomial_n_k) return chrec_dont_know; return fold_build2 (MULT_EXPR, type, chrec, binomial_n_k); }
static int loop_destroy(lua_State *L) { loop_t *lo = get_loop(L, 1); struct ev_loop* loop = lo->loop; if(loop) { lo->loop = 0; ev_loop_destroy(loop); } return 0; }
static bool evolution_function_is_invariant_rec_p (tree chrec, int loopnum) { if (evolution_function_is_constant_p (chrec)) return true; if (TREE_CODE (chrec) == SSA_NAME && (loopnum == 0 || expr_invariant_in_loop_p (get_loop (cfun, loopnum), chrec))) return true; if (TREE_CODE (chrec) == POLYNOMIAL_CHREC) { if (CHREC_VARIABLE (chrec) == (unsigned) loopnum || flow_loop_nested_p (get_loop (cfun, loopnum), get_chrec_loop (chrec)) || !evolution_function_is_invariant_rec_p (CHREC_RIGHT (chrec), loopnum) || !evolution_function_is_invariant_rec_p (CHREC_LEFT (chrec), loopnum)) return false; return true; } switch (TREE_OPERAND_LENGTH (chrec)) { case 2: if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 1), loopnum)) return false; case 1: if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 0), loopnum)) return false; return true; default: return false; } return false; }
static tree chrec_component_in_loop_num (tree chrec, unsigned loop_num, bool right) { tree component; struct loop *loop = get_loop (cfun, loop_num), *chloop; if (automatically_generated_chrec_p (chrec)) return chrec; switch (TREE_CODE (chrec)) { case POLYNOMIAL_CHREC: chloop = get_chrec_loop (chrec); if (chloop == loop) { if (right) component = CHREC_RIGHT (chrec); else component = CHREC_LEFT (chrec); if (TREE_CODE (CHREC_LEFT (chrec)) != POLYNOMIAL_CHREC || CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec)) return component; else return build_polynomial_chrec (loop_num, chrec_component_in_loop_num (CHREC_LEFT (chrec), loop_num, right), component); } else if (flow_loop_nested_p (chloop, loop)) /* There is no evolution part in this loop. */ return NULL_TREE; else { gcc_assert (flow_loop_nested_p (loop, chloop)); return chrec_component_in_loop_num (CHREC_LEFT (chrec), loop_num, right); } default: if (right) return NULL_TREE; else return chrec; } }
// L statck: // 4: ud // 3: cb // 2: flags // 1: loop static int loop_run(lua_State *L) { struct ev_loop *loop; loop_t *lo = get_loop(L, 1); int flags = luaL_checkinteger(L, 2); luaL_checktype(L, 3, LUA_TFUNCTION); luaL_checkany(L, 4); lua_pushcfunction(L, traceback); loop = lo->loop; ev_set_userdata(loop, L); lua_pushboolean(L, ev_run(loop, flags)); ev_set_userdata(loop, NULL); return 1; }
int main(int argc, char **argv) { int ret; if(sigaction(SIGINT, &sigact, NULL) < 0 || sigaction(SIGTERM, &sigact, NULL) < 0) { perror("Error installing signal handler"); return 1; } if(initialise_options(&opt, argc, argv) < 0) return 1; ret = get_loop(&opt); destroy_options(&opt); return ret; }
static int timer_again(lua_State *L) { ev_timer *w = get_timer(L, 1); loop_t *lo = get_loop(L, 2); ev_timer_again(lo->loop, w); return 0; }
//------------------------------create_new_if_for_predicate------------------------ // create a new if above the uct_if_pattern for the predicate to be promoted. // // before after // ---------- ---------- // ctrl ctrl // | | // | | // v v // iff new_iff // / \ / \ // / \ / \ // v v v v // uncommon_proj cont_proj if_uct if_cont // \ | | | | // \ | | | | // v v v | v // rgn loop | iff // | | / \ // | | / \ // v | v v // uncommon_trap | uncommon_proj cont_proj // \ \ | | // \ \ | | // v v v v // rgn loop // | // | // v // uncommon_trap // // // We will create a region to guard the uct call if there is no one there. // The true projecttion (if_cont) of the new_iff is returned. // This code is also used to clone predicates to clonned loops. ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, Deoptimization::DeoptReason reason) { assert(is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!"); IfNode* iff = cont_proj->in(0)->as_If(); ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con); Node *rgn = uncommon_proj->unique_ctrl_out(); assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct"); uint proj_index = 1; // region's edge corresponding to uncommon_proj if (!rgn->is_Region()) { // create a region to guard the call assert(rgn->is_Call(), "must be call uct"); CallNode* call = rgn->as_Call(); IdealLoopTree* loop = get_loop(call); rgn = new (C) RegionNode(1); rgn->add_req(uncommon_proj); register_control(rgn, loop, uncommon_proj); _igvn.hash_delete(call); call->set_req(0, rgn); // When called from beautify_loops() idom is not constructed yet. if (_idom != NULL) { set_idom(call, rgn, dom_depth(rgn)); } } else { // Find region's edge corresponding to uncommon_proj for (; proj_index < rgn->req(); proj_index++) if (rgn->in(proj_index) == uncommon_proj) break; assert(proj_index < rgn->req(), "sanity"); } Node* entry = iff->in(0); if (new_entry != NULL) { // Clonning the predicate to new location. entry = new_entry; } // Create new_iff IdealLoopTree* lp = get_loop(entry); IfNode *new_iff = iff->clone()->as_If(); new_iff->set_req(0, entry); register_control(new_iff, lp, entry); Node *if_cont = new (C) IfTrueNode(new_iff); Node *if_uct = new (C) IfFalseNode(new_iff); if (cont_proj->is_IfFalse()) { // Swap Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp; } register_control(if_cont, lp, new_iff); register_control(if_uct, get_loop(rgn), new_iff); // if_uct to rgn _igvn.hash_delete(rgn); rgn->add_req(if_uct); // When called from beautify_loops() idom is not constructed yet. if (_idom != NULL) { Node* ridom = idom(rgn); Node* nrdom = dom_lca(ridom, new_iff); set_idom(rgn, nrdom, dom_depth(rgn)); } // If rgn has phis add new edges which has the same // value as on original uncommon_proj pass. assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last"); bool has_phi = false; for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) { Node* use = rgn->fast_out(i); if (use->is_Phi() && use->outcnt() > 0) { assert(use->in(0) == rgn, ""); _igvn.rehash_node_delayed(use); use->add_req(use->in(proj_index)); has_phi = true; } } assert(!has_phi || rgn->req() > 3, "no phis when region is created"); if (new_entry == NULL) { // Attach if_cont to iff _igvn.hash_delete(iff); iff->set_req(0, if_cont); if (_idom != NULL) { set_idom(iff, if_cont, dom_depth(iff)); } } return if_cont->as_Proj(); }
unsigned vectorize_loops (void) { unsigned int i; unsigned int num_vectorized_loops = 0; unsigned int vect_loops_num; loop_iterator li; struct loop *loop; vect_loops_num = number_of_loops (); /* Bail out if there are no loops. */ if (vect_loops_num <= 1) return 0; /* Fix the verbosity level if not defined explicitly by the user. */ vect_set_dump_settings (false); init_stmt_vec_info_vec (); /* ----------- Analyze loops. ----------- */ /* If some loop was duplicated, it gets bigger number than all previously defined loops. This fact allows us to run only over initial loops skipping newly generated ones. */ FOR_EACH_LOOP (li, loop, 0) if (optimize_loop_nest_for_speed_p (loop)) { loop_vec_info loop_vinfo; vect_location = find_loop_location (loop); if (vect_location != UNKNOWN_LOC && vect_verbosity_level > REPORT_NONE) fprintf (vect_dump, "\nAnalyzing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); loop_vinfo = vect_analyze_loop (loop); loop->aux = loop_vinfo; if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo)) continue; if (vect_location != UNKNOWN_LOC && vect_verbosity_level > REPORT_NONE) fprintf (vect_dump, "\n\nVectorizing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); vect_transform_loop (loop_vinfo); num_vectorized_loops++; } vect_location = UNKNOWN_LOC; statistics_counter_event (cfun, "Vectorized loops", num_vectorized_loops); if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS) || (num_vectorized_loops > 0 && vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))) fprintf (vect_dump, "vectorized %u loops in function.\n", num_vectorized_loops); /* ----------- Finalize. ----------- */ mark_sym_for_renaming (gimple_vop (cfun)); for (i = 1; i < vect_loops_num; i++) { loop_vec_info loop_vinfo; loop = get_loop (i); if (!loop) continue; loop_vinfo = (loop_vec_info) loop->aux; destroy_loop_vec_info (loop_vinfo, true); loop->aux = NULL; } free_stmt_vec_info_vec (); return num_vectorized_loops > 0 ? TODO_cleanup_cfg : 0; }
unsigned vectorize_loops (void) { unsigned int i; unsigned int num_vectorized_loops = 0; unsigned int vect_loops_num; loop_iterator li; struct loop *loop; vect_loops_num = number_of_loops (cfun); /* Bail out if there are no loops. */ if (vect_loops_num <= 1) return 0; init_stmt_vec_info_vec (); /* ----------- Analyze loops. ----------- */ /* If some loop was duplicated, it gets bigger number than all previously defined loops. This fact allows us to run only over initial loops skipping newly generated ones. */ FOR_EACH_LOOP (li, loop, 0) if (optimize_loop_nest_for_speed_p (loop)) { loop_vec_info loop_vinfo; vect_location = find_loop_location (loop); if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC && dump_enabled_p ()) dump_printf (MSG_NOTE, "\nAnalyzing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); loop_vinfo = vect_analyze_loop (loop); loop->aux = loop_vinfo; if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo)) continue; if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC && dump_enabled_p ()) dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, "Vectorized loop\n"); vect_transform_loop (loop_vinfo); num_vectorized_loops++; } vect_location = UNKNOWN_LOC; statistics_counter_event (cfun, "Vectorized loops", num_vectorized_loops); if (dump_enabled_p () || (num_vectorized_loops > 0 && dump_enabled_p ())) dump_printf_loc (MSG_NOTE, vect_location, "vectorized %u loops in function.\n", num_vectorized_loops); /* ----------- Finalize. ----------- */ for (i = 1; i < vect_loops_num; i++) { loop_vec_info loop_vinfo; loop = get_loop (cfun, i); if (!loop) continue; loop_vinfo = (loop_vec_info) loop->aux; destroy_loop_vec_info (loop_vinfo, true); loop->aux = NULL; } free_stmt_vec_info_vec (); if (num_vectorized_loops > 0) { /* If we vectorized any loop only virtual SSA form needs to be updated. ??? Also while we try hard to update loop-closed SSA form we fail to properly do this in some corner-cases (see PR56286). */ rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa_only_virtuals); return TODO_cleanup_cfg; } return 0; }
static int loop_tostring(lua_State *L) { loop_t *lo = get_loop(L, 1); lua_pushfstring(L, "loop: %p", lo); return 1; }
unsigned vectorize_loops (void) { unsigned int i; unsigned int num_vectorized_loops = 0; unsigned int vect_loops_num; loop_iterator li; struct loop *loop; vect_loops_num = number_of_loops (); /* Bail out if there are no loops. */ if (vect_loops_num <= 1) return 0; init_stmt_vec_info_vec (); /* ----------- Analyze loops. ----------- */ /* If some loop was duplicated, it gets bigger number than all previously defined loops. This fact allows us to run only over initial loops skipping newly generated ones. */ FOR_EACH_LOOP (li, loop, 0) if (optimize_loop_nest_for_speed_p (loop)) { loop_vec_info loop_vinfo; vect_location = find_loop_location (loop); if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC && dump_enabled_p ()) dump_printf (MSG_ALL, "\nAnalyzing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); loop_vinfo = vect_analyze_loop (loop); loop->aux = loop_vinfo; if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo)) continue; if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC && dump_enabled_p ()) dump_printf (MSG_ALL, "\n\nVectorizing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); vect_transform_loop (loop_vinfo); num_vectorized_loops++; } vect_location = UNKNOWN_LOC; statistics_counter_event (cfun, "Vectorized loops", num_vectorized_loops); if (dump_enabled_p () || (num_vectorized_loops > 0 && dump_enabled_p ())) dump_printf_loc (MSG_ALL, vect_location, "vectorized %u loops in function.\n", num_vectorized_loops); /* ----------- Finalize. ----------- */ for (i = 1; i < vect_loops_num; i++) { loop_vec_info loop_vinfo; loop = get_loop (i); if (!loop) continue; loop_vinfo = (loop_vec_info) loop->aux; destroy_loop_vec_info (loop_vinfo, true); loop->aux = NULL; } free_stmt_vec_info_vec (); return num_vectorized_loops > 0 ? TODO_cleanup_cfg : 0; }
//------------------------------do_split_if------------------------------------ // Found an If getting its condition-code input from a Phi in the same block. // Split thru the Region. void PhaseIdealLoop::do_split_if( Node *iff ) { #ifndef PRODUCT if( PrintOpto && VerifyLoopOptimizations ) tty->print_cr("Split-if"); #endif C->set_major_progress(); Node *region = iff->in(0); Node *region_dom = idom(region); // We are going to clone this test (and the control flow with it) up through // the incoming merge point. We need to empty the current basic block. // Clone any instructions which must be in this block up through the merge // point. DUIterator i, j; bool progress = true; while (progress) { progress = false; for (i = region->outs(); region->has_out(i); i++) { Node* n = region->out(i); if( n == region ) continue; // The IF to be split is OK. if( n == iff ) continue; if( !n->is_Phi() ) { // Found pinned memory op or such if (split_up(n, region, iff)) { i = region->refresh_out_pos(i); progress = true; } continue; } assert( n->in(0) == region, "" ); // Recursively split up all users of a Phi for (j = n->outs(); n->has_out(j); j++) { Node* m = n->out(j); // If m is dead, throw it away, and declare progress if (_nodes[m->_idx] == NULL) { _igvn.remove_dead_node(m); // fall through } else if (m != iff && split_up(m, region, iff)) { // fall through } else { continue; } // Something unpredictable changed. // Tell the iterators to refresh themselves, and rerun the loop. i = region->refresh_out_pos(i); j = region->refresh_out_pos(j); progress = true; } } } // Now we have no instructions in the block containing the IF. // Split the IF. Node *new_iff = split_thru_region( iff, region ); // Replace both uses of 'new_iff' with Regions merging True/False // paths. This makes 'new_iff' go dead. Node *old_false, *old_true; Node *new_false, *new_true; for (DUIterator_Last j2min, j2 = iff->last_outs(j2min); j2 >= j2min; --j2) { Node *ifp = iff->last_out(j2); assert( ifp->Opcode() == Op_IfFalse || ifp->Opcode() == Op_IfTrue, "" ); ifp->set_req(0, new_iff); Node *ifpx = split_thru_region( ifp, region ); // Replace 'If' projection of a Region with a Region of // 'If' projections. ifpx->set_req(0, ifpx); // A TRUE RegionNode // Setup dominator info set_idom(ifpx, region_dom, dom_depth(region_dom) + 1); // Check for splitting loop tails if( get_loop(iff)->tail() == ifp ) get_loop(iff)->_tail = ifpx; // Replace in the graph with lazy-update mechanism new_iff->set_req(0, new_iff); // hook self so it does not go dead lazy_replace_proj( ifp, ifpx ); new_iff->set_req(0, region); // Record bits for later xforms if( ifp->Opcode() == Op_IfFalse ) { old_false = ifp; new_false = ifpx; } else { old_true = ifp; new_true = ifpx; } } _igvn.remove_dead_node(new_iff); // Lazy replace IDOM info with the region's dominator lazy_replace( iff, region_dom ); // Now make the original merge point go dead, by handling all its uses. small_cache region_cache; // Preload some control flow in region-cache region_cache.lru_insert( new_false, new_false ); region_cache.lru_insert( new_true , new_true ); // Now handle all uses of the splitting block for (DUIterator_Last kmin, k = region->last_outs(kmin); k >= kmin; --k) { Node* phi = region->last_out(k); if( !phi->in(0) ) { // Dead phi? Remove it _igvn.remove_dead_node(phi); continue; } assert( phi->in(0) == region, "" ); if( phi == region ) { // Found the self-reference phi->set_req(0, NULL); continue; // Break the self-cycle } // Expected common case: Phi hanging off of Region if( phi->is_Phi() ) { // Need a per-def cache. Phi represents a def, so make a cache small_cache phi_cache; // Inspect all Phi uses to make the Phi go dead for (DUIterator_Last lmin, l = phi->last_outs(lmin); l >= lmin; --l) { Node* use = phi->last_out(l); // Compute the new DEF for this USE. New DEF depends on the path // taken from the original DEF to the USE. The new DEF may be some // collection of PHI's merging values from different paths. The Phis // inserted depend only on the location of the USE. We use a // 2-element cache to handle multiple uses from the same block. handle_use( use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true ); } // End of while phi has uses // Because handle_use might relocate region->_out, // we must refresh the iterator. k = region->last_outs(kmin); // Remove the dead Phi _igvn.remove_dead_node( phi ); } else { // Random memory op guarded by Region. Compute new DEF for USE. handle_use( phi, region, ®ion_cache, region_dom, new_false, new_true, old_false, old_true ); } } // End of while merge point has phis // Any leftover bits in the splitting block must not have depended on local // Phi inputs (these have already been split-up). Hence it's safe to hoist // these guys to the dominating point. lazy_replace( region, region_dom ); #ifndef PRODUCT if( VerifyLoopOptimizations ) verify(); #endif }