Browse Source

Add `-microarch:<string>` (e.g. `-microarch:native`)

gingerBill 4 years ago
parent
commit
0be6ddc7e2
5 changed files with 67 additions and 9 deletions
  1. 7 0
      core/os/file_windows.odin
  2. 27 5
      src/build_settings.cpp
  3. 16 1
      src/llvm_backend.cpp
  4. 11 3
      src/main.cpp
  5. 6 0
      src/string.cpp

+ 7 - 0
core/os/file_windows.odin

@@ -64,6 +64,13 @@ close :: proc(fd: Handle) -> Errno {
 	return ERROR_NONE;
 }
 
+flush :: proc(fd: Handle) -> (err: Errno) {
+	if !win32.FlushFileBuffers(win32.HANDLE(fd)) {
+		err = Errno(win32.GetLastError());
+	}
+	return;
+}
+
 
 
 write :: proc(fd: Handle, data: []byte) -> (int, Errno) {

+ 27 - 5
src/build_settings.cpp

@@ -137,6 +137,7 @@ struct BuildContext {
 	String llc_flags;
 	String link_flags;
 	String extra_linker_flags;
+	String microarch;
 	BuildModeKind build_mode;
 	bool   generate_docs;
 	i32    optimization_level;
@@ -706,7 +707,9 @@ void init_build_context(TargetMetrics *cross_target) {
 	// across OSs. It doesn't make sense to allocate extra data on the heap
 	// here, so I just #defined the linker flags to keep things concise.
 	if (bc->metrics.arch == TargetArch_amd64) {
-		llc_flags = gb_string_appendc(llc_flags, "-march=x86-64 ");
+		if (bc->microarch.len == 0) {
+			llc_flags = gb_string_appendc(llc_flags, "-march=x86-64 ");
+		}
 
 		switch (bc->metrics.os) {
 		case TargetOs_windows:
@@ -718,11 +721,13 @@ void init_build_context(TargetMetrics *cross_target) {
 			bc->link_flags = str_lit("-arch x86-64 ");
 			break;
 		case TargetOs_freebsd:
-			bc->link_flags = str_lit("-arch x86-64");
+			bc->link_flags = str_lit("-arch x86-64 ");
 			break;
 		}
 	} else if (bc->metrics.arch == TargetArch_386) {
-		llc_flags = gb_string_appendc(llc_flags, "-march=x86 ");
+		if (bc->microarch.len == 0) {
+			llc_flags = gb_string_appendc(llc_flags, "-march=x86 ");
+		}
 
 		switch (bc->metrics.os) {
 		case TargetOs_windows:
@@ -736,7 +741,7 @@ void init_build_context(TargetMetrics *cross_target) {
 			bc->link_flags = str_lit("-arch x86 ");
 			break;
 		case TargetOs_freebsd:
-			bc->link_flags = str_lit("-arch x86");
+			bc->link_flags = str_lit("-arch x86 ");
 			break;
 		}
 	} else if (bc->metrics.arch == TargetArch_wasm32) {
@@ -745,11 +750,25 @@ void init_build_context(TargetMetrics *cross_target) {
 		gb_printf_err("Compiler Error: Unsupported architecture\n");;
 		gb_exit(1);
 	}
+	llc_flags = gb_string_appendc(llc_flags, " ");
 
 
 	bc->optimization_level = gb_clamp(bc->optimization_level, 0, 3);
 
 	gbString opt_flags = gb_string_make_reserve(heap_allocator(), 64);
+
+
+	if (bc->microarch.len != 0) {
+		opt_flags = gb_string_appendc(opt_flags, "-march=");
+		opt_flags = gb_string_append_length(opt_flags, bc->microarch.text, bc->microarch.len);
+		opt_flags = gb_string_appendc(opt_flags, " ");
+
+		// llc_flags = gb_string_appendc(opt_flags, "-march=");
+		// llc_flags = gb_string_append_length(llc_flags, bc->microarch.text, bc->microarch.len);
+		// llc_flags = gb_string_appendc(llc_flags, " ");
+	}
+
+
 	if (bc->optimization_level != 0) {
 		opt_flags = gb_string_append_fmt(opt_flags, "-O%d ", bc->optimization_level);
 		// NOTE(lachsinc): The following options were previously passed during call
@@ -761,7 +780,9 @@ void init_build_context(TargetMetrics *cross_target) {
 		opt_flags = gb_string_appendc(opt_flags, "-mem2reg -memcpyopt -die ");
 	}
 
-	bc->llc_flags = make_string_c(llc_flags);
+
+
+
 
 
 	// NOTE(lachsinc): This optimization option was previously required to get
@@ -772,6 +793,7 @@ void init_build_context(TargetMetrics *cross_target) {
 	// }
 
 	bc->opt_flags = make_string_c(opt_flags);
+	bc->llc_flags = make_string_c(llc_flags);
 
 
 	#undef LINK_FLAG_X64

+ 16 - 1
src/llvm_backend.cpp

@@ -11858,7 +11858,21 @@ void lb_generate_code(lbGenerator *gen) {
 		code_mode = LLVMCodeModelJITDefault;
 	}
 
-	LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(target, target_triple, "generic", "", LLVMCodeGenLevelNone, LLVMRelocDefault, code_mode);
+	char const *host_cpu_name = LLVMGetHostCPUName();
+	char const *llvm_cpu = "generic";
+	char const *llvm_features = "";
+	if (build_context.microarch.len != 0) {
+		if (build_context.microarch == "native") {
+			llvm_cpu = host_cpu_name;
+		} else {
+			llvm_cpu = alloc_cstring(heap_allocator(), build_context.microarch);
+		}
+		if (gb_strcmp(llvm_cpu, host_cpu_name) == 0) {
+			llvm_features = LLVMGetHostCPUFeatures();
+		}
+	}
+
+	LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(target, target_triple, llvm_cpu, llvm_features, LLVMCodeGenLevelNone, LLVMRelocDefault, code_mode);
 	defer (LLVMDisposeTargetMachine(target_machine));
 
 	LLVMSetModuleDataLayout(mod, LLVMCreateTargetDataLayout(target_machine));
@@ -12424,6 +12438,7 @@ void lb_generate_code(lbGenerator *gen) {
 	defer (LLVMDisposePassManager(module_pass_manager));
 	LLVMAddAlwaysInlinerPass(module_pass_manager);
 	LLVMAddStripDeadPrototypesPass(module_pass_manager);
+	LLVMAddAnalysisPasses(target_machine, module_pass_manager);
 	// if (build_context.optimization_level >= 2) {
 	// 	LLVMAddArgumentPromotionPass(module_pass_manager);
 	// 	LLVMAddConstantMergePass(module_pass_manager);

+ 11 - 3
src/main.cpp

@@ -583,8 +583,9 @@ enum BuildFlagKind {
 	BuildFlag_UseLLVMApi,
 	BuildFlag_IgnoreUnknownAttributes,
 	BuildFlag_ExtraLinkerFlags,
-	BuildFlag_DisallowDo,
+	BuildFlag_Microarch,
 
+	BuildFlag_DisallowDo,
 	BuildFlag_DefaultToNilAllocator,
 
 	BuildFlag_Compact,
@@ -681,9 +682,10 @@ bool parse_build_flags(Array<String> args) {
 	add_flag(&build_flags, BuildFlag_Vet,               str_lit("vet"),                 BuildFlagParam_None);
 	add_flag(&build_flags, BuildFlag_UseLLVMApi,        str_lit("llvm-api"),            BuildFlagParam_None);
 	add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None);
-	add_flag(&build_flags, BuildFlag_ExtraLinkerFlags,  str_lit("extra-linker-flags"), BuildFlagParam_String);
-	add_flag(&build_flags, BuildFlag_DisallowDo,        str_lit("disallow-do"), BuildFlagParam_None);
+	add_flag(&build_flags, BuildFlag_ExtraLinkerFlags,  str_lit("extra-linker-flags"),              BuildFlagParam_String);
+	add_flag(&build_flags, BuildFlag_Microarch,         str_lit("microarch"),                       BuildFlagParam_String);
 
+	add_flag(&build_flags, BuildFlag_DisallowDo,            str_lit("disallow-do"),              BuildFlagParam_None);
 	add_flag(&build_flags, BuildFlag_DefaultToNilAllocator, str_lit("default-to-nil-allocator"), BuildFlagParam_None);
 
 	add_flag(&build_flags, BuildFlag_Compact, str_lit("compact"), BuildFlagParam_None);
@@ -1109,6 +1111,12 @@ bool parse_build_flags(Array<String> args) {
 							build_context.extra_linker_flags = value.value_string;
 							break;
 
+						case BuildFlag_Microarch:
+							GB_ASSERT(value.kind == ExactValue_String);
+							build_context.microarch = value.value_string;
+							string_to_lower(&build_context.microarch);
+							break;
+
 						case BuildFlag_DisallowDo:
 							build_context.disallow_do = true;
 							break;

+ 6 - 0
src/string.cpp

@@ -125,6 +125,12 @@ gb_inline bool str_eq_ignore_case(String const &a, String const &b) {
 	return false;
 }
 
+void string_to_lower(String *s) {
+	for (isize i = 0; i < s->len; i++) {
+		s->text[i] = gb_char_to_lower(s->text[i]);
+	}
+}
+
 int string_compare(String const &x, String const &y) {
 	if (x.len != y.len || x.text != y.text) {
 		isize n, fast, offset, curr_block;