duke@435: /* duke@435: * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: #ifndef PRODUCT duke@435: duke@435: class Compile; duke@435: class PhaseIFG; duke@435: class PhaseChaitin; duke@435: class Matcher; duke@435: class Node; duke@435: class InlineTree; duke@435: class ciMethod; duke@435: duke@435: class IdealGraphPrinter duke@435: { duke@435: private: duke@435: duke@435: enum State duke@435: { duke@435: Invalid, duke@435: Valid, duke@435: New duke@435: }; duke@435: duke@435: private: duke@435: duke@435: static const char *INDENT; duke@435: static const char *TOP_ELEMENT; duke@435: static const char *GROUP_ELEMENT; duke@435: static const char *GRAPH_ELEMENT; duke@435: static const char *PROPERTIES_ELEMENT; duke@435: static const char *EDGES_ELEMENT; duke@435: static const char *PROPERTY_ELEMENT; duke@435: static const char *EDGE_ELEMENT; duke@435: static const char *NODE_ELEMENT; duke@435: static const char *NODES_ELEMENT; duke@435: static const char *CONTROL_FLOW_ELEMENT; duke@435: static const char *REMOVE_EDGE_ELEMENT; duke@435: static const char *REMOVE_NODE_ELEMENT; duke@435: static const char *METHOD_NAME_PROPERTY; duke@435: static const char *BLOCK_NAME_PROPERTY; duke@435: static const char *BLOCK_DOMINATOR_PROPERTY; duke@435: static const char *BLOCK_ELEMENT; duke@435: static const char *SUCCESSORS_ELEMENT; duke@435: static const char *SUCCESSOR_ELEMENT; duke@435: static const char *METHOD_IS_PUBLIC_PROPERTY; duke@435: static const char *METHOD_IS_STATIC_PROPERTY; duke@435: static const char *TRUE_VALUE; duke@435: static const char *NODE_NAME_PROPERTY; duke@435: static const char *EDGE_NAME_PROPERTY; duke@435: static const char *NODE_ID_PROPERTY; duke@435: static const char *FROM_PROPERTY; duke@435: static const char *TO_PROPERTY; duke@435: static const char *PROPERTY_NAME_PROPERTY; duke@435: static const char *GRAPH_NAME_PROPERTY; duke@435: static const char *INDEX_PROPERTY; duke@435: static const char *METHOD_ELEMENT; duke@435: static const char *INLINE_ELEMENT; duke@435: static const char *BYTECODES_ELEMENT; duke@435: static const char *METHOD_BCI_PROPERTY; duke@435: static const char *METHOD_SHORT_NAME_PROPERTY; duke@435: static const char *ASSEMBLY_ELEMENT; duke@435: duke@435: class Property { duke@435: duke@435: private: duke@435: duke@435: const char *_name; duke@435: const char *_value; duke@435: duke@435: public: duke@435: duke@435: Property(); duke@435: Property(const Property* p); duke@435: ~Property(); duke@435: Property(const char *name, const char *value); duke@435: Property(const char *name, int value); duke@435: bool equals(Property* p); duke@435: void print(IdealGraphPrinter *printer); duke@435: void print_as_attribute(IdealGraphPrinter *printer); duke@435: bool is_null(); duke@435: void clean(); duke@435: const char *name(); duke@435: duke@435: static const char* dup(const char *str) { duke@435: char * copy = new char[strlen(str)+1]; duke@435: strcpy(copy, str); duke@435: return copy; duke@435: } duke@435: duke@435: }; duke@435: duke@435: class Properties { duke@435: duke@435: private: duke@435: duke@435: GrowableArray *list; duke@435: duke@435: public: duke@435: duke@435: Properties(); duke@435: ~Properties(); duke@435: void add(Property *p); duke@435: void remove(const char *name); duke@435: bool equals(Properties* p); duke@435: void print(IdealGraphPrinter *printer); duke@435: void print_as_attributes(IdealGraphPrinter *printer); duke@435: void clean(); duke@435: duke@435: }; duke@435: duke@435: duke@435: class Description { duke@435: duke@435: private: duke@435: duke@435: State _state; duke@435: duke@435: public: duke@435: duke@435: Description(); duke@435: duke@435: State state(); duke@435: void set_state(State s); duke@435: void print(IdealGraphPrinter *printer); duke@435: virtual void print_changed(IdealGraphPrinter *printer) = 0; duke@435: virtual void print_removed(IdealGraphPrinter *printer) = 0; duke@435: duke@435: }; duke@435: duke@435: class NodeDescription : public Description{ duke@435: duke@435: public: duke@435: duke@435: static int count; duke@435: duke@435: private: duke@435: duke@435: GrowableArray _succs; duke@435: int _block_index; duke@435: uintptr_t _id; duke@435: Properties _properties; duke@435: Node* _node; duke@435: duke@435: public: duke@435: duke@435: NodeDescription(Node* node); duke@435: ~NodeDescription(); duke@435: Node* node(); duke@435: duke@435: // void set_node(Node* node); duke@435: GrowableArray* succs(); duke@435: void init_succs(); duke@435: void clear_succs(); duke@435: void add_succ(NodeDescription *desc); duke@435: int block_index(); duke@435: void set_block_index(int i); duke@435: Properties* properties(); duke@435: virtual void print_changed(IdealGraphPrinter *printer); duke@435: virtual void print_removed(IdealGraphPrinter *printer); duke@435: bool equals(NodeDescription *desc); duke@435: uint id(); duke@435: duke@435: }; duke@435: duke@435: class Block { duke@435: duke@435: private: duke@435: duke@435: NodeDescription *_start; duke@435: NodeDescription *_proj; duke@435: GrowableArray _succs; duke@435: GrowableArray _nodes; duke@435: GrowableArray _dominates; duke@435: GrowableArray _children; duke@435: int _semi; duke@435: int _parent; duke@435: GrowableArray _pred; duke@435: GrowableArray _bucket; duke@435: int _index; duke@435: int _dominator; duke@435: int _ancestor; duke@435: int _label; duke@435: duke@435: public: duke@435: duke@435: Block(); duke@435: Block(int index); duke@435: duke@435: void add_node(NodeDescription *n); duke@435: GrowableArray* nodes(); duke@435: GrowableArray* children(); duke@435: void add_child(int i); duke@435: void add_succ(int index); duke@435: GrowableArray* succs(); duke@435: GrowableArray* dominates(); duke@435: void add_dominates(int i); duke@435: NodeDescription *start(); duke@435: NodeDescription *proj(); duke@435: void set_start(NodeDescription *n); duke@435: void set_proj(NodeDescription *n); duke@435: duke@435: int label(); duke@435: void set_label(int i); duke@435: int ancestor(); duke@435: void set_ancestor(int i); duke@435: int index(); duke@435: int dominator(); duke@435: void set_dominator(int i); duke@435: int parent(); duke@435: void set_parent(int i); duke@435: int semi(); duke@435: GrowableArray* bucket(); duke@435: void add_to_bucket(int i); duke@435: void clear_bucket(); duke@435: GrowableArray* pred(); duke@435: void set_semi(int i); duke@435: void add_pred(int i); duke@435: duke@435: }; duke@435: duke@435: class EdgeDescription : public Description { duke@435: duke@435: private: duke@435: duke@435: int _from; duke@435: int _to; duke@435: int _index; duke@435: public: duke@435: duke@435: EdgeDescription(int from, int to, int index); duke@435: ~EdgeDescription(); duke@435: duke@435: virtual void print_changed(IdealGraphPrinter *printer); duke@435: virtual void print_removed(IdealGraphPrinter *printer); duke@435: bool equals(EdgeDescription *desc); duke@435: int from(); duke@435: int to(); duke@435: }; duke@435: duke@435: duke@435: static int _file_count; duke@435: networkStream *_stream; duke@435: outputStream *_output; duke@435: ciMethod *_current_method; duke@435: GrowableArray _nodes; duke@435: GrowableArray _edges; duke@435: int _depth; duke@435: Arena *_arena; duke@435: char buffer[128]; duke@435: bool _should_send_method; duke@435: PhaseChaitin* _chaitin; duke@435: bool _clear_nodes; duke@435: Matcher* _matcher; duke@435: bool _traverse_outs; duke@435: duke@435: void start_element_helper(const char *name, Properties *properties, bool endElement, bool print_indent = false, bool print_return = true); duke@435: NodeDescription *create_node_description(Node* node); duke@435: duke@435: static void pre_node(Node* node, void *env); duke@435: static void post_node(Node* node, void *env); duke@435: duke@435: void schedule_latest(int **common_dominator, GrowableArray* blocks); duke@435: void build_common_dominator(int **common_dominator, int index, GrowableArray* blocks); duke@435: void compress(int index, GrowableArray* blocks); duke@435: int eval(int index, GrowableArray* blocks); duke@435: void link(int index1, int index2, GrowableArray* blocks); duke@435: void build_dominators(GrowableArray* blocks); duke@435: void build_blocks(Node *node); duke@435: void walk(Node *n); duke@435: void start_element(const char *name, Properties *properties = NULL, bool print_indent = false, bool print_return = true); duke@435: void simple_element(const char *name, Properties *properties = NULL, bool print_indent = false); duke@435: void end_element(const char *name, bool print_indent = false, bool print_return = true); duke@435: void print_edge(int from, int to, int index); duke@435: void print_indent(); duke@435: void print_method(ciMethod *method, int bci, InlineTree *tree); duke@435: void print_inline_tree(InlineTree *tree); duke@435: void clear_nodes(); duke@435: duke@435: IdealGraphPrinter(); duke@435: ~IdealGraphPrinter(); duke@435: duke@435: public: duke@435: duke@435: static void clean_up(); duke@435: static IdealGraphPrinter *printer(); duke@435: duke@435: bool traverse_outs(); duke@435: void set_traverse_outs(bool b); duke@435: void print_ifg(PhaseIFG* ifg); duke@435: outputStream *output(); duke@435: void print_inlining(Compile* compile); duke@435: void begin_method(Compile* compile); duke@435: void end_method(); duke@435: void print_method(Compile* compile, const char *name, int level=1, bool clear_nodes = false); duke@435: void print(Compile* compile, const char *name, Node *root, int level=1, bool clear_nodes = false); duke@435: void print_xml(const char *name); duke@435: duke@435: duke@435: }; duke@435: duke@435: #endif