src/share/vm/opto/idealGraphPrinter.cpp

Fri, 07 Mar 2008 11:09:13 -0800

author
kvn
date
Fri, 07 Mar 2008 11:09:13 -0800
changeset 476
874b2c4f43d1
parent 435
a61af66fc99e
child 657
2a1a77d3458f
permissions
-rw-r--r--

6667605: (Escape Analysis) inline java constructors when EA is on
Summary: java constructors should be inlined to be able scalar replace a new object
Reviewed-by: rasbold

duke@435 1 /*
duke@435 2 * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
duke@435 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@435 20 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@435 21 * have any questions.
duke@435 22 *
duke@435 23 */
duke@435 24
duke@435 25 #include "incls/_precompiled.incl"
duke@435 26 #include "incls/_idealGraphPrinter.cpp.incl"
duke@435 27
duke@435 28 #ifndef PRODUCT
duke@435 29
duke@435 30 // Constants
duke@435 31 // Keep consistent with Java constants
duke@435 32 const char *IdealGraphPrinter::INDENT = " ";
duke@435 33 const char *IdealGraphPrinter::TOP_ELEMENT = "graphDocument";
duke@435 34 const char *IdealGraphPrinter::GROUP_ELEMENT = "group";
duke@435 35 const char *IdealGraphPrinter::GRAPH_ELEMENT = "graph";
duke@435 36 const char *IdealGraphPrinter::PROPERTIES_ELEMENT = "properties";
duke@435 37 const char *IdealGraphPrinter::EDGES_ELEMENT = "edges";
duke@435 38 const char *IdealGraphPrinter::PROPERTY_ELEMENT = "p";
duke@435 39 const char *IdealGraphPrinter::EDGE_ELEMENT = "edge";
duke@435 40 const char *IdealGraphPrinter::NODE_ELEMENT = "node";
duke@435 41 const char *IdealGraphPrinter::NODES_ELEMENT = "nodes";
duke@435 42 const char *IdealGraphPrinter::REMOVE_EDGE_ELEMENT = "removeEdge";
duke@435 43 const char *IdealGraphPrinter::REMOVE_NODE_ELEMENT = "removeNode";
duke@435 44 const char *IdealGraphPrinter::METHOD_NAME_PROPERTY = "name";
duke@435 45 const char *IdealGraphPrinter::METHOD_IS_PUBLIC_PROPERTY = "public";
duke@435 46 const char *IdealGraphPrinter::METHOD_IS_STATIC_PROPERTY = "static";
duke@435 47 const char *IdealGraphPrinter::TRUE_VALUE = "true";
duke@435 48 const char *IdealGraphPrinter::NODE_NAME_PROPERTY = "name";
duke@435 49 const char *IdealGraphPrinter::EDGE_NAME_PROPERTY = "name";
duke@435 50 const char *IdealGraphPrinter::NODE_ID_PROPERTY = "id";
duke@435 51 const char *IdealGraphPrinter::FROM_PROPERTY = "from";
duke@435 52 const char *IdealGraphPrinter::TO_PROPERTY = "to";
duke@435 53 const char *IdealGraphPrinter::PROPERTY_NAME_PROPERTY = "name";
duke@435 54 const char *IdealGraphPrinter::GRAPH_NAME_PROPERTY = "name";
duke@435 55 const char *IdealGraphPrinter::INDEX_PROPERTY = "index";
duke@435 56 const char *IdealGraphPrinter::METHOD_ELEMENT = "method";
duke@435 57 const char *IdealGraphPrinter::INLINE_ELEMENT = "inline";
duke@435 58 const char *IdealGraphPrinter::BYTECODES_ELEMENT = "bytecodes";
duke@435 59 const char *IdealGraphPrinter::METHOD_BCI_PROPERTY = "bci";
duke@435 60 const char *IdealGraphPrinter::METHOD_SHORT_NAME_PROPERTY = "shortName";
duke@435 61 const char *IdealGraphPrinter::CONTROL_FLOW_ELEMENT = "controlFlow";
duke@435 62 const char *IdealGraphPrinter::BLOCK_NAME_PROPERTY = "name";
duke@435 63 const char *IdealGraphPrinter::BLOCK_DOMINATOR_PROPERTY = "dom";
duke@435 64 const char *IdealGraphPrinter::BLOCK_ELEMENT = "block";
duke@435 65 const char *IdealGraphPrinter::SUCCESSORS_ELEMENT = "successors";
duke@435 66 const char *IdealGraphPrinter::SUCCESSOR_ELEMENT = "successor";
duke@435 67 const char *IdealGraphPrinter::ASSEMBLY_ELEMENT = "assembly";
duke@435 68
duke@435 69 int IdealGraphPrinter::_file_count = 0;
duke@435 70
duke@435 71 IdealGraphPrinter *IdealGraphPrinter::printer() {
duke@435 72 if (PrintIdealGraphLevel == 0) return NULL;
duke@435 73
duke@435 74 JavaThread *thread = JavaThread::current();
duke@435 75 if (!thread->is_Compiler_thread()) return NULL;
duke@435 76
duke@435 77 CompilerThread *compiler_thread = (CompilerThread *)thread;
duke@435 78 if (compiler_thread->ideal_graph_printer() == NULL) {
duke@435 79 IdealGraphPrinter *printer = new IdealGraphPrinter();
duke@435 80 compiler_thread->set_ideal_graph_printer(printer);
duke@435 81 }
duke@435 82
duke@435 83 return compiler_thread->ideal_graph_printer();
duke@435 84 }
duke@435 85
duke@435 86 void IdealGraphPrinter::clean_up() {
duke@435 87 JavaThread *p;
duke@435 88 for (p = Threads::first(); p; p = p->next()) {
duke@435 89 if (p->is_Compiler_thread()) {
duke@435 90 CompilerThread *c = (CompilerThread *)p;
duke@435 91 IdealGraphPrinter *printer = c->ideal_graph_printer();
duke@435 92 if (printer) {
duke@435 93 delete printer;
duke@435 94 }
duke@435 95 c->set_ideal_graph_printer(NULL);
duke@435 96 }
duke@435 97 }
duke@435 98 }
duke@435 99
duke@435 100 // Constructor, either file or network output
duke@435 101 IdealGraphPrinter::IdealGraphPrinter() {
duke@435 102
duke@435 103 _traverse_outs = false;
duke@435 104 _should_send_method = true;
duke@435 105 _output = NULL;
duke@435 106 buffer[0] = 0;
duke@435 107 _depth = 0;
duke@435 108 _current_method = NULL;
duke@435 109 assert(!_current_method, "current method must be initialized to NULL");
duke@435 110 _arena = new Arena();
duke@435 111
duke@435 112 _stream = new (ResourceObj::C_HEAP) networkStream();
duke@435 113
duke@435 114 if (PrintIdealGraphFile != NULL) {
duke@435 115 ThreadCritical tc;
duke@435 116 // User wants all output to go to files
duke@435 117 if (_file_count != 0) {
duke@435 118 ResourceMark rm;
duke@435 119 stringStream st;
duke@435 120 const char* dot = strrchr(PrintIdealGraphFile, '.');
duke@435 121 if (dot) {
duke@435 122 st.write(PrintIdealGraphFile, dot - PrintIdealGraphFile);
duke@435 123 st.print("%d%s", _file_count, dot);
duke@435 124 } else {
duke@435 125 st.print("%s%d", PrintIdealGraphFile, _file_count);
duke@435 126 }
duke@435 127 _output = new (ResourceObj::C_HEAP) fileStream(st.as_string());
duke@435 128 } else {
duke@435 129 _output = new (ResourceObj::C_HEAP) fileStream(PrintIdealGraphFile);
duke@435 130 }
duke@435 131 _file_count++;
duke@435 132 } else {
duke@435 133 // Try to connect to visualizer
duke@435 134 if (_stream->connect(PrintIdealGraphAddress, PrintIdealGraphPort)) {
duke@435 135 char c = 0;
duke@435 136 _stream->read(&c, 1);
duke@435 137 if (c != 'y') {
duke@435 138 tty->print_cr("Client available, but does not want to receive data!");
duke@435 139 _stream->close();
duke@435 140 delete _stream;
duke@435 141 _stream = NULL;
duke@435 142 return;
duke@435 143 }
duke@435 144 _output = _stream;
duke@435 145 } else {
duke@435 146 // It would be nice if we could shut down cleanly but it should
duke@435 147 // be an error if we can't connect to the visualizer.
duke@435 148 fatal2("Couldn't connect to visualizer at %s:%d", PrintIdealGraphAddress, PrintIdealGraphPort);
duke@435 149 }
duke@435 150 }
duke@435 151
duke@435 152 start_element(TOP_ELEMENT);
duke@435 153 }
duke@435 154
duke@435 155 // Destructor, close file or network stream
duke@435 156 IdealGraphPrinter::~IdealGraphPrinter() {
duke@435 157
duke@435 158 end_element(TOP_ELEMENT);
duke@435 159
duke@435 160 if (_stream) {
duke@435 161 delete _stream;
duke@435 162 if (_stream == _output) {
duke@435 163 _output = NULL;
duke@435 164 }
duke@435 165 _stream = NULL;
duke@435 166 }
duke@435 167
duke@435 168 if (_output) {
duke@435 169 delete _output;
duke@435 170 _output = NULL;
duke@435 171 }
duke@435 172 }
duke@435 173
duke@435 174 void IdealGraphPrinter::print_ifg(PhaseIFG* ifg) {
duke@435 175
duke@435 176 // Code to print an interference graph to tty, currently not used
duke@435 177
duke@435 178 /*
duke@435 179 if (!_current_method) return;
duke@435 180 // Remove neighbor colors
duke@435 181
duke@435 182 for (uint i = 0; i < ifg._maxlrg; i++) {
duke@435 183
duke@435 184 IndexSet *s = ifg.neighbors(i);
duke@435 185 IndexSetIterator elements(s);
duke@435 186 uint neighbor;
duke@435 187 while ((neighbor = elements.next()) != 0) {
duke@435 188 tty->print_cr("Edge between %d and %d\n", i, neighbor);
duke@435 189 }
duke@435 190 }
duke@435 191
duke@435 192
duke@435 193 for (uint i = 0; i < ifg._maxlrg; i++) {
duke@435 194 LRG &l = ifg.lrgs(i);
duke@435 195 if (l._def) {
duke@435 196 OptoReg::Name name = l.reg();
duke@435 197 tty->print("OptoReg::dump: ");
duke@435 198 OptoReg::dump(name);
duke@435 199 tty->print_cr("");
duke@435 200 tty->print_cr("name=%d\n", name);
duke@435 201 if (name) {
duke@435 202 if (OptoReg::is_stack(name)) {
duke@435 203 tty->print_cr("Stack number %d\n", OptoReg::reg2stack(name));
duke@435 204
duke@435 205 } else if (!OptoReg::is_valid(name)) {
duke@435 206 tty->print_cr("BAD!!!");
duke@435 207 } else {
duke@435 208
duke@435 209 if (OptoReg::is_reg(name)) {
duke@435 210 tty->print_cr(OptoReg::regname(name));
duke@435 211 } else {
duke@435 212 int x = 0;
duke@435 213 }
duke@435 214 }
duke@435 215 int x = 0;
duke@435 216 }
duke@435 217
duke@435 218 if (l._def == NodeSentinel) {
duke@435 219 tty->print("multiple mapping from %d: ", i);
duke@435 220 for (int j=0; j<l._defs->length(); j++) {
duke@435 221 tty->print("%d ", l._defs->at(j)->_idx);
duke@435 222 }
duke@435 223 tty->print_cr("");
duke@435 224 } else {
duke@435 225 tty->print_cr("mapping between %d and %d\n", i, l._def->_idx);
duke@435 226 }
duke@435 227 }
duke@435 228 }*/
duke@435 229 }
duke@435 230
duke@435 231 void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree) {
duke@435 232
duke@435 233 Properties properties;
duke@435 234 stringStream str;
duke@435 235 method->print_name(&str);
duke@435 236
duke@435 237 stringStream shortStr;
duke@435 238 method->print_short_name(&shortStr);
duke@435 239
duke@435 240
duke@435 241 properties.add(new Property(METHOD_NAME_PROPERTY, str.as_string()));
duke@435 242 properties.add(new Property(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string()));
duke@435 243 properties.add(new Property(METHOD_BCI_PROPERTY, bci));
duke@435 244 start_element(METHOD_ELEMENT, &properties);
duke@435 245
duke@435 246 start_element(BYTECODES_ELEMENT);
duke@435 247 output()->print_cr("<![CDATA[");
duke@435 248 method->print_codes_on(output());
duke@435 249 output()->print_cr("]]>");
duke@435 250 end_element(BYTECODES_ELEMENT);
duke@435 251
duke@435 252 start_element(INLINE_ELEMENT);
duke@435 253 if (tree != NULL) {
duke@435 254 GrowableArray<InlineTree *> subtrees = tree->subtrees();
duke@435 255 for (int i = 0; i < subtrees.length(); i++) {
duke@435 256 print_inline_tree(subtrees.at(i));
duke@435 257 }
duke@435 258 }
duke@435 259 end_element(INLINE_ELEMENT);
duke@435 260
duke@435 261 end_element(METHOD_ELEMENT);
duke@435 262 output()->flush();
duke@435 263 }
duke@435 264
duke@435 265 void IdealGraphPrinter::print_inline_tree(InlineTree *tree) {
duke@435 266
duke@435 267 if (tree == NULL) return;
duke@435 268
duke@435 269 ciMethod *method = tree->method();
duke@435 270 print_method(tree->method(), tree->caller_bci(), tree);
duke@435 271
duke@435 272 }
duke@435 273
duke@435 274 void IdealGraphPrinter::clear_nodes() {
duke@435 275 // for (int i = 0; i < _nodes.length(); i++) {
duke@435 276 // _nodes.at(i)->clear_node();
duke@435 277 // }
duke@435 278 }
duke@435 279
duke@435 280 void IdealGraphPrinter::print_inlining(Compile* compile) {
duke@435 281
duke@435 282 // Print inline tree
duke@435 283 if (_should_send_method) {
duke@435 284 InlineTree *inlineTree = compile->ilt();
duke@435 285 if (inlineTree != NULL) {
duke@435 286 print_inline_tree(inlineTree);
duke@435 287 } else {
duke@435 288 // print this method only
duke@435 289 }
duke@435 290 }
duke@435 291 }
duke@435 292
duke@435 293 // Has to be called whenever a method is compiled
duke@435 294 void IdealGraphPrinter::begin_method(Compile* compile) {
duke@435 295
duke@435 296 ciMethod *method = compile->method();
duke@435 297 assert(_output, "output stream must exist!");
duke@435 298 assert(method, "null methods are not allowed!");
duke@435 299 assert(!_current_method, "current method must be null!");
duke@435 300
duke@435 301 _arena->destruct_contents();
duke@435 302
duke@435 303 start_element(GROUP_ELEMENT);
duke@435 304
duke@435 305 // Print properties
duke@435 306 Properties properties;
duke@435 307
duke@435 308 // Add method name
duke@435 309 stringStream strStream;
duke@435 310 method->print_name(&strStream);
duke@435 311 properties.add(new Property(METHOD_NAME_PROPERTY, strStream.as_string()));
duke@435 312
duke@435 313 if (method->flags().is_public()) {
duke@435 314 properties.add(new Property(METHOD_IS_PUBLIC_PROPERTY, TRUE_VALUE));
duke@435 315 }
duke@435 316
duke@435 317 if (method->flags().is_static()) {
duke@435 318 properties.add(new Property(METHOD_IS_STATIC_PROPERTY, TRUE_VALUE));
duke@435 319 }
duke@435 320
duke@435 321 properties.print(this);
duke@435 322
duke@435 323 if (_stream) {
duke@435 324 char answer = 0;
duke@435 325 _stream->flush();
duke@435 326 int result = _stream->read(&answer, 1);
duke@435 327 _should_send_method = (answer == 'y');
duke@435 328 }
duke@435 329
duke@435 330 this->_nodes = GrowableArray<NodeDescription *>(_arena, 2, 0, NULL);
duke@435 331 this->_edges = GrowableArray< EdgeDescription * >(_arena, 2, 0, NULL);
duke@435 332
duke@435 333
duke@435 334 this->_current_method = method;
duke@435 335
duke@435 336
duke@435 337
duke@435 338 _output->flush();
duke@435 339 }
duke@435 340
duke@435 341 // Has to be called whenever a method has finished compilation
duke@435 342 void IdealGraphPrinter::end_method() {
duke@435 343
duke@435 344 // if (finish && !in_method) return;
duke@435 345
duke@435 346 nmethod* method = (nmethod*)this->_current_method->code();
duke@435 347
duke@435 348 start_element(ASSEMBLY_ELEMENT);
duke@435 349 // Disassembler::decode(method, _output);
duke@435 350 end_element(ASSEMBLY_ELEMENT);
duke@435 351
duke@435 352
duke@435 353 end_element(GROUP_ELEMENT);
duke@435 354 _current_method = NULL;
duke@435 355 _output->flush();
duke@435 356 for (int i = 0; i < _nodes.length(); i++) {
duke@435 357 NodeDescription *desc = _nodes.at(i);
duke@435 358 if (desc) {
duke@435 359 delete desc;
duke@435 360 _nodes.at_put(i, NULL);
duke@435 361 }
duke@435 362 }
duke@435 363 this->_nodes.clear();
duke@435 364
duke@435 365
duke@435 366 for (int i = 0; i < _edges.length(); i++) {
duke@435 367 // for (int j=0; j<_edges.at(i)->length(); j++) {
duke@435 368 EdgeDescription *conn = _edges.at(i);
duke@435 369 conn->print(this);
duke@435 370 if (conn) {
duke@435 371 delete conn;
duke@435 372 _edges.at_put(i, NULL);
duke@435 373 }
duke@435 374 //}
duke@435 375 //_edges.at(i)->clear();
duke@435 376 //delete _edges.at(i);
duke@435 377 //_edges.at_put(i, NULL);
duke@435 378 }
duke@435 379 this->_edges.clear();
duke@435 380
duke@435 381 // in_method = false;
duke@435 382 }
duke@435 383
duke@435 384 // Outputs an XML start element
duke@435 385 void IdealGraphPrinter::start_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */, bool print_return /* = true */) {
duke@435 386
duke@435 387 start_element_helper(s, properties, false, print_indent, print_return);
duke@435 388 _depth++;
duke@435 389
duke@435 390 }
duke@435 391
duke@435 392 // Outputs an XML start element without body
duke@435 393 void IdealGraphPrinter::simple_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */) {
duke@435 394 start_element_helper(s, properties, true, print_indent, true);
duke@435 395 }
duke@435 396
duke@435 397 // Outputs an XML start element. If outputEnd is true, the element has no body.
duke@435 398 void IdealGraphPrinter::start_element_helper(const char *s, Properties *properties, bool outputEnd, bool print_indent /* = false */, bool print_return /* = true */) {
duke@435 399
duke@435 400 assert(_output, "output stream must exist!");
duke@435 401
duke@435 402 if (print_indent) this->print_indent();
duke@435 403 _output->print("<");
duke@435 404 _output->print(s);
duke@435 405 if (properties) properties->print_as_attributes(this);
duke@435 406
duke@435 407 if (outputEnd) {
duke@435 408 _output->print("/");
duke@435 409 }
duke@435 410
duke@435 411 _output->print(">");
duke@435 412 if (print_return) _output->print_cr("");
duke@435 413
duke@435 414 }
duke@435 415
duke@435 416 // Print indent
duke@435 417 void IdealGraphPrinter::print_indent() {
duke@435 418 for (int i = 0; i < _depth; i++) {
duke@435 419 _output->print(INDENT);
duke@435 420 }
duke@435 421 }
duke@435 422
duke@435 423 // Outputs an XML end element
duke@435 424 void IdealGraphPrinter::end_element(const char *s, bool print_indent /* = true */, bool print_return /* = true */) {
duke@435 425
duke@435 426 assert(_output, "output stream must exist!");
duke@435 427
duke@435 428 _depth--;
duke@435 429
duke@435 430 if (print_indent) this->print_indent();
duke@435 431 _output->print("</");
duke@435 432 _output->print(s);
duke@435 433 _output->print(">");
duke@435 434 if (print_return) _output->print_cr("");
duke@435 435
duke@435 436 }
duke@435 437
duke@435 438 bool IdealGraphPrinter::traverse_outs() {
duke@435 439 return _traverse_outs;
duke@435 440 }
duke@435 441
duke@435 442 void IdealGraphPrinter::set_traverse_outs(bool b) {
duke@435 443 _traverse_outs = b;
duke@435 444 }
duke@435 445
duke@435 446 void IdealGraphPrinter::walk(Node *start) {
duke@435 447
duke@435 448
duke@435 449 VectorSet visited(Thread::current()->resource_area());
duke@435 450 GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL);
duke@435 451 nodeStack.push(start);
duke@435 452 visited.test_set(start->_idx);
duke@435 453 while(nodeStack.length() > 0) {
duke@435 454
duke@435 455 Node *n = nodeStack.pop();
duke@435 456 IdealGraphPrinter::pre_node(n, this);
duke@435 457
duke@435 458 if (_traverse_outs) {
duke@435 459 for (DUIterator i = n->outs(); n->has_out(i); i++) {
duke@435 460 Node* p = n->out(i);
duke@435 461 if (!visited.test_set(p->_idx)) {
duke@435 462 nodeStack.push(p);
duke@435 463 }
duke@435 464 }
duke@435 465 }
duke@435 466
duke@435 467 for ( uint i = 0; i < n->len(); i++ ) {
duke@435 468 if ( n->in(i) ) {
duke@435 469 if (!visited.test_set(n->in(i)->_idx)) {
duke@435 470 nodeStack.push(n->in(i));
duke@435 471 }
duke@435 472 }
duke@435 473 }
duke@435 474 }
duke@435 475 }
duke@435 476
duke@435 477 void IdealGraphPrinter::compress(int index, GrowableArray<Block>* blocks) {
duke@435 478 Block *block = blocks->adr_at(index);
duke@435 479
duke@435 480 int ancestor = block->ancestor();
duke@435 481 assert(ancestor != -1, "");
duke@435 482
duke@435 483 Block *ancestor_block = blocks->adr_at(ancestor);
duke@435 484 if (ancestor_block->ancestor() != -1) {
duke@435 485 compress(ancestor, blocks);
duke@435 486
duke@435 487 int label = block->label();
duke@435 488 Block *label_block = blocks->adr_at(label);
duke@435 489
duke@435 490 int ancestor_label = ancestor_block->label();
duke@435 491 Block *ancestor_label_block = blocks->adr_at(label);
duke@435 492 if (ancestor_label_block->semi() < label_block->semi()) {
duke@435 493 block->set_label(ancestor_label);
duke@435 494 }
duke@435 495
duke@435 496 block->set_ancestor(ancestor_block->ancestor());
duke@435 497 }
duke@435 498 }
duke@435 499
duke@435 500 int IdealGraphPrinter::eval(int index, GrowableArray<Block>* blocks) {
duke@435 501 Block *block = blocks->adr_at(index);
duke@435 502 if (block->ancestor() == -1) {
duke@435 503 return index;
duke@435 504 } else {
duke@435 505 compress(index, blocks);
duke@435 506 return block->label();
duke@435 507 }
duke@435 508 }
duke@435 509
duke@435 510 void IdealGraphPrinter::link(int index1, int index2, GrowableArray<Block>* blocks) {
duke@435 511 Block *block2 = blocks->adr_at(index2);
duke@435 512 block2->set_ancestor(index1);
duke@435 513 }
duke@435 514
duke@435 515 void IdealGraphPrinter::build_dominators(GrowableArray<Block>* blocks) {
duke@435 516
duke@435 517 if (blocks->length() == 0) return;
duke@435 518
duke@435 519 GrowableArray<int> stack;
duke@435 520 stack.append(0);
duke@435 521
duke@435 522 GrowableArray<Block *> array;
duke@435 523
duke@435 524 assert(blocks->length() > 0, "");
duke@435 525 blocks->adr_at(0)->set_dominator(0);
duke@435 526
duke@435 527 int n = 0;
duke@435 528 while(!stack.is_empty()) {
duke@435 529 int index = stack.pop();
duke@435 530 Block *block = blocks->adr_at(index);
duke@435 531 block->set_semi(n);
duke@435 532 array.append(block);
duke@435 533 n = n + 1;
duke@435 534 for (int i = 0; i < block->succs()->length(); i++) {
duke@435 535 int succ_index = block->succs()->at(i);
duke@435 536 Block *succ = blocks->adr_at(succ_index);
duke@435 537 if (succ->semi() == -1) {
duke@435 538 succ->set_parent(index);
duke@435 539 stack.push(succ_index);
duke@435 540 }
duke@435 541 succ->add_pred(index);
duke@435 542 }
duke@435 543 }
duke@435 544
duke@435 545 for (int i=n-1; i>0; i--) {
duke@435 546 Block *block = array.at(i);
duke@435 547 int block_index = block->index();
duke@435 548 for (int j=0; j<block->pred()->length(); j++) {
duke@435 549 int pred_index = block->pred()->at(j);
duke@435 550 int cur_index = eval(pred_index, blocks);
duke@435 551
duke@435 552 Block *cur_block = blocks->adr_at(cur_index);
duke@435 553 if (cur_block->semi() < block->semi()) {
duke@435 554 block->set_semi(cur_block->semi());
duke@435 555 }
duke@435 556 }
duke@435 557
duke@435 558 int semi_index = block->semi();
duke@435 559 Block *semi_block = array.at(semi_index);
duke@435 560 semi_block->add_to_bucket(block_index);
duke@435 561
duke@435 562 link(block->parent(), block_index, blocks);
duke@435 563 Block *parent_block = blocks->adr_at(block->parent());
duke@435 564
duke@435 565 for (int j=0; j<parent_block->bucket()->length(); j++) {
duke@435 566 int cur_index = parent_block->bucket()->at(j);
duke@435 567 int new_index = eval(cur_index, blocks);
duke@435 568 Block *cur_block = blocks->adr_at(cur_index);
duke@435 569 Block *new_block = blocks->adr_at(new_index);
duke@435 570 int dom = block->parent();
duke@435 571
duke@435 572 if (new_block->semi() < cur_block->semi()) {
duke@435 573 dom = new_index;
duke@435 574 }
duke@435 575
duke@435 576 cur_block->set_dominator(dom);
duke@435 577 }
duke@435 578
duke@435 579 parent_block->clear_bucket();
duke@435 580 }
duke@435 581
duke@435 582 for (int i=1; i < n; i++) {
duke@435 583
duke@435 584 Block *block = array.at(i);
duke@435 585 int block_index = block->index();
duke@435 586
duke@435 587 int semi_index = block->semi();
duke@435 588 Block *semi_block = array.at(semi_index);
duke@435 589
duke@435 590 if (block->dominator() != semi_block->index()) {
duke@435 591 int new_dom = blocks->adr_at(block->dominator())->dominator();
duke@435 592 block->set_dominator(new_dom);
duke@435 593 }
duke@435 594 }
duke@435 595
duke@435 596 for (int i = 0; i < blocks->length(); i++) {
duke@435 597 if (blocks->adr_at(i)->dominator() == -1) {
duke@435 598 blocks->adr_at(i)->set_dominator(0);
duke@435 599 }
duke@435 600 }
duke@435 601
duke@435 602 // Build dominates array
duke@435 603 for (int i=1; i < blocks->length(); i++) {
duke@435 604 Block *block = blocks->adr_at(i);
duke@435 605 int dominator = block->dominator();
duke@435 606 Block *dom_block = blocks->adr_at(dominator);
duke@435 607 dom_block->add_dominates(i);
duke@435 608 dom_block->add_child(i);
duke@435 609
duke@435 610 while(dominator != 0) {
duke@435 611 dominator = dom_block->dominator();
duke@435 612 dom_block = blocks->adr_at(dominator);
duke@435 613 dom_block->add_child(i);
duke@435 614 }
duke@435 615 }
duke@435 616 }
duke@435 617
duke@435 618 void IdealGraphPrinter::build_common_dominator(int **common_dominator, int index, GrowableArray<Block>* blocks) {
duke@435 619
duke@435 620 common_dominator[index][index] = index;
duke@435 621 Block *block = blocks->adr_at(index);
duke@435 622 for (int i = 0; i < block->dominates()->length(); i++) {
duke@435 623 Block *dominated = blocks->adr_at(block->dominates()->at(i));
duke@435 624
duke@435 625 for (int j=0; j<dominated->children()->length(); j++) {
duke@435 626 Block *child = blocks->adr_at(dominated->children()->at(j));
duke@435 627 common_dominator[index][child->index()] = common_dominator[child->index()][index] = index;
duke@435 628
duke@435 629 for (int k=0; k<i; k++) {
duke@435 630 Block *other_dominated = blocks->adr_at(block->dominates()->at(k));
duke@435 631 common_dominator[child->index()][other_dominated->index()] = common_dominator[other_dominated->index()][child->index()] = index;
duke@435 632
duke@435 633 for (int l=0 ; l<other_dominated->children()->length(); l++) {
duke@435 634 Block *other_child = blocks->adr_at(other_dominated->children()->at(l));
duke@435 635 common_dominator[child->index()][other_child->index()] = common_dominator[other_child->index()][child->index()] = index;
duke@435 636 }
duke@435 637 }
duke@435 638 }
duke@435 639
duke@435 640 build_common_dominator(common_dominator, dominated->index(), blocks);
duke@435 641 }
duke@435 642 }
duke@435 643
duke@435 644 void IdealGraphPrinter::schedule_latest(int **common_dominator, GrowableArray<Block>* blocks) {
duke@435 645
duke@435 646 int queue_size = _nodes.length() + 1;
duke@435 647 NodeDescription **queue = NEW_RESOURCE_ARRAY(NodeDescription *, queue_size);
duke@435 648 int queue_start = 0;
duke@435 649 int queue_end = 0;
duke@435 650 Arena *a = new Arena();
duke@435 651 VectorSet on_queue(a);
duke@435 652
duke@435 653 for (int i = 0; i < _nodes.length(); i++) {
duke@435 654 NodeDescription *desc = _nodes.at(i);
duke@435 655 if (desc) {
duke@435 656 desc->init_succs();
duke@435 657 }
duke@435 658 }
duke@435 659
duke@435 660 for (int i = 0; i < _nodes.length(); i++) {
duke@435 661 NodeDescription *desc = _nodes.at(i);
duke@435 662 if (desc) {
duke@435 663 for (uint j=0; j<desc->node()->len(); j++) {
duke@435 664 Node *n = desc->node()->in(j);
duke@435 665 if (n) {
duke@435 666 NodeDescription *other_desc = _nodes.at(n->_idx);
duke@435 667 other_desc->add_succ(desc);
duke@435 668 }
duke@435 669 }
duke@435 670 }
duke@435 671 }
duke@435 672
duke@435 673 for (int i = 0; i < _nodes.length(); i++) {
duke@435 674 NodeDescription *desc = _nodes.at(i);
duke@435 675 if (desc && desc->block_index() == -1) {
duke@435 676
duke@435 677 // Put Phi into same block as region
duke@435 678 if (desc->node()->is_Phi() && desc->node()->in(0) && _nodes.at(desc->node()->in(0)->_idx)->block_index() != -1) {
duke@435 679 int index = _nodes.at(desc->node()->in(0)->_idx)->block_index();
duke@435 680 desc->set_block_index(index);
duke@435 681 blocks->adr_at(index)->add_node(desc);
duke@435 682
duke@435 683 // Put Projections to same block as parent
duke@435 684 } else if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) {
duke@435 685 int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index();
duke@435 686 desc->set_block_index(index);
duke@435 687 blocks->adr_at(index)->add_node(desc);
duke@435 688 } else {
duke@435 689 queue[queue_end] = desc;
duke@435 690 queue_end++;
duke@435 691 on_queue.set(desc->node()->_idx);
duke@435 692 }
duke@435 693 }
duke@435 694 }
duke@435 695
duke@435 696
duke@435 697 int z = 0;
duke@435 698 while(queue_start != queue_end && z < 10000) {
duke@435 699
duke@435 700 NodeDescription *desc = queue[queue_start];
duke@435 701 queue_start = (queue_start + 1) % queue_size;
duke@435 702 on_queue >>= desc->node()->_idx;
duke@435 703
duke@435 704 Node* node = desc->node();
duke@435 705
duke@435 706 if (desc->succs()->length() == 0) {
duke@435 707 int x = 0;
duke@435 708 }
duke@435 709
duke@435 710 int block_index = -1;
duke@435 711 if (desc->succs()->length() != 0) {
duke@435 712 for (int i = 0; i < desc->succs()->length(); i++) {
duke@435 713 NodeDescription *cur_desc = desc->succs()->at(i);
duke@435 714 if (cur_desc != desc) {
duke@435 715 if (cur_desc->succs()->length() == 0) {
duke@435 716
duke@435 717 // Ignore nodes with 0 successors
duke@435 718
duke@435 719 } else if (cur_desc->block_index() == -1) {
duke@435 720
duke@435 721 // Let this node schedule first
duke@435 722 block_index = -1;
duke@435 723 break;
duke@435 724
duke@435 725 } else if (cur_desc->node()->is_Phi()){
duke@435 726
duke@435 727 // Special treatment for Phi functions
duke@435 728 PhiNode *phi = cur_desc->node()->as_Phi();
duke@435 729 assert(phi->in(0) && phi->in(0)->is_Region(), "Must have region node in first input");
duke@435 730 RegionNode *region = phi->in(0)->as_Region();
duke@435 731
duke@435 732 for (uint j=1; j<phi->len(); j++) {
duke@435 733 Node *cur_phi_input = phi->in(j);
duke@435 734 if (cur_phi_input == desc->node() && region->in(j)) {
duke@435 735 NodeDescription *cur_region_input = _nodes.at(region->in(j)->_idx);
duke@435 736 if (cur_region_input->block_index() == -1) {
duke@435 737
duke@435 738 // Let this node schedule first
duke@435 739 block_index = -1;
duke@435 740 break;
duke@435 741 } else {
duke@435 742 if (block_index == -1) {
duke@435 743 block_index = cur_region_input->block_index();
duke@435 744 } else {
duke@435 745 block_index = common_dominator[block_index][cur_region_input->block_index()];
duke@435 746 }
duke@435 747 }
duke@435 748 }
duke@435 749 }
duke@435 750
duke@435 751 } else {
duke@435 752 if (block_index == -1) {
duke@435 753 block_index = cur_desc->block_index();
duke@435 754 } else {
duke@435 755 block_index = common_dominator[block_index][cur_desc->block_index()];
duke@435 756 }
duke@435 757 }
duke@435 758 }
duke@435 759 }
duke@435 760 }
duke@435 761
duke@435 762 if (block_index == -1) {
duke@435 763 queue[queue_end] = desc;
duke@435 764 queue_end = (queue_end + 1) % queue_size;
duke@435 765 on_queue.set(desc->node()->_idx);
duke@435 766 z++;
duke@435 767 } else {
duke@435 768 assert(desc->block_index() == -1, "");
duke@435 769 desc->set_block_index(block_index);
duke@435 770 blocks->adr_at(block_index)->add_node(desc);
duke@435 771 z = 0;
duke@435 772 }
duke@435 773 }
duke@435 774
duke@435 775 for (int i = 0; i < _nodes.length(); i++) {
duke@435 776 NodeDescription *desc = _nodes.at(i);
duke@435 777 if (desc && desc->block_index() == -1) {
duke@435 778
duke@435 779 //if (desc->node()->is_Proj() || desc->node()->is_Con()) {
duke@435 780 Node *parent = desc->node()->in(0);
duke@435 781 uint cur = 1;
duke@435 782 while(!parent && cur < desc->node()->len()) {
duke@435 783 parent = desc->node()->in(cur);
duke@435 784 cur++;
duke@435 785 }
duke@435 786
duke@435 787 if (parent && _nodes.at(parent->_idx)->block_index() != -1) {
duke@435 788 int index = _nodes.at(parent->_idx)->block_index();
duke@435 789 desc->set_block_index(index);
duke@435 790 blocks->adr_at(index)->add_node(desc);
duke@435 791 } else {
duke@435 792 desc->set_block_index(0);
duke@435 793 blocks->adr_at(0)->add_node(desc);
duke@435 794 //ShouldNotReachHere();
duke@435 795 }
duke@435 796 //}
duke@435 797 /*
duke@435 798 if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) {
duke@435 799 int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index();
duke@435 800 desc->set_block_index(index);
duke@435 801 blocks->adr_at(index)->add_node(desc);
duke@435 802 } */
duke@435 803 }
duke@435 804 }
duke@435 805
duke@435 806 for (int i = 0; i < _nodes.length(); i++) {
duke@435 807 NodeDescription *desc = _nodes.at(i);
duke@435 808 if (desc) {
duke@435 809 desc->clear_succs();
duke@435 810 }
duke@435 811 }
duke@435 812
duke@435 813 for (int i = 0; i < _nodes.length(); i++) {
duke@435 814 NodeDescription *desc = _nodes.at(i);
duke@435 815 if (desc) {
duke@435 816 int block_index = desc->block_index();
duke@435 817
duke@435 818 assert(block_index >= 0 && block_index < blocks->length(), "Block index must be in range");
duke@435 819 assert(blocks->adr_at(block_index)->nodes()->contains(desc), "Node must be child of block");
duke@435 820 }
duke@435 821 }
duke@435 822 a->destruct_contents();
duke@435 823 }
duke@435 824
duke@435 825 void IdealGraphPrinter::build_blocks(Node *root) {
duke@435 826
duke@435 827 Arena *a = new Arena();
duke@435 828 Node_Stack stack(a, 100);
duke@435 829
duke@435 830 VectorSet visited(a);
duke@435 831 stack.push(root, 0);
duke@435 832 GrowableArray<Block> blocks(a, 2, 0, Block(0));
duke@435 833
duke@435 834 for (int i = 0; i < _nodes.length(); i++) {
duke@435 835 if (_nodes.at(i)) _nodes.at(i)->set_block_index(-1);
duke@435 836 }
duke@435 837
duke@435 838
duke@435 839 // Order nodes such that node index is equal to idx
duke@435 840 for (int i = 0; i < _nodes.length(); i++) {
duke@435 841
duke@435 842 if (_nodes.at(i)) {
duke@435 843 NodeDescription *node = _nodes.at(i);
duke@435 844 int index = node->node()->_idx;
duke@435 845 if (index != i) {
duke@435 846 _nodes.at_grow(index);
duke@435 847 NodeDescription *tmp = _nodes.at(index);
duke@435 848 *(_nodes.adr_at(index)) = node;
duke@435 849 *(_nodes.adr_at(i)) = tmp;
duke@435 850 i--;
duke@435 851 }
duke@435 852 }
duke@435 853 }
duke@435 854
duke@435 855 for (int i = 0; i < _nodes.length(); i++) {
duke@435 856 NodeDescription *node = _nodes.at(i);
duke@435 857 if (node) {
duke@435 858 assert(node->node()->_idx == (uint)i, "");
duke@435 859 }
duke@435 860 }
duke@435 861
duke@435 862 while(stack.is_nonempty()) {
duke@435 863
duke@435 864 //Node *n = stack.node();
duke@435 865 //int index = stack.index();
duke@435 866 Node *proj = stack.node();//n->in(index);
duke@435 867 const Node *parent = proj->is_block_proj();
duke@435 868 if (parent == NULL) {
duke@435 869 parent = proj;
duke@435 870 }
duke@435 871
duke@435 872 if (!visited.test_set(parent->_idx)) {
duke@435 873
duke@435 874 NodeDescription *end_desc = _nodes.at(parent->_idx);
duke@435 875 int block_index = blocks.length();
duke@435 876 Block block(block_index);
duke@435 877 blocks.append(block);
duke@435 878 Block *b = blocks.adr_at(block_index);
duke@435 879 b->set_start(end_desc);
duke@435 880 // assert(end_desc->block_index() == -1, "");
duke@435 881 end_desc->set_block_index(block_index);
duke@435 882 b->add_node(end_desc);
duke@435 883
duke@435 884 // Skip any control-pinned middle'in stuff
duke@435 885 Node *p = proj;
duke@435 886 NodeDescription *start_desc = NULL;
duke@435 887 do {
duke@435 888 proj = p; // Update pointer to last Control
duke@435 889 if (p->in(0) == NULL) {
duke@435 890 start_desc = end_desc;
duke@435 891 break;
duke@435 892 }
duke@435 893 p = p->in(0); // Move control forward
duke@435 894 start_desc = _nodes.at(p->_idx);
duke@435 895 assert(start_desc, "");
duke@435 896
duke@435 897 if (start_desc != end_desc && start_desc->block_index() == -1) {
duke@435 898 assert(start_desc->block_index() == -1, "");
duke@435 899 assert(block_index < blocks.length(), "");
duke@435 900 start_desc->set_block_index(block_index);
duke@435 901 b->add_node(start_desc);
duke@435 902 }
duke@435 903 } while( !p->is_block_proj() &&
duke@435 904 !p->is_block_start() );
duke@435 905
duke@435 906 for (uint i = 0; i < start_desc->node()->len(); i++) {
duke@435 907
duke@435 908 Node *pred_node = start_desc->node()->in(i);
duke@435 909
duke@435 910
duke@435 911 if (pred_node && pred_node != start_desc->node()) {
duke@435 912 const Node *cur_parent = pred_node->is_block_proj();
duke@435 913 if (cur_parent != NULL) {
duke@435 914 pred_node = (Node *)cur_parent;
duke@435 915 }
duke@435 916
duke@435 917 NodeDescription *pred_node_desc = _nodes.at(pred_node->_idx);
duke@435 918 if (pred_node_desc->block_index() != -1) {
duke@435 919 blocks.adr_at(pred_node_desc->block_index())->add_succ(block_index);
duke@435 920 }
duke@435 921 }
duke@435 922 }
duke@435 923
duke@435 924 for (DUIterator_Fast dmax, i = end_desc->node()->fast_outs(dmax); i < dmax; i++) {
duke@435 925 Node* cur_succ = end_desc->node()->fast_out(i);
duke@435 926 NodeDescription *cur_succ_desc = _nodes.at(cur_succ->_idx);
duke@435 927
duke@435 928 DUIterator_Fast dmax2, i2 = cur_succ->fast_outs(dmax2);
duke@435 929 if (cur_succ->is_block_proj() && i2 < dmax2 && !cur_succ->is_Root()) {
duke@435 930
duke@435 931 for (; i2<dmax2; i2++) {
duke@435 932 Node *cur_succ2 = cur_succ->fast_out(i2);
duke@435 933 if (cur_succ2) {
duke@435 934 cur_succ_desc = _nodes.at(cur_succ2->_idx);
duke@435 935 if (cur_succ_desc == NULL) {
duke@435 936 // dead node so skip it
duke@435 937 continue;
duke@435 938 }
duke@435 939 if (cur_succ2 != end_desc->node() && cur_succ_desc->block_index() != -1) {
duke@435 940 b->add_succ(cur_succ_desc->block_index());
duke@435 941 }
duke@435 942 }
duke@435 943 }
duke@435 944
duke@435 945 } else {
duke@435 946
duke@435 947 if (cur_succ != end_desc->node() && cur_succ_desc && cur_succ_desc->block_index() != -1) {
duke@435 948 b->add_succ(cur_succ_desc->block_index());
duke@435 949 }
duke@435 950 }
duke@435 951 }
duke@435 952
duke@435 953
duke@435 954 int num_preds = p->len();
duke@435 955 int bottom = -1;
duke@435 956 if (p->is_Region() || p->is_Phi()) {
duke@435 957 bottom = 0;
duke@435 958 }
duke@435 959
duke@435 960 int pushed = 0;
duke@435 961 for (int i=num_preds - 1; i > bottom; i--) {
duke@435 962 if (p->in(i) != NULL && p->in(i) != p) {
duke@435 963 stack.push(p->in(i), 0);
duke@435 964 pushed++;
duke@435 965 }
duke@435 966 }
duke@435 967
duke@435 968 if (pushed == 0 && p->is_Root() && !_matcher) {
duke@435 969 // Special case when backedges to root are not yet built
duke@435 970 for (int i = 0; i < _nodes.length(); i++) {
duke@435 971 if (_nodes.at(i) && _nodes.at(i)->node()->is_SafePoint() && _nodes.at(i)->node()->outcnt() == 0) {
duke@435 972 stack.push(_nodes.at(i)->node(), 0);
duke@435 973 }
duke@435 974 }
duke@435 975 }
duke@435 976
duke@435 977 } else {
duke@435 978 stack.pop();
duke@435 979 }
duke@435 980 }
duke@435 981
duke@435 982 build_dominators(&blocks);
duke@435 983
duke@435 984 int **common_dominator = NEW_RESOURCE_ARRAY(int *, blocks.length());
duke@435 985 for (int i = 0; i < blocks.length(); i++) {
duke@435 986 int *cur = NEW_RESOURCE_ARRAY(int, blocks.length());
duke@435 987 common_dominator[i] = cur;
duke@435 988
duke@435 989 for (int j=0; j<blocks.length(); j++) {
duke@435 990 cur[j] = 0;
duke@435 991 }
duke@435 992 }
duke@435 993
duke@435 994 for (int i = 0; i < blocks.length(); i++) {
duke@435 995 blocks.adr_at(i)->add_child(blocks.adr_at(i)->index());
duke@435 996 }
duke@435 997 build_common_dominator(common_dominator, 0, &blocks);
duke@435 998
duke@435 999 schedule_latest(common_dominator, &blocks);
duke@435 1000
duke@435 1001 start_element(CONTROL_FLOW_ELEMENT);
duke@435 1002
duke@435 1003 for (int i = 0; i < blocks.length(); i++) {
duke@435 1004 Block *block = blocks.adr_at(i);
duke@435 1005
duke@435 1006 Properties props;
duke@435 1007 props.add(new Property(BLOCK_NAME_PROPERTY, i));
duke@435 1008 props.add(new Property(BLOCK_DOMINATOR_PROPERTY, block->dominator()));
duke@435 1009 start_element(BLOCK_ELEMENT, &props);
duke@435 1010
duke@435 1011 if (block->succs()->length() > 0) {
duke@435 1012 start_element(SUCCESSORS_ELEMENT);
duke@435 1013 for (int j=0; j<block->succs()->length(); j++) {
duke@435 1014 int cur_index = block->succs()->at(j);
duke@435 1015 if (cur_index != 0 /* start_block has must not have inputs */) {
duke@435 1016 Properties properties;
duke@435 1017 properties.add(new Property(BLOCK_NAME_PROPERTY, cur_index));
duke@435 1018 simple_element(SUCCESSOR_ELEMENT, &properties);
duke@435 1019 }
duke@435 1020 }
duke@435 1021 end_element(SUCCESSORS_ELEMENT);
duke@435 1022 }
duke@435 1023
duke@435 1024 start_element(NODES_ELEMENT);
duke@435 1025
duke@435 1026 for (int j=0; j<block->nodes()->length(); j++) {
duke@435 1027 NodeDescription *n = block->nodes()->at(j);
duke@435 1028 Properties properties;
duke@435 1029 properties.add(new Property(NODE_ID_PROPERTY, n->id()));
duke@435 1030 simple_element(NODE_ELEMENT, &properties);
duke@435 1031 }
duke@435 1032
duke@435 1033 end_element(NODES_ELEMENT);
duke@435 1034
duke@435 1035 end_element(BLOCK_ELEMENT);
duke@435 1036 }
duke@435 1037
duke@435 1038
duke@435 1039 end_element(CONTROL_FLOW_ELEMENT);
duke@435 1040
duke@435 1041 a->destruct_contents();
duke@435 1042 }
duke@435 1043
duke@435 1044 void IdealGraphPrinter::print_method(Compile* compile, const char *name, int level, bool clear_nodes) {
duke@435 1045 print(compile, name, (Node *)compile->root(), level, clear_nodes);
duke@435 1046 }
duke@435 1047
duke@435 1048 // Print current ideal graph
duke@435 1049 void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, int level, bool clear_nodes) {
duke@435 1050
duke@435 1051 // if (finish && !in_method) return;
duke@435 1052 if (!_current_method || !_should_send_method || level > PrintIdealGraphLevel) return;
duke@435 1053
duke@435 1054 assert(_current_method, "newMethod has to be called first!");
duke@435 1055
duke@435 1056 if (clear_nodes) {
duke@435 1057 int x = 0;
duke@435 1058 }
duke@435 1059
duke@435 1060 _clear_nodes = clear_nodes;
duke@435 1061
duke@435 1062 // Warning, unsafe cast?
duke@435 1063 _chaitin = (PhaseChaitin *)compile->regalloc();
duke@435 1064 _matcher = compile->matcher();
duke@435 1065
duke@435 1066
duke@435 1067 // Update nodes
duke@435 1068 for (int i = 0; i < _nodes.length(); i++) {
duke@435 1069 NodeDescription *desc = _nodes.at(i);
duke@435 1070 if (desc) {
duke@435 1071 desc->set_state(Invalid);
duke@435 1072 }
duke@435 1073 }
duke@435 1074 Node *n = node;
duke@435 1075 walk(n);
duke@435 1076
duke@435 1077 // Update edges
duke@435 1078 for (int i = 0; i < _edges.length(); i++) {
duke@435 1079 _edges.at(i)->set_state(Invalid);
duke@435 1080 }
duke@435 1081
duke@435 1082 for (int i = 0; i < _nodes.length(); i++) {
duke@435 1083 NodeDescription *desc = _nodes.at(i);
duke@435 1084 if (desc && desc->state() != Invalid) {
duke@435 1085
duke@435 1086 int to = desc->id();
duke@435 1087 uint len = desc->node()->len();
duke@435 1088 for (uint j=0; j<len; j++) {
duke@435 1089 Node *n = desc->node()->in(j);
duke@435 1090
duke@435 1091 if (n) {
duke@435 1092
duke@435 1093
duke@435 1094 intptr_t from = (intptr_t)n;
duke@435 1095
duke@435 1096 // Assert from node is valid
duke@435 1097 /*
duke@435 1098 bool ok = false;
duke@435 1099 for (int k=0; k<_nodes.length(); k++) {
duke@435 1100 NodeDescription *desc = _nodes.at(k);
duke@435 1101 if (desc && desc->id() == from) {
duke@435 1102 assert(desc->state() != Invalid, "");
duke@435 1103 ok = true;
duke@435 1104 }
duke@435 1105 }
duke@435 1106 assert(ok, "");*/
duke@435 1107
duke@435 1108 uint index = j;
duke@435 1109 if (index >= desc->node()->req()) {
duke@435 1110 index = desc->node()->req();
duke@435 1111 }
duke@435 1112
duke@435 1113 print_edge(from, to, index);
duke@435 1114 }
duke@435 1115 }
duke@435 1116 }
duke@435 1117 }
duke@435 1118
duke@435 1119 bool is_different = false;
duke@435 1120
duke@435 1121 for (int i = 0; i < _nodes.length(); i++) {
duke@435 1122 NodeDescription *desc = _nodes.at(i);
duke@435 1123 if (desc && desc->state() != Valid) {
duke@435 1124 is_different = true;
duke@435 1125 break;
duke@435 1126 }
duke@435 1127 }
duke@435 1128
duke@435 1129 if (!is_different) {
duke@435 1130 for (int i = 0; i < _edges.length(); i++) {
duke@435 1131 EdgeDescription *conn = _edges.at(i);
duke@435 1132 if (conn && conn->state() != Valid) {
duke@435 1133 is_different = true;
duke@435 1134 break;
duke@435 1135 }
duke@435 1136 }
duke@435 1137 }
duke@435 1138
duke@435 1139 // No changes -> do not print graph
duke@435 1140 if (!is_different) return;
duke@435 1141
duke@435 1142 Properties properties;
duke@435 1143 properties.add(new Property(GRAPH_NAME_PROPERTY, (const char *)name));
duke@435 1144 start_element(GRAPH_ELEMENT, &properties);
duke@435 1145
duke@435 1146 start_element(NODES_ELEMENT);
duke@435 1147 for (int i = 0; i < _nodes.length(); i++) {
duke@435 1148 NodeDescription *desc = _nodes.at(i);
duke@435 1149 if (desc) {
duke@435 1150 desc->print(this);
duke@435 1151 if (desc->state() == Invalid) {
duke@435 1152 delete desc;
duke@435 1153 _nodes.at_put(i, NULL);
duke@435 1154 } else {
duke@435 1155 desc->set_state(Valid);
duke@435 1156 }
duke@435 1157 }
duke@435 1158 }
duke@435 1159 end_element(NODES_ELEMENT);
duke@435 1160
duke@435 1161 build_blocks(node);
duke@435 1162
duke@435 1163 start_element(EDGES_ELEMENT);
duke@435 1164 for (int i = 0; i < _edges.length(); i++) {
duke@435 1165 EdgeDescription *conn = _edges.at(i);
duke@435 1166
duke@435 1167 // Assert from and to nodes are valid
duke@435 1168 /*
duke@435 1169 if (!conn->state() == Invalid) {
duke@435 1170 bool ok1 = false;
duke@435 1171 bool ok2 = false;
duke@435 1172 for (int j=0; j<_nodes.length(); j++) {
duke@435 1173 NodeDescription *desc = _nodes.at(j);
duke@435 1174 if (desc && desc->id() == conn->from()) {
duke@435 1175 ok1 = true;
duke@435 1176 }
duke@435 1177
duke@435 1178 if (desc && desc->id() == conn->to()) {
duke@435 1179 ok2 = true;
duke@435 1180 }
duke@435 1181 }
duke@435 1182
duke@435 1183 assert(ok1, "from node not found!");
duke@435 1184 assert(ok2, "to node not found!");
duke@435 1185 }*/
duke@435 1186
duke@435 1187 conn->print(this);
duke@435 1188 if (conn->state() == Invalid) {
duke@435 1189 _edges.remove_at(i);
duke@435 1190 delete conn;
duke@435 1191 i--;
duke@435 1192 }
duke@435 1193 }
duke@435 1194
duke@435 1195 end_element(EDGES_ELEMENT);
duke@435 1196
duke@435 1197 end_element(GRAPH_ELEMENT);
duke@435 1198
duke@435 1199 _output->flush();
duke@435 1200 }
duke@435 1201
duke@435 1202 // Print edge
duke@435 1203 void IdealGraphPrinter::print_edge(int from, int to, int index) {
duke@435 1204
duke@435 1205 EdgeDescription *conn = new EdgeDescription(from, to, index);
duke@435 1206 for (int i = 0; i < _edges.length(); i++) {
duke@435 1207 if (_edges.at(i)->equals(conn)) {
duke@435 1208 conn->set_state(Valid);
duke@435 1209 delete _edges.at(i);
duke@435 1210 _edges.at_put(i, conn);
duke@435 1211 return;
duke@435 1212 }
duke@435 1213 }
duke@435 1214
duke@435 1215 _edges.append(conn);
duke@435 1216 }
duke@435 1217
duke@435 1218 extern const char *NodeClassNames[];
duke@435 1219
duke@435 1220 // Create node description
duke@435 1221 IdealGraphPrinter::NodeDescription *IdealGraphPrinter::create_node_description(Node* node) {
duke@435 1222
duke@435 1223 #ifndef PRODUCT
duke@435 1224 node->_in_dump_cnt++;
duke@435 1225 NodeDescription *desc = new NodeDescription(node);
duke@435 1226 desc->properties()->add(new Property(NODE_NAME_PROPERTY, (const char *)node->Name()));
duke@435 1227
duke@435 1228 const Type *t = node->bottom_type();
duke@435 1229 desc->properties()->add(new Property("type", (const char *)Type::msg[t->base()]));
duke@435 1230
duke@435 1231 desc->properties()->add(new Property("idx", node->_idx));
duke@435 1232 #ifdef ASSERT
duke@435 1233 desc->properties()->add(new Property("debug_idx", node->_debug_idx));
duke@435 1234 #endif
duke@435 1235
duke@435 1236
duke@435 1237 const jushort flags = node->flags();
duke@435 1238 if (flags & Node::Flag_is_Copy) {
duke@435 1239 desc->properties()->add(new Property("is_copy", "true"));
duke@435 1240 }
duke@435 1241 if (flags & Node::Flag_is_Call) {
duke@435 1242 desc->properties()->add(new Property("is_call", "true"));
duke@435 1243 }
duke@435 1244 if (flags & Node::Flag_rematerialize) {
duke@435 1245 desc->properties()->add(new Property("rematerialize", "true"));
duke@435 1246 }
duke@435 1247 if (flags & Node::Flag_needs_anti_dependence_check) {
duke@435 1248 desc->properties()->add(new Property("needs_anti_dependence_check", "true"));
duke@435 1249 }
duke@435 1250 if (flags & Node::Flag_is_macro) {
duke@435 1251 desc->properties()->add(new Property("is_macro", "true"));
duke@435 1252 }
duke@435 1253 if (flags & Node::Flag_is_Con) {
duke@435 1254 desc->properties()->add(new Property("is_con", "true"));
duke@435 1255 }
duke@435 1256 if (flags & Node::Flag_is_cisc_alternate) {
duke@435 1257 desc->properties()->add(new Property("is_cisc_alternate", "true"));
duke@435 1258 }
duke@435 1259 if (flags & Node::Flag_is_Branch) {
duke@435 1260 desc->properties()->add(new Property("is_branch", "true"));
duke@435 1261 }
duke@435 1262 if (flags & Node::Flag_is_block_start) {
duke@435 1263 desc->properties()->add(new Property("is_block_start", "true"));
duke@435 1264 }
duke@435 1265 if (flags & Node::Flag_is_Goto) {
duke@435 1266 desc->properties()->add(new Property("is_goto", "true"));
duke@435 1267 }
duke@435 1268 if (flags & Node::Flag_is_dead_loop_safe) {
duke@435 1269 desc->properties()->add(new Property("is_dead_loop_safe", "true"));
duke@435 1270 }
duke@435 1271 if (flags & Node::Flag_may_be_short_branch) {
duke@435 1272 desc->properties()->add(new Property("may_be_short_branch", "true"));
duke@435 1273 }
duke@435 1274 if (flags & Node::Flag_is_safepoint_node) {
duke@435 1275 desc->properties()->add(new Property("is_safepoint_node", "true"));
duke@435 1276 }
duke@435 1277 if (flags & Node::Flag_is_pc_relative) {
duke@435 1278 desc->properties()->add(new Property("is_pc_relative", "true"));
duke@435 1279 }
duke@435 1280
duke@435 1281 if (_matcher) {
duke@435 1282 if (_matcher->is_shared(desc->node())) {
duke@435 1283 desc->properties()->add(new Property("is_shared", "true"));
duke@435 1284 } else {
duke@435 1285 desc->properties()->add(new Property("is_shared", "false"));
duke@435 1286 }
duke@435 1287
duke@435 1288 if (_matcher->is_dontcare(desc->node())) {
duke@435 1289 desc->properties()->add(new Property("is_dontcare", "true"));
duke@435 1290 } else {
duke@435 1291 desc->properties()->add(new Property("is_dontcare", "false"));
duke@435 1292 }
duke@435 1293 }
duke@435 1294
duke@435 1295 if (node->is_Proj()) {
duke@435 1296 desc->properties()->add(new Property("con", (int)node->as_Proj()->_con));
duke@435 1297 }
duke@435 1298
duke@435 1299 if (node->is_Mach()) {
duke@435 1300 desc->properties()->add(new Property("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]));
duke@435 1301 }
duke@435 1302
duke@435 1303
duke@435 1304
duke@435 1305
duke@435 1306
duke@435 1307 outputStream *oldTty = tty;
duke@435 1308 buffer[0] = 0;
duke@435 1309 stringStream s2(buffer, sizeof(buffer) - 1);
duke@435 1310
duke@435 1311 node->dump_spec(&s2);
duke@435 1312 assert(s2.size() < sizeof(buffer), "size in range");
duke@435 1313 desc->properties()->add(new Property("dump_spec", buffer));
duke@435 1314
duke@435 1315 if (node->is_block_proj()) {
duke@435 1316 desc->properties()->add(new Property("is_block_proj", "true"));
duke@435 1317 }
duke@435 1318
duke@435 1319 if (node->is_block_start()) {
duke@435 1320 desc->properties()->add(new Property("is_block_start", "true"));
duke@435 1321 }
duke@435 1322
duke@435 1323 const char *short_name = "short_name";
duke@435 1324 if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) {
duke@435 1325 int index = node->as_Proj()->_con - TypeFunc::Parms;
duke@435 1326 if (index >= 10) {
duke@435 1327 desc->properties()->add(new Property(short_name, "PA"));
duke@435 1328 } else {
duke@435 1329 sprintf(buffer, "P%d", index);
duke@435 1330 desc->properties()->add(new Property(short_name, buffer));
duke@435 1331 }
duke@435 1332 } else if (strcmp(node->Name(), "IfTrue") == 0) {
duke@435 1333 desc->properties()->add(new Property(short_name, "T"));
duke@435 1334 } else if (strcmp(node->Name(), "IfFalse") == 0) {
duke@435 1335 desc->properties()->add(new Property(short_name, "F"));
duke@435 1336 } else if ((node->is_Con() && node->is_Type()) || node->is_Proj()) {
duke@435 1337
duke@435 1338 if (t->base() == Type::Int && t->is_int()->is_con()) {
duke@435 1339 const TypeInt *typeInt = t->is_int();
duke@435 1340 assert(typeInt->is_con(), "must be constant");
duke@435 1341 jint value = typeInt->get_con();
duke@435 1342
duke@435 1343 // max. 2 chars allowed
duke@435 1344 if (value >= -9 && value <= 99) {
duke@435 1345 sprintf(buffer, "%d", value);
duke@435 1346 desc->properties()->add(new Property(short_name, buffer));
duke@435 1347 }
duke@435 1348 else
duke@435 1349 {
duke@435 1350 desc->properties()->add(new Property(short_name, "I"));
duke@435 1351 }
duke@435 1352 } else if (t == Type::TOP) {
duke@435 1353 desc->properties()->add(new Property(short_name, "^"));
duke@435 1354 } else if (t->base() == Type::Long && t->is_long()->is_con()) {
duke@435 1355 const TypeLong *typeLong = t->is_long();
duke@435 1356 assert(typeLong->is_con(), "must be constant");
duke@435 1357 jlong value = typeLong->get_con();
duke@435 1358
duke@435 1359 // max. 2 chars allowed
duke@435 1360 if (value >= -9 && value <= 99) {
duke@435 1361 sprintf(buffer, "%d", value);
duke@435 1362 desc->properties()->add(new Property(short_name, buffer));
duke@435 1363 }
duke@435 1364 else
duke@435 1365 {
duke@435 1366 desc->properties()->add(new Property(short_name, "L"));
duke@435 1367 }
duke@435 1368 } else if (t->base() == Type::KlassPtr) {
duke@435 1369 const TypeKlassPtr *typeKlass = t->is_klassptr();
duke@435 1370 desc->properties()->add(new Property(short_name, "CP"));
duke@435 1371 } else if (t->base() == Type::Control) {
duke@435 1372 desc->properties()->add(new Property(short_name, "C"));
duke@435 1373 } else if (t->base() == Type::Memory) {
duke@435 1374 desc->properties()->add(new Property(short_name, "M"));
duke@435 1375 } else if (t->base() == Type::Abio) {
duke@435 1376 desc->properties()->add(new Property(short_name, "IO"));
duke@435 1377 } else if (t->base() == Type::Return_Address) {
duke@435 1378 desc->properties()->add(new Property(short_name, "RA"));
duke@435 1379 } else if (t->base() == Type::AnyPtr) {
duke@435 1380 desc->properties()->add(new Property(short_name, "P"));
duke@435 1381 } else if (t->base() == Type::RawPtr) {
duke@435 1382 desc->properties()->add(new Property(short_name, "RP"));
duke@435 1383 } else if (t->base() == Type::AryPtr) {
duke@435 1384 desc->properties()->add(new Property(short_name, "AP"));
duke@435 1385 }
duke@435 1386 }
duke@435 1387
duke@435 1388 if (node->is_SafePoint()) {
duke@435 1389 SafePointNode *safePointNode = node->as_SafePoint();
duke@435 1390 if (safePointNode->jvms()) {
duke@435 1391 stringStream bciStream;
duke@435 1392 bciStream.print("%d ", safePointNode->jvms()->bci());
duke@435 1393 JVMState *caller = safePointNode->jvms()->caller();
duke@435 1394 while(caller) {
duke@435 1395 bciStream.print("%d ", caller->bci());
duke@435 1396
duke@435 1397 caller = caller->caller();
duke@435 1398 }
duke@435 1399 desc->properties()->add(new Property("bci", bciStream.as_string()));
duke@435 1400 }
duke@435 1401 }
duke@435 1402
duke@435 1403 if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) {
duke@435 1404 buffer[0] = 0;
duke@435 1405 _chaitin->dump_register(node, buffer);
duke@435 1406 desc->properties()->add(new Property("reg", buffer));
duke@435 1407 desc->properties()->add(new Property("lrg", _chaitin->n2lidx(node)));
duke@435 1408 }
duke@435 1409
duke@435 1410
duke@435 1411 node->_in_dump_cnt--;
duke@435 1412 return desc;
duke@435 1413 #else
duke@435 1414 return NULL;
duke@435 1415 #endif
duke@435 1416 }
duke@435 1417
duke@435 1418 void IdealGraphPrinter::pre_node(Node* node, void *env) {
duke@435 1419
duke@435 1420 IdealGraphPrinter *printer = (IdealGraphPrinter *)env;
duke@435 1421
duke@435 1422 NodeDescription *newDesc = printer->create_node_description(node);
duke@435 1423
duke@435 1424 if (printer->_clear_nodes) {
duke@435 1425
duke@435 1426 printer->_nodes.append(newDesc);
duke@435 1427 } else {
duke@435 1428
duke@435 1429 NodeDescription *desc = printer->_nodes.at_grow(node->_idx, NULL);
duke@435 1430
duke@435 1431 if (desc && desc->equals(newDesc)) {
duke@435 1432 //desc->set_state(Valid);
duke@435 1433 //desc->set_node(node);
duke@435 1434 delete desc;
duke@435 1435 printer->_nodes.at_put(node->_idx, NULL);
duke@435 1436 newDesc->set_state(Valid);
duke@435 1437 //printer->_nodes.at_put(node->_idx, newDesc);
duke@435 1438 } else {
duke@435 1439
duke@435 1440 if (desc && desc->id() == newDesc->id()) {
duke@435 1441 delete desc;
duke@435 1442 printer->_nodes.at_put(node->_idx, NULL);
duke@435 1443 newDesc->set_state(New);
duke@435 1444
duke@435 1445 }
duke@435 1446
duke@435 1447 //if (desc) {
duke@435 1448 // delete desc;
duke@435 1449 //}
duke@435 1450
duke@435 1451 //printer->_nodes.at_put(node->_idx, newDesc);
duke@435 1452 }
duke@435 1453
duke@435 1454 printer->_nodes.append(newDesc);
duke@435 1455 }
duke@435 1456 }
duke@435 1457
duke@435 1458 void IdealGraphPrinter::post_node(Node* node, void *env) {
duke@435 1459 }
duke@435 1460
duke@435 1461 outputStream *IdealGraphPrinter::output() {
duke@435 1462 return _output;
duke@435 1463 }
duke@435 1464
duke@435 1465 IdealGraphPrinter::Description::Description() {
duke@435 1466 _state = New;
duke@435 1467 }
duke@435 1468
duke@435 1469 void IdealGraphPrinter::Description::print(IdealGraphPrinter *printer) {
duke@435 1470 if (_state == Invalid) {
duke@435 1471 print_removed(printer);
duke@435 1472 } else if (_state == New) {
duke@435 1473 print_changed(printer);
duke@435 1474 }
duke@435 1475 }
duke@435 1476
duke@435 1477 void IdealGraphPrinter::Description::set_state(State s) {
duke@435 1478 _state = s;
duke@435 1479 }
duke@435 1480
duke@435 1481 IdealGraphPrinter::State IdealGraphPrinter::Description::state() {
duke@435 1482 return _state;
duke@435 1483 }
duke@435 1484
duke@435 1485 void IdealGraphPrinter::Block::set_proj(NodeDescription *n) {
duke@435 1486 _proj = n;
duke@435 1487 }
duke@435 1488
duke@435 1489 void IdealGraphPrinter::Block::set_start(NodeDescription *n) {
duke@435 1490 _start = n;
duke@435 1491 }
duke@435 1492
duke@435 1493 int IdealGraphPrinter::Block::semi() {
duke@435 1494 return _semi;
duke@435 1495 }
duke@435 1496
duke@435 1497 int IdealGraphPrinter::Block::parent() {
duke@435 1498 return _parent;
duke@435 1499 }
duke@435 1500
duke@435 1501 GrowableArray<int>* IdealGraphPrinter::Block::bucket() {
duke@435 1502 return &_bucket;
duke@435 1503 }
duke@435 1504
duke@435 1505 GrowableArray<int>* IdealGraphPrinter::Block::children() {
duke@435 1506 return &_children;
duke@435 1507 }
duke@435 1508
duke@435 1509 void IdealGraphPrinter::Block::add_child(int i) {
duke@435 1510 _children.append(i);
duke@435 1511 }
duke@435 1512
duke@435 1513 GrowableArray<int>* IdealGraphPrinter::Block::dominates() {
duke@435 1514 return &_dominates;
duke@435 1515 }
duke@435 1516
duke@435 1517 void IdealGraphPrinter::Block::add_dominates(int i) {
duke@435 1518 _dominates.append(i);
duke@435 1519 }
duke@435 1520
duke@435 1521 void IdealGraphPrinter::Block::add_to_bucket(int i) {
duke@435 1522 _bucket.append(i);
duke@435 1523 }
duke@435 1524
duke@435 1525 void IdealGraphPrinter::Block::clear_bucket() {
duke@435 1526 _bucket.clear();
duke@435 1527 }
duke@435 1528
duke@435 1529 void IdealGraphPrinter::Block::set_dominator(int i) {
duke@435 1530 _dominator = i;
duke@435 1531 }
duke@435 1532
duke@435 1533 void IdealGraphPrinter::Block::set_label(int i) {
duke@435 1534 _label = i;
duke@435 1535 }
duke@435 1536
duke@435 1537 int IdealGraphPrinter::Block::label() {
duke@435 1538 return _label;
duke@435 1539 }
duke@435 1540
duke@435 1541 int IdealGraphPrinter::Block::ancestor() {
duke@435 1542 return _ancestor;
duke@435 1543 }
duke@435 1544
duke@435 1545 void IdealGraphPrinter::Block::set_ancestor(int i) {
duke@435 1546 _ancestor = i;
duke@435 1547 }
duke@435 1548
duke@435 1549 int IdealGraphPrinter::Block::dominator() {
duke@435 1550 return _dominator;
duke@435 1551 }
duke@435 1552
duke@435 1553 int IdealGraphPrinter::Block::index() {
duke@435 1554 return _index;
duke@435 1555 }
duke@435 1556
duke@435 1557 void IdealGraphPrinter::Block::set_parent(int i) {
duke@435 1558 _parent = i;
duke@435 1559 }
duke@435 1560
duke@435 1561 GrowableArray<int>* IdealGraphPrinter::Block::pred() {
duke@435 1562 return &_pred;
duke@435 1563 }
duke@435 1564
duke@435 1565 void IdealGraphPrinter::Block::set_semi(int i) {
duke@435 1566 _semi = i;
duke@435 1567 }
duke@435 1568
duke@435 1569 IdealGraphPrinter::Block::Block() {
duke@435 1570 }
duke@435 1571
duke@435 1572 IdealGraphPrinter::Block::Block(int index) {
duke@435 1573 _index = index;
duke@435 1574 _label = index;
duke@435 1575 _semi = -1;
duke@435 1576 _ancestor = -1;
duke@435 1577 _dominator = -1;
duke@435 1578 }
duke@435 1579
duke@435 1580 void IdealGraphPrinter::Block::add_pred(int i) {
duke@435 1581 _pred.append(i);
duke@435 1582 }
duke@435 1583
duke@435 1584 IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::proj() {
duke@435 1585 return _proj;
duke@435 1586 }
duke@435 1587
duke@435 1588 IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::start() {
duke@435 1589 return _start;
duke@435 1590 }
duke@435 1591
duke@435 1592 GrowableArray<int>* IdealGraphPrinter::Block::succs() {
duke@435 1593 return &_succs;
duke@435 1594 }
duke@435 1595
duke@435 1596 void IdealGraphPrinter::Block::add_succ(int index) {
duke@435 1597
duke@435 1598 if (this->_index == 16 && index == 15) {
duke@435 1599 int x = 0;
duke@435 1600 }
duke@435 1601
duke@435 1602 if (!_succs.contains(index)) {
duke@435 1603 _succs.append(index);
duke@435 1604 }
duke@435 1605 }
duke@435 1606
duke@435 1607
duke@435 1608 void IdealGraphPrinter::Block::add_node(NodeDescription *n) {
duke@435 1609 if (!_nodes.contains(n)) {
duke@435 1610 _nodes.append(n);
duke@435 1611 }
duke@435 1612 }
duke@435 1613
duke@435 1614 GrowableArray<IdealGraphPrinter::NodeDescription *>* IdealGraphPrinter::Block::nodes() {
duke@435 1615 return &_nodes;
duke@435 1616 }
duke@435 1617
duke@435 1618 int IdealGraphPrinter::NodeDescription::count = 0;
duke@435 1619
duke@435 1620 IdealGraphPrinter::NodeDescription::NodeDescription(Node* node) : _node(node) {
duke@435 1621 _id = (intptr_t)(node);
duke@435 1622 _block_index = -1;
duke@435 1623 }
duke@435 1624
duke@435 1625 IdealGraphPrinter::NodeDescription::~NodeDescription() {
duke@435 1626 _properties.clean();
duke@435 1627 }
duke@435 1628
duke@435 1629 // void IdealGraphPrinter::NodeDescription::set_node(Node* node) {
duke@435 1630 // //this->_node = node;
duke@435 1631 // }
duke@435 1632
duke@435 1633 int IdealGraphPrinter::NodeDescription::block_index() {
duke@435 1634 return _block_index;
duke@435 1635 }
duke@435 1636
duke@435 1637
duke@435 1638 GrowableArray<IdealGraphPrinter::NodeDescription *>* IdealGraphPrinter::NodeDescription::succs() {
duke@435 1639 return &_succs;
duke@435 1640 }
duke@435 1641
duke@435 1642 void IdealGraphPrinter::NodeDescription::clear_succs() {
duke@435 1643 _succs.clear();
duke@435 1644 }
duke@435 1645
duke@435 1646 void IdealGraphPrinter::NodeDescription::init_succs() {
duke@435 1647 _succs = GrowableArray<NodeDescription *>();
duke@435 1648 }
duke@435 1649
duke@435 1650 void IdealGraphPrinter::NodeDescription::add_succ(NodeDescription *desc) {
duke@435 1651 _succs.append(desc);
duke@435 1652 }
duke@435 1653
duke@435 1654 void IdealGraphPrinter::NodeDescription::set_block_index(int i) {
duke@435 1655 _block_index = i;
duke@435 1656 }
duke@435 1657
duke@435 1658 bool IdealGraphPrinter::NodeDescription::equals(NodeDescription *desc) {
duke@435 1659 if (desc == NULL) return false;
duke@435 1660 if (desc->id() != id()) return false;
duke@435 1661 return properties()->equals(desc->properties());
duke@435 1662 }
duke@435 1663
duke@435 1664 Node* IdealGraphPrinter::NodeDescription::node() {
duke@435 1665 return _node;
duke@435 1666 }
duke@435 1667
duke@435 1668 IdealGraphPrinter::Properties* IdealGraphPrinter::NodeDescription::properties() {
duke@435 1669 return &_properties;
duke@435 1670 }
duke@435 1671
duke@435 1672 uint IdealGraphPrinter::NodeDescription::id() {
duke@435 1673 return _id;
duke@435 1674 }
duke@435 1675
duke@435 1676 void IdealGraphPrinter::NodeDescription::print_changed(IdealGraphPrinter *printer) {
duke@435 1677
duke@435 1678
duke@435 1679 Properties properties;
duke@435 1680 properties.add(new Property(NODE_ID_PROPERTY, id()));
duke@435 1681 printer->start_element(NODE_ELEMENT, &properties);
duke@435 1682
duke@435 1683 this->properties()->print(printer);
duke@435 1684
duke@435 1685
duke@435 1686 printer->end_element(NODE_ELEMENT);
duke@435 1687 }
duke@435 1688
duke@435 1689 void IdealGraphPrinter::NodeDescription::print_removed(IdealGraphPrinter *printer) {
duke@435 1690
duke@435 1691 Properties properties;
duke@435 1692 properties.add(new Property(NODE_ID_PROPERTY, id()));
duke@435 1693 printer->simple_element(REMOVE_NODE_ELEMENT, &properties);
duke@435 1694 }
duke@435 1695
duke@435 1696 IdealGraphPrinter::EdgeDescription::EdgeDescription(int from, int to, int index) {
duke@435 1697 this->_from = from;
duke@435 1698 this->_to = to;
duke@435 1699 this->_index = index;
duke@435 1700 }
duke@435 1701
duke@435 1702 IdealGraphPrinter::EdgeDescription::~EdgeDescription() {
duke@435 1703 }
duke@435 1704
duke@435 1705 int IdealGraphPrinter::EdgeDescription::from() {
duke@435 1706 return _from;
duke@435 1707 }
duke@435 1708
duke@435 1709 int IdealGraphPrinter::EdgeDescription::to() {
duke@435 1710 return _to;
duke@435 1711 }
duke@435 1712
duke@435 1713 void IdealGraphPrinter::EdgeDescription::print_changed(IdealGraphPrinter *printer) {
duke@435 1714
duke@435 1715 Properties properties;
duke@435 1716 properties.add(new Property(INDEX_PROPERTY, _index));
duke@435 1717 properties.add(new Property(FROM_PROPERTY, _from));
duke@435 1718 properties.add(new Property(TO_PROPERTY, _to));
duke@435 1719 printer->simple_element(EDGE_ELEMENT, &properties);
duke@435 1720 }
duke@435 1721
duke@435 1722 void IdealGraphPrinter::EdgeDescription::print_removed(IdealGraphPrinter *printer) {
duke@435 1723
duke@435 1724 Properties properties;
duke@435 1725 properties.add(new Property(INDEX_PROPERTY, _index));
duke@435 1726 properties.add(new Property(FROM_PROPERTY, _from));
duke@435 1727 properties.add(new Property(TO_PROPERTY, _to));
duke@435 1728 printer->simple_element(REMOVE_EDGE_ELEMENT, &properties);
duke@435 1729 }
duke@435 1730
duke@435 1731 bool IdealGraphPrinter::EdgeDescription::equals(IdealGraphPrinter::EdgeDescription *desc) {
duke@435 1732 if (desc == NULL) return false;
duke@435 1733 return (_from == desc->_from && _to == desc->_to && _index == desc->_index);
duke@435 1734 }
duke@435 1735
duke@435 1736 IdealGraphPrinter::Properties::Properties() : list(new (ResourceObj::C_HEAP) GrowableArray<Property *>(2, 0, NULL, true)) {
duke@435 1737 }
duke@435 1738
duke@435 1739 IdealGraphPrinter::Properties::~Properties() {
duke@435 1740 clean();
duke@435 1741 delete list;
duke@435 1742 }
duke@435 1743
duke@435 1744 void IdealGraphPrinter::Properties::add(Property *p) {
duke@435 1745 assert(p != NULL, "Property not NULL");
duke@435 1746 list->append(p);
duke@435 1747 }
duke@435 1748
duke@435 1749 void IdealGraphPrinter::Properties::print(IdealGraphPrinter *printer) {
duke@435 1750 printer->start_element(PROPERTIES_ELEMENT);
duke@435 1751
duke@435 1752 for (int i = 0; i < list->length(); i++) {
duke@435 1753 list->at(i)->print(printer);
duke@435 1754 }
duke@435 1755
duke@435 1756 printer->end_element(PROPERTIES_ELEMENT);
duke@435 1757 }
duke@435 1758
duke@435 1759 void IdealGraphPrinter::Properties::clean() {
duke@435 1760 for (int i = 0; i < list->length(); i++) {
duke@435 1761 delete list->at(i);
duke@435 1762 list->at_put(i, NULL);
duke@435 1763 }
duke@435 1764 list->clear();
duke@435 1765 assert(list->length() == 0, "List cleared");
duke@435 1766 }
duke@435 1767
duke@435 1768 void IdealGraphPrinter::Properties::remove(const char *name) {
duke@435 1769 for (int i = 0; i < list->length(); i++) {
duke@435 1770 if (strcmp(list->at(i)->name(), name) == 0) {
duke@435 1771 delete list->at(i);
duke@435 1772 list->remove_at(i);
duke@435 1773 i--;
duke@435 1774 }
duke@435 1775 }
duke@435 1776 }
duke@435 1777
duke@435 1778 void IdealGraphPrinter::Properties::print_as_attributes(IdealGraphPrinter *printer) {
duke@435 1779
duke@435 1780 for (int i = 0; i < list->length(); i++) {
duke@435 1781 assert(list->at(i) != NULL, "Property not null!");
duke@435 1782 printer->output()->print(" ");
duke@435 1783 list->at(i)->print_as_attribute(printer);
duke@435 1784 }
duke@435 1785 }
duke@435 1786
duke@435 1787 bool IdealGraphPrinter::Properties::equals(Properties* p) {
duke@435 1788 if (p->list->length() != this->list->length()) return false;
duke@435 1789
duke@435 1790 for (int i = 0; i < list->length(); i++) {
duke@435 1791 assert(list->at(i) != NULL, "Property not null!");
duke@435 1792 if (!list->at(i)->equals(p->list->at(i))) return false;
duke@435 1793 }
duke@435 1794
duke@435 1795 return true;
duke@435 1796 }
duke@435 1797
duke@435 1798 IdealGraphPrinter::Property::Property() {
duke@435 1799 _name = NULL;
duke@435 1800 _value = NULL;
duke@435 1801 }
duke@435 1802
duke@435 1803 const char *IdealGraphPrinter::Property::name() {
duke@435 1804 return _name;
duke@435 1805 }
duke@435 1806
duke@435 1807 IdealGraphPrinter::Property::Property(const Property* p) {
duke@435 1808
duke@435 1809 this->_name = NULL;
duke@435 1810 this->_value = NULL;
duke@435 1811
duke@435 1812 if (p->_name != NULL) {
duke@435 1813 _name = dup(p->_name);
duke@435 1814 }
duke@435 1815
duke@435 1816 if (p->_value) {
duke@435 1817 _value = dup(p->_value);
duke@435 1818 }
duke@435 1819 }
duke@435 1820
duke@435 1821 IdealGraphPrinter::Property::~Property() {
duke@435 1822
duke@435 1823 clean();
duke@435 1824 }
duke@435 1825
duke@435 1826 IdealGraphPrinter::Property::Property(const char *name, const char *value) {
duke@435 1827
duke@435 1828 assert(name, "Name must not be null!");
duke@435 1829 assert(value, "Value must not be null!");
duke@435 1830
duke@435 1831 _name = dup(name);
duke@435 1832 _value = dup(value);
duke@435 1833 }
duke@435 1834
duke@435 1835 IdealGraphPrinter::Property::Property(const char *name, int intValue) {
duke@435 1836 _name = dup(name);
duke@435 1837
duke@435 1838 stringStream stream;
duke@435 1839 stream.print("%d", intValue);
duke@435 1840 _value = dup(stream.as_string());
duke@435 1841 }
duke@435 1842
duke@435 1843 void IdealGraphPrinter::Property::clean() {
duke@435 1844 if (_name) {
duke@435 1845 delete _name;
duke@435 1846 _name = NULL;
duke@435 1847 }
duke@435 1848
duke@435 1849 if (_value) {
duke@435 1850 delete _value;
duke@435 1851 _value = NULL;
duke@435 1852 }
duke@435 1853 }
duke@435 1854
duke@435 1855
duke@435 1856 bool IdealGraphPrinter::Property::is_null() {
duke@435 1857 return _name == NULL;
duke@435 1858 }
duke@435 1859
duke@435 1860 void IdealGraphPrinter::Property::print(IdealGraphPrinter *printer) {
duke@435 1861
duke@435 1862 assert(!is_null(), "null properties cannot be printed!");
duke@435 1863 Properties properties;
duke@435 1864 properties.add(new Property(PROPERTY_NAME_PROPERTY, _name));
duke@435 1865 printer->start_element(PROPERTY_ELEMENT, &properties, false, false);
duke@435 1866 printer->print_xml(_value);
duke@435 1867 printer->end_element(PROPERTY_ELEMENT, false, true);
duke@435 1868 }
duke@435 1869
duke@435 1870 void IdealGraphPrinter::Property::print_as_attribute(IdealGraphPrinter *printer) {
duke@435 1871
duke@435 1872 printer->output()->print(_name);
duke@435 1873 printer->output()->print("=\"");
duke@435 1874 printer->print_xml(_value);
duke@435 1875 printer->output()->print("\"");
duke@435 1876 }
duke@435 1877
duke@435 1878
duke@435 1879 bool IdealGraphPrinter::Property::equals(Property* p) {
duke@435 1880
duke@435 1881 if (is_null() && p->is_null()) return true;
duke@435 1882 if (is_null()) return false;
duke@435 1883 if (p->is_null()) return false;
duke@435 1884
duke@435 1885 int cmp1 = strcmp(p->_name, _name);
duke@435 1886 if (cmp1 != 0) return false;
duke@435 1887
duke@435 1888 int cmp2 = strcmp(p->_value, _value);
duke@435 1889 if (cmp2 != 0) return false;
duke@435 1890
duke@435 1891 return true;
duke@435 1892 }
duke@435 1893
duke@435 1894 void IdealGraphPrinter::print_xml(const char *value) {
duke@435 1895 size_t len = strlen(value);
duke@435 1896
duke@435 1897 char buf[2];
duke@435 1898 buf[1] = 0;
duke@435 1899 for (size_t i = 0; i < len; i++) {
duke@435 1900 char c = value[i];
duke@435 1901
duke@435 1902 switch(c) {
duke@435 1903 case '<':
duke@435 1904 output()->print("&lt;");
duke@435 1905 break;
duke@435 1906
duke@435 1907 case '>':
duke@435 1908 output()->print("&gt;");
duke@435 1909 break;
duke@435 1910
duke@435 1911 default:
duke@435 1912 buf[0] = c;
duke@435 1913 output()->print(buf);
duke@435 1914 break;
duke@435 1915 }
duke@435 1916 }
duke@435 1917 }
duke@435 1918
duke@435 1919 #endif

mercurial