Skip to content

Instantly share code, notes, and snippets.

@Abhiroop
Last active July 1, 2018 14:33
Show Gist options
  • Save Abhiroop/a54dededff3d10f9186746e67154e173 to your computer and use it in GitHub Desktop.
Save Abhiroop/a54dededff3d10f9186746e67154e173 to your computer and use it in GitHub Desktop.
This is write up on how we go about enriching the Xmm, Ymm, Zmm registers of the GlobalReg type with more information.
Here we are talking about all the places where the GlobalReg type is being used.
compiler/cmm/Cmm.hs
CmmProc constructor of the GenCmmDecl data types has a field which hold a list of live GlobalRegs. This represents the list of
live GlobalRegs
compiler/cmm/CmmCallConv.hs
There are a number of uses of GlobalReg in this module but this is mostly concerned with helper functions which report about
which GlobalRegs are available.
compiler/cmm/CmmExpr.hs
GlobalReg is defined here:
data GlobalReg
= ......
| XmmReg -- 128-bit SIMD vector register
{-# UNPACK #-} !Int -- its number
| YmmReg -- 256-bit SIMD vector register
{-# UNPACK #-} !Int -- its number
| ZmmReg -- 512-bit SIMD vector register
{-# UNPACK #-} !Int -- its number
.........
The function which we want to enrich also exists here:
globalRegType :: DynFlags -> GlobalReg -> CmmType
Others are mostly helper functions.
compiler/cmm/CmmLive.hs
This module, as the name implies, does liveness analysis. There is nothing in here which will stop us from adding Length
and Width info.
compiler/cmm/CmmNode.hs
The module represent a node of the Hoopl Graph.
This module has GlobalReg as an argument to a number of places:
CmmUnwind :: [(GlobalReg, Maybe CmmExpr)] -> CmmNode O O
CmmCall :: {....
, cml_args_regs :: [GlobalReg],
.....}
There are number of comments here about how the GlobalReg are mapped to machine registers and some liveness business but
none of the logic seem to be defined here. This is more a store of all the data types. We can investigate this in some detail.
compiler/cmm/CmmSink.hs
this is the sinking assignment optimization pass and while this mentions GlobalReg a number of times, by the time the code
reaches here, GlobalReg has already been translated into CmmReg and it talks in context of that.
compiler/cmm/CmmUtils.hs
Name implies, this is just a "util" module. And has a few util function which refers to "GlobalReg" but all of this in the
context of Cmm registers not the STG registers.
compiler/cmm/Debug.hs
GlobalReg has something to do with stack unwinding which I don't fully understand but I have seen at least 5 comments on
stack unwinding by now, this module has this:
-- | Maps registers to expressions that yield their "old" values
-- further up the stack. Most interesting for the stack pointer @Sp@,
-- but might be useful to document saved registers, too. Note that a
-- register's value will be 'Nothing' when the register's previous
-- value cannot be reconstructed.
type UnwindTable = Map.Map GlobalReg (Maybe UnwindExpr)
-- | Expressions, used for unwind information
data UnwindExpr = UwConst !Int -- ^ literal value
| UwReg !GlobalReg !Int -- ^ register plus offset
| UwDeref UnwindExpr -- ^ pointer dereferencing
| UwLabel CLabel
| UwPlus UnwindExpr UnwindExpr
| UwMinus UnwindExpr UnwindExpr
| UwTimes UnwindExpr UnwindExpr
deriving (Eq)
I need to find out what is this stack unwinding business.
compiler/cmm/MkGraph.hs
Contains all the utility functions for creating a CmmGraph
This uses the GlobalReg. There exists a lot of logic in this part of the code which utilizes GlobalReg. There is a mention
of GlobalReg in a number of places but I did not investigate the logic in depth.
compiler/codeGen/CgUtils.hs
baseRegOffset :: DynFlags -> GlobalReg -> Int
This function calculates offsets of GlobalReg and Length and Width should not be an issue.
**Imp Function**
get_GlobalReg_addr :: DynFlags -> GlobalReg -> CmmExpr
Signature implies it converts a GlobalReg to CmmExpr, however it uses GlobalRegType internally
compiler/codeGen/StgCmmMonad.hs
Contains the FCode RWS monad which doesn't contains many functions which accepts a list of GlobalRegs and plumbs it
through the codegenerator. Looks like a harmless module to me.
compiler/codeGen/StgCmmUtils.hs
Again another util module. Not sure why it contains the exact same function `get_GlobalReg_addr` as defined in CgUtils.hs
compiler/codeGen/CodeGen/Platform.hs
V.IMP
Maps the GlobalReg to RealReg which are actual available Machine Registers. This module is a wrapper, all the actual
mapping are defined in include files.
Investigate: includes/CodeGen.Platform.hs etc
These are the places where we have to change
compiler/llvmGen/LlvmCodeGen/Base.hs
llvm codegenrator tracks the live GlobalRegs.
similarly
compiler/llvmGen/LlvmCodeGen/CodeGen.hs
but they don't touch the constructors of GlobalReg, atleast inside this module.
compiler/llvmGen/LlvmCodeGen/Regs.hs
Nothing very relevant
compiler/nativeGen/Dwarf/Types.hs
There are a number of uses of GlobalReg inside this module. But all internally refer the globalRegMaybe function which we
have to worry about
compiler/nativeGen/X86/CodeGen.hs
compiler/nativeGen/SPARC/CodeGen/Base.hs:
compiler/nativeGen/PPC/CodeGen.hs
All the main 3 NCG use to GlobalReg, by calling the globalRegMaybe function which we have to modify.
The CmmLex and CmmParse files of the stage1 and stage2 build refer to GlobalReg, but nothing relevant here.
Thats all.
Final Verdict.
We need to worry about the change in the include files:
includes/CodeGen.Platform.hs etc
where the `globalRegMaybe` function is defined. I have only worked with the compiler directory, so not sure how a change in
the include files affect the compiler and the build process in general but this is the most crucial step in general.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment