#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 task_struct {
  int dummy;
};
struct rq {
  int dummy;
};

/* Variables and functions */
int /*<<< orphan*/ fire_sched_out_preempt_notifiers(struct task_struct *,
                                                    struct task_struct *);
int /*<<< orphan*/ perf_event_task_sched_out(struct task_struct *,
                                             struct task_struct *);
int /*<<< orphan*/ prepare_arch_switch(struct task_struct *);
int /*<<< orphan*/ prepare_lock_switch(struct rq *, struct task_struct *);
int /*<<< orphan*/ sched_info_switch(struct rq *, struct task_struct *,
                                     struct task_struct *);
void prepare_task_switch(struct rq *rq, struct task_struct *prev,
                         struct task_struct *next) {
  sched_info_switch(rq, prev, next);
  perf_event_task_sched_out(prev, next);
  fire_sched_out_preempt_notifiers(prev, next);
  prepare_lock_switch(rq, next);
  prepare_arch_switch(next);
}


x86 assembly (clang, -O0):
<prepare_task_switch>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
call   1070 <sched_info_switch@plt>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1030 <perf_event_task_sched_out@plt>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <fire_sched_out_preempt_notifiers@plt>
mov    -0x8(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1060 <prepare_lock_switch@plt>
mov    -0x18(%rbp),%rdi
call   1050 <prepare_arch_switch@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<prepare_task_switch>:
push   %r15
push   %r14
push   %rbx
mov    %rdx,%rbx
mov    %rsi,%r14
mov    %rdi,%r15
call   1070 <sched_info_switch@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1030 <perf_event_task_sched_out@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1040 <fire_sched_out_preempt_notifiers@plt>
mov    %r15,%rdi
mov    %rbx,%rsi
call   1060 <prepare_lock_switch@plt>
mov    %rbx,%rdi
pop    %rbx
pop    %r14
pop    %r15
jmp    1050 <prepare_arch_switch@plt>

LLVM IR (-O0):
%struct.rq = type { i32 }
%struct.task_struct = type { i32 }
define void @prepare_task_switch(%struct.rq* %0, %struct.task_struct* %1, %struct.task_struct* %2) {
%4 = alloca %struct.rq*
%5 = alloca %struct.task_struct*
%6 = alloca %struct.task_struct*
store %struct.rq* %0, %struct.rq** %4
store %struct.task_struct* %1, %struct.task_struct** %5
store %struct.task_struct* %2, %struct.task_struct** %6
%7 = load %struct.rq*, %struct.rq** %4
%8 = load %struct.task_struct*, %struct.task_struct** %5
%9 = load %struct.task_struct*, %struct.task_struct** %6
%10 = call i32 @sched_info_switch(%struct.rq* %7, %struct.task_struct* %8, %struct.task_struct* %9)
%11 = load %struct.task_struct*, %struct.task_struct** %5
%12 = load %struct.task_struct*, %struct.task_struct** %6
%13 = call i32 @perf_event_task_sched_out(%struct.task_struct* %11, %struct.task_struct* %12)
%14 = load %struct.task_struct*, %struct.task_struct** %5
%15 = load %struct.task_struct*, %struct.task_struct** %6
%16 = call i32 @fire_sched_out_preempt_notifiers(%struct.task_struct* %14, %struct.task_struct* %15)
%17 = load %struct.rq*, %struct.rq** %4
%18 = load %struct.task_struct*, %struct.task_struct** %6
%19 = call i32 @prepare_lock_switch(%struct.rq* %17, %struct.task_struct* %18)
%20 = load %struct.task_struct*, %struct.task_struct** %6
%21 = call i32 @prepare_arch_switch(%struct.task_struct* %20)
ret void
}

LLVM IR (-O2):
%struct.rq = type { i32 }
%struct.task_struct = type { i32 }
define void @prepare_task_switch(%struct.rq* %0, %struct.task_struct* %1, %struct.task_struct* %2) {
%4 = tail call i32 @sched_info_switch(%struct.rq* %0, %struct.task_struct* %1, %struct.task_struct* %2)
%5 = tail call i32 @perf_event_task_sched_out(%struct.task_struct* %1, %struct.task_struct* %2)
%6 = tail call i32 @fire_sched_out_preempt_notifiers(%struct.task_struct* %1, %struct.task_struct* %2)
%7 = tail call i32 @prepare_lock_switch(%struct.rq* %0, %struct.task_struct* %2)
%8 = tail call i32 @prepare_arch_switch(%struct.task_struct* %2)
ret void
}