diff options
| -rw-r--r-- | ir_function_inlining.cpp | 24 | ||||
| -rw-r--r-- | ir_hierarchical_visitor.cpp | 14 | ||||
| -rw-r--r-- | ir_hierarchical_visitor.h | 5 | 
3 files changed, 41 insertions, 2 deletions
| diff --git a/ir_function_inlining.cpp b/ir_function_inlining.cpp index effb01c8f6..d74de650e0 100644 --- a/ir_function_inlining.cpp +++ b/ir_function_inlining.cpp @@ -91,6 +91,26 @@ do_function_inlining(exec_list *instructions)     return v.progress;  } +static void +replace_return_with_assignment(ir_instruction *ir, void *data) +{ +   ir_variable *retval = (ir_variable *)data; +   ir_return *ret = ir->as_return(); + +   if (ret) { +      if (ret->value) { +	 ir_rvalue *lhs = new ir_dereference_variable(retval); +	 ret->insert_before(new ir_assignment(lhs, ret->value, NULL)); +	 ret->remove(); +      } else { +	 /* un-valued return has to be the last return, or we shouldn't +	  * have reached here. (see can_inline()). +	  */ +	 assert(!ret->next->is_tail_sentinal()); +      } +   } +} +  ir_rvalue *  ir_call::generate_inline(ir_instruction *next_ir)  { @@ -145,8 +165,10 @@ ir_call::generate_inline(ir_instruction *next_ir)     /* Generate the inlined body of the function. */     foreach_iter(exec_list_iterator, iter, callee->body) {        ir_instruction *ir = (ir_instruction *)iter.get(); +      ir_instruction *new_ir = ir->clone(ht); -      next_ir->insert_before(ir->clone(ht)); +      next_ir->insert_before(new_ir); +      visit_tree(new_ir, replace_return_with_assignment, retval);     }     /* Copy back the value of any 'out' parameters from the function body diff --git a/ir_hierarchical_visitor.cpp b/ir_hierarchical_visitor.cpp index 63ce8784ad..0d520b127f 100644 --- a/ir_hierarchical_visitor.cpp +++ b/ir_hierarchical_visitor.cpp @@ -268,3 +268,17 @@ ir_hierarchical_visitor::run(exec_list *instructions)  	 break;     }  } + + +void +visit_tree(ir_instruction *ir, +	   void (*callback)(class ir_instruction *ir, void *data), +	   void *data) +{ +   ir_hierarchical_visitor v; + +   v.callback = callback; +   v.data = data; + +   ir->accept(&v); +} diff --git a/ir_hierarchical_visitor.h b/ir_hierarchical_visitor.h index e741155e19..8b9e49dab1 100644 --- a/ir_hierarchical_visitor.h +++ b/ir_hierarchical_visitor.h @@ -139,7 +139,6 @@ public:      */     void run(struct exec_list *instructions); -protected:     /**      * Callback function that is invoked on entry to each node visited.      * @@ -156,4 +155,8 @@ protected:     void *data;  }; +void visit_tree(ir_instruction *ir, +		void (*callback)(class ir_instruction *ir, void *data), +		void *data); +  #endif /* IR_HIERARCHICAL_VISITOR_H */ | 
