Version 4 (modified by jstolarek, 20 months ago) (diff)


Jan Stolarek's internship notes


Some points made by Geoffrey:

  • In the past, LLVM could not recognize all loops output by the LLVm back end as loops. Perhaps that has changed.
  • Answering the question "What does loopification do that isn't already being done?" would still be useful
  • So figuring out how to make LLVM recognize more loops would be good.
  • if you write a simple, tight loop in Haskell of the sort a C compiler would vectorize, will LLVm vectorize it? If not, why?

Some points made by Austin Seipp:

  • i took the time to implement a half-assed almost-working loopification pass a few months ago. the sinking pass by Simon is what really does a huge amount of the optimizations Kryzsztof's thesis attacked differently. but i think doing loopification could maybe lead to identifying things like loop invariant expressions. it can't bootstrap the compiler with it (JS: it = Austin's patch). i think whenever i tie the knot in the new graph, i don't abandon parts of the old CmmNode, which then causes dead labels to hang around
  • oh, yeah, and as i noted in the commit message, you have to be careful when ordering those optimizations around. this is obviously only a valid transform pre-CPS. also you have to run a block elimination passes, otherwise things can happen where work can get duplicated into empty blocks
  • i think another problem is that the new codegen doesn't always discard empty basic blocks which pisses off the native code generator (see #7574 ) so we need a little refactoring to handle that correctly, too, by being able to do SCC passes from any particular node
  • i think that the fix for #7574 is probably pretty easily actually, it just requires shuffling things around. oh, and to be clear it's not *empty* basic blocks, it's *unreachable* basic blocks that make the codegen mad

#7574 bug can be triggered with ./inplace/bin/ghc-stage2 -c -no-hs-main -fasm -O2 ./testsuite/tests/llvm/should_compile/T7571.cmm

Various clean-up tasks


  • main/HscMain.lhs:1300`. Is:
| otherwise
  = {-# SCC "cmmPipeline" #-}
    let initTopSRT = initUs_ us emptySRT in

    let run_pipeline topSRT cmmgroup = do
          (topSRT, cmmgroup) <- cmmPipeline hsc_env topSRT cmmgroup
          return (topSRT,cmmgroup)

    in do topSRT <- Stream.mapAccumL run_pipeline initTopSRT ppr_stream1
          Stream.yield (srtToData topSRT)

The <- / return sequence in the definition of run_pipeline can be eliminated, which allows to remove the do notation, which allows to do eta-reduction, which (finally) allows to remove the run_pipeline binding and using (cmmPipeline hsc_env) instead:

| otherwise
  = {-# SCC "cmmPipeline" #-}
    let initTopSRT = initUs_ us emptySRT
    in do topSRT <- Stream.mapAccumL (cmmPipeline hsc_env) initTopSRT ppr_stream1
          Stream.yield (srtToData topSRT)
  • cmm/CmmLive.hs:106. This function is not used (unless there is some auto-generated code that uses it, but I doubt it):
removeDeadAssignments :: DynFlags -> CmmGraph
                      -> UniqSM (CmmGraph, BlockEnv CmmLocalLive)

It is however referenced in some of the comments!

  • cmm/CmmRewriteAssignments.hs is not used at all?
  • cmm/CmmUtils.hs, function toBlockListEntryFirst - perhaps it would be safer to return a tuple in this case? This would probably make the invariant more explicit.


  • NewCodeGenPipeline has some outdated sections in the Cmm pipeline description: Add spill/reload, Rewrite assignments. So far I only marked them as OUTDATED
  • NewCodeGenModules - mostly outdated. Mentioned data types and modules no longer exist.