You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

function_block.h 5.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
  3. *
  4. * Copyright 2019-2021 Huawei Technologies Co., Ltd
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #ifndef MINDSPORE_CCSRC_PIPELINE_JIT_PARSE_FUNCTION_BLOCK_H_
  19. #define MINDSPORE_CCSRC_PIPELINE_JIT_PARSE_FUNCTION_BLOCK_H_
  20. #include <vector>
  21. #include <string>
  22. #include <map>
  23. #include <set>
  24. #include <unordered_map>
  25. #include <memory>
  26. #include <utility>
  27. #include "pipeline/jit/parse/parse_base.h"
  28. #include "utils/log_adapter.h"
  29. #include "utils/ordered_set.h"
  30. namespace mindspore {
  31. namespace parse {
  32. class Parser;
  33. class NameSpace;
  34. class Symbol;
  35. class FunctionBlock;
  36. using FunctionBlockPtr = std::shared_ptr<FunctionBlock>;
  37. // A function block is a straight-line code sequence with no branches, every block has one one exit point
  38. // which is return. When parsing function, loop or branch , we use function block to track the structure of
  39. // the original source code.
  40. class FunctionBlock : public std::enable_shared_from_this<FunctionBlock> {
  41. public:
  42. explicit FunctionBlock(const Parser &parser);
  43. virtual ~FunctionBlock() {}
  44. FuncGraphPtr func_graph() { return func_graph_; }
  45. void WriteVariable(const std::string &var_name, const AnfNodePtr &node);
  46. AnfNodePtr ReadVariable(const std::string &var_name);
  47. void AddPrevBlock(const FunctionBlockPtr &block);
  48. void SetPhiArgument(const ParameterPtr &phi);
  49. bool CollectRemovablePhi(const ParameterPtr &phi);
  50. // A block is matured if all its predecessors is generated
  51. void Mature();
  52. CNodePtr ForceToBoolNode(const AnfNodePtr &cond);
  53. CNodePtr ForceToWhileCond(const AnfNodePtr &cond);
  54. void Jump(const FunctionBlockPtr &block, const AnfNodePtr &node);
  55. AnfNodePtr SearchReplaceNode(const std::string &var, const ParameterPtr &phi);
  56. void ConditionalJump(AnfNodePtr condNode, const FunctionBlockPtr &trueBlock, const FunctionBlockPtr &falseBlock,
  57. bool unroll_loop = true);
  58. // Create cnode for the assign statement like self.target = source.
  59. void SetStateAssign(const AnfNodePtr &target, const AnfNodePtr &source);
  60. void AddGlobalVar(const std::string &var_name) { (void)global_vars_.insert(var_name); }
  61. bool IsGlobalVar(const std::string &var_name) { return global_vars_.find(var_name) != global_vars_.end(); }
  62. AnfNodePtr MakeResolveAstOp(const py::object &op);
  63. AnfNodePtr MakeResolveClassMember(const std::string &attr);
  64. AnfNodePtr MakeResolveSymbol(const std::string &value);
  65. AnfNodePtr MakeResolveOperation(const std::string &value);
  66. AnfNodePtr MakeResolve(const std::shared_ptr<NameSpace> &name_space, const std::shared_ptr<Symbol> &resolve_symbol);
  67. const std::unordered_map<ParameterPtr, AnfNodePtr> &removable_phis() const { return removable_phis_; }
  68. void FindIsolatedNodes();
  69. void AddIsolatedNode(const AnfNodePtr &target);
  70. void AttachIsolatedNodesBeforeReturn();
  71. private:
  72. // Block graph
  73. FuncGraphPtr func_graph_;
  74. // Block parser
  75. const Parser &parser_;
  76. // A block is matured if all its prev_blocks is processed
  77. bool matured_;
  78. // Store the nest-level block.
  79. // Refer to comments in Parser::func_block_list_;
  80. std::vector<FunctionBlock *> prev_blocks_;
  81. // Store args and variable's node, use a bool flag to indicate if the variable is used.
  82. std::map<std::string, std::pair<AnfNodePtr, bool>> vars_;
  83. // Map the parameter node to variable, it can be resolved if the block's predecessors are processed
  84. std::map<ParameterPtr, std::string> phi_nodes_;
  85. // Jumps map the successor block and the function call that perform jump
  86. // Refer to comments in Parser::func_block_list_ that how to break the cyclic reference
  87. std::map<FunctionBlock *, CNodePtr> jumps_;
  88. // Keep all removable phis which will be removed in one pass.
  89. std::unordered_map<ParameterPtr, AnfNodePtr> removable_phis_;
  90. // Keep the map for the resolve node to the removable phi node.
  91. // For the case that ReadVariable returns a phi node although this phi node
  92. // generated in the prev block is identified as removable. The other blocks
  93. // should find this phi node.
  94. std::unordered_map<AnfNodePtr, ParameterPtr> resolve_to_removable_phis_;
  95. // Hold declared global variables in function
  96. std::set<std::string> global_vars_;
  97. // Keep new made resolve symbol for the variable not found in vars_.
  98. std::unordered_map<std::string, AnfNodePtr> var_to_resolve_;
  99. // Isolated nodes.
  100. OrderedSet<AnfNodePtr> isolated_nodes_;
  101. };
  102. } // namespace parse
  103. } // namespace mindspore
  104. #endif // MINDSPORE_CCSRC_PIPELINE_JIT_PARSE_FUNCTION_BLOCK_H_