// File: yhirose[P]fizzbuzzlang/./peglib.h
// Function: std::shared_ptr<peg::AstBase<peg::EmptyType>> peg::AstOptimizer::optimize<peg::AstBase<peg::EmptyType>>(std::shared_ptr<peg::AstBase<peg::EmptyType>>, std::shared_ptr<peg::AstBase<peg::EmptyType>>)
std::shared_ptr<T> optimize(std::shared_ptr<T> original,
                              std::shared_ptr<T> parent = nullptr) {
    auto found =
        std::find(rules_.begin(), rules_.end(), original->name) != rules_.end();
    auto opt = mode_ ? !found : found;

    if (opt && original->nodes.size() == 1) {
      auto child = optimize(original->nodes[0], parent);
      auto ast = std::make_shared<T>(*child, original->name.data(),
                                     original->choice_count, original->position,
                                     original->length, original->choice);
      for (auto node : ast->nodes) {
        node->parent = ast;
      }
      return ast;
    }

    auto ast = std::make_shared<T>(*original);
    ast->parent = parent;
    ast->nodes.clear();
    for (auto node : original->nodes) {
      auto child = optimize(node, ast);
      ast->nodes.push_back(child);
    }
    return ast;
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rcx, -0x148(%rbp)
movq %rdx, -0x130(%rbp)
movq %rdi, -0x140(%rbp)
movq %rdi, %rax
movq %rax, -0x138(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x128(%rbp)
addq $0x8, %rdi
callq 0x12570
movq -0x128(%rbp), %rdi
movq %rax, -0x38(%rbp)
addq $0x8, %rdi
callq 0x125a0
movq -0x130(%rbp), %rdi
movq %rax, -0x40(%rbp)
callq 0x13720
movq %rax, %rdx
addq $0x30, %rdx
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x12520
movq -0x128(%rbp), %rdi
movq %rax, -0x30(%rbp)
addq $0x8, %rdi
callq 0x125a0
movq %rax, -0x48(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x125d0
movb %al, %cl
movq -0x128(%rbp), %rax
andb $0x1, %cl
movb %cl, -0x21(%rbp)
testb $0x1, (%rax)
je 0x9da0c
movb -0x21(%rbp), %al
xorb $-0x1, %al
movb %al, -0x149(%rbp)
jmp 0x9da15
movb -0x21(%rbp), %al
movb %al, -0x149(%rbp)
movb -0x149(%rbp), %al
andb $0x1, %al
movb %al, -0x49(%rbp)
testb $0x1, -0x49(%rbp)
je 0x9dcb4
movq -0x130(%rbp), %rdi
callq 0x13720
movq %rax, %rdi
addq $0xc0, %rdi
callq 0x134a0
cmpq $0x1, %rax
jne 0x9dcb4
movq -0x130(%rbp), %rdi
callq 0x13720
movq %rax, %rdi
addq $0xc0, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x9e220
movq %rax, %rsi
leaq -0x70(%rbp), %rdi
movq %rdi, -0x160(%rbp)
callq 0x13010
movq -0x148(%rbp), %rsi
leaq -0x80(%rbp), %rdi
movq %rdi, -0x158(%rbp)
callq 0x13010
movq -0x128(%rbp), %rsi
movq -0x160(%rbp), %rdx
movq -0x158(%rbp), %rcx
leaq -0x60(%rbp), %rdi
callq 0x9d940
jmp 0x9dab8
leaq -0x80(%rbp), %rdi
callq 0x13040
leaq -0x70(%rbp), %rdi
callq 0x13040
movb $0x0, -0x8d(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x130e0
movq -0x130(%rbp), %rdi
movq %rax, -0x180(%rbp)
callq 0x13720
movq %rax, %rdi
addq $0x30, %rdi
callq 0xa4d0
movq -0x130(%rbp), %rdi
movq %rax, -0x98(%rbp)
callq 0x13720
movq -0x130(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x178(%rbp)
callq 0x13720
movq -0x130(%rbp), %rdi
addq $0x50, %rax
movq %rax, -0x170(%rbp)
callq 0x13720
movq -0x130(%rbp), %rdi
addq $0x58, %rax
movq %rax, -0x168(%rbp)
callq 0x13720
movq -0x140(%rbp), %rdi
movq -0x180(%rbp), %rsi
movq -0x178(%rbp), %rcx
movq -0x170(%rbp), %r8
movq -0x168(%rbp), %r9
movq %rax, %rdx
addq $0x68, %rdx
movq %rsp, %rax
movq %rdx, (%rax)
leaq -0x98(%rbp), %rdx
callq 0x9e240
jmp 0x9db8f
movq -0x140(%rbp), %rdi
callq 0x13720
addq $0xc0, %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rdi
callq 0x9a620
movq %rax, -0xa8(%rbp)
movq -0xa0(%rbp), %rdi
callq 0x9a650
movq %rax, -0xb0(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x9a680
testb $0x1, %al
jne 0x9dbea
jmp 0x9dc8a
leaq -0xa8(%rbp), %rdi
callq 0x9a6c0
movq %rax, %rsi
leaq -0xc0(%rbp), %rdi
callq 0x13010
leaq -0xc0(%rbp), %rdi
callq 0x13720
movq -0x140(%rbp), %rsi
movq %rax, %rdi
addq $0xd8, %rdi
callq 0x9a6e0
leaq -0xc0(%rbp), %rdi
callq 0x13040
leaq -0xa8(%rbp), %rdi
callq 0x9a710
jmp 0x9dbce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x13040
leaq -0x70(%rbp), %rdi
callq 0x13040
jmp 0x9dede
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x13040
jmp 0x9dede
movb $0x1, -0x8d(%rbp)
testb $0x1, -0x8d(%rbp)
jne 0x9dca6
movq -0x140(%rbp), %rdi
callq 0x13040
leaq -0x60(%rbp), %rdi
callq 0x13040
jmp 0x9dece
movq -0x130(%rbp), %rdi
movb $0x0, -0xc1(%rbp)
callq 0x130e0
movq -0x140(%rbp), %rdi
movq %rax, %rsi
callq 0x9e2e0
movq -0x140(%rbp), %rdi
callq 0x13720
movq -0x148(%rbp), %rsi
movq %rax, %rdi
addq $0xd8, %rdi
callq 0x9a6e0
movq -0x140(%rbp), %rdi
callq 0x13720
movq %rax, %rdi
addq $0xc0, %rdi
callq 0x9e350
movq -0x130(%rbp), %rdi
callq 0x13720
addq $0xc0, %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x9a620
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x9a650
movq %rax, -0xe0(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x9a680
testb $0x1, %al
jne 0x9dd6e
jmp 0x9deb0
leaq -0xd8(%rbp), %rdi
callq 0x9a6c0
movq %rax, %rsi
leaq -0xf0(%rbp), %rdi
movq %rdi, -0x198(%rbp)
callq 0x13010
movq -0x198(%rbp), %rsi
leaq -0x110(%rbp), %rdi
movq %rdi, -0x190(%rbp)
callq 0x13010
movq -0x140(%rbp), %rsi
leaq -0x120(%rbp), %rdi
movq %rdi, -0x188(%rbp)
callq 0x13010
movq -0x128(%rbp), %rsi
movq -0x190(%rbp), %rdx
movq -0x188(%rbp), %rcx
leaq -0x100(%rbp), %rdi
callq 0x9d940
jmp 0x9dde7
leaq -0x120(%rbp), %rdi
callq 0x13040
leaq -0x110(%rbp), %rdi
callq 0x13040
movq -0x140(%rbp), %rdi
callq 0x13720
movq %rax, %rdi
addq $0xc0, %rdi
leaq -0x100(%rbp), %rsi
callq 0x9e370
jmp 0x9de23
leaq -0x100(%rbp), %rdi
callq 0x13040
leaq -0xf0(%rbp), %rdi
callq 0x13040
leaq -0xd8(%rbp), %rdi
callq 0x9a710
jmp 0x9dd52
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x13040
leaq -0x110(%rbp), %rdi
callq 0x13040
jmp 0x9de96
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x13040
leaq -0xf0(%rbp), %rdi
callq 0x13040
movq -0x140(%rbp), %rdi
callq 0x13040
jmp 0x9dede
movb $0x1, -0xc1(%rbp)
testb $0x1, -0xc1(%rbp)
jne 0x9decc
movq -0x140(%rbp), %rdi
callq 0x13040
jmp 0x9dece
movq -0x138(%rbp), %rax
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
movq -0x88(%rbp), %rdi
callq 0xa650
nopw (%rax,%rax)