[Bf-blender-cvs] [6666b84] object_nodes: Use persistent pass managers for optimization, rather than creating them every time.

Lukas Tönne noreply at git.blender.org
Wed Jun 15 16:46:14 CEST 2016


Commit: 6666b841826090be4279a8c3af3f7e7b76e9f7bc
Author: Lukas Tönne
Date:   Thu Jun 9 16:11:18 2016 +0200
Branches: object_nodes
https://developer.blender.org/rB6666b841826090be4279a8c3af3f7e7b76e9f7bc

Use persistent pass managers for optimization, rather than creating them every time.

===================================================================

M	source/blender/blenvm/llvm/llvm_compiler.cc
M	source/blender/blenvm/llvm/llvm_compiler.h
M	source/blender/blenvm/llvm/llvm_engine.cc
M	source/blender/blenvm/llvm/llvm_engine.h

===================================================================

diff --git a/source/blender/blenvm/llvm/llvm_compiler.cc b/source/blender/blenvm/llvm/llvm_compiler.cc
index ccb3395..98f8362 100644
--- a/source/blender/blenvm/llvm/llvm_compiler.cc
+++ b/source/blender/blenvm/llvm/llvm_compiler.cc
@@ -171,57 +171,6 @@ llvm::Function *LLVMCompilerBase::codegen_node_function(const string &name, cons
 	return func;
 }
 
-void LLVMCompilerBase::optimize_function(llvm::Function *func, int opt_level)
-{
-	using namespace llvm;
-	using legacy::FunctionPassManager;
-	using legacy::PassManager;
-	
-	module()->setDataLayout(llvm_execution_engine()->getDataLayout());
-	module()->setTargetTriple(llvm_execution_engine()->getTargetMachine()->getTargetTriple());
-	
-	FunctionPassManager FPM(module());
-	PassManager MPM;
-	
-#if 0
-	/* Set up the optimizer pipeline.
-	 * Start with registering info about how the
-	 * target lays out data structures.
-	 */
-	FPM.add(new DataLayoutPass(*llvm_execution_engine()->getDataLayout()));
-	/* Provide basic AliasAnalysis support for GVN. */
-	FPM.add(createBasicAliasAnalysisPass());
-	/* Do simple "peephole" optimizations and bit-twiddling optzns. */
-	FPM.add(createInstructionCombiningPass());
-	/* Reassociate expressions. */
-	FPM.add(createReassociatePass());
-	/* Eliminate Common SubExpressions. */
-	FPM.add(createGVNPass());
-	/* Simplify the control flow graph (deleting unreachable blocks, etc). */
-	FPM.add(createCFGSimplificationPass());
-	
-	FPM.doInitialization();
-#endif
-	
-	PassManagerBuilder builder;
-	builder.OptLevel = opt_level;
-	
-	builder.populateModulePassManager(MPM);
-	if (opt_level > 1) {
-		/* Inline small functions */
-		MPM.add(createFunctionInliningPass());
-	}
-	
-	if (opt_level > 1) {
-		/* Optimize memcpy intrinsics */
-		FPM.add(createMemCpyOptPass());
-	}
-	builder.populateFunctionPassManager(FPM);
-	
-	MPM.run(*module());
-	FPM.run(*func);
-}
-
 void LLVMCompilerBase::expand_node(llvm::BasicBlock *block, const NodeInstance *node, ExpressionMap &outputs)
 {
 	switch (node->type->kind()) {
@@ -394,8 +343,8 @@ FunctionLLVM *LLVMCompilerBase::compile_function(const string &name, const NodeG
 	BLI_assert(module()->getFunction(name) && "Function not registered in module!");
 	BLI_assert(func != NULL && "codegen_node_function returned NULL!");
 	
-	BLI_assert(opt_level >= 0 && opt_level <= 3 && "Invalid optimization level (must be between 0 and 3)");
-	optimize_function(func, opt_level);
+	llvm_optimize_module(module(), opt_level);
+	llvm_optimize_function(func, opt_level);
 	
 	verifyFunction(*func, &outs());
 	verifyModule(*module(), &outs());
@@ -451,8 +400,8 @@ void LLVMCompilerBase::debug_function(const string &name, const NodeGraph &graph
 	BLI_assert(module()->getFunction(name) && "Function not registered in module!");
 	BLI_assert(func != NULL && "codegen_node_function returned NULL!");
 	
-	BLI_assert(opt_level >= 0 && opt_level <= 3 && "Invalid optimization level (must be between 0 and 3)");
-	optimize_function(func, opt_level);
+	llvm_optimize_module(module(), opt_level);
+	llvm_optimize_function(func, opt_level);
 	
 	file_ostream stream(file);
 	debug_assembly_annotation_writer aaw;
diff --git a/source/blender/blenvm/llvm/llvm_compiler.h b/source/blender/blenvm/llvm/llvm_compiler.h
index c05935b..0851b84 100644
--- a/source/blender/blenvm/llvm/llvm_compiler.h
+++ b/source/blender/blenvm/llvm/llvm_compiler.h
@@ -124,8 +124,6 @@ protected:
 	void create_module(const string &name);
 	void destroy_module();
 	
-	void optimize_function(llvm::Function *func, int opt_level);
-	
 	llvm::BasicBlock *codegen_function_body_expression(const NodeGraph &graph, llvm::Function *func);
 	llvm::Function *codegen_node_function(const string &name, const NodeGraph &graph);
 	
diff --git a/source/blender/blenvm/llvm/llvm_engine.cc b/source/blender/blenvm/llvm/llvm_engine.cc
index 1228c94..10ef102 100644
--- a/source/blender/blenvm/llvm/llvm_engine.cc
+++ b/source/blender/blenvm/llvm/llvm_engine.cc
@@ -49,6 +49,8 @@ namespace blenvm {
 
 static llvm::ExecutionEngine *theEngine = NULL;
 static llvm::Module *theModule = NULL;
+static llvm::legacy::PassManager *theModulePassMgr[3] = {0};
+static llvm::legacy::FunctionPassManager *theFunctionPassMgr[3] = {0};
 
 bool llvm_has_external_impl_value(OpCode node_op) {
 #define DEF_OPCODE(op) \
@@ -131,6 +133,58 @@ static llvm::ExecutionEngine *create_execution_engine()
 	return engine;
 }
 
+static void create_pass_managers()
+{
+	using namespace llvm;
+	using legacy::FunctionPassManager;
+	using legacy::PassManager;
+	
+	BLI_assert(theModule != NULL && "theModule must be initialized for pass managers!");
+	
+	for (int opt_level = 0; opt_level < 3; ++opt_level) {
+		theModulePassMgr[opt_level] = new PassManager();
+		theFunctionPassMgr[opt_level] = new FunctionPassManager(theModule);
+		
+		PassManager &MPM = *theModulePassMgr[opt_level];
+		FunctionPassManager &FPM = *theFunctionPassMgr[opt_level];
+		
+#if 0
+		/* Set up the optimizer pipeline.
+		 * Start with registering info about how the
+		 * target lays out data structures.
+		 */
+		FPM.add(new DataLayoutPass(*llvm_execution_engine()->getDataLayout()));
+		/* Provide basic AliasAnalysis support for GVN. */
+		FPM.add(createBasicAliasAnalysisPass());
+		/* Do simple "peephole" optimizations and bit-twiddling optzns. */
+		FPM.add(createInstructionCombiningPass());
+		/* Reassociate expressions. */
+		FPM.add(createReassociatePass());
+		/* Eliminate Common SubExpressions. */
+		FPM.add(createGVNPass());
+		/* Simplify the control flow graph (deleting unreachable blocks, etc). */
+		FPM.add(createCFGSimplificationPass());
+		
+		FPM.doInitialization();
+#endif
+		
+		PassManagerBuilder builder;
+		builder.OptLevel = opt_level;
+		
+		builder.populateModulePassManager(MPM);
+		if (opt_level > 1) {
+			/* Inline small functions */
+			MPM.add(createFunctionInliningPass());
+		}
+		
+		builder.populateFunctionPassManager(FPM);
+		if (opt_level > 1) {
+			/* Optimize memcpy intrinsics */
+			FPM.add(createMemCpyOptPass());
+		}
+	}
+}
+
 void llvm_init()
 {
 	using namespace llvm;
@@ -141,6 +195,8 @@ void llvm_init()
 	
 	BLI_assert(theEngine == NULL);
 	theEngine = create_execution_engine();
+	
+	create_pass_managers();
 }
 
 void llvm_free()
@@ -149,6 +205,13 @@ void llvm_free()
 		delete theEngine;
 		theEngine = NULL;
 	}
+	
+	for (int opt_level = 0; opt_level < 3; ++opt_level) {
+		if (theModulePassMgr[opt_level])
+			delete theModulePassMgr[opt_level];
+		if (theFunctionPassMgr[opt_level])
+			delete theFunctionPassMgr[opt_level];
+	}
 }
 
 llvm::ExecutionEngine *llvm_execution_engine()
@@ -156,4 +219,29 @@ llvm::ExecutionEngine *llvm_execution_engine()
 	return theEngine;
 }
 
+void llvm_optimize_module(llvm::Module *mod, int opt_level)
+{
+	using namespace llvm;
+	
+	BLI_assert(opt_level >= 0 && opt_level <= 3 && "Invalid optimization level (must be between 0 and 3)");
+	
+	PassManager &MPM = *theModulePassMgr[opt_level];
+	
+	mod->setDataLayout(theEngine->getDataLayout());
+	mod->setTargetTriple(theEngine->getTargetMachine()->getTargetTriple());
+	
+	MPM.run(*mod);
+}
+
+void llvm_optimize_function(llvm::Function *func, int opt_level)
+{
+	using namespace llvm;
+	
+	BLI_assert(opt_level >= 0 && opt_level <= 3 && "Invalid optimization level (must be between 0 and 3)");
+	
+	FunctionPassManager &FPM = *theFunctionPassMgr[opt_level];
+	
+	FPM.run(*func);
+}
+
 } /* namespace llvm */
diff --git a/source/blender/blenvm/llvm/llvm_engine.h b/source/blender/blenvm/llvm/llvm_engine.h
index 5b56062..601a883 100644
--- a/source/blender/blenvm/llvm/llvm_engine.h
+++ b/source/blender/blenvm/llvm/llvm_engine.h
@@ -37,6 +37,8 @@
 
 namespace llvm {
 class ExecutionEngine;
+class Function;
+class Module;
 }
 
 namespace blenvm {
@@ -46,6 +48,9 @@ void llvm_free();
 
 llvm::ExecutionEngine *llvm_execution_engine();
 
+void llvm_optimize_module(llvm::Module *mod, int opt_level);
+void llvm_optimize_function(llvm::Function *func, int opt_level);
+
 bool llvm_has_external_impl_value(OpCode op);
 bool llvm_has_external_impl_deriv(OpCode op);




More information about the Bf-blender-cvs mailing list