On 25/02/2010 02:00, David Terei wrote:
Do we envisage doing anything complex to the Llvm code inside GHC in the
future? I can't think of a reason to.
One thing I would like to investigate at some point is to have the LLVM
binding use the C++ API of LLVM instead of printing out LLVM Assembly.
This should potentially speed up the compilation process since it would
replace the current 4 passes (generate LLVM Assembly, convert to bitcode
[llvm-as], optimise [opt], compile to native code [llc]). With just one.
I believe the current design would be easier to extend for this purpose
then the simplified one you propose. After trying this out I'd be happy
to simplify the LLVM binding if we stick with the current approach of
generating LLVM assembly and calling the tools.
That sounds like a good plan. But in that case wouldn't it make sense
to use the LLVM binding from Hackage?
hunk ./compiler/ghc.cabal.in 44
+Flag llvm
+ Description: Build the LLVM code generator.
+ Default: False
+ Manual: True
CLEAN Is there a good reason to want to disable the LLVM support, or
can it always be compiled in?
Since the LLVM back-end requires TNTC to be disabled, yes it should be
disable by default.
The point I wanted to make was that there's no harm in compiling in the
LLVM support, even if it can't be used (the flag itself should be
disabled, of course). The benefit is that compilation errors in the
LLVM backend code can't creep in, because it's part of validate. We do
the same thing for the native backends, incedentally.
+Flag unreg
+ Description: Build an unregistered version.
+ Default: False
+ Manual: True
+
XXX Is this necessary? As far as I'm aware an unregisterised build
currently works.
hunk ./compiler/ghc.cabal.in 101
+ if flag(llvm)
+ CPP-Options: -DLLVM
+ if flag(unreg)
+ CPP-Options: -DNO_REGS -DUSE_MINIINTERPRETER
XXX Why is this necessary? These CPP flags are added by GHC itself
(StaticFlagParser.unregFlags).
I did this at the time as I was finding that unregistered builds of GHC
still used the BaseReg. All other registers were disabled but the
BaseReg was still being used.
That shouldn't happen. In any case, let's leave out this unreg stuff
and investigate the problem separately.
+-- Deal with Cmm registers
+--
+-- Specifically, force use of register table (in memory), not pinned
+-- hardware registers as the LLVM back-end doesn't support this.
+--
+
+module LlvmCodeGen.Regs (
+
+ RealReg, realRegsOrdered, getRealRegReg, getRealRegArg,
getGlobalRegAddr
+
+ ) where
CLEAN Unless I'm mistaken, most of this module can go away.
1. Use fixAssigns from the NCG.
2. Print out GlobalRegs as "stg_whatever..."
Then you don't need to bake in the register mapping (a maintenance
headache), and a lot of this code can go away: the RealReg type and
everything using it.
I have to think about this one. Regs can defiantly be cleaned up, no
question I'm just not sure about removing RealReg. Its purpose right now
is three things:
1) 'getGlobalRegAddr' makes STG registers into real registers or table
offsets.
2) STG registers as said have hard coded names in the code the LLVM
back-end generates. 'getRealRegReg', 'getRealRegArg'. These methods
return the correctly named LLVM local register for a particular STG
register.
3) realRegsOrdered encodes the calling convention for this target.
E.g for x86-32 = [RR_Base, RR_Sp, RR_Hp, RR_R1].
This encodes the number and order of the registers which are part of the
calling convention. Here is the LLVM code for x86-32
CCIfType<[i32], CCAssignToReg<[EBX, EBP, EDI, ESI]>>,
So its quite simple really, just the number of registers pinned and the
order they should be used as arguments.
The first two purposes can be removed. I'm just not so sure about the
third at the moment. Will look into this more, have to check what's
already provided by NCG again.
Ok, so let me be a bit clearer about what I'm proposing.
If you use share fixAssigns and cmmToCmm with the NCG, then any
GlobalReg which is not assigned to a machine register on the target
architecture gets transformed into a BaseReg[n] access. So you're left
with Cmm code containing references to only machine-reg GlobalRegs. In
the LLVM backend you just apply a simple transformation to turn
GlobalRegs into LLVM variables, e.g.
CmmGlobal Sp -> %stg_terei_spReg
You're right that function definitions still need to list the registers
in the architecture-specific ordering, but I don't think you need your
own RealReg type: just use GlobalReg.
Cheers,
Simon
_______________________________________________
Cvs-ghc mailing list
Cvs-ghc@haskell.org
http://www.haskell.org/mailman/listinfo/cvs-ghc