Commit bbc0d440b8

Timon Kruiper <timonkruiper@gmail.com>
2019-07-01 15:22:57
Added ZigLLVMCreateTargetMachine and pass function-sections flag Also added extra cache line
Added the ZigLVVMCreateTargetMachine to self hosted zig code
1 parent 7586f61
src/codegen.cpp
@@ -7042,7 +7042,7 @@ static void zig_llvm_emit_output(CodeGen *g) {
         case EmitFileTypeBinary:
             if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
                         ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small,
-                        g->enable_time_report, g->function_sections))
+                        g->enable_time_report))
             {
                 zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg);
             }
@@ -7058,7 +7058,7 @@ static void zig_llvm_emit_output(CodeGen *g) {
         case EmitFileTypeAssembly:
             if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
                         ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small,
-                        g->enable_time_report, g->function_sections))
+                        g->enable_time_report))
             {
                 zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg);
             }
@@ -7068,7 +7068,7 @@ static void zig_llvm_emit_output(CodeGen *g) {
         case EmitFileTypeLLVMIr:
             if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
                         ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small,
-                        g->enable_time_report, g->function_sections))
+                        g->enable_time_report))
             {
                 zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg);
             }
@@ -8130,8 +8130,9 @@ static void init(CodeGen *g) {
         target_specific_features = "";
     }
 
-    g->target_machine = LLVMCreateTargetMachine(target_ref, buf_ptr(&g->triple_str),
-            target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, LLVMCodeModelDefault);
+    g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->triple_str),
+            target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
+            LLVMCodeModelDefault, g->function_sections);
 
     g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine);
 
@@ -9448,6 +9449,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
     cache_bool(ch, g->have_dynamic_link);
     cache_bool(ch, g->have_stack_probing);
     cache_bool(ch, g->is_dummy_so);
+    cache_bool(ch, g->function_sections);
     cache_buf_opt(ch, g->mmacosx_version_min);
     cache_buf_opt(ch, g->mios_version_min);
     cache_usize(ch, g->version_major);
src/zig_llvm.cpp
@@ -39,7 +39,9 @@
 #include <llvm/Support/TargetParser.h>
 #include <llvm/Support/Timer.h>
 #include <llvm/Support/raw_ostream.h>
+#include <llvm/Support/TargetRegistry.h>
 #include <llvm/Target/TargetMachine.h>
+#include <llvm/Target/CodeGenCWrappers.h>
 #include <llvm/Transforms/Coroutines.h>
 #include <llvm/Transforms/IPO.h>
 #include <llvm/Transforms/IPO/AlwaysInliner.h>
@@ -93,9 +95,63 @@ static const bool assertions_on = true;
 static const bool assertions_on = false;
 #endif
 
+LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,
+    const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
+    LLVMCodeModel CodeModel, bool function_sections)
+{
+    Optional<Reloc::Model> RM;
+    switch (Reloc){
+        case LLVMRelocStatic:
+            RM = Reloc::Static;
+            break;
+        case LLVMRelocPIC:
+            RM = Reloc::PIC_;
+            break;
+        case LLVMRelocDynamicNoPic:
+            RM = Reloc::DynamicNoPIC;
+            break;
+        case LLVMRelocROPI:
+            RM = Reloc::ROPI;
+            break;
+        case LLVMRelocRWPI:
+            RM = Reloc::RWPI;
+            break;
+        case LLVMRelocROPI_RWPI:
+            RM = Reloc::ROPI_RWPI;
+            break;
+        default:
+            break;
+    }
+
+    bool JIT;
+    Optional<CodeModel::Model> CM = unwrap(CodeModel, JIT);
+
+    CodeGenOpt::Level OL;
+    switch (Level) {
+        case LLVMCodeGenLevelNone:
+            OL = CodeGenOpt::None;
+            break;
+        case LLVMCodeGenLevelLess:
+            OL = CodeGenOpt::Less;
+            break;
+        case LLVMCodeGenLevelAggressive:
+            OL = CodeGenOpt::Aggressive;
+            break;
+        default:
+            OL = CodeGenOpt::Default;
+            break;
+    }
+
+    TargetOptions opt;
+    opt.FunctionSections = function_sections;
+
+    return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(
+        reinterpret_cast<Target*>(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM,  OL, JIT)));
+}
+
 bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
         const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,
-        bool is_small, bool time_report, bool function_sections)
+        bool is_small, bool time_report)
 {
     TimePassesIsEnabled = time_report;
 
@@ -108,8 +164,6 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
     TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
     target_machine->setO0WantsFastISel(true);
 
-    target_machine->Options.FunctionSections = function_sections;
-
     Module* module = unwrap(module_ref);
 
     PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder();
src/zig_llvm.h
@@ -56,7 +56,11 @@ enum ZigLLVM_EmitOutputType {
 
 ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
         const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,
-        bool is_small, bool time_report, bool function_sections);
+        bool is_small, bool time_report);
+
+ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,
+    const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
+    LLVMCodeModel CodeModel, bool function_sections);
 
 ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref);
 
src-self-hosted/compilation.zig
@@ -516,6 +516,7 @@ pub const Compilation = struct {
             opt_level,
             reloc_mode,
             llvm.CodeModelDefault,
+            false // TODO: add -ffunction-sections option
         ) orelse return error.OutOfMemory;
         defer llvm.DisposeTargetMachine(comp.target_machine);
 
src-self-hosted/llvm.zig
@@ -163,8 +163,8 @@ extern fn LLVMCopyStringRepOfTargetData(TD: *TargetData) ?[*]u8;
 pub const CreateTargetDataLayout = LLVMCreateTargetDataLayout;
 extern fn LLVMCreateTargetDataLayout(T: *TargetMachine) ?*TargetData;
 
-pub const CreateTargetMachine = LLVMCreateTargetMachine;
-extern fn LLVMCreateTargetMachine(
+pub const CreateTargetMachine = ZigLLVMCreateTargetMachine;
+extern fn ZigLLVMCreateTargetMachine(
     T: *Target,
     Triple: [*]const u8,
     CPU: [*]const u8,
@@ -172,6 +172,7 @@ extern fn LLVMCreateTargetMachine(
     Level: CodeGenOptLevel,
     Reloc: RelocMode,
     CodeModel: CodeModel,
+    function_sections: bool,
 ) ?*TargetMachine;
 
 pub const GetHostCPUName = LLVMGetHostCPUName;
@@ -283,7 +284,6 @@ extern fn ZigLLVMTargetMachineEmitToFile(
     error_message: *[*]u8,
     is_debug: bool,
     is_small: bool,
-    function_sections: bool,
 ) bool;
 
 pub const BuildCall = ZigLLVMBuildCall;