//------------------------------create_new_if_for_predicate------------------------ // Create a new if below new_entry for the predicate to be cloned (IGVN optimization) ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, Deoptimization::DeoptReason reason) { assert(new_entry != 0, "only used for clone predicate"); assert(PhaseIdealLoop::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(); rgn = new (C) RegionNode(1); register_new_node_with_optimizer(rgn); rgn->add_req(uncommon_proj); hash_delete(call); call->set_req(0, 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"); } // Create new_iff in new location. IfNode *new_iff = iff->clone()->as_If(); new_iff->set_req(0, new_entry); register_new_node_with_optimizer(new_iff); 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_new_node_with_optimizer(if_cont); register_new_node_with_optimizer(if_uct); // if_uct to rgn hash_delete(rgn); rgn->add_req(if_uct); // If rgn has phis add corresponding 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) { 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"); return if_cont->as_Proj(); }
virtual void print_inlining_late(const char* msg) { CallNode* call = call_node(); Compile* C = Compile::current(); C->print_inlining_assert_ready(); C->print_inlining(method(), call->jvms()->depth()-1, call->jvms()->bci(), msg); C->print_inlining_move_to(this); C->print_inlining_update_delayed(this); }
QoreListNode *CallStack::getCallStack() const { QoreListNode *l = new QoreListNode; CallNode *c = tail; while (c) { l->push(c->getInfo()); c = c->prev; } return l; }
void CallStack::pop(ExceptionSink *xsink) { QORE_TRACE("CallStack::pop()"); CallNode *c; { QoreAutoRWReadLocker l(thread_stack_lock); c = tail; tail = tail->prev; if (tail) tail->next = 0; } c->objectDeref(xsink); }
//------------------------------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(); }
virtual void print_inlining_late(const char* msg) { CallNode* call = call_node(); Compile* C = Compile::current(); C->print_inlining_insert(this); C->print_inlining(method(), call->jvms()->depth()-1, call->jvms()->bci(), msg); }
void Graph::toDotLines(std::string s, raw_ostream *stream) { Instruction *A; StringRef File; OpNode *op; VarNode *va; CallNode *ca; ostringstream label; MDNode *N; unsigned Line; (*stream) << "digraph \"DFG for \'" << s << "\' \"{\n"; (*stream) << "label=\"DFG for \'" << s << "\' \";\n"; std::map<GraphNode*, int> DefinedNodes; for (std::set<GraphNode*>::iterator node = nodes.begin(), end = nodes.end(); node != end; node++) { label.str(""); if ((op = dyn_cast<OpNode>((*node)))) { if (op->getValue() != NULL) { if ((A = dyn_cast<Instruction>(op->getValue()))) { if ((N = A->getMetadata("dbg"))) { DILocation Loc(N); File = Loc.getFilename(); Line = Loc.getLineNumber(); label << File.str() << " " << Line; } else { label << "null"; } } }else label << "null"; }else if ((va = dyn_cast<VarNode>((*node)))) { if (va->getValue() != NULL) { if ((A = dyn_cast<Instruction>(va->getValue()))) { if ((N = A->getMetadata("dbg"))) { DILocation Loc(N); File = Loc.getFilename(); Line = Loc.getLineNumber(); label << File.str() << " " << Line; } else { label << "null"; } } }else label << "null"; }else if ((ca = dyn_cast<CallNode>((*node)))) { if (ca->getValue() != NULL) { if ((A = dyn_cast<Instruction>(ca->getValue()))) { if ((N = A->getMetadata("dbg"))) { DILocation Loc(N); File = Loc.getFilename(); Line = Loc.getLineNumber(); label << File.str() << " " << Line; } else { label << "null"; } } }else label << "null"; } if (DefinedNodes.count(*node) == 0) { (*stream) << (*node)->getName() << "[shape=" << (*node)->getShape() << ",style=" << (*node)->getStyle() << ",label=\"" << label.str() << "\"]\n"; DefinedNodes[*node] = 1; } std::map<GraphNode*, edgeType> succs = (*node)->getSuccessors(); for (std::map<GraphNode*, edgeType>::iterator succ = succs.begin(), s_end = succs.end(); succ != s_end; succ++) { label.str(""); if ((op = dyn_cast<OpNode>((succ->first)))) { if (op->getValue() != NULL) { if ((A = dyn_cast<Instruction>(op->getValue()))) { if ((N = A->getMetadata("dbg"))) { DILocation Loc(N); File = Loc.getFilename(); Line = Loc.getLineNumber(); label << File.str() << " " << Line; } else { label << "null"; } } }else label << "null"; }else if ((va = dyn_cast<VarNode>((succ->first)))) { if (va->getValue() != NULL) { if ((A = dyn_cast<Instruction>(va->getValue()))) { if ((N = A->getMetadata("dbg"))) { DILocation Loc(N); File = Loc.getFilename(); Line = Loc.getLineNumber(); label << File.str() << " " << Line; } else { label << "null"; } } }else label << "null"; }else if ((ca = dyn_cast<CallNode>((succ->first)))) { if (ca->getValue() != NULL) { if ((A = dyn_cast<Instruction>(ca->getValue()))) { if ((N = A->getMetadata("dbg"))) { DILocation Loc(N); File = Loc.getFilename(); Line = Loc.getLineNumber(); label << File.str() << " " << Line; } else { label << "null"; } } }else label << "null"; } if (DefinedNodes.count(succ->first) == 0) { (*stream) << (succ->first)->getName() << "[shape=" << (succ->first)->getShape() << ",style=" << (succ->first)->getStyle() << ",label=\"" << label.str() << "\"]\n"; DefinedNodes[succ->first] = 1; } //Source (*stream) << "\"" << (*node)->getName() << "\""; (*stream) << "->"; //Destination (*stream) << "\"" << (succ->first)->getName() << "\""; if (succ->second == etControl) (*stream) << " [style=dashed]"; (*stream) << "\n"; } } (*stream) << "}\n\n"; }