36dd492cb7cb — Leonard Ritter 2 months ago
* LLVM: O0 performs dead code elimination and instruction combination by default
* LLVM: delay optimization until after module cache key has been built, so we only optimize once
M include/scopes/config.h +1 -1
@@ 19,7 19,7 @@ 
 // turning this on is detrimental to startup time
 // scopes output is typically clean enough to provide fairly good performance
 // on its own.
-// #define SCOPES_OPTIMIZE_ASSEMBLY CF_O1
+#define SCOPES_OPTIMIZE_ASSEMBLY CF_O0
 
 // any location error aborts immediately and can not be caught
 #define SCOPES_EARLY_ABORT 0

          
M src/execution.cpp +80 -8
@@ 10,6 10,7 @@ 
 #include "symbol.hpp"
 #include "cache.hpp"
 #include "compiler_flags.hpp"
+#include "timer.hpp"
 
 #ifdef SCOPES_WIN32
 #include "dlfcn.h"

          
@@ 25,6 26,10 @@ 
 #include <llvm-c/LLJIT.h>
 #include <llvm-c/OrcEE.h>
 
+#include <llvm-c/Transforms/PassManagerBuilder.h>
+#include <llvm-c/Transforms/InstCombine.h>
+#include <llvm-c/Transforms/IPO.h>
+
 #include <limits.h>
 
 #include <stdio.h>

          
@@ 44,6 49,55 @@ 
 
 namespace scopes {
 
+////////////////////////////////////////////////////////////////////////////////
+
+void build_and_run_opt_passes(LLVMModuleRef module, int opt_level) {
+    LLVMPassManagerBuilderRef passBuilder;
+
+    passBuilder = LLVMPassManagerBuilderCreate();
+    LLVMPassManagerBuilderSetOptLevel(passBuilder, opt_level);
+    //LLVMPassManagerBuilderSetOptLevel(passBuilder, 1);
+    LLVMPassManagerBuilderSetSizeLevel(passBuilder, 2);
+    if (opt_level == 0) {
+        LLVMPassManagerBuilderSetDisableUnrollLoops(passBuilder, true);
+    }
+    //LLVMAddInstructionCombiningPass(passBuilder);
+    #if 1
+    if (opt_level >= 2) {
+        LLVMPassManagerBuilderUseInlinerWithThreshold(passBuilder, 225);
+    }
+    #endif
+
+    LLVMPassManagerRef functionPasses =
+      LLVMCreateFunctionPassManagerForModule(module);
+    LLVMPassManagerRef modulePasses =
+      LLVMCreatePassManager();
+    //LLVMAddAnalysisPasses(LLVMGetExecutionEngineTargetMachine(ee), functionPasses);
+
+    LLVMPassManagerBuilderPopulateFunctionPassManager(passBuilder,
+                                                      functionPasses);
+    LLVMPassManagerBuilderPopulateModulePassManager(passBuilder, modulePasses);
+
+    LLVMPassManagerBuilderDispose(passBuilder);
+    if (opt_level == 0) {
+        LLVMAddDeadArgEliminationPass(modulePasses);
+        LLVMAddInstructionCombiningPass(modulePasses);
+    }
+
+    LLVMInitializeFunctionPassManager(functionPasses);
+    for (LLVMValueRef value = LLVMGetFirstFunction(module);
+         value; value = LLVMGetNextFunction(value))
+      LLVMRunFunctionPassManager(functionPasses, value);
+    LLVMFinalizeFunctionPassManager(functionPasses);
+
+    LLVMRunPassManager(modulePasses, module);
+
+    LLVMDisposePassManager(functionPasses);
+    LLVMDisposePassManager(modulePasses);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 static void *global_c_namespace = nullptr;
 //static LLVMOrcJITStackRef orc = nullptr;
 static LLVMOrcLLJITRef orc = nullptr;

          
@@ 249,6 303,19 @@ SCOPES_RESULT(void) init_execution() {
 
 static std::vector<const PointerMap *> pointer_maps;
 
+static LLVMMemoryBufferRef module_to_membuffer(LLVMModuleRef module) {
+    LLVMMemoryBufferRef irbuf = nullptr;
+#if SCOPES_CACHE_KEY_BITCODE
+        irbuf = LLVMWriteBitcodeToMemoryBuffer(module);
+#else
+        char *s = LLVMPrintModuleToString(module);
+        irbuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(s, strlen(s),
+            "irbuf");
+        LLVMDisposeMessage(s);
+#endif
+    return irbuf;
+}
+
 SCOPES_RESULT(void) add_module(LLVMModuleRef module, const PointerMap &map,
     uint64_t compiler_flags) {
     SCOPES_RESULT_TYPE(void);

          
@@ 258,14 325,7 @@ SCOPES_RESULT(void) add_module(LLVMModul
     LLVMMemoryBufferRef irbuf = nullptr;
     LLVMMemoryBufferRef membuf = nullptr;
     if (cache) {
-#if SCOPES_CACHE_KEY_BITCODE
-        irbuf = LLVMWriteBitcodeToMemoryBuffer(module);
-#else
-        char *s = LLVMPrintModuleToString(module);
-        irbuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(s, strlen(s),
-            "irbuf");
-        LLVMDisposeMessage(s);
-#endif
+        irbuf = module_to_membuffer(module);
     }
 
     const String *key = nullptr;

          
@@ 375,6 435,18 @@ SCOPES_RESULT(void) add_module(LLVMModul
     }
 skip_cache:
     {
+        if (compiler_flags & CF_O3) {
+            Timer optimize_timer(TIMER_Optimize);
+            int level = 0;
+            if ((compiler_flags & CF_O3) == CF_O1)
+                level = 1;
+            else if ((compiler_flags & CF_O3) == CF_O2)
+                level = 2;
+            else if ((compiler_flags & CF_O3) == CF_O3)
+                level = 3;
+            build_and_run_opt_passes(module, level);
+        }
+
         auto target_machine = get_jit_target_machine();
         assert(target_machine);
 

          
M src/execution.hpp +1 -0
@@ 38,6 38,7 @@ LLVMTargetMachineRef get_jit_target_mach
 LLVMTargetMachineRef get_object_target_machine();
 void add_jit_event_listener(LLVMJITEventListenerRef listener);
 SCOPES_RESULT(void) add_object(const char *path);
+void build_and_run_opt_passes(LLVMModuleRef module, int opt_level);
 
 void init_llvm();
 

          
M src/gen_llvm.cpp +6 -58
@@ 34,8 34,6 @@ 
 #include <llvm-c/Core.h>
 //#include <llvm-c/ExecutionEngine.h>
 #include <llvm-c/Analysis.h>
-#include <llvm-c/Transforms/PassManagerBuilder.h>
-#include <llvm-c/Transforms/InstCombine.h>
 #include <llvm-c/Disassembler.h>
 #include <llvm-c/Support.h>
 #include <llvm-c/DebugInfo.h>

          
@@ 79,45 77,6 @@ LLVMAttributeRef LLVMCreateTypeAttribute
 // IL->LLVM IR GENERATOR
 //------------------------------------------------------------------------------
 
-static void build_and_run_opt_passes(LLVMModuleRef module, int opt_level) {
-    LLVMPassManagerBuilderRef passBuilder;
-
-    passBuilder = LLVMPassManagerBuilderCreate();
-    LLVMPassManagerBuilderSetOptLevel(passBuilder, opt_level);
-    //LLVMPassManagerBuilderSetOptLevel(passBuilder, 1);
-    LLVMPassManagerBuilderSetSizeLevel(passBuilder, 2);
-    //LLVMPassManagerBuilderSetDisableUnrollLoops(passBuilder, true);
-    //LLVMAddInstructionCombiningPass(passBuilder);
-    #if 1
-    if (opt_level >= 2) {
-        LLVMPassManagerBuilderUseInlinerWithThreshold(passBuilder, 225);
-    }
-    #endif
-
-    LLVMPassManagerRef functionPasses =
-      LLVMCreateFunctionPassManagerForModule(module);
-    LLVMPassManagerRef modulePasses =
-      LLVMCreatePassManager();
-    //LLVMAddAnalysisPasses(LLVMGetExecutionEngineTargetMachine(ee), functionPasses);
-
-    LLVMPassManagerBuilderPopulateFunctionPassManager(passBuilder,
-                                                      functionPasses);
-    LLVMPassManagerBuilderPopulateModulePassManager(passBuilder, modulePasses);
-
-    LLVMPassManagerBuilderDispose(passBuilder);
-
-    LLVMInitializeFunctionPassManager(functionPasses);
-    for (LLVMValueRef value = LLVMGetFirstFunction(module);
-         value; value = LLVMGetNextFunction(value))
-      LLVMRunFunctionPassManager(functionPasses, value);
-    LLVMFinalizeFunctionPassManager(functionPasses);
-
-    LLVMRunPassManager(modulePasses, module);
-
-    LLVMDisposePassManager(functionPasses);
-    LLVMDisposePassManager(modulePasses);
-}
-
 const double deg2rad = 0.017453292519943295;
 const double rad2deg = 57.29577951308232;
 

          
@@ 3501,23 3460,6 @@ SCOPES_RESULT(ConstPointerRef) compile(c
     }
 #endif
 
-    if (flags & CF_O3) {
-        Timer optimize_timer(TIMER_Optimize);
-        int level = 0;
-        if ((flags & CF_O3) == CF_O1)
-            level = 1;
-        else if ((flags & CF_O3) == CF_O2)
-            level = 2;
-        else if ((flags & CF_O3) == CF_O3)
-            level = 3;
-        build_and_run_opt_passes(module, level);
-    }
-    if (flags & CF_DumpModule) {
-        LLVMDumpModule(module);
-    } else if (flags & CF_DumpFunction) {
-        LLVMDumpValue(func);
-    }
-
     std::string funcname;
     {
         size_t length = 0;

          
@@ 3536,6 3478,12 @@ SCOPES_RESULT(ConstPointerRef) compile(c
 
     SCOPES_CHECK_RESULT(add_module(module, ctx.pointer_map, flags));
 
+    if (flags & CF_DumpModule) {
+        LLVMDumpModule(module);
+    } else if (flags & CF_DumpFunction) {
+        LLVMDumpValue(func);
+    }
+
 #if 1
     for (auto sym : bindsyms) {
         void *ptr = (void *)SCOPES_GET_RESULT(get_address(sym.c_str()));

          
M src/prover.cpp +11 -0
@@ 2842,6 2842,17 @@ repeat:
                 return op;
             } else {
                 assert(iidx != -1ull);
+                /*
+                // search for a prior matching insertion
+                TypedValueRef v = _T;
+                while (v.isa<InsertValue>() && !is_unique(v->get_type())) {
+                    auto iv = v.cast<InsertValue>();
+                    if (iv->index == iidx) {
+                        return TypedValueRef(call.anchor(), iv->element);
+                    }
+                    v = iv->value;
+                }
+                */
                 auto op = ExtractValue::from(_T, iidx);
                 op->hack_change_value(VIEWTYPE1(op->get_type(), _T));
                 return TypedValueRef(call.anchor(), op);

          
M testing/test_alignment.sc +4 -2
@@ 1,11 1,13 @@ 
 
 using import testing
 
+fn unconst (x) x
+
 # test alignment
 inline test-alignment (T verbose?)
     let size alignment =
-        ptrtoint (getelementptr (nullof (mutable pointer T)) 1) u64
-        ptrtoint (getelementptr (nullof (mutable pointer (tuple bool T))) 0 1) u64
+        ptrtoint (getelementptr (unconst (nullof (mutable pointer T))) 1) u64
+        ptrtoint (getelementptr (unconst (nullof (mutable pointer (tuple bool T)))) 0 1) u64
     static-if verbose?
         print T "size =" size "alignment =" alignment
     if (size != (sizeof T))

          
M testing/test_codegen.sc +1 -1
@@ 4,6 4,6 @@ using import testing
 fn elidable (x)
     extractvalue (insertvalue x 1 0) 0
 
-compile (static-typify elidable (tuple i32 i32)) 'dump-function 'O1
+compile (static-typify elidable (tuple i32 i32)) 'dump-function 'O0
 
 ;
  No newline at end of file