1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* -*- c++ -*- */ 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software. 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#pragma once 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef IR_HIERARCHICAL_VISITOR_H 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define IR_HIERARCHICAL_VISITOR_H 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Enumeration values returned by visit methods to guide processing 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum ir_visitor_status { 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_continue, /**< Continue visiting as normal. */ 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_continue_with_parent, /**< Don't visit siblings, continue w/parent. */ 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_stop /**< Stop visiting immediately. */ 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Base class of hierarchical visitors of IR instruction trees 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Hierarchical visitors differ from traditional visitors in a couple of 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * important ways. Rather than having a single \c visit method for each 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * subclass in the composite, there are three kinds of visit methods. 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Leaf-node classes have a traditional \c visit method. Internal-node 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * classes have a \c visit_enter method, which is invoked just before 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * processing child nodes, and a \c visit_leave method which is invoked just 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * after processing child nodes. 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In addition, each visit method and the \c accept methods in the composite 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * have a return value which guides the navigation. Any of the visit methods 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * can choose to continue visiting the tree as normal (by returning \c 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * visit_continue), terminate visiting any further nodes immediately (by 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * returning \c visit_stop), or stop visiting sibling nodes (by returning \c 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * visit_continue_with_parent). 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * These two changes combine to allow nagivation of children to be implemented 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in the composite's \c accept method. The \c accept method for a leaf-node 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * class will simply call the \c visit method, as usual, and pass its return 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * value on. The \c accept method for internal-node classes will call the \c 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * visit_enter method, call the \c accpet method of each child node, and, 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * finally, call the \c visit_leave method. If any of these return a value 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * other that \c visit_continue, the correct action must be taken. 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The final benefit is that the hierarchical visitor base class need not be 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * abstract. Default implementations of every \c visit, \c visit_enter, and 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \c visit_leave method can be provided. By default each of these methods 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * simply returns \c visit_continue. This allows a significant reduction in 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * derived class code. 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For more information about hierarchical visitors, see: 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * http://c2.com/cgi/wiki?HierarchicalVisitorPattern 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * http://c2.com/cgi/wiki?HierarchicalVisitorDiscussion 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ir_hierarchical_visitor { 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_hierarchical_visitor(); 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \name Visit methods for leaf-node classes 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*@{*/ 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit(class ir_rvalue *); 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit(class ir_variable *); 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit(class ir_constant *); 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit(class ir_loop_jump *); 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ir_dereference_variable isn't technically a leaf, but it is treated as a 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * leaf here for a couple reasons. By not automatically visiting the one 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * child ir_variable node from the ir_dereference_variable, ir_variable 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * nodes can always be handled as variable declarations. Code that used 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * non-hierarchical visitors had to set an "in a dereference" flag to 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * determine how to handle an ir_variable. By forcing the visitor to 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * handle the ir_variable within the ir_dereference_variable visitor, this 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * kludge can be avoided. 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In addition, I can envision no use for having separate enter and leave 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * methods. Anything that could be done in the enter and leave methods 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that couldn't just be done in the visit method. 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit(class ir_dereference_variable *); 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*@}*/ 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \name Visit methods for internal-node classes 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*@{*/ 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_loop *); 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_loop *); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_function_signature *); 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_function_signature *); 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_function *); 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_function *); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_expression *); 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_expression *); 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_texture *); 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_texture *); 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_swizzle *); 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_swizzle *); 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_dereference_array *); 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_dereference_array *); 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_dereference_record *); 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_dereference_record *); 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_assignment *); 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_assignment *); 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_call *); 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_call *); 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_return *); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_return *); 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_discard *); 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_discard *); 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_enter(class ir_if *); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ir_visitor_status visit_leave(class ir_if *); 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*@}*/ 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Utility function to process a linked list of instructions with a visitor 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void run(struct exec_list *instructions); 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Some visitors may need to insert new variable declarations and 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * assignments for portions of a subtree, which means they need a 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pointer to the current instruction in the stream, not just their 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * node in the tree rooted at that instruction. 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is implemented by visit_list_elements -- if the visitor is 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * not called by it, nothing good will happen. 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org class ir_instruction *base_ir; 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Callback function that is invoked on entry to each node visited. 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \warning 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Visitor classes derived from \c ir_hierarchical_visitor \b may \b not 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * invoke this function. This can be used, for example, to cause the 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * callback to be invoked on every node type execpt one. 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void (*callback)(class ir_instruction *ir, void *data); 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Extra data parameter passed to the per-node callback function 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *data; 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Currently in the LHS of an assignment? 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is set and cleared by the \c ir_assignment::accept method. 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool in_assignee; 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid visit_tree(ir_instruction *ir, 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void (*callback)(class ir_instruction *ir, void *data), 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *data); 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status visit_list_elements(ir_hierarchical_visitor *v, exec_list *l, 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool statement_list = true); 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* IR_HIERARCHICAL_VISITOR_H */ 186