On Friday 24 July 2009 10:01:49 José Fonseca wrote: > On Thu, 2009-07-23 at 16:38 -0700, Zack Rusin wrote: > > I thought about that and discarded that for the following reasons: > > 1) it doesn't solve the main/core problem of the representation: how to > > represent vectors. > > Aren't LLVM vector types (http://llvm.org/docs/LangRef.html#t_vector) > good enough?
Yes, they are, but that's not what we're trying to answer. Looking at DCL IN[0] DCL OUT[0] MOV OUT[0], IN[0].xzzz in aos that will be decl <4 x float> out decl <4 x float > in out = shuffle(in, 0, 2, 2, 2); for soa4 that will be decl <4 x float> outx decl <4 x float> outy decl <4 x float> outz decl <4 x float> outw decl <4 x float> inx decl <4 x float> iny decl <4 x float> inz decl <4 x float> inw outx = inx outy = inz outz = inz outw = inz for soa16 that will be decl <16 x float> outx decl <16 x float> outy decl <16 x float> outz decl <16 x float> outw decl <16 x float> inx decl <16 x float> iny decl <16 x float> inz decl <16 x float> inw outx = inx outy = inz outz = inz outw = inz And that's for a trivial mov. Each path obviously generates very different code. The code that is currently in gallivm basically creates a new compiler for each of these. Which is one way of dealing with it. I, personally, didn't like it at all, but didn't have at the time better solution for that. Furthermore it's not just the compilation - inputs and outputs needs to be swizzled differently for each of those paths as well, so preamble and postamble has to be generated for them as well. > The vector width could be a global parameter computed before starting > the TGSI -> LLVM IR translation, which takes in account not only the > target platform but the input/output data types (e.g. SSE2 has different > vector widths for different data types). > > For mimd vs simd we could have two variations -- SoA and AoS. Again, we > could have this as a initial parameter, or two abstract classes derived > from Instruction, from which the driver would then derive from. Yes, that's pretty much exactly what the code in gallivm does right now. Lets you pick representation aos/soa, and vector width and then tries to generate the code as it was told. It's not very successful at it though =) (mainly because the actual generation paths for one are completely different from the other, so if it's working in aos it doesn't mean anything for soa) > My suggestion of an abstract Instruction class with virtual methods was > just for the sake of argument. You can achieve the same thing with a C > structure of function pointers together with the included LLVM C > bindings (http://llvm.org/svn/llvm-project/llvm/trunk/include/llvm-c/) > which appears to fully cover the IR generation interfaces. To be honest I don't think that using LLVM from C for our purposes is a good idea. Mainly because it will be impossible to do because backends (the actual code-generators for given hardware) will need to be C++ anyway so we'll again end up with a mix of C++ and C. It's just that the interface from C++ is a lot nicer than the stuff that was wrapped in C. > > That wouldn't work because LLVM wouldn't know what to do with them which > > would defeat the whole reason for using LLVM (i.e. it would make > > optimization passes do nothing). > > Good point. But can't the same argument be done for intrinsics? The > existing optimization passes don't know what to do with them either. Essentially they can treat them just as every other instructions with known semantics e.g. for <4 x float> madd(const <4 x float> a, const <4 x float>) all it needs to know is that it's an instruction that takes two inputs, doesn't modify them and returns an output. So optimizations still work. While generating assembly /before/ the code generator runs means that there's a black hole in the code that can technically do, well, anything really. > http://llvm.org/docs/ExtendingLLVM.html strongly discourages extending > LLVM, and if the LLVM IR is not good enough then the question inevitably > is: does it make sense to use LLVM at all? LLVM ir is good enough. I'm not sure what's the argument for it not being good enough. We're contemplating the usage of intrinsics because it's easier to code- generate from them. Essentially trying to follow "Gallium should make the process of writing drivers easier" mantra. You can perfectly well do reg-exp matching in the code-generator to extract the same/similar information, it just makes code-generators (drivers in our case) a lot more difficult. > I know we have been considering using LLVM on Mesa & Gallium state > tracker for GLSL -> TGSI translation. I believe it is an use case very > different from the pipe driver. But I wonder how much would LLVM gives > us there. After all, the LL in LLVM stands for low level, and TGSI is > still quite high level in some regards. (I'm playing devil's advocate > here, because I personally prefer we don't reinvent the well everytime) We're doing it because we're completely incapable of writing a decent compiler framework, because we have no chances of writing the kinds of optimizing compiler that is needed for modern graphics apps, because when using llvm we won't have to maintain the compiler part of our graphics stack and because without llvm we have no chances of implementing things like OpenCL. So it simply comes down to the fact that we simply can't even "write" the wheel, which makes the process of reinventing it even more difficult =) > I haven't though of caching yet. But I plan to write unit tests for each > IR generator component (pixel (un)packing, texture sampling, etc), > regardless if the outcome is a monolithic function or not. From my > experience so far it doesn't take more than a dozen of instructions to > make the IR hard to understand. Sounds great. z ------------------------------------------------------------------------------ _______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mesa3d-dev