11591693c7b415e9869157c711fe11263c95d74eDavid Li/* -*- c++ -*- */ 21591693c7b415e9869157c711fe11263c95d74eDavid Li/* 31591693c7b415e9869157c711fe11263c95d74eDavid Li * Copyright © 2010 Intel Corporation 41591693c7b415e9869157c711fe11263c95d74eDavid Li * 51591693c7b415e9869157c711fe11263c95d74eDavid Li * Permission is hereby granted, free of charge, to any person obtaining a 61591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of this software and associated documentation files (the "Software"), 71591693c7b415e9869157c711fe11263c95d74eDavid Li * to deal in the Software without restriction, including without limitation 81591693c7b415e9869157c711fe11263c95d74eDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense, 91591693c7b415e9869157c711fe11263c95d74eDavid Li * and/or sell copies of the Software, and to permit persons to whom the 101591693c7b415e9869157c711fe11263c95d74eDavid Li * Software is furnished to do so, subject to the following conditions: 111591693c7b415e9869157c711fe11263c95d74eDavid Li * 121591693c7b415e9869157c711fe11263c95d74eDavid Li * The above copyright notice and this permission notice (including the next 131591693c7b415e9869157c711fe11263c95d74eDavid Li * paragraph) shall be included in all copies or substantial portions of the 141591693c7b415e9869157c711fe11263c95d74eDavid Li * Software. 151591693c7b415e9869157c711fe11263c95d74eDavid Li * 161591693c7b415e9869157c711fe11263c95d74eDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 171591693c7b415e9869157c711fe11263c95d74eDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 181591693c7b415e9869157c711fe11263c95d74eDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 191591693c7b415e9869157c711fe11263c95d74eDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 201591693c7b415e9869157c711fe11263c95d74eDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 211591693c7b415e9869157c711fe11263c95d74eDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 221591693c7b415e9869157c711fe11263c95d74eDavid Li * DEALINGS IN THE SOFTWARE. 231591693c7b415e9869157c711fe11263c95d74eDavid Li */ 241591693c7b415e9869157c711fe11263c95d74eDavid Li 251591693c7b415e9869157c711fe11263c95d74eDavid Li#pragma once 261591693c7b415e9869157c711fe11263c95d74eDavid Li#ifndef IR_HIERARCHICAL_VISITOR_H 271591693c7b415e9869157c711fe11263c95d74eDavid Li#define IR_HIERARCHICAL_VISITOR_H 281591693c7b415e9869157c711fe11263c95d74eDavid Li 291591693c7b415e9869157c711fe11263c95d74eDavid Li/** 301591693c7b415e9869157c711fe11263c95d74eDavid Li * Enumeration values returned by visit methods to guide processing 311591693c7b415e9869157c711fe11263c95d74eDavid Li */ 321591693c7b415e9869157c711fe11263c95d74eDavid Lienum ir_visitor_status { 331591693c7b415e9869157c711fe11263c95d74eDavid Li visit_continue, /**< Continue visiting as normal. */ 341591693c7b415e9869157c711fe11263c95d74eDavid Li visit_continue_with_parent, /**< Don't visit siblings, continue w/parent. */ 351591693c7b415e9869157c711fe11263c95d74eDavid Li visit_stop /**< Stop visiting immediately. */ 361591693c7b415e9869157c711fe11263c95d74eDavid Li}; 371591693c7b415e9869157c711fe11263c95d74eDavid Li 381591693c7b415e9869157c711fe11263c95d74eDavid Li 391591693c7b415e9869157c711fe11263c95d74eDavid Li/** 401591693c7b415e9869157c711fe11263c95d74eDavid Li * Base class of hierarchical visitors of IR instruction trees 411591693c7b415e9869157c711fe11263c95d74eDavid Li * 421591693c7b415e9869157c711fe11263c95d74eDavid Li * Hierarchical visitors differ from traditional visitors in a couple of 431591693c7b415e9869157c711fe11263c95d74eDavid Li * important ways. Rather than having a single \c visit method for each 441591693c7b415e9869157c711fe11263c95d74eDavid Li * subclass in the composite, there are three kinds of visit methods. 451591693c7b415e9869157c711fe11263c95d74eDavid Li * Leaf-node classes have a traditional \c visit method. Internal-node 461591693c7b415e9869157c711fe11263c95d74eDavid Li * classes have a \c visit_enter method, which is invoked just before 471591693c7b415e9869157c711fe11263c95d74eDavid Li * processing child nodes, and a \c visit_leave method which is invoked just 481591693c7b415e9869157c711fe11263c95d74eDavid Li * after processing child nodes. 491591693c7b415e9869157c711fe11263c95d74eDavid Li * 501591693c7b415e9869157c711fe11263c95d74eDavid Li * In addition, each visit method and the \c accept methods in the composite 511591693c7b415e9869157c711fe11263c95d74eDavid Li * have a return value which guides the navigation. Any of the visit methods 521591693c7b415e9869157c711fe11263c95d74eDavid Li * can choose to continue visiting the tree as normal (by returning \c 531591693c7b415e9869157c711fe11263c95d74eDavid Li * visit_continue), terminate visiting any further nodes immediately (by 541591693c7b415e9869157c711fe11263c95d74eDavid Li * returning \c visit_stop), or stop visiting sibling nodes (by returning \c 551591693c7b415e9869157c711fe11263c95d74eDavid Li * visit_continue_with_parent). 561591693c7b415e9869157c711fe11263c95d74eDavid Li * 571591693c7b415e9869157c711fe11263c95d74eDavid Li * These two changes combine to allow nagivation of children to be implemented 581591693c7b415e9869157c711fe11263c95d74eDavid Li * in the composite's \c accept method. The \c accept method for a leaf-node 591591693c7b415e9869157c711fe11263c95d74eDavid Li * class will simply call the \c visit method, as usual, and pass its return 601591693c7b415e9869157c711fe11263c95d74eDavid Li * value on. The \c accept method for internal-node classes will call the \c 611591693c7b415e9869157c711fe11263c95d74eDavid Li * visit_enter method, call the \c accpet method of each child node, and, 621591693c7b415e9869157c711fe11263c95d74eDavid Li * finally, call the \c visit_leave method. If any of these return a value 631591693c7b415e9869157c711fe11263c95d74eDavid Li * other that \c visit_continue, the correct action must be taken. 641591693c7b415e9869157c711fe11263c95d74eDavid Li * 651591693c7b415e9869157c711fe11263c95d74eDavid Li * The final benefit is that the hierarchical visitor base class need not be 661591693c7b415e9869157c711fe11263c95d74eDavid Li * abstract. Default implementations of every \c visit, \c visit_enter, and 671591693c7b415e9869157c711fe11263c95d74eDavid Li * \c visit_leave method can be provided. By default each of these methods 681591693c7b415e9869157c711fe11263c95d74eDavid Li * simply returns \c visit_continue. This allows a significant reduction in 691591693c7b415e9869157c711fe11263c95d74eDavid Li * derived class code. 701591693c7b415e9869157c711fe11263c95d74eDavid Li * 711591693c7b415e9869157c711fe11263c95d74eDavid Li * For more information about hierarchical visitors, see: 721591693c7b415e9869157c711fe11263c95d74eDavid Li * 731591693c7b415e9869157c711fe11263c95d74eDavid Li * http://c2.com/cgi/wiki?HierarchicalVisitorPattern 741591693c7b415e9869157c711fe11263c95d74eDavid Li * http://c2.com/cgi/wiki?HierarchicalVisitorDiscussion 751591693c7b415e9869157c711fe11263c95d74eDavid Li */ 761591693c7b415e9869157c711fe11263c95d74eDavid Li 771591693c7b415e9869157c711fe11263c95d74eDavid Liclass ir_hierarchical_visitor { 781591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 791591693c7b415e9869157c711fe11263c95d74eDavid Li ir_hierarchical_visitor(); 80d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li virtual ~ir_hierarchical_visitor() { } // GCC error about accessible nonvirtual dctor 811591693c7b415e9869157c711fe11263c95d74eDavid Li 821591693c7b415e9869157c711fe11263c95d74eDavid Li /** 831591693c7b415e9869157c711fe11263c95d74eDavid Li * \name Visit methods for leaf-node classes 841591693c7b415e9869157c711fe11263c95d74eDavid Li */ 851591693c7b415e9869157c711fe11263c95d74eDavid Li /*@{*/ 861591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(class ir_variable *); 871591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(class ir_constant *); 881591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(class ir_loop_jump *); 891591693c7b415e9869157c711fe11263c95d74eDavid Li 901591693c7b415e9869157c711fe11263c95d74eDavid Li /** 911591693c7b415e9869157c711fe11263c95d74eDavid Li * ir_dereference_variable isn't technically a leaf, but it is treated as a 921591693c7b415e9869157c711fe11263c95d74eDavid Li * leaf here for a couple reasons. By not automatically visiting the one 931591693c7b415e9869157c711fe11263c95d74eDavid Li * child ir_variable node from the ir_dereference_variable, ir_variable 941591693c7b415e9869157c711fe11263c95d74eDavid Li * nodes can always be handled as variable declarations. Code that used 951591693c7b415e9869157c711fe11263c95d74eDavid Li * non-hierarchical visitors had to set an "in a dereference" flag to 961591693c7b415e9869157c711fe11263c95d74eDavid Li * determine how to handle an ir_variable. By forcing the visitor to 971591693c7b415e9869157c711fe11263c95d74eDavid Li * handle the ir_variable within the ir_dereference_variable visitor, this 981591693c7b415e9869157c711fe11263c95d74eDavid Li * kludge can be avoided. 991591693c7b415e9869157c711fe11263c95d74eDavid Li * 1001591693c7b415e9869157c711fe11263c95d74eDavid Li * In addition, I can envision no use for having separate enter and leave 1011591693c7b415e9869157c711fe11263c95d74eDavid Li * methods. Anything that could be done in the enter and leave methods 1021591693c7b415e9869157c711fe11263c95d74eDavid Li * that couldn't just be done in the visit method. 1031591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1041591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(class ir_dereference_variable *); 1051591693c7b415e9869157c711fe11263c95d74eDavid Li /*@}*/ 1061591693c7b415e9869157c711fe11263c95d74eDavid Li 1071591693c7b415e9869157c711fe11263c95d74eDavid Li /** 1081591693c7b415e9869157c711fe11263c95d74eDavid Li * \name Visit methods for internal-node classes 1091591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1101591693c7b415e9869157c711fe11263c95d74eDavid Li /*@{*/ 1111591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_loop *); 1121591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_loop *); 1131591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_function_signature *); 1141591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_function_signature *); 1151591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_function *); 1161591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_function *); 1171591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_expression *); 1181591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_expression *); 1191591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_texture *); 1201591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_texture *); 1211591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_swizzle *); 1221591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_swizzle *); 1231591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_dereference_array *); 1241591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_dereference_array *); 1251591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_dereference_record *); 1261591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_dereference_record *); 1271591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_assignment *); 1281591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_assignment *); 1291591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_call *); 1301591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_call *); 1311591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_return *); 1321591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_return *); 1331591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_discard *); 1341591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_discard *); 1351591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(class ir_if *); 1361591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(class ir_if *); 1371591693c7b415e9869157c711fe11263c95d74eDavid Li /*@}*/ 1381591693c7b415e9869157c711fe11263c95d74eDavid Li 1391591693c7b415e9869157c711fe11263c95d74eDavid Li 1401591693c7b415e9869157c711fe11263c95d74eDavid Li /** 1411591693c7b415e9869157c711fe11263c95d74eDavid Li * Utility function to process a linked list of instructions with a visitor 1421591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1431591693c7b415e9869157c711fe11263c95d74eDavid Li void run(struct exec_list *instructions); 1441591693c7b415e9869157c711fe11263c95d74eDavid Li 1451591693c7b415e9869157c711fe11263c95d74eDavid Li /* Some visitors may need to insert new variable declarations and 1461591693c7b415e9869157c711fe11263c95d74eDavid Li * assignments for portions of a subtree, which means they need a 1471591693c7b415e9869157c711fe11263c95d74eDavid Li * pointer to the current instruction in the stream, not just their 1481591693c7b415e9869157c711fe11263c95d74eDavid Li * node in the tree rooted at that instruction. 1491591693c7b415e9869157c711fe11263c95d74eDavid Li * 1501591693c7b415e9869157c711fe11263c95d74eDavid Li * This is implemented by visit_list_elements -- if the visitor is 1511591693c7b415e9869157c711fe11263c95d74eDavid Li * not called by it, nothing good will happen. 1521591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1531591693c7b415e9869157c711fe11263c95d74eDavid Li class ir_instruction *base_ir; 1541591693c7b415e9869157c711fe11263c95d74eDavid Li 1551591693c7b415e9869157c711fe11263c95d74eDavid Li /** 1561591693c7b415e9869157c711fe11263c95d74eDavid Li * Callback function that is invoked on entry to each node visited. 1571591693c7b415e9869157c711fe11263c95d74eDavid Li * 1581591693c7b415e9869157c711fe11263c95d74eDavid Li * \warning 1591591693c7b415e9869157c711fe11263c95d74eDavid Li * Visitor classes derived from \c ir_hierarchical_visitor \b may \b not 1601591693c7b415e9869157c711fe11263c95d74eDavid Li * invoke this function. This can be used, for example, to cause the 1611591693c7b415e9869157c711fe11263c95d74eDavid Li * callback to be invoked on every node type execpt one. 1621591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1631591693c7b415e9869157c711fe11263c95d74eDavid Li void (*callback)(class ir_instruction *ir, void *data); 1641591693c7b415e9869157c711fe11263c95d74eDavid Li 1651591693c7b415e9869157c711fe11263c95d74eDavid Li /** 1661591693c7b415e9869157c711fe11263c95d74eDavid Li * Extra data parameter passed to the per-node callback function 1671591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1681591693c7b415e9869157c711fe11263c95d74eDavid Li void *data; 1691591693c7b415e9869157c711fe11263c95d74eDavid Li 1701591693c7b415e9869157c711fe11263c95d74eDavid Li /** 1711591693c7b415e9869157c711fe11263c95d74eDavid Li * Currently in the LHS of an assignment? 1721591693c7b415e9869157c711fe11263c95d74eDavid Li * 1731591693c7b415e9869157c711fe11263c95d74eDavid Li * This is set and cleared by the \c ir_assignment::accept method. 1741591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1751591693c7b415e9869157c711fe11263c95d74eDavid Li bool in_assignee; 1761591693c7b415e9869157c711fe11263c95d74eDavid Li}; 1771591693c7b415e9869157c711fe11263c95d74eDavid Li 1781591693c7b415e9869157c711fe11263c95d74eDavid Livoid visit_tree(ir_instruction *ir, 1791591693c7b415e9869157c711fe11263c95d74eDavid Li void (*callback)(class ir_instruction *ir, void *data), 1801591693c7b415e9869157c711fe11263c95d74eDavid Li void *data); 1811591693c7b415e9869157c711fe11263c95d74eDavid Li 1821591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status visit_list_elements(ir_hierarchical_visitor *v, exec_list *l); 1831591693c7b415e9869157c711fe11263c95d74eDavid Li 1841591693c7b415e9869157c711fe11263c95d74eDavid Li#endif /* IR_HIERARCHICAL_VISITOR_H */ 185