#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 string {
  int dummy;
};
struct list_item {
  int dummy;
};
struct list {
  int dummy;
};
struct graph_node {
  int dummy;
};
struct graph {
  int dummy;
};

/* Variables and functions */
struct graph_node *get_or_add_node(struct graph *, struct string *);
int /*<<< orphan*/ graph_add_dependency(struct graph *, struct graph_node *,
                                        struct graph_node *);
struct string *list_get_data(struct list_item *);
struct list_item *list_head(struct list *);
struct list_item *list_next(struct list_item *);
void add_dependencies(struct graph *graph, struct list *dependents,
                      struct list *dependencies) {
  struct list_item *dependent_item;
  dependent_item = list_head(dependents);
  while (dependent_item != NULL) {
    struct string *dependent_name;
    struct graph_node *dependent;
    struct list_item *dependency_item;
    dependent_name = list_get_data(dependent_item);
    dependent = get_or_add_node(graph, dependent_name);
    dependency_item = list_head(dependencies);
    while (dependency_item != NULL) {
      struct string *dependency_name;
      struct graph_node *dependency;
      dependency_name = list_get_data(dependency_item);
      dependency = get_or_add_node(graph, dependency_name);
      graph_add_dependency(graph, dependent, dependency);
      dependency_item = list_next(dependency_item);
    }
    dependent_item = list_next(dependent_item);
  }
}


x86 assembly (clang, -O0):
<add_dependencies>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x10(%rbp),%rdi
call   1060 <list_head@plt>
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
je     1205 <add_dependencies+0xb5>
mov    -0x20(%rbp),%rdi
call   1040 <list_get_data@plt>
mov    %rax,-0x28(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x28(%rbp),%rsi
call   1070 <get_or_add_node@plt>
mov    %rax,-0x30(%rbp)
mov    -0x18(%rbp),%rdi
call   1060 <list_head@plt>
mov    %rax,-0x38(%rbp)
cmpq   $0x0,-0x38(%rbp)
je     11f3 <add_dependencies+0xa3>
mov    -0x38(%rbp),%rdi
call   1040 <list_get_data@plt>
mov    %rax,-0x40(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x40(%rbp),%rsi
call   1070 <get_or_add_node@plt>
mov    %rax,-0x48(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x30(%rbp),%rsi
mov    -0x48(%rbp),%rdx
call   1030 <graph_add_dependency@plt>
mov    -0x38(%rbp),%rdi
call   1050 <list_next@plt>
mov    %rax,-0x38(%rbp)
jmp    11a7 <add_dependencies+0x57>
mov    -0x20(%rbp),%rdi
call   1050 <list_next@plt>
mov    %rax,-0x20(%rbp)
jmp    1171 <add_dependencies+0x21>
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<add_dependencies>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rdx,%r14
mov    %rdi,%r13
mov    %rsi,%rdi
call   1060 <list_head@plt>
test   %rax,%rax
je     11f3 <add_dependencies+0xa3>
mov    %rax,%r15
jmp    1190 <add_dependencies+0x40>
cs nopw 0x0(%rax,%rax,1)
nop
mov    %r15,%rdi
call   1050 <list_next@plt>
mov    %rax,%r15
test   %rax,%rax
je     11f3 <add_dependencies+0xa3>
mov    %r15,%rdi
call   1040 <list_get_data@plt>
mov    %r13,%rdi
mov    %rax,%rsi
call   1070 <get_or_add_node@plt>
mov    %rax,%r12
mov    %r14,%rdi
call   1060 <list_head@plt>
test   %rax,%rax
je     1180 <add_dependencies+0x30>
mov    %rax,%rbx
cs nopw 0x0(%rax,%rax,1)
mov    %rbx,%rdi
call   1040 <list_get_data@plt>
mov    %r13,%rdi
mov    %rax,%rsi
call   1070 <get_or_add_node@plt>
mov    %r13,%rdi
mov    %r12,%rsi
mov    %rax,%rdx
call   1030 <graph_add_dependency@plt>
mov    %rbx,%rdi
call   1050 <list_next@plt>
mov    %rax,%rbx
test   %rax,%rax
jne    11c0 <add_dependencies+0x70>
jmp    1180 <add_dependencies+0x30>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct.graph = type { i32 }
%struct.list = type { i32 }
%struct.list_item = type { i32 }
%struct.string = type { i32 }
%struct.graph_node = type { i32 }
define void @add_dependencies(%struct.graph* %0, %struct.list* %1, %struct.list* %2) {
%4 = alloca %struct.graph*
%5 = alloca %struct.list*
%6 = alloca %struct.list*
%7 = alloca %struct.list_item*
%8 = alloca %struct.string*
%9 = alloca %struct.graph_node*
%10 = alloca %struct.list_item*
%11 = alloca %struct.string*
%12 = alloca %struct.graph_node*
store %struct.graph* %0, %struct.graph** %4
store %struct.list* %1, %struct.list** %5
store %struct.list* %2, %struct.list** %6
%13 = load %struct.list*, %struct.list** %5
%14 = call %struct.list_item* @list_head(%struct.list* %13)
store %struct.list_item* %14, %struct.list_item** %7
br label %15
15: ; preds = %41, %3
%16 = load %struct.list_item*, %struct.list_item** %7
%17 = icmp ne %struct.list_item* %16, null
br i1 %17, label %18, label %44
18: ; preds = %15
%19 = load %struct.list_item*, %struct.list_item** %7
%20 = call %struct.string* @list_get_data(%struct.list_item* %19)
store %struct.string* %20, %struct.string** %8
%21 = load %struct.graph*, %struct.graph** %4
%22 = load %struct.string*, %struct.string** %8
%23 = call %struct.graph_node* @get_or_add_node(%struct.graph* %21, %struct.string* %22)
store %struct.graph_node* %23, %struct.graph_node** %9
%24 = load %struct.list*, %struct.list** %6
%25 = call %struct.list_item* @list_head(%struct.list* %24)
store %struct.list_item* %25, %struct.list_item** %10
br label %26
26: ; preds = %29, %18
%27 = load %struct.list_item*, %struct.list_item** %10
%28 = icmp ne %struct.list_item* %27, null
br i1 %28, label %29, label %41
29: ; preds = %26
%30 = load %struct.list_item*, %struct.list_item** %10
%31 = call %struct.string* @list_get_data(%struct.list_item* %30)
store %struct.string* %31, %struct.string** %11
%32 = load %struct.graph*, %struct.graph** %4
%33 = load %struct.string*, %struct.string** %11
%34 = call %struct.graph_node* @get_or_add_node(%struct.graph* %32, %struct.string* %33)
store %struct.graph_node* %34, %struct.graph_node** %12
%35 = load %struct.graph*, %struct.graph** %4
%36 = load %struct.graph_node*, %struct.graph_node** %9
%37 = load %struct.graph_node*, %struct.graph_node** %12
%38 = call i32 @graph_add_dependency(%struct.graph* %35, %struct.graph_node* %36, %struct.graph_node* %37)
%39 = load %struct.list_item*, %struct.list_item** %10
%40 = call %struct.list_item* @list_next(%struct.list_item* %39)
store %struct.list_item* %40, %struct.list_item** %10
br label %26
41: ; preds = %26
%42 = load %struct.list_item*, %struct.list_item** %7
%43 = call %struct.list_item* @list_next(%struct.list_item* %42)
store %struct.list_item* %43, %struct.list_item** %7
br label %15
44: ; preds = %15
ret void
}

LLVM IR (-O2):
%struct.graph = type { i32 }
%struct.list = type { i32 }
%struct.list_item = type { i32 }
%struct.string = type { i32 }
%struct.graph_node = type { i32 }
define void @add_dependencies(%struct.graph* %0, %struct.list* %1, %struct.list* %2) {
%4 = tail call %struct.list_item* @list_head(%struct.list* %1)
%5 = icmp eq %struct.list_item* %4, null
br i1 %5, label %22, label %6
6: ; preds = %3, %19
%7 = phi %struct.list_item* [ %20, %19 ], [ %4, %3 ]
%8 = tail call %struct.string* @list_get_data(%struct.list_item* %7)
%9 = tail call %struct.graph_node* @get_or_add_node(%struct.graph* %0, %struct.string* %8)
%10 = tail call %struct.list_item* @list_head(%struct.list* %2)
%11 = icmp eq %struct.list_item* %10, null
br i1 %11, label %19, label %12
12: ; preds = %6, %12
%13 = phi %struct.list_item* [ %17, %12 ], [ %10, %6 ]
%14 = tail call %struct.string* @list_get_data(%struct.list_item* %13)
%15 = tail call %struct.graph_node* @get_or_add_node(%struct.graph* %0, %struct.string* %14)
%16 = tail call i32 @graph_add_dependency(%struct.graph* %0, %struct.graph_node* %9, %struct.graph_node* %15)
%17 = tail call %struct.list_item* @list_next(%struct.list_item* %13)
%18 = icmp eq %struct.list_item* %17, null
br i1 %18, label %19, label %12
19: ; preds = %12, %6
%20 = tail call %struct.list_item* @list_next(%struct.list_item* %7)
%21 = icmp eq %struct.list_item* %20, null
br i1 %21, label %22, label %6
22: ; preds = %19, %3
ret void
}