|
|
|
@ -22,6 +22,7 @@
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include "pipeline/jit/parse/resolve.h"
|
|
|
|
|
#include "frontend/operator/ops.h"
|
|
|
|
@ -1215,6 +1216,21 @@ FunctionBlockPtr Parser::GenerateBlockInFor(const TraceInfoPtr &trace_info) {
|
|
|
|
|
return body_block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int64_t GetForTransToWhileLoop() {
|
|
|
|
|
static const auto loop_str = common::GetEnv("ENV_FOR_TO_WHILE_LOOP");
|
|
|
|
|
// int64 support 63bits positive num mostly.
|
|
|
|
|
if (loop_str.size() > 63 || loop_str.empty()) {
|
|
|
|
|
return MAX_FOR_LOOP_COUNT;
|
|
|
|
|
}
|
|
|
|
|
if (std::any_of(loop_str.begin(), loop_str.end(), [](char c) { return c < '0' || c > '9'; })) {
|
|
|
|
|
return MAX_FOR_LOOP_COUNT;
|
|
|
|
|
}
|
|
|
|
|
int64_t loop_count;
|
|
|
|
|
std::stringstream ss;
|
|
|
|
|
ss << loop_str;
|
|
|
|
|
ss >> loop_count;
|
|
|
|
|
return loop_count;
|
|
|
|
|
}
|
|
|
|
|
// A for loop will generate 3 functions :the test, the body, and the continuation
|
|
|
|
|
// for x in xs:
|
|
|
|
|
// body
|
|
|
|
@ -1231,8 +1247,8 @@ FunctionBlockPtr Parser::ParseFor(const FunctionBlockPtr &block, const py::objec
|
|
|
|
|
py::object iter_obj = python_adapter::GetPyObjAttr(node, NAMED_PRIMITIVE_ITER);
|
|
|
|
|
AnfNodePtr iter_node = ParseExprNode(block, iter_obj);
|
|
|
|
|
CNodePtr len_iter = block->func_graph()->NewCNode({op_len, iter_node});
|
|
|
|
|
CNodePtr bool_node =
|
|
|
|
|
block->func_graph()->NewCNode({NewValueNode(prim::kPrimScalarLt), len_iter, NewValueNode(MAX_FOR_LOOP_COUNT)});
|
|
|
|
|
CNodePtr bool_node = block->func_graph()->NewCNode(
|
|
|
|
|
{NewValueNode(prim::kPrimScalarLt), len_iter, NewValueNode(GetForTransToWhileLoop())});
|
|
|
|
|
|
|
|
|
|
// create statement 'if len(xs) < prim::MAX_FOR_LOOP_COUNT then ParseForIter else ParseForLoop'
|
|
|
|
|
FunctionBlockPtr true_block = nullptr;
|
|
|
|
|