authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-30 16:59:31-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-30 16:59:31-04:00
logba3d21ca67af0ce47841bc2d0258903ccaf89a75
tree36947cb623508014b1215ee2f986580c8f575732
parent588d2862d90b65b7227975ecd3c8dfdaabbdefc6

better divTrunc codegen

branch and phi instead of select instruction fixes division test for windows. See #302

3 files changed, 29 insertions(+), 5 deletions(-)

src/all_types.hpp+1
...@@ -1510,6 +1510,7 @@ struct CodeGen {...@@ -1510,6 +1510,7 @@ struct CodeGen {
1510 size_t version_patch;1510 size_t version_patch;
1511 bool verbose;1511 bool verbose;
1512 bool verbose_link;1512 bool verbose_link;
1513 bool verbose_ir;
1513 ErrColor err_color;1514 ErrColor err_color;
1514 ImportTableEntry *root_import;1515 ImportTableEntry *root_import;
1515 ImportTableEntry *bootstrap_import;1516 ImportTableEntry *bootstrap_import;
src/codegen.cpp+23-5
...@@ -1343,10 +1343,28 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m...@@ -1343,10 +1343,28 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
1343 return result;1343 return result;
1344 case DivKindTrunc:1344 case DivKindTrunc:
1345 {1345 {
1346 LLVMValueRef floored = gen_floor(g, result, type_entry);1346 LLVMBasicBlockRef ltz_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncLTZero");
1347 LLVMValueRef ceiled = gen_ceil(g, result, type_entry);1347 LLVMBasicBlockRef gez_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncGEZero");
1348 LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncEnd");
1348 LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, "");1349 LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, "");
1349 return LLVMBuildSelect(g->builder, ltz, ceiled, floored, "");1350 LLVMBuildCondBr(g->builder, ltz, ltz_block, gez_block);
1351
1352 LLVMPositionBuilderAtEnd(g->builder, ltz_block);
1353 LLVMValueRef ceiled = gen_ceil(g, result, type_entry);
1354 LLVMBasicBlockRef ceiled_end_block = LLVMGetInsertBlock(g->builder);
1355 LLVMBuildBr(g->builder, end_block);
1356
1357 LLVMPositionBuilderAtEnd(g->builder, gez_block);
1358 LLVMValueRef floored = gen_floor(g, result, type_entry);
1359 LLVMBasicBlockRef floored_end_block = LLVMGetInsertBlock(g->builder);
1360 LLVMBuildBr(g->builder, end_block);
1361
1362 LLVMPositionBuilderAtEnd(g->builder, end_block);
1363 LLVMValueRef phi = LLVMBuildPhi(g->builder, type_entry->type_ref, "");
1364 LLVMValueRef incoming_values[] = { ceiled, floored };
1365 LLVMBasicBlockRef incoming_blocks[] = { ceiled_end_block, floored_end_block };
1366 LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
1367 return phi;
1350 }1368 }
1351 case DivKindFloor:1369 case DivKindFloor:
1352 return gen_floor(g, result, type_entry);1370 return gen_floor(g, result, type_entry);
...@@ -4080,7 +4098,7 @@ static void validate_inline_fns(CodeGen *g) {...@@ -4080,7 +4098,7 @@ static void validate_inline_fns(CodeGen *g) {
4080}4098}
40814099
4082static void do_code_gen(CodeGen *g) {4100static void do_code_gen(CodeGen *g) {
4083 if (g->verbose) {4101 if (g->verbose || g->verbose_ir) {
4084 fprintf(stderr, "\nCode Generation:\n");4102 fprintf(stderr, "\nCode Generation:\n");
4085 fprintf(stderr, "------------------\n");4103 fprintf(stderr, "------------------\n");
4086 }4104 }
...@@ -4358,7 +4376,7 @@ static void do_code_gen(CodeGen *g) {...@@ -4358,7 +4376,7 @@ static void do_code_gen(CodeGen *g) {
43584376
4359 ZigLLVMDIBuilderFinalize(g->dbuilder);4377 ZigLLVMDIBuilderFinalize(g->dbuilder);
43604378
4361 if (g->verbose) {4379 if (g->verbose || g->verbose_ir) {
4362 LLVMDumpModule(g->module);4380 LLVMDumpModule(g->module);
4363 }4381 }
43644382
src/main.cpp+5
...@@ -48,6 +48,7 @@ static int usage(const char *arg0) {...@@ -48,6 +48,7 @@ static int usage(const char *arg0) {
48 " --target-os [name] specify target operating system\n"48 " --target-os [name] specify target operating system\n"
49 " --verbose turn on compiler debug output\n"49 " --verbose turn on compiler debug output\n"
50 " --verbose-link turn on compiler debug output for linking only\n"50 " --verbose-link turn on compiler debug output for linking only\n"
51 " --verbose-ir turn on compiler debug output for IR only\n"
51 " --zig-std-dir [path] directory where zig standard library resides\n"52 " --zig-std-dir [path] directory where zig standard library resides\n"
52 " -dirafter [dir] same as -isystem but do it last\n"53 " -dirafter [dir] same as -isystem but do it last\n"
53 " -isystem [dir] add additional search path for other .h files\n"54 " -isystem [dir] add additional search path for other .h files\n"
...@@ -186,6 +187,7 @@ int main(int argc, char **argv) {...@@ -186,6 +187,7 @@ int main(int argc, char **argv) {
186 const char *out_name = nullptr;187 const char *out_name = nullptr;
187 bool verbose = false;188 bool verbose = false;
188 bool verbose_link = false;189 bool verbose_link = false;
190 bool verbose_ir = false;
189 ErrColor color = ErrColorAuto;191 ErrColor color = ErrColorAuto;
190 const char *libc_lib_dir = nullptr;192 const char *libc_lib_dir = nullptr;
191 const char *libc_static_lib_dir = nullptr;193 const char *libc_static_lib_dir = nullptr;
...@@ -352,6 +354,8 @@ int main(int argc, char **argv) {...@@ -352,6 +354,8 @@ int main(int argc, char **argv) {
352 verbose = true;354 verbose = true;
353 } else if (strcmp(arg, "--verbose-link") == 0) {355 } else if (strcmp(arg, "--verbose-link") == 0) {
354 verbose_link = true;356 verbose_link = true;
357 } else if (strcmp(arg, "--verbose-ir") == 0) {
358 verbose_ir = true;
355 } else if (strcmp(arg, "-mwindows") == 0) {359 } else if (strcmp(arg, "-mwindows") == 0) {
356 mwindows = true;360 mwindows = true;
357 } else if (strcmp(arg, "-mconsole") == 0) {361 } else if (strcmp(arg, "-mconsole") == 0) {
...@@ -630,6 +634,7 @@ int main(int argc, char **argv) {...@@ -630,6 +634,7 @@ int main(int argc, char **argv) {
630 codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));634 codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));
631 codegen_set_verbose(g, verbose);635 codegen_set_verbose(g, verbose);
632 g->verbose_link = verbose_link;636 g->verbose_link = verbose_link;
637 g->verbose_ir = verbose_ir;
633 codegen_set_errmsg_color(g, color);638 codegen_set_errmsg_color(g, color);
634639
635 for (size_t i = 0; i < lib_dirs.length; i += 1) {640 for (size_t i = 0; i < lib_dirs.length; i += 1) {