// File: /workspace/github_c_makefile_star2_O3/MaoKo[P]FGFX/fgfl/src/regex_node.c
// Function: remove_useless_epsilon
bool
remove_useless_epsilon(regex_node_t* root) {
    if (!root)
        { return (false); }

    switch (root->kind_ast) {
        case AST_DOT:
        case AST_SYMBOL:
        case AST_CLASS:
            return (false);

        case AST_EPSILON:
            return (true);

        case AST_UNION:
            if ((remove_useless_epsilon(root->left))
                    && (remove_useless_epsilon(root->right))) {

                del_regex_node(root->left);
                del_regex_node(root->right);

                root->kind_ast = AST_EPSILON;
                return (true);
            }
            else
                { return (false); }

        case AST_LOOK:
        case AST_CONCAT: ;
            bool left = remove_useless_epsilon(root->left);
            bool right = remove_useless_epsilon(root->right);

            if (left || right) {
                if (left)
                    { del_regex_node(root->left); }
                if (right)
                    { del_regex_node(root->right); }

                if (left && right) {
                    root->kind_ast = AST_EPSILON;
                    return (true);
                }
                else {
                    regex_node_t* src_node = NULL_NODE;
                    if (!left)
                        { src_node = root->left; }
                    else
                        { src_node = root->right; }
                    memcpy(root, src_node, sizeof(*src_node));
                    FREE(src_node);
                }
            }
            return (false);

        case AST_STAR:
        case AST_QUES:
        case AST_PLUS:
        case AST_TILDE:
        case AST_OPTION:
            if (remove_useless_epsilon(root->left)) {
                del_regex_node(root->left);
                root->kind_ast = AST_EPSILON;
                return (true);
            }
            else
                { return (false); }

        default:
            return (false);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x7f60
movq %rdi, %rbx
movl (%rdi), %ecx
xorl %eax, %eax
cmpq $0xb, %rcx
ja 0x7f62
leaq 0x3e3c(%rip), %rdx      # 0xbcdc
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq 0x10(%rbx), %rdi
callq 0x7e71
testb %al, %al
je 0x7f60
movq 0x10(%rbx), %rdi
callq 0x7b74
movl $0xb, (%rbx)
movb $0x1, %al
jmp 0x7f62
movq 0x10(%rbx), %rdi
callq 0x7e71
movl %eax, %r15d
movq 0x18(%rbx), %rdi
callq 0x7e71
movl %eax, %r14d
movl %r15d, %eax
orb %r14b, %al
cmpb $0x1, %al
jne 0x7f60
leaq 0x10(%rbx), %r13
leaq 0x18(%rbx), %r12
testb %r15b, %r15b
je 0x7f38
movq (%r13), %rdi
callq 0x7b74
testb %r14b, %r14b
jne 0x7f32
jmp 0x7f49
movq 0x10(%rbx), %rdi
callq 0x7e71
testb %al, %al
je 0x7f60
movq 0x18(%rbx), %rdi
callq 0x7e71
testb %al, %al
je 0x7f60
movq 0x10(%rbx), %rdi
callq 0x7b74
movq 0x18(%rbx), %rdi
jmp 0x7ebe
testb %r14b, %r14b
je 0x7f46
movq (%r12), %rdi
callq 0x7b74
movq %r13, %r12
movq (%r12), %rdi
movups (%rdi), %xmm0
movups 0x10(%rdi), %xmm1
movups %xmm1, 0x10(%rbx)
movups %xmm0, (%rbx)
callq 0x2040
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq