Optimized macro codegen on simpler code.

This commit is contained in:
Christoffer Lerno
2021-11-18 00:02:44 +01:00
committed by Christoffer Lerno
parent 7b04e7cf85
commit bfde58b9a5
8 changed files with 283 additions and 314 deletions

View File

@@ -4509,6 +4509,14 @@ static inline void gencontext_emit_expression_list_expr(GenContext *context, BEV
static inline void llvm_emit_return_block(GenContext *context, BEValue *be_value, Type *type, Ast **stmts)
{
// First case - an empty block
unsigned count = vec_size(stmts);
if (!count)
{
llvm_value_set(be_value, NULL, type_void);
return;
}
Type *type_lowered = type_lowering(type);
LLVMValueRef old_ret_out = context->return_out;
LLVMBasicBlockRef saved_block_return_exit = context->block_return_exit;
@@ -4533,23 +4541,65 @@ static inline void llvm_emit_return_block(GenContext *context, BEValue *be_value
context->error_var = NULL;
context->catch_block = NULL;
VECEACH(stmts, i)
// Process all but the last statement.
for (unsigned i = 0; i < count - 1; i++)
{
llvm_emit_stmt(context, stmts[i]);
}
Ast *last_stmt = stmts[count - 1];
do
{
// Do we have more than one exit?
// Then follow the normal path.
if (!llvm_basic_block_is_unused(expr_block)) break;
// Do we have a void function? That's the only
// possible case if the last statement isn't return.
if (last_stmt->ast_kind != AST_RETURN_STMT) break;
// Defers? In that case we also use the default behaviour.
// We might optimize this later.
if (last_stmt->return_stmt.defer) break;
Expr *ret_expr = last_stmt->return_stmt.expr;
// If this is a void return, we can just skip here!
if (!ret_expr)
{
llvm_value_set(be_value, NULL, type_void);
goto DONE;
}
// Failable? Then we use the normal path
if (IS_FAILABLE(ret_expr)) break;
// Optimization, emit directly to value
llvm_emit_expr(context, be_value, ret_expr);
// And remove the alloca
LLVMInstructionRemoveFromParent(context->return_out);
goto DONE;
} while (0);
// Emit the last statement
llvm_emit_stmt(context, last_stmt);
// In the case of a void with no return, then this may be true.
if (llvm_basic_block_is_unused(expr_block))
{
// Skip the expr block.
assert(!context->return_out);
llvm_value_set(be_value, NULL, type_void);
goto DONE;
}
llvm_emit_br(context, expr_block);
// Emit the exit block.
llvm_emit_block(context, expr_block);
context->return_out = old_ret_out;
context->catch_block = error_block;
context->error_var = error_out;
context->block_return_exit = saved_block_return_exit;
context->block_failable_exit = saved_block_failable_exit;
context->block_error_var = saved_block_error;
context->in_block--;
if (return_out)
{
llvm_value_set_address(be_value, return_out, type_lowered);
@@ -4558,6 +4608,16 @@ static inline void llvm_emit_return_block(GenContext *context, BEValue *be_value
{
llvm_value_set(be_value, NULL, type_void);
}
DONE:
context->return_out = old_ret_out;
context->catch_block = error_block;
context->error_var = error_out;
context->block_return_exit = saved_block_return_exit;
context->block_failable_exit = saved_block_failable_exit;
context->block_error_var = saved_block_error;
context->in_block--;
}
static inline void llvm_emit_expr_block(GenContext *context, BEValue *be_value, Expr *expr)

View File

@@ -1 +1 @@
#define COMPILER_VERSION "PRE.3"
#define COMPILER_VERSION "PRE.4"

View File

@@ -17,50 +17,38 @@ fn void main()
// #expect: typeof_example.ll
%f = alloca float, align 4
%i = alloca i32, align 4
%value = alloca float, align 4
%blockret = alloca i32, align 4
%temp = alloca float, align 4
%result = alloca i32*, align 8
%f2 = alloca float, align 4
%value1 = alloca i32, align 4
%blockret2 = alloca float, align 4
%temp3 = alloca i32, align 4
%result4 = alloca float*, align 8
store float 1.000000e+02, float* %f, align 4
%0 = load float, float* %f, align 4
store float %0, float* %value, align 4
%1 = load float, float* %value, align 4
store float %1, float* %temp, align 4
%ptrptr = bitcast float* %temp to i32*
store i32* %ptrptr, i32** %result, align 8
%2 = load i32*, i32** %result, align 8
%3 = load i32, i32* %2, align 8
store i32 %3, i32* %blockret, align 4
br label %expr_block.exit
expr_block.exit:
%4 = load i32, i32* %blockret, align 4
store i32 %4, i32* %i, align 4
%5 = load i32, i32* %i, align 4
store i32 %5, i32* %value1, align 4
%6 = load i32, i32* %value1, align 4
store i32 %6, i32* %temp3, align 4
%ptrptr5 = bitcast i32* %temp3 to float*
store float* %ptrptr5, float** %result4, align 8
%7 = load float*, float** %result4, align 8
%8 = load float, float* %7, align 8
store float %8, float* %blockret2, align 4
br label %expr_block.exit6
expr_block.exit6:
%9 = load float, float* %blockret2, align 4
store float %9, float* %f2, align 4
%10 = load float, float* %f, align 4
%fpfpext = fpext float %10 to double
%11 = load i32, i32* %i, align 4
%12 = load float, float* %f2, align 4
%fpfpext7 = fpext float %12 to double
call void (i8*, ...) @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0), double %fpfpext, i32 %11, double %fpfpext7)
ret void
%f = alloca float, align 4
%i = alloca i32, align 4
%value = alloca float, align 4
%temp = alloca float, align 4
%result = alloca i32*, align 8
%f2 = alloca float, align 4
%value1 = alloca i32, align 4
%temp2 = alloca i32, align 4
%result3 = alloca float*, align 8
store float 1.000000e+02, float* %f, align 4
%0 = load float, float* %f, align 4
store float %0, float* %value, align 4
%1 = load float, float* %value, align 4
store float %1, float* %temp, align 4
%ptrptr = bitcast float* %temp to i32*
store i32* %ptrptr, i32** %result, align 8
%2 = load i32*, i32** %result, align 8
%3 = load i32, i32* %2, align 8
store i32 %3, i32* %i, align 4
%4 = load i32, i32* %i, align 4
store i32 %4, i32* %value1, align 4
%5 = load i32, i32* %value1, align 4
store i32 %5, i32* %temp2, align 4
%ptrptr4 = bitcast i32* %temp2 to float*
store float* %ptrptr4, float** %result3, align 8
%6 = load float*, float** %result3, align 8
%7 = load float, float* %6, align 8
store float %7, float* %f2, align 4
%8 = load float, float* %f, align 4
%fpfpext = fpext float %8 to double
%9 = load i32, i32* %i, align 4
%10 = load float, float* %f2, align 4
%fpfpext5 = fpext float %10 to double
call void (i8*, ...) @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0), double %fpfpext, i32 %9, double %fpfpext5)
ret void

View File

@@ -39,7 +39,6 @@ entry:
%b = alloca i32, align 4
%a1 = alloca i32 (i32)*, align 8
%b2 = alloca i32, align 4
%blockret = alloca i32, align 4
store i32 2, i32* %a, align 4
store i32 3, i32* %b, align 4
store i32 (i32)* @example.square, i32 (i32)** %a1, align 8
@@ -47,14 +46,9 @@ entry:
%0 = load i32 (i32)*, i32 (i32)** %a1, align 8
%1 = load i32, i32* %b2, align 4
%2 = call i32 %0(i32 %1)
store i32 %2, i32* %blockret, align 4
br label %expr_block.exit
expr_block.exit: ; preds = %entry
%3 = load i32, i32* %blockret, align 4
%4 = load i32, i32* %a, align 4
%add = add i32 %3, %4
%5 = load i32, i32* %b, align 4
%add3 = add i32 %add, %5
%3 = load i32, i32* %a, align 4
%add = add i32 %2, %3
%4 = load i32, i32* %b, align 4
%add3 = add i32 %add, %4
ret i32 %add3
}

View File

@@ -83,20 +83,17 @@ define void @main()
%6 = load i32, i32* %x, align 4
%7 = load i32, i32* %dy, align 4
%8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i32 0, i32 0), i32 %6, i32 %7)
br label %expr_block.exit
expr_block.exit:
store i32 10, i32* %times, align 4
store i32 0, i32* %i, align 4
br label %for.cond
for.cond:
for.cond: ; preds = %for.inc, %entry
%9 = load i32, i32* %i, align 4
%10 = load i32, i32* %times, align 4
%lt = icmp slt i32 %9, %10
br i1 %lt, label %for.body, label %for.exit
for.body:
for.body: ; preds = %for.cond
%11 = load i32, i32* %i, align 4
%add = add i32 %11, 1
store i32 %add, i32* %loop, align 4
@@ -104,14 +101,12 @@ for.body:
%13 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.1, i32 0, i32 0), i32 %12)
br label %for.inc
for.inc:
for.inc: ; preds = %for.body
%14 = load i32, i32* %i, align 4
%add1 = add i32 %14, 1
store i32 %add1, i32* %i, align 4
br label %for.cond
for.exit:
br label %expr_block.exit2
expr_block.exit2:
for.exit: ; preds = %for.cond
ret void
}

View File

@@ -19,48 +19,24 @@ fn void test()
/* #expect: type_params.ll
%x = alloca i32, align 4
%blockret = alloca i32, align 4
%a = alloca i32, align 4
%d = alloca double, align 8
%blockret1 = alloca double, align 8
%a2 = alloca double, align 8
%a1 = alloca double, align 8
%d2 = alloca double, align 8
%blockret4 = alloca double, align 8
%a5 = alloca double, align 8
%a2 = alloca double, align 8
%z = alloca i16, align 2
%blockret7 = alloca i16, align 2
%a8 = alloca i16, align 2
%a3 = alloca i16, align 2
store i32 0, i32* %a, align 4
%0 = load i32, i32* %a, align 4
store i32 %0, i32* %blockret, align 4
br label %expr_block.exit
expr_block.exit: ; preds = %entry
%1 = load i32, i32* %blockret, align 4
store i32 %1, i32* %x, align 4
store i32 %0, i32* %x, align 4
store double 0.000000e+00, double* %a1, align 8
%1 = load double, double* %a1, align 8
store double %1, double* %d, align 8
store double 0.000000e+00, double* %a2, align 8
%2 = load double, double* %a2, align 8
store double %2, double* %blockret1, align 8
br label %expr_block.exit3
expr_block.exit3: ; preds = %expr_block.exit
%3 = load double, double* %blockret1, align 8
store double %3, double* %d, align 8
store double 0.000000e+00, double* %a5, align 8
%4 = load double, double* %a5, align 8
store double %4, double* %blockret4, align 8
br label %expr_block.exit6
expr_block.exit6: ; preds = %expr_block.exit3
%5 = load double, double* %blockret4, align 8
store double %5, double* %d2, align 8
store i16 0, i16* %a8, align 2
%6 = load i16, i16* %a8, align 2
store i16 %6, i16* %blockret7, align 2
br label %expr_block.exit9
expr_block.exit9: ; preds = %expr_block.exit6
%7 = load i16, i16* %blockret7, align 2
store i16 %7, i16* %z, align 2
store double %2, double* %d2, align 8
store i16 0, i16* %a3, align 2
%3 = load i16, i16* %a3, align 2
store i16 %3, i16* %z, align 2
ret void
}

View File

@@ -87,7 +87,6 @@ entry:
%x = alloca i16, align 2
%z = alloca %Foo, align 2
%expr = alloca %Foo, align 2
%blockret = alloca i64, align 8
%x1 = alloca i64, align 8
%b = alloca i16*, align 8
%to = alloca i16*, align 8
@@ -131,12 +130,7 @@ for.inc: ; preds = %for.body
for.exit: ; preds = %for.cond
%12 = load i64, i64* %x1, align 8
store i64 %12, i64* %blockret, align 8
br label %expr_block.exit
expr_block.exit: ; preds = %for.exit
%13 = load i64, i64* %blockret, align 8
ret i64 %13
ret i64 %12
}
; Function Attrs: nounwind
@@ -144,7 +138,6 @@ define i32 @userland_bitcast.test(float %0) #0 {
entry:
%x = alloca float, align 4
%expr = alloca float, align 4
%blockret = alloca [4 x i8], align 1
%x1 = alloca [4 x i8], align 1
%b = alloca i8*, align 8
%to = alloca i8*, align 8
@@ -183,17 +176,11 @@ for.inc: ; preds = %for.body
br label %for.cond
for.exit: ; preds = %for.cond
%9 = bitcast [4 x i8]* %blockret to i8*
%9 = bitcast i32* %tempcoerce to i8*
%10 = bitcast [4 x i8]* %x1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %9, i8* align 1 %10, i32 4, i1 false)
br label %expr_block.exit
expr_block.exit: ; preds = %for.exit
%11 = bitcast i32* %tempcoerce to i8*
%12 = bitcast [4 x i8]* %blockret to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %11, i8* align 1 %12, i32 4, i1 false)
%13 = load i32, i32* %tempcoerce, align 4
ret i32 %13
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %9, i8* align 1 %10, i32 4, i1 false)
%11 = load i32, i32* %tempcoerce, align 4
ret i32 %11
}
; Function Attrs: nounwind
@@ -202,33 +189,29 @@ entry:
%f = alloca float, align 4
%i = alloca i32, align 4
%expr = alloca float, align 4
%blockret = alloca i32, align 4
%x = alloca i32, align 4
%b = alloca i32*, align 8
%to = alloca i32*, align 8
%i1 = alloca i64, align 8
%f2 = alloca float, align 4
%expr3 = alloca i32, align 4
%blockret4 = alloca float, align 4
%x5 = alloca float, align 4
%b6 = alloca i32*, align 8
%to7 = alloca i32*, align 8
%i9 = alloca i64, align 8
%x4 = alloca float, align 4
%b5 = alloca i32*, align 8
%to6 = alloca i32*, align 8
%i8 = alloca i64, align 8
%d = alloca double, align 8
%l = alloca i64, align 8
%expr20 = alloca double, align 8
%blockret21 = alloca i64, align 8
%x22 = alloca i64, align 8
%b23 = alloca i64*, align 8
%to25 = alloca i64*, align 8
%i26 = alloca i64, align 8
%expr18 = alloca double, align 8
%x19 = alloca i64, align 8
%b20 = alloca i64*, align 8
%to22 = alloca i64*, align 8
%i23 = alloca i64, align 8
%d2 = alloca double, align 8
%expr36 = alloca double, align 8
%blockret37 = alloca double, align 8
%x38 = alloca double, align 8
%b39 = alloca i64*, align 8
%to41 = alloca i64*, align 8
%i43 = alloca i64, align 8
%expr32 = alloca double, align 8
%x33 = alloca double, align 8
%b34 = alloca i64*, align 8
%to36 = alloca i64*, align 8
%i38 = alloca i64, align 8
store float 0x4028B4BC60000000, float* %f, align 4
%0 = load float, float* %f, align 4
store float %0, float* %expr, align 4
@@ -262,137 +245,117 @@ for.inc: ; preds = %for.body
for.exit: ; preds = %for.cond
%8 = load i32, i32* %x, align 4
store i32 %8, i32* %blockret, align 4
br label %expr_block.exit
store i32 %8, i32* %i, align 4
%9 = load i32, i32* %i, align 4
store i32 %9, i32* %expr3, align 4
store i32* %expr3, i32** %b5, align 8
%ptrptr7 = bitcast float* %x4 to i32*
store i32* %ptrptr7, i32** %to6, align 8
store i64 0, i64* %i8, align 8
br label %for.cond9
expr_block.exit: ; preds = %for.exit
%9 = load i32, i32* %blockret, align 4
store i32 %9, i32* %i, align 4
%10 = load i32, i32* %i, align 4
store i32 %10, i32* %expr3, align 4
store i32* %expr3, i32** %b6, align 8
%ptrptr8 = bitcast float* %x5 to i32*
store i32* %ptrptr8, i32** %to7, align 8
store i64 0, i64* %i9, align 8
br label %for.cond10
for.cond9: ; preds = %for.inc14, %for.exit
%10 = load i64, i64* %i8, align 8
%lt10 = icmp ult i64 %10, 4
br i1 %lt10, label %for.body11, label %for.exit16
for.cond10: ; preds = %for.inc15, %expr_block.exit
%11 = load i64, i64* %i9, align 8
%lt11 = icmp ult i64 %11, 4
br i1 %lt11, label %for.body12, label %for.exit17
for.body11: ; preds = %for.cond9
%11 = load i32*, i32** %to6, align 8
%12 = load i64, i64* %i8, align 8
%ptroffset12 = getelementptr inbounds i32, i32* %11, i64 %12
%13 = load i32*, i32** %b5, align 8
%14 = load i64, i64* %i8, align 8
%ptroffset13 = getelementptr inbounds i32, i32* %13, i64 %14
%15 = load i32, i32* %ptroffset13, align 4
store i32 %15, i32* %ptroffset12, align 4
br label %for.inc14
for.body12: ; preds = %for.cond10
%12 = load i32*, i32** %to7, align 8
%13 = load i64, i64* %i9, align 8
%ptroffset13 = getelementptr inbounds i32, i32* %12, i64 %13
%14 = load i32*, i32** %b6, align 8
%15 = load i64, i64* %i9, align 8
%ptroffset14 = getelementptr inbounds i32, i32* %14, i64 %15
%16 = load i32, i32* %ptroffset14, align 4
store i32 %16, i32* %ptroffset13, align 4
br label %for.inc15
for.inc14: ; preds = %for.body11
%16 = load i64, i64* %i8, align 8
%add15 = add i64 %16, 4
store i64 %add15, i64* %i8, align 8
br label %for.cond9
for.inc15: ; preds = %for.body12
%17 = load i64, i64* %i9, align 8
%add16 = add i64 %17, 4
store i64 %add16, i64* %i9, align 8
br label %for.cond10
for.exit17: ; preds = %for.cond10
%18 = load float, float* %x5, align 4
store float %18, float* %blockret4, align 4
br label %expr_block.exit18
expr_block.exit18: ; preds = %for.exit17
%19 = load float, float* %blockret4, align 4
store float %19, float* %f2, align 4
%20 = load float, float* %f, align 4
%fpfpext = fpext float %20 to double
%21 = load i32, i32* %i, align 4
%22 = load float, float* %f2, align 4
%fpfpext19 = fpext float %22 to double
call void (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i32 0, i32 0), double %fpfpext, i32 %21, double %fpfpext19)
for.exit16: ; preds = %for.cond9
%17 = load float, float* %x4, align 4
store float %17, float* %f2, align 4
%18 = load float, float* %f, align 4
%fpfpext = fpext float %18 to double
%19 = load i32, i32* %i, align 4
%20 = load float, float* %f2, align 4
%fpfpext17 = fpext float %20 to double
call void (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i32 0, i32 0), double %fpfpext, i32 %19, double %fpfpext17)
store double 1.235300e+268, double* %d, align 8
%23 = load double, double* %d, align 8
store double %23, double* %expr20, align 8
%ptrptr24 = bitcast double* %expr20 to i64*
store i64* %ptrptr24, i64** %b23, align 8
store i64* %x22, i64** %to25, align 8
store i64 0, i64* %i26, align 8
br label %for.cond27
%21 = load double, double* %d, align 8
store double %21, double* %expr18, align 8
%ptrptr21 = bitcast double* %expr18 to i64*
store i64* %ptrptr21, i64** %b20, align 8
store i64* %x19, i64** %to22, align 8
store i64 0, i64* %i23, align 8
br label %for.cond24
for.cond27: ; preds = %for.inc32, %expr_block.exit18
%24 = load i64, i64* %i26, align 8
%lt28 = icmp ult i64 %24, 8
br i1 %lt28, label %for.body29, label %for.exit34
for.cond24: ; preds = %for.inc29, %for.exit16
%22 = load i64, i64* %i23, align 8
%lt25 = icmp ult i64 %22, 8
br i1 %lt25, label %for.body26, label %for.exit31
for.body29: ; preds = %for.cond27
%25 = load i64*, i64** %to25, align 8
%26 = load i64, i64* %i26, align 8
%ptroffset30 = getelementptr inbounds i64, i64* %25, i64 %26
%27 = load i64*, i64** %b23, align 8
%28 = load i64, i64* %i26, align 8
%ptroffset31 = getelementptr inbounds i64, i64* %27, i64 %28
%29 = load i64, i64* %ptroffset31, align 8
store i64 %29, i64* %ptroffset30, align 8
br label %for.inc32
for.body26: ; preds = %for.cond24
%23 = load i64*, i64** %to22, align 8
%24 = load i64, i64* %i23, align 8
%ptroffset27 = getelementptr inbounds i64, i64* %23, i64 %24
%25 = load i64*, i64** %b20, align 8
%26 = load i64, i64* %i23, align 8
%ptroffset28 = getelementptr inbounds i64, i64* %25, i64 %26
%27 = load i64, i64* %ptroffset28, align 8
store i64 %27, i64* %ptroffset27, align 8
br label %for.inc29
for.inc32: ; preds = %for.body29
%30 = load i64, i64* %i26, align 8
%add33 = add i64 %30, 8
store i64 %add33, i64* %i26, align 8
br label %for.cond27
for.inc29: ; preds = %for.body26
%28 = load i64, i64* %i23, align 8
%add30 = add i64 %28, 8
store i64 %add30, i64* %i23, align 8
br label %for.cond24
for.exit34: ; preds = %for.cond27
%31 = load i64, i64* %x22, align 8
store i64 %31, i64* %blockret21, align 8
br label %expr_block.exit35
for.exit31: ; preds = %for.cond24
%29 = load i64, i64* %x19, align 8
store i64 %29, i64* %l, align 8
%30 = load double, double* %d, align 8
store double %30, double* %expr32, align 8
%ptrptr35 = bitcast double* %expr32 to i64*
store i64* %ptrptr35, i64** %b34, align 8
%ptrptr37 = bitcast double* %x33 to i64*
store i64* %ptrptr37, i64** %to36, align 8
store i64 0, i64* %i38, align 8
br label %for.cond39
expr_block.exit35: ; preds = %for.exit34
%32 = load i64, i64* %blockret21, align 8
store i64 %32, i64* %l, align 8
%33 = load double, double* %d, align 8
store double %33, double* %expr36, align 8
%ptrptr40 = bitcast double* %expr36 to i64*
store i64* %ptrptr40, i64** %b39, align 8
%ptrptr42 = bitcast double* %x38 to i64*
store i64* %ptrptr42, i64** %to41, align 8
store i64 0, i64* %i43, align 8
br label %for.cond44
for.cond39: ; preds = %for.inc44, %for.exit31
%31 = load i64, i64* %i38, align 8
%lt40 = icmp ult i64 %31, 8
br i1 %lt40, label %for.body41, label %for.exit46
for.cond44: ; preds = %for.inc49, %expr_block.exit35
%34 = load i64, i64* %i43, align 8
%lt45 = icmp ult i64 %34, 8
br i1 %lt45, label %for.body46, label %for.exit51
for.body41: ; preds = %for.cond39
%32 = load i64*, i64** %to36, align 8
%33 = load i64, i64* %i38, align 8
%ptroffset42 = getelementptr inbounds i64, i64* %32, i64 %33
%34 = load i64*, i64** %b34, align 8
%35 = load i64, i64* %i38, align 8
%ptroffset43 = getelementptr inbounds i64, i64* %34, i64 %35
%36 = load i64, i64* %ptroffset43, align 8
store i64 %36, i64* %ptroffset42, align 8
br label %for.inc44
for.body46: ; preds = %for.cond44
%35 = load i64*, i64** %to41, align 8
%36 = load i64, i64* %i43, align 8
%ptroffset47 = getelementptr inbounds i64, i64* %35, i64 %36
%37 = load i64*, i64** %b39, align 8
%38 = load i64, i64* %i43, align 8
%ptroffset48 = getelementptr inbounds i64, i64* %37, i64 %38
%39 = load i64, i64* %ptroffset48, align 8
store i64 %39, i64* %ptroffset47, align 8
br label %for.inc49
for.inc44: ; preds = %for.body41
%37 = load i64, i64* %i38, align 8
%add45 = add i64 %37, 8
store i64 %add45, i64* %i38, align 8
br label %for.cond39
for.inc49: ; preds = %for.body46
%40 = load i64, i64* %i43, align 8
%add50 = add i64 %40, 8
store i64 %add50, i64* %i43, align 8
br label %for.cond44
for.exit51: ; preds = %for.cond44
%41 = load double, double* %x38, align 8
store double %41, double* %blockret37, align 8
br label %expr_block.exit52
expr_block.exit52: ; preds = %for.exit51
%42 = load double, double* %blockret37, align 8
store double %42, double* %d2, align 8
%43 = load double, double* %d, align 8
%44 = load i64, i64* %l, align 8
%45 = load double, double* %d2, align 8
call void (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.1, i32 0, i32 0), double %43, i64 %44, double %45)
for.exit46: ; preds = %for.cond39
%38 = load double, double* %x33, align 8
store double %38, double* %d2, align 8
%39 = load double, double* %d, align 8
%40 = load i64, i64* %l, align 8
%41 = load double, double* %d2, align 8
call void (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.1, i32 0, i32 0), double %39, i64 %40, double %41)
ret void
}

View File

@@ -45,11 +45,10 @@ entry:
%f = alloca i32, align 4
%.iterator = alloca %FooIterator, align 8
%f1 = alloca %Foo*, align 8
%blockret = alloca %FooIterator, align 8
%literal = alloca %FooIterator, align 8
%it = alloca %FooIterator*, align 8
%value = alloca i32*, align 8
%blockret2 = alloca i8, align 1
%blockret = alloca i8, align 1
%0 = bitcast [3 x i32]* %i to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast ([3 x i32]* @.__const to i8*), i32 12, i1 false)
%1 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
@@ -64,68 +63,62 @@ entry:
%6 = getelementptr inbounds %FooIterator, %FooIterator* %literal, i32 0, i32 1
%7 = load %Foo*, %Foo** %f1, align 8
store %Foo* %7, %Foo** %6, align 8
%8 = bitcast %FooIterator* %blockret to i8*
%8 = bitcast %FooIterator* %.iterator to i8*
%9 = bitcast %FooIterator* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %8, i8* align 8 %9, i32 16, i1 false)
br label %expr_block.exit
expr_block.exit: ; preds = %entry
%10 = bitcast %FooIterator* %.iterator to i8*
%11 = bitcast %FooIterator* %blockret to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %10, i8* align 8 %11, i32 16, i1 false)
br label %for.cond
for.cond: ; preds = %expr_block.exit
for.cond: ; preds = %entry
store %FooIterator* %.iterator, %FooIterator** %it, align 8
store i32* %f, i32** %value, align 8
%12 = load %FooIterator*, %FooIterator** %it, align 8
%13 = getelementptr inbounds %FooIterator, %FooIterator* %12, i32 0, i32 0
%14 = load i64, i64* %13, align 8
%15 = load %FooIterator*, %FooIterator** %it, align 8
%16 = getelementptr inbounds %FooIterator, %FooIterator* %15, i32 0, i32 1
%17 = load %Foo*, %Foo** %16, align 8
%18 = getelementptr inbounds %Foo, %Foo* %17, i32 0, i32 0
%19 = getelementptr inbounds %"int[]", %"int[]"* %18, i32 0, i32 1
%20 = load i64, i64* %19, align 8
%eq = icmp eq i64 %14, %20
%10 = load %FooIterator*, %FooIterator** %it, align 8
%11 = getelementptr inbounds %FooIterator, %FooIterator* %10, i32 0, i32 0
%12 = load i64, i64* %11, align 8
%13 = load %FooIterator*, %FooIterator** %it, align 8
%14 = getelementptr inbounds %FooIterator, %FooIterator* %13, i32 0, i32 1
%15 = load %Foo*, %Foo** %14, align 8
%16 = getelementptr inbounds %Foo, %Foo* %15, i32 0, i32 0
%17 = getelementptr inbounds %"int[]", %"int[]"* %16, i32 0, i32 1
%18 = load i64, i64* %17, align 8
%eq = icmp eq i64 %12, %18
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %for.cond
store i8 0, i8* %blockret2, align 1
br label %expr_block.exit3
store i8 0, i8* %blockret, align 1
br label %expr_block.exit
if.exit: ; preds = %for.cond
%21 = load i32*, i32** %value, align 8
%22 = load %FooIterator*, %FooIterator** %it, align 8
%23 = getelementptr inbounds %FooIterator, %FooIterator* %22, i32 0, i32 1
%24 = load %Foo*, %Foo** %23, align 8
%25 = getelementptr inbounds %Foo, %Foo* %24, i32 0, i32 0
%26 = getelementptr inbounds %"int[]", %"int[]"* %25, i32 0, i32 0
%27 = load i32*, i32** %26, align 8
%28 = load %FooIterator*, %FooIterator** %it, align 8
%29 = getelementptr inbounds %FooIterator, %FooIterator* %28, i32 0, i32 0
%30 = load i64, i64* %29, align 8
%add = add i64 %30, 1
store i64 %add, i64* %29, align 8
%ptroffset = getelementptr inbounds i32, i32* %27, i64 %30
%31 = load i32, i32* %ptroffset, align 4
store i32 %31, i32* %21, align 8
store i8 1, i8* %blockret2, align 1
br label %expr_block.exit3
%19 = load i32*, i32** %value, align 8
%20 = load %FooIterator*, %FooIterator** %it, align 8
%21 = getelementptr inbounds %FooIterator, %FooIterator* %20, i32 0, i32 1
%22 = load %Foo*, %Foo** %21, align 8
%23 = getelementptr inbounds %Foo, %Foo* %22, i32 0, i32 0
%24 = getelementptr inbounds %"int[]", %"int[]"* %23, i32 0, i32 0
%25 = load i32*, i32** %24, align 8
%26 = load %FooIterator*, %FooIterator** %it, align 8
%27 = getelementptr inbounds %FooIterator, %FooIterator* %26, i32 0, i32 0
%28 = load i64, i64* %27, align 8
%add = add i64 %28, 1
store i64 %add, i64* %27, align 8
%ptroffset = getelementptr inbounds i32, i32* %25, i64 %28
%29 = load i32, i32* %ptroffset, align 4
store i32 %29, i32* %19, align 8
store i8 1, i8* %blockret, align 1
br label %expr_block.exit
expr_block.exit3: ; preds = %if.exit, %if.then
%32 = load i8, i8* %blockret2, align 1
%33 = trunc i8 %32 to i1
br i1 %33, label %for.body, label %for.exit
expr_block.exit: ; preds = %if.exit, %if.then
%30 = load i8, i8* %blockret, align 1
%31 = trunc i8 %30 to i1
br i1 %31, label %for.body, label %for.exit
for.body: ; preds = %expr_block.exit3
%34 = load i32, i32* %f, align 4
%35 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %34)
for.body: ; preds = %expr_block.exit
%32 = load i32, i32* %f, align 4
%33 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %32)
br label %while.begin
while.begin: ; preds = %for.body
br label %for.exit
for.exit: ; preds = %while.begin, %expr_block.exit3
for.exit: ; preds = %while.begin, %expr_block.exit
ret void
}