Initial stab at LLVM integration.
authorZack Rusin <zack@tungstengraphics.com>
Mon, 8 Oct 2007 14:24:35 +0000 (10:24 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Wed, 24 Oct 2007 15:21:03 +0000 (11:21 -0400)
configs/default
src/mesa/Makefile
src/mesa/pipe/llvm/llvmtgsi.cpp [new file with mode: 0644]
src/mesa/pipe/llvm/llvmtgsi.h [new file with mode: 0644]
src/mesa/pipe/p_state.h
src/mesa/pipe/softpipe/sp_quad_fs.c
src/mesa/sources
src/mesa/state_tracker/st_program.c

index a7de3f813d6bc0c95d032e7640d88a1c50c0f8ab..ac8de653ec35b92d31bd377899c895f45b17256e 100644 (file)
@@ -65,10 +65,29 @@ DRIVER_DIRS = x11 osmesa
 # Which subdirs under $(TOP)/progs/ to enter:
 PROGRAM_DIRS = demos redbook samples glsl xdemos
 
+LLVM_VERSION := $(shell llvm-config --version)
+
+ifeq ($(LLVM_VERSION),)
+  $(warning Could not find LLVM! Make Sure 'llvm-config' is in the path)
+  MESA_NO_LLVM=1
+else
+  MESA_NO_LLVM=0
+  $(info Using LLVM version: $(LLVM_VERSION))
+endif
+
+ifeq ($(MESA_NO_LLVM),0)
+  LLVM_CFLAGS=`llvm-config --cflags` -DMESA_NO_LLVM=0
+  LLVM_CXXFLAGS=`llvm-config --cxxflags` -DMESA_NO_LLVM=0 -Wno-long-long
+  LLVM_LDFLAGS=`llvm-config --ldflags`
+  LLVM_LIBS=`llvm-config --libs`
+else
+  LLVM_CFLAGS=-DMESA_NO_LLVM=1
+  LLVM_CXXFLAGS=-DMESA_NO_LLVM=1
+endif
 
 # Library/program dependencies
 #EXTRA_LIB_PATH ?=
-GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread
+GL_LIB_DEPS = $(LLVM_LDFLAGS) $(LLVM_LIBS) $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread
 OSMESA_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB)
 GLU_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) -lm
 GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) $(EXTRA_LIB_PATH) -lX11 -lXmu -lXt -lXi -lm
index 9dde96ee21f3520b9b8cbd554e15431c8a78818e..cb7c466f47505f4d46e5c4858315511539dc27d9 100644 (file)
@@ -16,10 +16,10 @@ SOFTPIPE_LIB = $(TOP)/src/mesa/pipe/softpipe/libsoftpipe.a
 .SUFFIXES : .cpp
 
 .c.o:
-       $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
+       $(CC) -c $(LLVM_CFLAGS) $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
 
 .cpp.o:
-       $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@
+       $(CXX) -c $(LLVM_CXXFLAGS) $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@
 
 .S.o:
        $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
diff --git a/src/mesa/pipe/llvm/llvmtgsi.cpp b/src/mesa/pipe/llvm/llvmtgsi.cpp
new file mode 100644 (file)
index 0000000..857eb1c
--- /dev/null
@@ -0,0 +1,158 @@
+#include "llvmtgsi.h"
+
+#include "pipe/tgsi/exec/tgsi_exec.h"
+#include "pipe/tgsi/exec/tgsi_token.h"
+#include "pipe/tgsi/exec/tgsi_build.h"
+#include "pipe/tgsi/exec/tgsi_util.h"
+#include "pipe/tgsi/exec/tgsi_parse.h"
+#include "pipe/tgsi/exec/tgsi_dump.h"
+//#include "pipe/tgsi/tgsi_platform.h"
+
+#include <llvm/Module.h>
+#include <llvm/CallingConv.h>
+#include <llvm/Constants.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/Instructions.h>
+#include <llvm/ModuleProvider.h>
+#include <llvm/ParameterAttributes.h>
+#include <llvm/Support/PatternMatch.h>
+#include <llvm/ExecutionEngine/JIT.h>
+#include <llvm/ExecutionEngine/Interpreter.h>
+#include <llvm/ExecutionEngine/GenericValue.h>
+#include <llvm/Support/MemoryBuffer.h>
+#include <llvm/Bitcode/ReaderWriter.h>
+#include <iostream>
+
+
+static void
+translate_declaration(llvm::Module *module,
+                      struct tgsi_full_declaration *decl,
+                      struct tgsi_full_declaration *fd)
+{
+}
+
+
+static void
+translate_immediate(llvm::Module *module,
+                    struct tgsi_full_immediate *imm)
+{
+}
+
+
+static void
+translate_instruction(llvm::Module *module,
+                      struct tgsi_full_instruction *inst,
+                      struct tgsi_full_instruction *fi)
+{
+}
+
+
+static llvm::Module *
+tgsi_to_llvm(const struct tgsi_token *tokens)
+{
+   llvm::Module *mod = new llvm::Module("tgsi");
+   struct tgsi_parse_context parse;
+   struct tgsi_full_instruction fi;
+   struct tgsi_full_declaration fd;
+
+   tgsi_parse_init(&parse, tokens);
+
+   //parse.FullHeader.Processor.Processor
+
+   //parse.FullVersion.Version.MajorVersion
+   //parse.FullVersion.Version.MinorVersion
+
+   //parse.FullHeader.Header.HeaderSize
+   //parse.FullHeader.Header.BodySize
+   //parse.FullHeader.Processor.Processor
+
+   fi = tgsi_default_full_instruction();
+   fd = tgsi_default_full_declaration();
+
+   while(!tgsi_parse_end_of_tokens(&parse)) {
+      tgsi_parse_token(&parse);
+
+      fprintf(stderr, "Translating %d\n", parse.FullToken.Token.Type);
+
+      switch (parse.FullToken.Token.Type) {
+      case TGSI_TOKEN_TYPE_DECLARATION:
+         translate_declaration(mod,
+                               &parse.FullToken.FullDeclaration,
+                               &fd);
+         break;
+
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+         translate_immediate(mod,
+                             &parse.FullToken.FullImmediate);
+         break;
+
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+         translate_instruction(mod,
+                               &parse.FullToken.FullInstruction,
+                               &fi);
+         break;
+
+      default:
+         assert(0);
+      }
+   }
+
+   //TXT("\ntgsi-dump end -------------------\n");
+
+   tgsi_parse_free(&parse);
+
+   return mod;
+}
+
+struct ga_llvm_prog *
+ga_llvm_from_tgsi(const struct tgsi_token *tokens)
+{
+   std::cout << "Creating llvm " <<std::endl;
+   struct ga_llvm_prog *ga_llvm =
+      (struct ga_llvm_prog *)malloc(sizeof(struct ga_llvm_prog));
+   llvm::Module *mod = tgsi_to_llvm(tokens);
+   llvm::ExistingModuleProvider *mp =
+      new llvm::ExistingModuleProvider(mod);
+   //llvm::ExecutionEngine *ee =
+   //   llvm::ExecutionEngine::create(mp, false);
+
+   ga_llvm->module = mod;
+   ga_llvm->engine = 0;//ee;
+   fprintf(stderr, "DUMPX \n");
+   //tgsi_dump(tokens, TGSI_DUMP_VERBOSE);
+   tgsi_dump(tokens, 0);
+   fprintf(stderr, "DUMPEND \n");
+
+   return ga_llvm;
+}
+
+void ga_llvm_prog_delete(struct ga_llvm_prog *prog)
+{
+   llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
+   delete mod;
+   prog->module = 0;
+   prog->engine = 0;
+   free(prog);
+}
+
+int ga_llvm_prog_exec(struct ga_llvm_prog *prog)
+{
+   //std::cout << "START "<<std::endl;
+   llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
+   llvm::Function *func = mod->getFunction("main");
+   llvm::ExecutionEngine *ee = static_cast<llvm::ExecutionEngine*>(prog->engine);
+
+   std::vector<llvm::GenericValue> args(0);
+   //args[0] = GenericValue(&st);
+   //std::cout << "Mod is "<<*mod;
+   //std::cout << "\n\nRunning llvm: " << std::endl;
+   if (func) {
+      std::cout << "Func is "<<func;
+      llvm::GenericValue gv = ee->runFunction(func, args);
+   }
+
+//delete ee;
+//delete mp;
+
+   return 0;
+}
diff --git a/src/mesa/pipe/llvm/llvmtgsi.h b/src/mesa/pipe/llvm/llvmtgsi.h
new file mode 100644 (file)
index 0000000..c0cee91
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef LLVMTGSI_H
+#define LLVMTGSI_H
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+struct tgsi_exec_machine;
+struct tgsi_token;
+struct tgsi_sampler;
+
+struct ga_llvm_prog {
+   void *module;
+   void *engine;
+};
+struct ga_llvm_prog *
+ga_llvm_from_tgsi(const struct tgsi_token *tokens);
+
+void ga_llvm_prog_delete(struct ga_llvm_prog *prog);
+
+int ga_llvm_prog_exec(struct ga_llvm_prog *prog);
+
+#if defined __cplusplus
+} // extern "C"
+#endif
+
+#endif
index 4a18d25ab89a4b59705e8fe903ec60b29362ca15..69b11588e0777db62e8efc527b50a57669e57f37 100644 (file)
@@ -58,6 +58,7 @@
 
 /* fwd decl */
 struct pipe_surface;
+struct ga_llvm_prog;
 
 /* opaque type */
 struct pipe_buffer_handle;
@@ -153,6 +154,8 @@ struct pipe_shader_state {
 #endif
    void (*executable)();
 
+   const struct ga_llvm_prog *llvm_prog;
+
    ubyte num_inputs;
    ubyte num_outputs;
    ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */
index 9f85f7c30ce6d37cac1b0ccc387177f4dba57301..035f05170bccd565fdf08fd56214b784c9971b34 100644 (file)
@@ -35,6 +35,8 @@
 #include "pipe/p_util.h"
 #include "pipe/p_defines.h"
 
+#include "pipe/llvm/llvmtgsi.h"
+
 #include "sp_context.h"
 #include "sp_headers.h"
 #include "sp_quad.h"
@@ -107,6 +109,7 @@ shade_quad(
          machine->InterpCoefs );
    }
    else {
+      ga_llvm_prog_exec(softpipe->fs->llvm_prog);
       quad->mask &= tgsi_exec_machine_run( machine );
    }
 
index fea3234db3a7d41515e4c095ae647ecbf96f9f79..41c3ae387edd2718955f6d0a3beb2d98d45ca941 100644 (file)
@@ -188,6 +188,11 @@ TGSIDECO_SOURCES = \
 TGSIMESA_SOURCES = \
        pipe/tgsi/mesa/mesa_to_tgsi.c
 
+ifeq ($(MESA_NO_LLVM),0)
+  LLVMTGSI_SOURCES = \
+       pipe/llvm/llvmtgsi.cpp
+endif
+
 STATECACHE_SOURCES = \
        pipe/cso_cache/cso_hash.c \
        pipe/cso_cache/cso_cache.c
@@ -366,6 +371,7 @@ FBDEV_DRIVER_SOURCES =                      \
 ALL_SOURCES = \
        $(GLAPI_SOURCES)        \
        $(SOLO_SOURCES)         \
+        $(LLVMTGSI_SOURCES)     \
        $(ASM_SOURCES)          \
        $(COMMON_DRIVER_SOURCES)\
        $(X11_DRIVER_SOURCES)   \
@@ -392,13 +398,15 @@ SOLO_SOURCES = \
 
 CORE_SOURCES = \
        $(GLAPI_SOURCES)        \
-       $(SOLO_SOURCES)
+       $(SOLO_SOURCES)         \
+       $(LLVMTGSI_SOURCES)
 
 
 ### Object files
 
 SOLO_OBJECTS = \
        $(SOLO_SOURCES:.c=.o) \
+       $(LLVMTGSI_SOURCES:.cpp=.o) \
        $(ASM_SOURCES:.S=.o)
 
 GLAPI_OBJECTS = \
index 5b6fa70dff4f0eb35471106361b262d8e76f74b3..edb2703101f9b8a8ec83513ca925978aa804bfd8 100644 (file)
@@ -39,6 +39,7 @@
 #include "pipe/draw/draw_context.h"
 #include "pipe/tgsi/mesa/mesa_to_tgsi.h"
 #include "pipe/tgsi/exec/tgsi_core.h"
+#include "pipe/llvm/llvmtgsi.h"
 
 #include "st_context.h"
 #include "st_cache.h"
@@ -250,6 +251,7 @@ st_translate_vertex_program(struct st_context *st,
                                 tokensOut, maxTokens);
 
    vs.tokens = tokensOut;
+   vs.llvm_prog = ga_llvm_from_tgsi(vs.tokens);
    cso = st_cached_vs_state(st, &vs);
    stvp->vs = cso;
 
@@ -405,7 +407,7 @@ st_translate_fragment_program(struct st_context *st,
                                 tokensOut, maxTokens);
 
    fs.tokens = tokensOut;
-
+   fs.llvm_prog = ga_llvm_from_tgsi(fs.tokens);
    cso = st_cached_fs_state(st, &fs);
    stfp->fs = cso;