Main Page Modules Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages
function_inline Class Reference#include <inliner.h>
Inheritance diagram for function_inline:
List of all members.
|
Public Types |
enum | Order { Preorder,
Postorder,
Both
} |
enum | Depth { Subtree,
NodeOnly
} |
Public Member Functions |
| function_inline (set< threeAddrNode * > &m, map< declNode *, procNode * > &m2, set< procNode * > &s1, set< procNode * > &s2) |
virtual Node * | at_threeAddr (threeAddrNode *ta, Order ord) |
virtual Node * | at_proc (procNode *p, Order ord) |
void | insert_proc (procNode *m) |
void | process (callGraph &cg) |
|
Methods to get and set fields in the class.
|
Order | order () const |
| Return the order in which Nodes of an AST should be visited.
|
Depth | depth () const |
| Return which Nodes of an AST should be visited.
|
bool | delete_old () const |
| Return whether this Changer deletes Nodes which are removed from the AST by "at_" methods.
|
|
These methods define the functions that should be performed when different classes of Nodes are encountered in the AST. The most specific "at_" method that matches a given Node's class will be called.
|
virtual Node * | at_node (Node *the_node, Order ord) |
virtual Node * | at_unit (unitNode *the_unit, Order ord) |
virtual Node * | at_def (defNode *the_def, Order ord) |
virtual Node * | at_decl (declNode *the_decl, Order ord) |
virtual Node * | at_subdecl (subdeclNode *the_subdecl, Order ord) |
virtual Node * | at_type (typeNode *the_type, Order ord) |
virtual Node * | at_prim (primNode *the_prim, Order ord) |
virtual Node * | at_tdef (tdefNode *the_tdef, Order ord) |
virtual Node * | at_ptr (ptrNode *the_ptr, Order ord) |
virtual Node * | at_array (arrayNode *the_array, Order ord) |
virtual Node * | at_func (funcNode *the_func, Order ord) |
virtual Node * | at_sue (sueNode *the_sue, Order ord) |
virtual Node * | at_struct (structNode *the_struct, Order ord) |
virtual Node * | at_union (unionNode *the_union, Order ord) |
virtual Node * | at_enum (enumNode *the_enum, Order ord) |
virtual Node * | at_suespec (suespecNode *the_suespec, Order ord) |
virtual Node * | at_expr (exprNode *the_expr, Order ord) |
virtual Node * | at_index (indexNode *the_index, Order ord) |
virtual Node * | at_const (constNode *the_const, Order ord) |
virtual Node * | at_id (idNode *the_id, Order ord) |
virtual Node * | at_binary (binaryNode *the_binary, Order ord) |
virtual Node * | at_unary (unaryNode *the_unary, Order ord) |
virtual Node * | at_cast (castNode *the_cast, Order ord) |
virtual Node * | at_comma (commaNode *the_comma, Order ord) |
virtual Node * | at_ternary (ternaryNode *the_ternary, Order ord) |
virtual Node * | at_call (callNode *the_call, Order ord) |
virtual Node * | at_initializer (initializerNode *the_initializer, Order ord) |
virtual Node * | at_stmt (stmtNode *the_stmt, Order ord) |
virtual Node * | at_block (blockNode *the_block, Order ord) |
virtual Node * | at_basicblock (basicblockNode *the_basicblock, Order ord) |
virtual Node * | at_exprstmt (exprstmtNode *the_exprstmt, Order ord) |
virtual Node * | at_target (targetNode *the_target, Order ord) |
virtual Node * | at_label (labelNode *the_label, Order ord) |
virtual Node * | at_case (caseNode *the_case, Order ord) |
virtual Node * | at_selection (selectionNode *the_selection, Order ord) |
virtual Node * | at_if (ifNode *the_if, Order ord) |
virtual Node * | at_switch (switchNode *the_switch, Order ord) |
virtual Node * | at_loop (loopNode *the_loop, Order ord) |
virtual Node * | at_while (whileNode *the_while, Order ord) |
virtual Node * | at_do (doNode *the_do, Order ord) |
virtual Node * | at_for (forNode *the_for, Order ord) |
virtual Node * | at_jump (jumpNode *the_jump, Order ord) |
virtual Node * | at_goto (gotoNode *the_goto, Order ord) |
virtual Node * | at_continue (continueNode *the_continue, Order ord) |
virtual Node * | at_break (breakNode *the_break, Order ord) |
virtual Node * | at_return (returnNode *the_return, Order ord) |
virtual Node * | at_attrib (attribNode *the_attrib, Order ord) |
virtual Node * | at_operand (operandNode *the_oper, Order ord) |
virtual Node * | at_conditiongoto (conditiongotoNode *the_condgoto, Order ord) |
virtual Node * | at_text (textNode *the_text, Order ord) |
Static Public Member Functions |
void | inline_functions (procNode *root) |
Private Member Functions |
bool | already_inlined_calls (callGraphNode *) |
bool | inlocalstack (procNode *p) |
stmtNode * | inliner (idNode *call, procNode *p, threeAddrNode *callsite) |
Private Attributes |
set< threeAddrNode * > & | _callinline |
map< declNode *, procNode * > & | _procmap |
set< procNode * > & | _procs |
set< procNode * > & | _inlined |
deque< procNode * > | _callstack |
deque< procNode * > | _localcallstack |
Detailed Description
This phase inlines all functions with type inline. It can be called from the command line with -fi. It needs both the cfg and a callgraph, so it calls both cfg_changer and callgraph_walker. This phase is NOT idempotent. It is idempotent assuming no recursive functions have been marked inline.
The function inliner works in two passes. The first identifies callsites which can/should be inlined. Under normal operation, it currently only inlines the call sites of functions of type inline. Hopefully, it will not be difficult to add other heuristics. The second pass inlines all call sites identified by the first pass.
After function inlining is complete, the code is re-dismantled to make certain all variables in each scope are unique.
Definition at line 72 of file inliner.h.
Member Enumeration Documentation
enum Changer::Depth [inherited]
|
|
|
- Enumeration values:
-
Definition at line 148 of file changer.h. |
enum Changer::Order [inherited]
|
|
|
- Enumeration values:
-
Definition at line 147 of file changer.h.
Referenced by whileNode::change(), unitNode::change(), unionNode::change(), unaryNode::change(), threeAddrNode::change(), textNode::change(), ternaryNode::change(), tdefNode::change(), switchNode::change(), suespecNode::change(), subdeclNode::change(), structNode::change(), returnNode::change(), ptrNode::change(), procNode::change(), primNode::change(), operandNode::change(), metastmtNode::change(), metaexprNode::change(), labelNode::change(), initializerNode::change(), ifNode::change(), idNode::change(), gotoNode::change(), funcNode::change(), forNode::change(), exprstmtNode::change(), enumNode::change(), doNode::change(), declNode::change(), continueNode::change(), constNode::change(), conditiongotoNode::change(), commaNode::change(), castNode::change(), caseNode::change(), callNode::change(), breakNode::change(), blockNode::change(), binaryNode::change(), basicblockNode::change(), attribNode::change(), and arrayNode::change(). |
Constructor & Destructor Documentation
Member Function Documentation
bool function_inline::already_inlined_calls |
( |
callGraphNode * |
|
) |
[private] |
|
virtual Node* Changer::at_array |
( |
arrayNode * |
the_array, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_attrib |
( |
attribNode * |
the_attrib, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_binary |
( |
binaryNode * |
the_binary, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_block |
( |
blockNode * |
the_block, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_break |
( |
breakNode * |
the_break, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_call |
( |
callNode * |
the_call, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_case |
( |
caseNode * |
the_case, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_cast |
( |
castNode * |
the_cast, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_comma |
( |
commaNode * |
the_comma, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_const |
( |
constNode * |
the_const, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_continue |
( |
continueNode * |
the_continue, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_decl |
( |
declNode * |
the_decl, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_def |
( |
defNode * |
the_def, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_do |
( |
doNode * |
the_do, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_enum |
( |
enumNode * |
the_enum, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_expr |
( |
exprNode * |
the_expr, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_exprstmt |
( |
exprstmtNode * |
the_exprstmt, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_for |
( |
forNode * |
the_for, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_func |
( |
funcNode * |
the_func, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_goto |
( |
gotoNode * |
the_goto, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_id |
( |
idNode * |
the_id, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_if |
( |
ifNode * |
the_if, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_index |
( |
indexNode * |
the_index, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_jump |
( |
jumpNode * |
the_jump, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_label |
( |
labelNode * |
the_label, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_loop |
( |
loopNode * |
the_loop, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_node |
( |
Node * |
the_node, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_operand |
( |
operandNode * |
the_oper, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_prim |
( |
primNode * |
the_prim, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_ptr |
( |
ptrNode * |
the_ptr, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_return |
( |
returnNode * |
the_return, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_stmt |
( |
stmtNode * |
the_stmt, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_struct |
( |
structNode * |
the_struct, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_subdecl |
( |
subdeclNode * |
the_subdecl, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_sue |
( |
sueNode * |
the_sue, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_suespec |
( |
suespecNode * |
the_suespec, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_switch |
( |
switchNode * |
the_switch, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_target |
( |
targetNode * |
the_target, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_tdef |
( |
tdefNode * |
the_tdef, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_ternary |
( |
ternaryNode * |
the_ternary, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_text |
( |
textNode * |
the_text, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
|
This function identifies callsites and calls the inliner
Reimplemented from Changer.
Definition at line 374 of file inliner.cc.
References _callinline, _callstack, _localcallstack, _procmap, idNode::decl(), Operator::FUNC_CALL, Id, inliner(), inlocalstack(), threeAddrNode::op(), Changer::Postorder, threeAddrNode::rhs1(), Node::typ(), and operandNode::var(). |
virtual Node* Changer::at_type |
( |
typeNode * |
the_type, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_unary |
( |
unaryNode * |
the_unary, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_union |
( |
unionNode * |
the_union, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_unit |
( |
unitNode * |
the_unit, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
virtual Node* Changer::at_while |
( |
whileNode * |
the_while, |
|
|
Order |
ord |
|
) |
[inline, virtual, inherited] |
|
bool Changer::delete_old |
( |
|
) |
const [inline, inherited] |
|
Depth Changer::depth |
( |
|
) |
const [inline, inherited] |
|
|
Return which Nodes of an AST should be visited.
A value of SubTree specifies that the entire AST should be traversed. A value of NodeOnly specifies that only the root Node in the AST should be visited.
Definition at line 204 of file changer.h. |
void function_inline::inline_functions |
( |
procNode * |
root |
) |
[static] |
|
|
Use this for non-command line inlining. Root is the top of the call graph. If null, main will be used. The code is expected to be in cfg form.
Definition at line 134 of file inliner.cc.
References identify_inlinees::callinline(), Dismantle::dismantle(), findmain(), identify_inlinees::inlined(), insert_proc(), Linker::link(), Linker::procedure_declarations(), process(), identify_inlinees::procs(), CBZ::Program, and unit_list_p. |
|
Formal arguments...
Local declarations...
Clone the call so we can cannibalize the actual arguments...
-- Use the initialize to pass the actual value
-- Important: set the decl location to BLOCK
-- Get the returned value
-- Copy the left-hand side of the binary node
-- Clone the procedure. Here we use the ref_clone because it preserves the internal references (that is, the local variable declaration pointers). That way we can use the name mangler to fix any conflicting variable names.
-- Remove the body...this is the return object. BUT, get the exit basic block first.
-- Fix the parameter passing: remove each formal parameter from the funcNode, use the actual argument from the callNode as the initializer, and add it to the block declarations of the body.
-- Assumption: last statement of the exit basic block is the return statement. This is true after the regular dismantle/CFG phase. Remove it.
-- If there is a returned value and a left-hand side at the callsite, then set up the appropriate assignment.
-- Create a new assignment statement and place it at the end of the basic block.
Definition at line 468 of file inliner.cc.
References threeAddrNode::arg_list(), funcNode::args(), ref_clone_changer::clone(), Node::coord(), procNode::decl(), decl_list, declNode::decl_location(), blockNode::decls(), procNode::exit(), procNode::get_body(), declNode::init(), funcNode::is_void_args(), threeAddrNode::lhs(), declNode::name(), operand_list, Return, procNode::return_decl(), blockNode::stmts(), Node::typ(), and declNode::type().
Referenced by at_threeAddr(). |
bool function_inline::inlocalstack |
( |
procNode * |
p |
) |
[private] |
|
void function_inline::insert_proc |
( |
procNode * |
m |
) |
|
|
Order Changer::order |
( |
|
) |
const [inline, inherited] |
|
|
Return the order in which Nodes of an AST should be visited.
Nodes can be visited before their children (Preorder), after their children (Postorder), or both (Both).
Definition at line 196 of file changer.h.
Referenced by whileNode::change(), unitNode::change(), unionNode::change(), unaryNode::change(), threeAddrNode::change(), textNode::change(), ternaryNode::change(), tdefNode::change(), switchNode::change(), suespecNode::change(), subdeclNode::change(), structNode::change(), returnNode::change(), ptrNode::change(), procNode::change(), primNode::change(), operandNode::change(), metastmtNode::change(), metaexprNode::change(), labelNode::change(), initializerNode::change(), ifNode::change(), idNode::change(), gotoNode::change(), funcNode::change(), forNode::change(), exprstmtNode::change(), enumNode::change(), doNode::change(), declNode::change(), continueNode::change(), constNode::change(), conditiongotoNode::change(), commaNode::change(), castNode::change(), caseNode::change(), callNode::change(), breakNode::change(), blockNode::change(), binaryNode::change(), basicblockNode::change(), attribNode::change(), and arrayNode::change(). |
void function_inline::process |
( |
callGraph & |
cg |
) |
|
|
Member Data Documentation
deque<procNode*> function_inline::_callstack [private]
|
|
set<procNode*>& function_inline::_inlined [private]
|
|
deque<procNode*> function_inline::_localcallstack [private]
|
|
set<procNode*>& function_inline::_procs [private]
|
|
The documentation for this class was generated from the following files:
|