22 static std::shared_ptr<ast::Expression>
unwrap(
const std::shared_ptr<ast::Expression>& expr) {
23 if (expr && expr->is_wrapped_expression()) {
24 const auto& e = std::dynamic_pointer_cast<ast::WrappedExpression>(expr);
25 return e->get_expression();
38 const std::shared_ptr<ast::FromStatement>& node) {
41 const auto& from =
unwrap(node->get_from());
42 const auto& to =
unwrap(node->get_to());
43 const auto& increment =
unwrap(node->get_increment());
47 if (!from->is_integer() || !to->is_integer() ||
48 (increment !=
nullptr && !increment->is_integer())) {
52 int start = std::dynamic_pointer_cast<ast::Integer>(from)->eval();
53 int end = std::dynamic_pointer_cast<ast::Integer>(to)->eval();
55 if (increment !=
nullptr) {
56 step = std::dynamic_pointer_cast<ast::Integer>(increment)->eval();
60 std::string index_var = node->get_node_name();
61 for (
int i = start; i <= end; i += step) {
63 const auto new_block = std::unique_ptr<ast::StatementBlock>(
64 node->get_statement_block()->clone());
66 statements.insert(statements.end(),
67 new_block->get_statements().begin(),
68 new_block->get_statements().end());
73 return std::make_shared<ast::ExpressionStatement>(block);
85 for (
auto iter = statements.begin(); iter != statements.end(); ++iter) {
86 if ((*iter)->is_from_statement()) {
87 const auto& statement = std::dynamic_pointer_cast<ast::FromStatement>((*iter));
91 if (!verbatim_blocks.empty()) {
92 logger->debug(
"LoopUnrollVisitor : can not unroll because of verbatim block");
98 if (new_statement !=
nullptr) {
101 const auto& before =
to_nmodl(statement);
102 const auto& after =
to_nmodl(new_statement);
103 logger->debug(
"LoopUnrollVisitor : \n {} \n unrolled to \n {}", before, after);