#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 */

/* Variables and functions */
int PROT_EXEC;
int PROT_READ;
int PROT_WRITE;
int /*<<< orphan*/ _SC_PAGESIZE;
int /*<<< orphan*/ mprotect(void *, int, int);
int sysconf(int /*<<< orphan*/);
void jit_flush_code(void *dest, void *end) {
  static unsigned long prev_page = 0, prev_length = 0;
  int page, length;
  static int page_size = -1;
  if (page_size == -1)
    page_size = sysconf(_SC_PAGESIZE);
  page = (long)dest & ~(page_size - 1);
  length = ((char *)end - (char *)page + page_size - 1) & ~(page_size - 1);
  if (page >= prev_page && page + length <= prev_page + prev_length)
    return;
  mprotect((void *)page, length, PROT_READ | PROT_WRITE | PROT_EXEC);
  if (page >= prev_page && page <= prev_page + prev_length)
    prev_length = page + length - prev_page;
  else if (page < prev_page && page + length >= prev_page &&
           page + length <= prev_page + prev_length)
    prev_length += prev_page - page, prev_page = page;
  else
    prev_page = page, prev_length = length;
}


x86 assembly (clang, -O0):
<jit_flush_code>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
cmpl   $0xffffffff,0x2ef9(%rip)
jne    1151 <jit_flush_code+0x31>
mov    0x2e9c(%rip),%rax
mov    (%rax),%edi
call   1040 <sysconf@plt>
mov    %eax,0x2edf(%rip)
mov    -0x8(%rbp),%rax
mov    0x2ed5(%rip),%ecx
sub    $0x1,%ecx
xor    $0xffffffff,%ecx
movslq %ecx,%rcx
and    %rcx,%rax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
sub    %rcx,%rax
movslq 0x2eb4(%rip),%rcx
add    %rcx,%rax
sub    $0x1,%rax
mov    0x2ea7(%rip),%ecx
sub    $0x1,%ecx
xor    $0xffffffff,%ecx
movslq %ecx,%rcx
and    %rcx,%rax
mov    %eax,-0x18(%rbp)
movslq -0x14(%rbp),%rax
cmp    0x2e9d(%rip),%rax
jb     11cd <jit_flush_code+0xad>
mov    -0x14(%rbp),%eax
add    -0x18(%rbp),%eax
cltq
mov    0x2e88(%rip),%rcx
add    0x2e89(%rip),%rcx
cmp    %rcx,%rax
ja     11cd <jit_flush_code+0xad>
jmp    12c7 <jit_flush_code+0x1a7>
movslq -0x14(%rbp),%rdi
mov    -0x18(%rbp),%esi
mov    0x2e1d(%rip),%rax
mov    (%rax),%edx
mov    0x2de4(%rip),%rax
or     (%rax),%edx
mov    0x2deb(%rip),%rax
or     (%rax),%edx
call   1030 <mprotect@plt>
movslq -0x14(%rbp),%rax
cmp    0x2e41(%rip),%rax
jb     123b <jit_flush_code+0x11b>
movslq -0x14(%rbp),%rax
mov    0x2e30(%rip),%rcx
add    0x2e31(%rip),%rcx
cmp    %rcx,%rax
ja     123b <jit_flush_code+0x11b>
mov    -0x14(%rbp),%eax
add    -0x18(%rbp),%eax
cltq
sub    0x2e11(%rip),%rax
mov    %rax,0x2e12(%rip)
jmp    12c7 <jit_flush_code+0x1a7>
movslq -0x14(%rbp),%rax
cmp    0x2dfa(%rip),%rax
jae    12ac <jit_flush_code+0x18c>
mov    -0x14(%rbp),%eax
add    -0x18(%rbp),%eax
cltq
cmp    0x2de5(%rip),%rax
jb     12ac <jit_flush_code+0x18c>
mov    -0x14(%rbp),%eax
add    -0x18(%rbp),%eax
cltq
mov    0x2dd0(%rip),%rcx
add    0x2dd1(%rip),%rcx
cmp    %rcx,%rax
ja     12ac <jit_flush_code+0x18c>
mov    0x2db9(%rip),%rax
movslq -0x14(%rbp),%rcx
sub    %rcx,%rax
add    0x2db3(%rip),%rax
mov    %rax,0x2dac(%rip)
movslq -0x14(%rbp),%rax
mov    %rax,0x2d99(%rip)
jmp    12c2 <jit_flush_code+0x1a2>
movslq -0x14(%rbp),%rax
mov    %rax,0x2d89(%rip)
movslq -0x18(%rbp),%rax
mov    %rax,0x2d86(%rip)
jmp    12c7 <jit_flush_code+0x1a7>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<jit_flush_code>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
mov    %rsi,%r12
mov    %rdi,%r14
mov    0x2efc(%rip),%eax
cmp    $0xffffffff,%eax
jne    114d <jit_flush_code+0x2d>
mov    0x2ea0(%rip),%rax
mov    (%rax),%edi
call   1040 <sysconf@plt>
mov    %eax,0x2ee3(%rip)
mov    %eax,%ecx
neg    %ecx
and    %ecx,%r14d
movslq %r14d,%r15
add    %eax,%r12d
mov    %r15d,%ebx
not    %ebx
add    %r12d,%ebx
and    %ecx,%ebx
mov    0x2ed5(%rip),%rax
cmp    %r15,%rax
ja     1187 <jit_flush_code+0x67>
lea    (%rbx,%r14,1),%ecx
movslq %ecx,%rcx
add    0x2eca(%rip),%rax
cmp    %rcx,%rax
jae    121a <jit_flush_code+0xfa>
mov    0x2e6a(%rip),%rax
mov    0x2e33(%rip),%rcx
mov    (%rcx),%edx
or     (%rax),%edx
mov    0x2e38(%rip),%rax
or     (%rax),%edx
mov    %r15,%rdi
mov    %ebx,%esi
call   1030 <mprotect@plt>
mov    0x2e8d(%rip),%rax
mov    %rax,%rcx
sub    %r15,%rcx
jbe    11e8 <jit_flush_code+0xc8>
add    %ebx,%r14d
movslq %r14d,%rdx
cmp    %rdx,%rax
ja     11f7 <jit_flush_code+0xd7>
mov    0x2e7b(%rip),%rsi
add    %rsi,%rax
cmp    %rdx,%rax
jb     11f7 <jit_flush_code+0xd7>
add    %rsi,%rcx
mov    %rcx,0x2e69(%rip)
mov    %r15,0x2e5a(%rip)
jmp    121a <jit_flush_code+0xfa>
mov    0x2e59(%rip),%rcx
add    %rax,%rcx
cmp    %r15,%rcx
jae    120a <jit_flush_code+0xea>
mov    %r15,0x2e42(%rip)
movslq %ebx,%rax
mov    %rax,0x2e40(%rip)
jmp    121a <jit_flush_code+0xfa>
add    %r14d,%ebx
movslq %ebx,%rcx
sub    %rax,%rcx
mov    %rcx,0x2e2e(%rip)
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@jit_flush_code.prev_page = internal global i64 0
@jit_flush_code.prev_length = internal global i64 0
@jit_flush_code.page_size = internal global i32 -1
@_SC_PAGESIZE = global i32 0
@PROT_READ = global i32 0
@PROT_WRITE = global i32 0
@PROT_EXEC = global i32 0
define void @jit_flush_code(i8* %0, i8* %1) {
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i32
store i8* %0, i8** %3
store i8* %1, i8** %4
%7 = load i32, i32* @jit_flush_code.page_size
%8 = icmp eq i32 %7, -1
br i1 %8, label %9, label %12
9: ; preds = %2
%10 = load i32, i32* @_SC_PAGESIZE
%11 = call i32 @sysconf(i32 %10)
store i32 %11, i32* @jit_flush_code.page_size
br label %12
12: ; preds = %9, %2
%13 = load i8*, i8** %3
%14 = ptrtoint i8* %13 to i64
%15 = load i32, i32* @jit_flush_code.page_size
%16 = sub nsw i32 %15, 1
%17 = xor i32 %16, -1
%18 = sext i32 %17 to i64
%19 = and i64 %14, %18
%20 = trunc i64 %19 to i32
store i32 %20, i32* %5
%21 = load i8*, i8** %4
%22 = load i32, i32* %5
%23 = sext i32 %22 to i64
%24 = inttoptr i64 %23 to i8*
%25 = ptrtoint i8* %21 to i64
%26 = ptrtoint i8* %24 to i64
%27 = sub i64 %25, %26
%28 = load i32, i32* @jit_flush_code.page_size
%29 = sext i32 %28 to i64
%30 = add nsw i64 %27, %29
%31 = sub nsw i64 %30, 1
%32 = load i32, i32* @jit_flush_code.page_size
%33 = sub nsw i32 %32, 1
%34 = xor i32 %33, -1
%35 = sext i32 %34 to i64
%36 = and i64 %31, %35
%37 = trunc i64 %36 to i32
store i32 %37, i32* %6
%38 = load i32, i32* %5
%39 = sext i32 %38 to i64
%40 = load i64, i64* @jit_flush_code.prev_page
%41 = icmp uge i64 %39, %40
br i1 %41, label %42, label %52
42: ; preds = %12
%43 = load i32, i32* %5
%44 = load i32, i32* %6
%45 = add nsw i32 %43, %44
%46 = sext i32 %45 to i64
%47 = load i64, i64* @jit_flush_code.prev_page
%48 = load i64, i64* @jit_flush_code.prev_length
%49 = add i64 %47, %48
%50 = icmp ule i64 %46, %49
br i1 %50, label %51, label %52
51: ; preds = %42
br label %117
52: ; preds = %42, %12
%53 = load i32, i32* %5
%54 = sext i32 %53 to i64
%55 = inttoptr i64 %54 to i8*
%56 = load i32, i32* %6
%57 = load i32, i32* @PROT_READ
%58 = load i32, i32* @PROT_WRITE
%59 = or i32 %57, %58
%60 = load i32, i32* @PROT_EXEC
%61 = or i32 %59, %60
%62 = call i32 @mprotect(i8* %55, i32 %56, i32 %61)
%63 = load i32, i32* %5
%64 = sext i32 %63 to i64
%65 = load i64, i64* @jit_flush_code.prev_page
%66 = icmp uge i64 %64, %65
br i1 %66, label %67, label %81
67: ; preds = %52
%68 = load i32, i32* %5
%69 = sext i32 %68 to i64
%70 = load i64, i64* @jit_flush_code.prev_page
%71 = load i64, i64* @jit_flush_code.prev_length
%72 = add i64 %70, %71
%73 = icmp ule i64 %69, %72
br i1 %73, label %74, label %81
74: ; preds = %67
%75 = load i32, i32* %5
%76 = load i32, i32* %6
%77 = add nsw i32 %75, %76
%78 = sext i32 %77 to i64
%79 = load i64, i64* @jit_flush_code.prev_page
%80 = sub i64 %78, %79
store i64 %80, i64* @jit_flush_code.prev_length
br label %117
81: ; preds = %67, %52
%82 = load i32, i32* %5
%83 = sext i32 %82 to i64
%84 = load i64, i64* @jit_flush_code.prev_page
%85 = icmp ult i64 %83, %84
br i1 %85, label %86, label %111
86: ; preds = %81
%87 = load i32, i32* %5
%88 = load i32, i32* %6
%89 = add nsw i32 %87, %88
%90 = sext i32 %89 to i64
%91 = load i64, i64* @jit_flush_code.prev_page
%92 = icmp uge i64 %90, %91
br i1 %92, label %93, label %111
93: ; preds = %86
%94 = load i32, i32* %5
%95 = load i32, i32* %6
%96 = add nsw i32 %94, %95
%97 = sext i32 %96 to i64
%98 = load i64, i64* @jit_flush_code.prev_page
%99 = load i64, i64* @jit_flush_code.prev_length
%100 = add i64 %98, %99
%101 = icmp ule i64 %97, %100
br i1 %101, label %102, label %111
102: ; preds = %93
%103 = load i64, i64* @jit_flush_code.prev_page
%104 = load i32, i32* %5
%105 = sext i32 %104 to i64
%106 = sub i64 %103, %105
%107 = load i64, i64* @jit_flush_code.prev_length
%108 = add i64 %107, %106
store i64 %108, i64* @jit_flush_code.prev_length
%109 = load i32, i32* %5
%110 = sext i32 %109 to i64
store i64 %110, i64* @jit_flush_code.prev_page
br label %116
111: ; preds = %93, %86, %81
%112 = load i32, i32* %5
%113 = sext i32 %112 to i64
store i64 %113, i64* @jit_flush_code.prev_page
%114 = load i32, i32* %6
%115 = sext i32 %114 to i64
store i64 %115, i64* @jit_flush_code.prev_length
br label %116
116: ; preds = %111, %102
br label %117
117: ; preds = %51, %116, %74
ret void
}

LLVM IR (-O2):
@jit_flush_code.prev_page = internal unnamed_addr global i64 0
@jit_flush_code.prev_length = internal unnamed_addr global i64 0
@jit_flush_code.page_size = internal unnamed_addr global i32 -1
@_SC_PAGESIZE = global i32 0
@PROT_READ = global i32 0
@PROT_WRITE = global i32 0
@PROT_EXEC = global i32 0
define void @jit_flush_code(i8* %0, i8* %1) {
%3 = load i32, i32* @jit_flush_code.page_size
%4 = icmp eq i32 %3, -1
br i1 %4, label %5, label %8
5: ; preds = %2
%6 = load i32, i32* @_SC_PAGESIZE
%7 = tail call i32 @sysconf(i32 %6)
store i32 %7, i32* @jit_flush_code.page_size
br label %8
8: ; preds = %5, %2
%9 = phi i32 [ %7, %5 ], [ %3, %2 ]
%10 = ptrtoint i8* %0 to i64
%11 = sub i32 0, %9
%12 = trunc i64 %10 to i32
%13 = and i32 %11, %12
%14 = sext i32 %13 to i64
%15 = inttoptr i64 %14 to i8*
%16 = ptrtoint i8* %1 to i64
%17 = trunc i64 %16 to i32
%18 = add i32 %17, -1
%19 = add i32 %18, %9
%20 = sub i32 %19, %13
%21 = and i32 %20, %11
%22 = load i64, i64* @jit_flush_code.prev_page
%23 = icmp ugt i64 %22, %14
br i1 %23, label %30, label %24
24: ; preds = %8
%25 = add nsw i32 %21, %13
%26 = sext i32 %25 to i64
%27 = load i64, i64* @jit_flush_code.prev_length
%28 = add i64 %27, %22
%29 = icmp ult i64 %28, %26
br i1 %29, label %30, label %60
30: ; preds = %24, %8
%31 = load i32, i32* @PROT_READ
%32 = load i32, i32* @PROT_WRITE
%33 = or i32 %32, %31
%34 = load i32, i32* @PROT_EXEC
%35 = or i32 %33, %34
%36 = tail call i32 @mprotect(i8* %15, i32 %21, i32 %35)
%37 = load i64, i64* @jit_flush_code.prev_page
%38 = icmp ugt i64 %37, %14
br i1 %38, label %47, label %39
39: ; preds = %30
%40 = load i64, i64* @jit_flush_code.prev_length
%41 = add i64 %40, %37
%42 = icmp ult i64 %41, %14
br i1 %42, label %58, label %43
43: ; preds = %39
%44 = add nsw i32 %21, %13
%45 = sext i32 %44 to i64
%46 = sub i64 %45, %37
store i64 %46, i64* @jit_flush_code.prev_length
br label %60
47: ; preds = %30
%48 = add nsw i32 %21, %13
%49 = sext i32 %48 to i64
%50 = icmp ugt i64 %37, %49
br i1 %50, label %58, label %51
51: ; preds = %47
%52 = load i64, i64* @jit_flush_code.prev_length
%53 = add i64 %52, %37
%54 = icmp ult i64 %53, %49
br i1 %54, label %58, label %55
55: ; preds = %51
%56 = sub i64 %37, %14
%57 = add i64 %56, %52
store i64 %57, i64* @jit_flush_code.prev_length
store i64 %14, i64* @jit_flush_code.prev_page
br label %60
58: ; preds = %39, %51, %47
store i64 %14, i64* @jit_flush_code.prev_page
%59 = sext i32 %21 to i64
store i64 %59, i64* @jit_flush_code.prev_length
br label %60
60: ; preds = %43, %58, %55, %24
ret void
}