void reduce(int length, int *profile, double *values, const char *location,
            double *matrix, int i0, int i1) {
  const char *row_prefix = "row";
  const char *row_sufix = ".txt";
  int i;
  for (i = i0; i < i1; i++) {
    char *row_file_name =
        malloc(sizeof(char) * (strlen(location) + strlen(row_prefix) +
                               strlen(row_sufix) + 10));
    sprintf(row_file_name, "%s/%s%d%s", location, row_prefix, i, row_sufix);
    setRowWithSparseVectorDouble(matrix, i - i0, length, row_file_name);
    reduceRhs(values, matrix, i - i0, length, profile);
    free(row_file_name);
  }
}


x86 assembly (clang, -O0):
<reduce>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    0x10(%rbp),%eax
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9d,-0x2c(%rbp)
lea    0xe77(%rip),%rax
mov    %rax,-0x38(%rbp)
lea    0xe70(%rip),%rax
mov    %rax,-0x40(%rbp)
mov    -0x2c(%rbp),%eax
mov    %eax,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cmp    0x10(%rbp),%eax
jge    125c <reduce+0xfc>
mov    -0x20(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,-0x60(%rbp)
mov    -0x38(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,%rcx
mov    -0x60(%rbp),%rax
add    %rcx,%rax
mov    %rax,-0x58(%rbp)
mov    -0x40(%rbp),%rdi
call   1040 <strlen@plt>
mov    -0x58(%rbp),%rdi
add    %rax,%rdi
add    $0xa,%rdi
shl    $0x0,%rdi
call   1050 <malloc@plt>
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%rdi
mov    -0x20(%rbp),%rdx
mov    -0x38(%rbp),%rcx
mov    -0x44(%rbp),%r8d
mov    -0x40(%rbp),%r9
lea    0xdff(%rip),%rsi
mov    $0x0,%al
call   1080 <sprintf@plt>
mov    -0x28(%rbp),%rdi
mov    -0x44(%rbp),%esi
sub    -0x2c(%rbp),%esi
mov    -0x4(%rbp),%edx
mov    -0x50(%rbp),%rcx
mov    $0x0,%al
call   1070 <setRowWithSparseVectorDouble@plt>
mov    -0x18(%rbp),%rdi
mov    -0x28(%rbp),%rsi
mov    -0x44(%rbp),%edx
sub    -0x2c(%rbp),%edx
mov    -0x4(%rbp),%ecx
mov    -0x10(%rbp),%r8
mov    $0x0,%al
call   1060 <reduceRhs@plt>
mov    -0x50(%rbp),%rdi
call   1030 <free@plt>
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    119e <reduce+0x3e>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<reduce>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %edi,0xc(%rsp)
mov    0x60(%rsp),%eax
mov    %r9,0x10(%rsp)
mov    %eax,0x8(%rsp)
cmp    %eax,%r9d
jge    1244 <reduce+0xe4>
mov    %r8,%rbp
mov    %rdx,%rbx
mov    %rsi,%r13
mov    0x8(%rsp),%eax
sub    0x10(%rsp),%eax
mov    %eax,0x8(%rsp)
xor    %r12d,%r12d
mov    %rdx,0x20(%rsp)
mov    %rcx,0x18(%rsp)
mov    0xc(%rsp),%r15d
nop
mov    0x10(%rsp),%rax
mov    %r13,%rbx
lea    (%rax,%r12,1),%r13d
mov    %rcx,%rdi
call   1040 <strlen@plt>
lea    0x11(%rax),%rdi
call   1050 <malloc@plt>
mov    %rax,%r14
mov    %rax,%rdi
lea    0xe2f(%rip),%rsi
mov    0x18(%rsp),%rdx
lea    0xe1a(%rip),%rcx
mov    %r13d,%r8d
mov    %rbx,%r13
mov    0x20(%rsp),%rbx
lea    0xe0c(%rip),%r9
xor    %eax,%eax
call   1080 <sprintf@plt>
mov    %rbp,%rdi
mov    %r12d,%esi
mov    %r15d,%edx
mov    %r14,%rcx
xor    %eax,%eax
call   1070 <setRowWithSparseVectorDouble@plt>
mov    %rbx,%rdi
mov    %rbp,%rsi
mov    %r12d,%edx
mov    %r15d,%ecx
mov    %r13,%r8
xor    %eax,%eax
call   1060 <reduceRhs@plt>
mov    %r14,%rdi
call   1030 <free@plt>
mov    0x18(%rsp),%rcx
add    $0x1,%r12d
cmp    %r12d,0x8(%rsp)
jne    11b0 <reduce+0x50>
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [4 x i8] c"row\00"
@.str.1 = [5 x i8] c".txt\00"
@.str.2 = [10 x i8] c"%s/%s%d%s\00"
define void @reduce(i32 %0, i32* %1, double* %2, i8* %3, double* %4, i32 %5, i32 %6) {
%8 = alloca i32
%9 = alloca i32*
%10 = alloca double*
%11 = alloca i8*
%12 = alloca double*
%13 = alloca i32
%14 = alloca i32
%15 = alloca i8*
%16 = alloca i8*
%17 = alloca i32
%18 = alloca i8*
store i32 %0, i32* %8
store i32* %1, i32** %9
store double* %2, double** %10
store i8* %3, i8** %11
store double* %4, double** %12
store i32 %5, i32* %13
store i32 %6, i32* %14
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8** %15
store i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0), i8** %16
%19 = load i32, i32* %13
store i32 %19, i32* %17
br label %20
20: ; preds = %58, %7
%21 = load i32, i32* %17
%22 = load i32, i32* %14
%23 = icmp slt i32 %21, %22
br i1 %23, label %24, label %61
24: ; preds = %20
%25 = load i8*, i8** %11
%26 = call i64 @strlen(i8* %25)
%27 = load i8*, i8** %15
%28 = call i64 @strlen(i8* %27)
%29 = add i64 %26, %28
%30 = load i8*, i8** %16
%31 = call i64 @strlen(i8* %30)
%32 = add i64 %29, %31
%33 = add i64 %32, 10
%34 = mul i64 1, %33
%35 = call i8* @malloc(i64 %34)
store i8* %35, i8** %18
%36 = load i8*, i8** %18
%37 = load i8*, i8** %11
%38 = load i8*, i8** %15
%39 = load i32, i32* %17
%40 = load i8*, i8** %16
%41 = call i32 (i8*, i8*, ...) @sprintf(i8* %36, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* %37, i8* %38, i32 %39, i8* %40)
%42 = load double*, double** %12
%43 = load i32, i32* %17
%44 = load i32, i32* %13
%45 = sub nsw i32 %43, %44
%46 = load i32, i32* %8
%47 = load i8*, i8** %18
%48 = call i32 (double*, i32, i32, i8*, ...) bitcast (i32 (...)* @setRowWithSparseVectorDouble to i32 (double*, i32, i32, i8*, ...)*)(double* %42, i32 %45, i32 %46, i8* %47)
%49 = load double*, double** %10
%50 = load double*, double** %12
%51 = load i32, i32* %17
%52 = load i32, i32* %13
%53 = sub nsw i32 %51, %52
%54 = load i32, i32* %8
%55 = load i32*, i32** %9
%56 = call i32 (double*, double*, i32, i32, i32*, ...) bitcast (i32 (...)* @reduceRhs to i32 (double*, double*, i32, i32, i32*, ...)*)(double* %49, double* %50, i32 %53, i32 %54, i32* %55)
%57 = load i8*, i8** %18
br label %58
58: ; preds = %24
%59 = load i32, i32* %17
%60 = add nsw i32 %59, 1
store i32 %60, i32* %17
br label %20
61: ; preds = %20
ret void
}

LLVM IR (-O2):
@.str = [4 x i8] c"row\00"
@.str.1 = [5 x i8] c".txt\00"
@.str.2 = [10 x i8] c"%s/%s%d%s\00"
define void @reduce(i32 %0, i32* %1, double* %2, i8* %3, double* %4, i32 %5, i32 %6) {
%8 = icmp slt i32 %5, %6
br i1 %8, label %9, label %20
9: ; preds = %7, %9
%10 = phi i32 [ %18, %9 ], [ %5, %7 ]
%11 = tail call i64 @strlen(i8* dereferenceable(1) %3)
%12 = add i64 %11, 17
%13 = tail call i8* @malloc(i64 %12)
%14 = tail call i32 (i8*, i8*, ...) @sprintf(i8* dereferenceable(1) %13, i8* dereferenceable(1) getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* %3, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %10, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0))
%15 = sub nsw i32 %10, %5
%16 = tail call i32 (double*, i32, i32, i8*, ...) bitcast (i32 (...)* @setRowWithSparseVectorDouble to i32 (double*, i32, i32, i8*, ...)*)(double* %4, i32 %15, i32 %0, i8* %13)
%17 = tail call i32 (double*, double*, i32, i32, i32*, ...) bitcast (i32 (...)* @reduceRhs to i32 (double*, double*, i32, i32, i32*, ...)*)(double* %2, double* %4, i32 %15, i32 %0, i32* %1)
tail call void @free(i8* %13)
%18 = add i32 %10, 1
%19 = icmp eq i32 %18, %6
br i1 %19, label %20, label %9
20: ; preds = %9, %7
ret void
}