summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2010-06-10 16:25:39 +0100
committerJosé Fonseca <[email protected]>2010-07-01 15:02:10 +0100
commite277d5c1f6b2c5a6d202561e67d2b6821a69ecc4 (patch)
treeced163d4cc9850c6cb9e46c3da2dd814c8acb191
parent83ced5a918fd597fe2cb2991ff9732920354718c (diff)
gallivm: Setup a global optimization pass.
Modules are still free to setup their own optimization passes, but for the normal case it should not be necessary.
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_init.c30
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_init.h1
2 files changed, 31 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c
index 44cfdc4d3fb..69353dea09e 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c
@@ -32,6 +32,8 @@
#include "lp_bld_debug.h"
#include "lp_bld_init.h"
+#include <llvm-c/Transforms/Scalar.h>
+
#ifdef DEBUG
unsigned gallivm_debug = 0;
@@ -50,6 +52,7 @@ LLVMModuleRef lp_build_module = NULL;
LLVMExecutionEngineRef lp_build_engine = NULL;
LLVMModuleProviderRef lp_build_provider = NULL;
LLVMTargetDataRef lp_build_target = NULL;
+LLVMPassManagerRef lp_build_pass = NULL;
/*
@@ -127,6 +130,33 @@ lp_build_init(void)
if (!lp_build_target)
lp_build_target = LLVMGetExecutionEngineTargetData(lp_build_engine);
+ if (!lp_build_pass) {
+ lp_build_pass = LLVMCreateFunctionPassManager(lp_build_provider);
+ LLVMAddTargetData(lp_build_target, lp_build_pass);
+
+ if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
+ /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+ * but there are more on SVN. */
+ /* TODO: Add more passes */
+ LLVMAddCFGSimplificationPass(lp_build_pass);
+ LLVMAddPromoteMemoryToRegisterPass(lp_build_pass);
+ LLVMAddConstantPropagationPass(lp_build_pass);
+ if(util_cpu_caps.has_sse4_1) {
+ /* FIXME: There is a bug in this pass, whereby the combination of fptosi
+ * and sitofp (necessary for trunc/floor/ceil/round implementation)
+ * somehow becomes invalid code.
+ */
+ LLVMAddInstructionCombiningPass(lp_build_pass);
+ }
+ LLVMAddGVNPass(lp_build_pass);
+ } else {
+ /* We need at least this pass to prevent the backends to fail in
+ * unexpected ways.
+ */
+ LLVMAddPromoteMemoryToRegisterPass(lp_build_pass);
+ }
+ }
+
util_cpu_detect();
#if 0
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h
index 0ec2afcd1be..a32ced9b4c3 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h
@@ -38,6 +38,7 @@ extern LLVMModuleRef lp_build_module;
extern LLVMExecutionEngineRef lp_build_engine;
extern LLVMModuleProviderRef lp_build_provider;
extern LLVMTargetDataRef lp_build_target;
+extern LLVMPassManagerRef lp_build_pass;
void