#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
struct rooted_tree {
  int dummy;
};
struct llist {
  int dummy;
};

/* Variables and functions */
struct llist *create_label_list(char **, int);
int /*<<< orphan*/ destroy_llist(struct llist *);
int /*<<< orphan*/ destroy_tree_cb_2(struct rooted_tree *,
                                     int /*<<< orphan*/ *);
struct rooted_tree *get_ordered_pattern_tree(char *);
int parse_labels(struct rooted_tree *, char **);
char *prune_tree(struct rooted_tree *, struct llist *);
struct llist *reverse_labels(struct rooted_tree *, struct llist *);
int /*<<< orphan*/ strcpy(char *, char *);
char *prune(char *tree, char *MAST, char *seed) {
  int MAST_lc, seed_lc;
  char labels[1000][200];
  char combined_labels[1000][200];
  int mast_lcnt, seed_lcnt, combined_lc = 0;
  struct rooted_tree *current_tree = get_ordered_pattern_tree(tree);
  struct rooted_tree *MAST_tree = get_ordered_pattern_tree(MAST);
  MAST_lc = parse_labels(MAST_tree, labels);
  for (mast_lcnt = 0; mast_lcnt < MAST_lc; mast_lcnt++)
    strcpy(combined_labels[combined_lc++], labels[mast_lcnt]);
  struct rooted_tree *seed_tree = get_ordered_pattern_tree(seed);
  seed_lc = parse_labels(seed_tree, labels);
  for (seed_lcnt = 0; seed_lcnt < seed_lc; seed_lcnt++)
    strcpy(combined_labels[combined_lc++], labels[seed_lcnt]);
  struct llist *combined_ll = create_label_list(combined_labels, combined_lc);
  struct llist *rev_combined_labels = reverse_labels(current_tree, combined_ll);
  char *new_MAST = prune_tree(current_tree, rev_combined_labels);
  destroy_tree_cb_2(current_tree, NULL);
  destroy_tree_cb_2(MAST_tree, NULL);
  destroy_tree_cb_2(seed_tree, NULL);
  destroy_llist(combined_ll);
  destroy_llist(rev_combined_labels);
  return new_MAST;
}


x86 assembly (clang, -O0):
<prune>:
push   %rbp
mov    %rsp,%rbp
sub    $0x61ae0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x61aac(%rbp)
mov    -0x8(%rbp),%rdi
call   1070 <get_ordered_pattern_tree@plt>
mov    %rax,-0x61ab8(%rbp)
mov    -0x10(%rbp),%rdi
call   1070 <get_ordered_pattern_tree@plt>
mov    %rax,-0x61ac0(%rbp)
mov    -0x61ac0(%rbp),%rdi
lea    -0x30d60(%rbp),%rsi
call   10a0 <parse_labels@plt>
mov    %eax,-0x1c(%rbp)
movl   $0x0,-0x61aa4(%rbp)
mov    -0x61aa4(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1245 <prune+0xc5>
mov    -0x61aac(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x61aac(%rbp)
cltq
lea    -0x61aa0(%rbp),%rdi
imul   $0xc8,%rax,%rax
add    %rax,%rdi
movslq -0x61aa4(%rbp),%rax
lea    -0x30d60(%rbp),%rsi
imul   $0xc8,%rax,%rax
add    %rax,%rsi
call   1040 <strcpy@plt>
mov    -0x61aa4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x61aa4(%rbp)
jmp    11e1 <prune+0x61>
mov    -0x18(%rbp),%rdi
call   1070 <get_ordered_pattern_tree@plt>
mov    %rax,-0x61ac8(%rbp)
mov    -0x61ac8(%rbp),%rdi
lea    -0x30d60(%rbp),%rsi
call   10a0 <parse_labels@plt>
mov    %eax,-0x20(%rbp)
movl   $0x0,-0x61aa8(%rbp)
mov    -0x61aa8(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    12d9 <prune+0x159>
mov    -0x61aac(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x61aac(%rbp)
cltq
lea    -0x61aa0(%rbp),%rdi
imul   $0xc8,%rax,%rax
add    %rax,%rdi
movslq -0x61aa8(%rbp),%rax
lea    -0x30d60(%rbp),%rsi
imul   $0xc8,%rax,%rax
add    %rax,%rsi
call   1040 <strcpy@plt>
mov    -0x61aa8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x61aa8(%rbp)
jmp    1275 <prune+0xf5>
lea    -0x61aa0(%rbp),%rdi
mov    -0x61aac(%rbp),%esi
call   1080 <create_label_list@plt>
mov    %rax,-0x61ad0(%rbp)
mov    -0x61ab8(%rbp),%rdi
mov    -0x61ad0(%rbp),%rsi
call   1090 <reverse_labels@plt>
mov    %rax,-0x61ad8(%rbp)
mov    -0x61ab8(%rbp),%rdi
mov    -0x61ad8(%rbp),%rsi
call   1060 <prune_tree@plt>
mov    %rax,-0x61ae0(%rbp)
mov    -0x61ab8(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1030 <destroy_tree_cb_2@plt>
mov    -0x61ac0(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1030 <destroy_tree_cb_2@plt>
mov    -0x61ac8(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1030 <destroy_tree_cb_2@plt>
mov    -0x61ad0(%rbp),%rdi
call   1050 <destroy_llist@plt>
mov    -0x61ad8(%rbp),%rdi
call   1050 <destroy_llist@plt>
mov    -0x61ae0(%rbp),%rax
add    $0x61ae0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<prune>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x61a98,%rsp
mov    %rdx,%r12
mov    %rsi,%rbx
call   1070 <get_ordered_pattern_tree@plt>
mov    %rax,%r15
mov    %rbx,%rdi
call   1070 <get_ordered_pattern_tree@plt>
lea    0x30d50(%rsp),%r14
mov    %rax,0x8(%rsp)
mov    %rax,%rdi
mov    %r14,%rsi
call   10a0 <parse_labels@plt>
test   %eax,%eax
jle    11f1 <prune+0x71>
mov    %eax,%r13d
mov    %eax,%ebx
lea    0x10(%rsp),%rbp
nopl   (%rax)
mov    %rbp,%rdi
mov    %r14,%rsi
call   1040 <strcpy@plt>
add    $0xc8,%rbp
add    $0xc8,%r14
add    $0xffffffffffffffff,%rbx
jne    11d0 <prune+0x50>
jmp    11f4 <prune+0x74>
xor    %r13d,%r13d
mov    %r12,%rdi
call   1070 <get_ordered_pattern_tree@plt>
mov    %rax,%r12
lea    0x30d50(%rsp),%rbx
mov    %rax,%rdi
mov    %rbx,%rsi
call   10a0 <parse_labels@plt>
test   %eax,%eax
jle    1269 <prune+0xe9>
mov    %r15,(%rsp)
mov    %r13d,%r13d
mov    %eax,%r14d
imul   $0xc8,%r13,%rax
lea    (%rsp,%rax,1),%rbp
add    $0x10,%rbp
neg    %r14
xor    %r15d,%r15d
cs nopw 0x0(%rax,%rax,1)
nop
mov    %rbp,%rdi
mov    %rbx,%rsi
call   1040 <strcpy@plt>
add    $0xc8,%rbp
add    $0xffffffffffffffff,%r15
add    $0xc8,%rbx
cmp    %r15,%r14
jne    1240 <prune+0xc0>
sub    %r15d,%r13d
mov    (%rsp),%r15
lea    0x10(%rsp),%rdi
mov    %r13d,%esi
call   1080 <create_label_list@plt>
mov    %rax,%rbx
mov    %r15,%rdi
mov    %rax,%rsi
call   1090 <reverse_labels@plt>
mov    %rax,%rbp
mov    %r15,%rdi
mov    %rax,%rsi
call   1060 <prune_tree@plt>
mov    %rax,%r13
mov    %r15,%rdi
xor    %esi,%esi
call   1030 <destroy_tree_cb_2@plt>
mov    0x8(%rsp),%rdi
xor    %esi,%esi
call   1030 <destroy_tree_cb_2@plt>
mov    %r12,%rdi
xor    %esi,%esi
call   1030 <destroy_tree_cb_2@plt>
mov    %rbx,%rdi
call   1050 <destroy_llist@plt>
mov    %rbp,%rdi
call   1050 <destroy_llist@plt>
mov    %r13,%rax
add    $0x61a98,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.rooted_tree = type { i32 }
%struct.llist = type { i32 }
define i8* @prune(i8* %0, i8* %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca [1000 x [200 x i8]]
%10 = alloca [1000 x [200 x i8]]
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca %struct.rooted_tree*
%15 = alloca %struct.rooted_tree*
%16 = alloca %struct.rooted_tree*
%17 = alloca %struct.llist*
%18 = alloca %struct.llist*
%19 = alloca i8*
store i8* %0, i8** %4
store i8* %1, i8** %5
store i8* %2, i8** %6
store i32 0, i32* %13
%20 = load i8*, i8** %4
%21 = call %struct.rooted_tree* @get_ordered_pattern_tree(i8* %20)
store %struct.rooted_tree* %21, %struct.rooted_tree** %14
%22 = load i8*, i8** %5
%23 = call %struct.rooted_tree* @get_ordered_pattern_tree(i8* %22)
store %struct.rooted_tree* %23, %struct.rooted_tree** %15
%24 = load %struct.rooted_tree*, %struct.rooted_tree** %15
%25 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %9, i64 0, i64 0
%26 = bitcast [200 x i8]* %25 to i8**
%27 = call i32 @parse_labels(%struct.rooted_tree* %24, i8** %26)
store i32 %27, i32* %7
store i32 0, i32* %11
br label %28
28: ; preds = %43, %3
%29 = load i32, i32* %11
%30 = load i32, i32* %7
%31 = icmp slt i32 %29, %30
br i1 %31, label %32, label %46
32: ; preds = %28
%33 = load i32, i32* %13
%34 = add nsw i32 %33, 1
store i32 %34, i32* %13
%35 = sext i32 %33 to i64
%36 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %10, i64 0, i64 %35
%37 = getelementptr inbounds [200 x i8], [200 x i8]* %36, i64 0, i64 0
%38 = load i32, i32* %11
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %9, i64 0, i64 %39
%41 = getelementptr inbounds [200 x i8], [200 x i8]* %40, i64 0, i64 0
%42 = call i32 @strcpy(i8* %37, i8* %41)
br label %43
43: ; preds = %32
%44 = load i32, i32* %11
%45 = add nsw i32 %44, 1
store i32 %45, i32* %11
br label %28
46: ; preds = %28
%47 = load i8*, i8** %6
%48 = call %struct.rooted_tree* @get_ordered_pattern_tree(i8* %47)
store %struct.rooted_tree* %48, %struct.rooted_tree** %16
%49 = load %struct.rooted_tree*, %struct.rooted_tree** %16
%50 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %9, i64 0, i64 0
%51 = bitcast [200 x i8]* %50 to i8**
%52 = call i32 @parse_labels(%struct.rooted_tree* %49, i8** %51)
store i32 %52, i32* %8
store i32 0, i32* %12
br label %53
53: ; preds = %68, %46
%54 = load i32, i32* %12
%55 = load i32, i32* %8
%56 = icmp slt i32 %54, %55
br i1 %56, label %57, label %71
57: ; preds = %53
%58 = load i32, i32* %13
%59 = add nsw i32 %58, 1
store i32 %59, i32* %13
%60 = sext i32 %58 to i64
%61 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %10, i64 0, i64 %60
%62 = getelementptr inbounds [200 x i8], [200 x i8]* %61, i64 0, i64 0
%63 = load i32, i32* %12
%64 = sext i32 %63 to i64
%65 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %9, i64 0, i64 %64
%66 = getelementptr inbounds [200 x i8], [200 x i8]* %65, i64 0, i64 0
%67 = call i32 @strcpy(i8* %62, i8* %66)
br label %68
68: ; preds = %57
%69 = load i32, i32* %12
%70 = add nsw i32 %69, 1
store i32 %70, i32* %12
br label %53
71: ; preds = %53
%72 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %10, i64 0, i64 0
%73 = bitcast [200 x i8]* %72 to i8**
%74 = load i32, i32* %13
%75 = call %struct.llist* @create_label_list(i8** %73, i32 %74)
store %struct.llist* %75, %struct.llist** %17
%76 = load %struct.rooted_tree*, %struct.rooted_tree** %14
%77 = load %struct.llist*, %struct.llist** %17
%78 = call %struct.llist* @reverse_labels(%struct.rooted_tree* %76, %struct.llist* %77)
store %struct.llist* %78, %struct.llist** %18
%79 = load %struct.rooted_tree*, %struct.rooted_tree** %14
%80 = load %struct.llist*, %struct.llist** %18
%81 = call i8* @prune_tree(%struct.rooted_tree* %79, %struct.llist* %80)
store i8* %81, i8** %19
%82 = load %struct.rooted_tree*, %struct.rooted_tree** %14
%83 = call i32 @destroy_tree_cb_2(%struct.rooted_tree* %82, i32* null)
%84 = load %struct.rooted_tree*, %struct.rooted_tree** %15
%85 = call i32 @destroy_tree_cb_2(%struct.rooted_tree* %84, i32* null)
%86 = load %struct.rooted_tree*, %struct.rooted_tree** %16
%87 = call i32 @destroy_tree_cb_2(%struct.rooted_tree* %86, i32* null)
%88 = load %struct.llist*, %struct.llist** %17
%89 = call i32 @destroy_llist(%struct.llist* %88)
%90 = load %struct.llist*, %struct.llist** %18
%91 = call i32 @destroy_llist(%struct.llist* %90)
%92 = load i8*, i8** %19
ret i8* %92
}

LLVM IR (-O2):
%struct.rooted_tree = type { i32 }
%struct.llist = type { i32 }
define i8* @prune(i8* %0, i8* %1, i8* %2) {
%4 = alloca [1000 x [200 x i8]]
%5 = alloca [1000 x [200 x i8]]
%6 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %4, i64 0, i64 0, i64 0
%7 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %5, i64 0, i64 0, i64 0
%8 = tail call %struct.rooted_tree* @get_ordered_pattern_tree(i8* %0)
%9 = tail call %struct.rooted_tree* @get_ordered_pattern_tree(i8* %1)
%10 = bitcast [1000 x [200 x i8]]* %4 to i8**
%11 = call i32 @parse_labels(%struct.rooted_tree* %9, i8** %10)
%12 = icmp sgt i32 %11, 0
br i1 %12, label %13, label %22
13: ; preds = %3
%14 = zext i32 %11 to i64
br label %15
15: ; preds = %13, %15
%16 = phi i64 [ 0, %13 ], [ %17, %15 ]
%17 = add nuw nsw i64 %16, 1
%18 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %5, i64 0, i64 %16, i64 0
%19 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %4, i64 0, i64 %16, i64 0
%20 = call i32 @strcpy(i8* %18, i8* %19)
%21 = icmp eq i64 %17, %14
br i1 %21, label %22, label %15
22: ; preds = %15, %3
%23 = phi i32 [ 0, %3 ], [ %11, %15 ]
%24 = call %struct.rooted_tree* @get_ordered_pattern_tree(i8* %2)
%25 = call i32 @parse_labels(%struct.rooted_tree* %24, i8** %10)
%26 = icmp sgt i32 %25, 0
br i1 %26, label %27, label %41
27: ; preds = %22
%28 = zext i32 %23 to i64
%29 = zext i32 %25 to i64
br label %30
30: ; preds = %27, %30
%31 = phi i64 [ %28, %27 ], [ %33, %30 ]
%32 = phi i64 [ 0, %27 ], [ %37, %30 ]
%33 = add nuw nsw i64 %31, 1
%34 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %5, i64 0, i64 %31, i64 0
%35 = getelementptr inbounds [1000 x [200 x i8]], [1000 x [200 x i8]]* %4, i64 0, i64 %32, i64 0
%36 = call i32 @strcpy(i8* %34, i8* %35)
%37 = add nuw nsw i64 %32, 1
%38 = icmp eq i64 %37, %29
br i1 %38, label %39, label %30
39: ; preds = %30
%40 = trunc i64 %33 to i32
br label %41
41: ; preds = %39, %22
%42 = phi i32 [ %23, %22 ], [ %40, %39 ]
%43 = bitcast [1000 x [200 x i8]]* %5 to i8**
%44 = call %struct.llist* @create_label_list(i8** %43, i32 %42)
%45 = call %struct.llist* @reverse_labels(%struct.rooted_tree* %8, %struct.llist* %44)
%46 = call i8* @prune_tree(%struct.rooted_tree* %8, %struct.llist* %45)
%47 = call i32 @destroy_tree_cb_2(%struct.rooted_tree* %8, i32* null)
%48 = call i32 @destroy_tree_cb_2(%struct.rooted_tree* %9, i32* null)
%49 = call i32 @destroy_tree_cb_2(%struct.rooted_tree* %24, i32* null)
%50 = call i32 @destroy_llist(%struct.llist* %44)
%51 = call i32 @destroy_llist(%struct.llist* %45)
ret i8* %46
}