From 4f6a3669c6b86375a31adedc3338db33aa973836 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 3 Mar 2010 11:43:22 +0100 Subject: [PATCH] Added expression sharing for external functions --- preprocessor/DataTree.cc | 53 ++++++++++++++++++++++++++++++++++++++++ preprocessor/DataTree.hh | 12 +++++++++ preprocessor/ExprNode.cc | 6 +++++ 3 files changed, 71 insertions(+) diff --git a/preprocessor/DataTree.cc b/preprocessor/DataTree.cc index cd20d8a9f..5c1b9d54f 100644 --- a/preprocessor/DataTree.cc +++ b/preprocessor/DataTree.cc @@ -466,6 +466,11 @@ NodeID DataTree::AddExternalFunction(int symb_id, const vector &arguments) { assert(symbol_table.getType(symb_id) == eExternalFunction); + + external_function_node_map_type::iterator it = external_function_node_map.find(make_pair(arguments, symb_id)); + if (it != external_function_node_map.end()) + return it->second; + return new ExternalFunctionNode(*this, symb_id, arguments); } @@ -473,6 +478,13 @@ NodeID DataTree::AddFirstDerivExternalFunctionNode(int top_level_symb_id, const vector &arguments, int input_index) { assert(symbol_table.getType(top_level_symb_id) == eExternalFunction); + + first_deriv_external_function_node_map_type::iterator it = + first_deriv_external_function_node_map.find(make_pair(make_pair(arguments, input_index), + top_level_symb_id)); + if (it != first_deriv_external_function_node_map.end()) + return it->second; + return new FirstDerivExternalFunctionNode(*this, top_level_symb_id, arguments, input_index); } @@ -480,6 +492,14 @@ NodeID DataTree::AddSecondDerivExternalFunctionNode(int top_level_symb_id, const vector &arguments, int input_index1, int input_index2) { assert(symbol_table.getType(top_level_symb_id) == eExternalFunction); + + second_deriv_external_function_node_map_type::iterator it = + second_deriv_external_function_node_map.find(make_pair(make_pair(arguments, + make_pair(input_index1, input_index2)), + top_level_symb_id)); + if (it != second_deriv_external_function_node_map.end()) + return it->second; + return new SecondDerivExternalFunctionNode(*this, top_level_symb_id, arguments, input_index1, input_index2); } @@ -541,3 +561,36 @@ DataTree::isTrinaryOpUsed(TrinaryOpcode opcode) const return false; } + +bool +DataTree::isExternalFunctionUsed(int symb_id) const +{ + for (external_function_node_map_type::const_iterator it = external_function_node_map.begin(); + it != external_function_node_map.end(); it++) + if (it->first.second == symb_id) + return true; + + return false; +} + +bool +DataTree::isFirstDerivExternalFunctionUsed(int symb_id) const +{ + for (first_deriv_external_function_node_map_type::const_iterator it = first_deriv_external_function_node_map.begin(); + it != first_deriv_external_function_node_map.end(); it++) + if (it->first.second == symb_id) + return true; + + return false; +} + +bool +DataTree::isSecondDerivExternalFunctionUsed(int symb_id) const +{ + for (second_deriv_external_function_node_map_type::const_iterator it = second_deriv_external_function_node_map.begin(); + it != second_deriv_external_function_node_map.end(); it++) + if (it->first.second == symb_id) + return true; + + return false; +} diff --git a/preprocessor/DataTree.hh b/preprocessor/DataTree.hh index 6b20e7e6c..ad5db189e 100644 --- a/preprocessor/DataTree.hh +++ b/preprocessor/DataTree.hh @@ -65,6 +65,12 @@ protected: binary_op_node_map_type binary_op_node_map; typedef map, NodeID>, TrinaryOpcode>, TrinaryOpNode *> trinary_op_node_map_type; trinary_op_node_map_type trinary_op_node_map; + typedef map, int>, ExternalFunctionNode *> external_function_node_map_type; + external_function_node_map_type external_function_node_map; + typedef map, int>, int>, FirstDerivExternalFunctionNode *> first_deriv_external_function_node_map_type; + first_deriv_external_function_node_map_type first_deriv_external_function_node_map; + typedef map, pair >, int>, SecondDerivExternalFunctionNode *> second_deriv_external_function_node_map_type; + second_deriv_external_function_node_map_type second_deriv_external_function_node_map; //! Stores local variables value (maps symbol ID to corresponding node) map local_variables_table; @@ -197,6 +203,12 @@ public: bool isBinaryOpUsed(BinaryOpcode opcode) const; //! Checks if a given trinary op is used somewhere in the data tree bool isTrinaryOpUsed(TrinaryOpcode opcode) const; + //! Checks if a given external function is used somewhere in the data tree + bool isExternalFunctionUsed(int symb_id) const; + //! Checks if a given first derivative external function is used somewhere in the data tree + bool isFirstDerivExternalFunctionUsed(int symb_id) const; + //! Checks if a given second derivative external function is used somewhere in the data tree + bool isSecondDerivExternalFunctionUsed(int symb_id) const; //! Thrown when trying to access an unknown variable by deriv_id class UnknownDerivIDException { diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index 6965ebd88..3ed558c9d 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -3181,6 +3181,8 @@ ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, symb_id(symb_id_arg), arguments(arguments_arg) { + // Add myself to the external function map + datatree.external_function_node_map[make_pair(arguments,symb_id)] = this; } void @@ -3428,6 +3430,8 @@ FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatre ExternalFunctionNode(datatree_arg, top_level_symb_id_arg, arguments_arg), inputIndex(inputIndex_arg) { + // Add myself to the first derivative external function map + datatree.first_deriv_external_function_node_map[make_pair(make_pair(arguments,inputIndex),symb_id)] = this; } NodeID @@ -3492,6 +3496,8 @@ SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode(DataTree &datat inputIndex1(inputIndex1_arg), inputIndex2(inputIndex2_arg) { + // Add myself to the second derivative external function map + datatree.second_deriv_external_function_node_map[make_pair(make_pair(arguments,make_pair(inputIndex1,inputIndex2)),symb_id)] = this; } NodeID