1. 11 Jul, 2000 2 commits
    • simonmar's avatar
      [project @ 2000-07-11 16:24:57 by simonmar] · ff755dd9
      simonmar authored
      remove unused imports
      ff755dd9
    • sewardj's avatar
      [project @ 2000-07-11 15:26:33 by sewardj] · 6254fd4a
      sewardj authored
      Fix up the sparc native code generator.  Mostly dull stuff.  Notable
      changes:
      
      * Cleaned up ccall mechanism for sparc somewhat.
      
      * Rearranged assignment of sparc floating point registers (includes/MachRegs.h)
        so the NCG's register allocator can handle the double-single pairing
        issue without modification.  Split VirtualRegF into VirtualRegF and
        VirtualRegD, and split RcFloating into RcFloat and RcDouble.  Net effect
        is that there are now three register classes -- int, float and double,
        and we pretend that sparc has some float and some double real regs.
      
      * (A fix for all platforms): propagate MachFloats through as StFloats,
        not StDoubles.  Amazingly, until now literal floats had been converted
        to and treated as doubles, including in ccalls.
      6254fd4a
  2. 16 Jun, 2000 1 commit
  3. 15 Jun, 2000 1 commit
    • sewardj's avatar
      [project @ 2000-06-15 08:38:25 by sewardj] · 665229e5
      sewardj authored
      Major thing: new register allocator.  Brief description follows.
      Should correctly handle code with loops in, even though we don't
      generate any such at the moment.  A lot of comments.  The previous
      machinery for spilling is retained, as is the idea of a fast-and-easy
      initial allocation attempt intended to deal with the majority of code
      blocks (about 60% on x86) very cheaply.  Many comments explaining
      in detail how it works :-)
      
      The Stix inliner is now on by default.  Integer code seems to run
      within about 1% of that -fvia-C.  x86 fp code is significantly worse,
      up to about 30% slower, depending on the amount of fp activity.
      
      Minor thing: lazyfication of the top-level NCG plumbing, so that the
      NCG doesn't require any greater residency than compiling to C, just a
      bit more time.  Created lazyThenUs and lazyMapUs for this purpose.
      
      The new allocator is somewhat, although not catastophically, slower
      than the old one.  Fixing of the long-standing NCG space leak more
      than makes up for it; overall hsc run-time is down about 5%, due to
      significantly reduced GC time.
      
      --------------------------------------------------------------------
      
      Instructions are numbered sequentially, starting at zero.
      
      A flow edge (FE) is a pair of insn numbers (MkFE Int Int) denoting
      a possible flow of control from the first insn to the second.
      
      The input to the register allocator is a list of instructions, which
      mention Regs.  A Reg can be a RealReg -- a real machine reg -- or a
      VirtualReg, which carries a unique.  After allocation, all the
      VirtualReg references will have been converted into RealRegs, and
      possibly some spill code will have been inserted.
      
      The heart of the register allocator works in four phases.
      
      1.  (find_flow_edges) Calculate all the FEs for the code list.
          Return them not as a [FE], but implicitly, as a pair of
          Array Int [Int], being the successor and predecessor maps
          for instructions.
      
      2.  (calc_liveness) Returns a FiniteMap FE RegSet.  For each
          FE, indicates the set of registers live on that FE.  Note
          that the set includes both RealRegs and VirtualRegs.  The
          former appear because the code could mention fixed register
          usages, and we need to take them into account from the start.
      
      3.  (calc_live_range_sets) Invert the above mapping, giving a
          FiniteMap Reg FeSet, indicating, for each virtual and real
          reg mentioned in the code, which FEs it is live on.
      
      4.  (calc_vreg_to_rreg_mapping) For virtual reg, try and find
          an allocatable real register for it.  Each real register has
          a "current commitment", indicating the set of FEs it is
          currently live on.  A virtual reg v can be assigned to
          real reg r iff v's live-fe-set does not intersect with r's
          current commitment fe-set.  If the assignment is made,
          v's live-fe-set is union'd into r's current commitment fe-set.
          There is also the minor restriction that v and r must be of
          the same register class (integer or floating).
      
          Once this mapping is established, we simply apply it to the
          input insns, and that's it.
      
          If no suitable real register can be found, the vreg is mapped
          to itself, and we deem allocation to have failed.  The partially
          allocated code is returned.  The higher echelons of the allocator
          (doGeneralAlloc and runRegAlloc) then cooperate to insert spill
          code and re-run allocation, until a successful allocation is found.
      665229e5
  4. 19 May, 2000 1 commit
  5. 18 May, 2000 1 commit
    • sewardj's avatar
      [project @ 2000-05-18 13:55:36 by sewardj] · 963cf411
      sewardj authored
      Teach the NCG about the dereferencing and naming conventions to be
      used when compiling for a DLLised world.  Some cleanups on the way
      too.  The scheme is that
      
      * All CLabels which are in different DLLs from the current module
        will, via the renamer, already be such that labelDynamic returns
        True for them.
      
      * Redo the StixPrim/StixMacro stuff so that all references to symbols
        in the RTS are via CLabels.  That means that the usual labelDynamic
        story can be used.
      
      * When a label is printed in PprMach, labelDynamic is consulted, to
        generate the __imp_ prefix if necessary.
      
      * In MachCode.stmt2Instrs, selectively ask derefDLL to walk trees
        before code generation and insert deferencing code around other-DLL
        symbols.
      
      * When generating Stix for SRTs, add 1 to other-DLL refs.
      
      * When generating static closures, insert a zero word before
        the _closure label.
      963cf411
  6. 16 Mar, 2000 1 commit
  7. 29 Feb, 2000 1 commit
  8. 28 Feb, 2000 1 commit
    • sewardj's avatar
      [project @ 2000-02-28 12:02:31 by sewardj] · 4070b105
      sewardj authored
      Many changes to improve the quality and correctness of generated code,
      both for x86 and all-platforms.  The intent is that the x86 NCG will
      now be good enough for general use.
      
      -- Add an almost-trivial Stix (generic) peephole optimiser, whose sole
         purpose is elide assignments to temporaries used only once, in the
         very next tree.  This generates substantially better code for
         conditionals on all platforms.  Enhance Stix constant folding to
         take advantage of the inlining.
      
         The inlining presents subsequent insn selection phases with more
         complex trees than would have previously been used to.  This has
         shown up several bugs in the x86 insn selectors, now fixed.
         (assumptions that data size is Word, when could be Byte,
          assumptions that an operand will always be in a temp reg, etc)
      
      -- x86: Use the FLDZ and FLD1 insns.
      
      -- x86: spill FP registers with 80-bit loads/stores so that
         Intel's extra 16 bits of accuracy are not lost.  If this isn't
         done, FP spills are not suitably transparent.  Increase the
         number of spill words available to 2048.
      
      -- x86: give the register allocator more flexibility in choosing
         spill temporaries.
      
      -- x86, RegAllocInfo.regUsage: fix error for GST, and rewrite to
         make it clearer.
      
      -- Correctly track movements in the C stack pointer, and generate
         correct spill code for archs which spill against the stack pointer
         even when the stack pointer moves.  Redo the x86 ccall mechanism
         to push args on the C stack in the normal way.  Rather than have
         the spiller have to analyse code sequences to determine the current
         stack offset, the insn selectors communicate the current offset
         whenever it changes by inserting a DELTA pseudo-insn.  Then the
         spiller only has to spot DELTAs.
      
         This means having a new native-code-generator monad (Stix.NatM)
         which carries both a UniqSupply and the current stack offset.
      
      -- Remove the asmPar/asmSeq ways of grouping insns together.
         In the presence of fixed registers, it is hard to demonstrate
         that insn selectors using asmPar always give correct code, and
         the extra complication doesn't help any.
      
         Also, directly construct code sequences using tree-based ordered
         lists (utils/OrdList.lhs) for linear-time appends, rather than
         the bizarrely complex method using fns and fn composition.
      
      -- Inline some hcats in printing of x86 address modes.
      
      -- Document more of the hidden assumptions which insn selection relies
         on, particular wrt addressing modes.
      4070b105
  9. 03 Feb, 2000 1 commit
    • sewardj's avatar
      [project @ 2000-02-03 18:01:03 by sewardj] · 1aa0765b
      sewardj authored
      Fix x86 NCG so the compiler can compile itself `-O':
      
      -- Implement fake x86 insn GITOD/GITOF.
      -- Implement primops ReadMutVarOp and WriteMutVarOp.
      -- Pro tem, disable use of %eax as a spill temp.
      -- Clarify wording of Rules of the Game comment in MachCode.
      1aa0765b
  10. 02 Feb, 2000 1 commit
    • sewardj's avatar
      [project @ 2000-02-02 11:40:33 by sewardj] · a040ea4a
      sewardj authored
      trivialCode on x86 is the heart of instruction selection for
      expressions.  It is definitely a non-trivial in complexity.
      To generate correct code it needs to observe preserve several
      delicate invariants, but didn't.
      
      -- Recorded in MachCode.lhs the "Rules of the Game"; ie what I think
         the required invariants are.
      
      -- Completely rewrote trivialCode (also shift_code).  I think it should
         handle all cases correctly, and has special treatment for literal
         operands.
      
      -- Updated NOTES file to record issues which need to be resolved
         before x86 nativeGen can be considered ready for public use.
      a040ea4a
  11. 01 Feb, 2000 1 commit
    • sewardj's avatar
      [project @ 2000-02-01 14:02:02 by sewardj] · 85ef3b32
      sewardj authored
      -- Cosmetic changes in register allocator.
      
      -- Implement macro HP_GEN_SEQ_NP.
      
      -- MachCode(trivialCode, x86): because one of the operands is also
         the destination (on this 2-address arch), it's invalid to sequence
         the code to compute the operands using asmParThen [code1, code2].
         since the order of assignments matters.  Fixed.
      85ef3b32
  12. 31 Jan, 2000 1 commit
  13. 28 Jan, 2000 2 commits
    • sewardj's avatar
      [project @ 2000-01-28 18:07:55 by sewardj] · c39373f1
      sewardj authored
      Modifications to make x86 register spilling to work reasonably.  It
      should work ok most of the time, although there is still a remote
      possibility that the allocator simply will be unable to complete
      spilling, and will just give up.
      
      -- Incrementally try with 0, 1, 2 and 3 spill regs, so as not to
         unduly restrict the supply of regs in code which doesn't need spilling.
      
      -- Remove the use of %ecx for shift values, so it is always available
         as the first-choice spill temporary.  For code which doesn't do
         int division, make %edx and %eax available for spilling too.
         Shifts by a non-constant amount (very rare) are now done by
         a short test-and-jump sequence, so that %ecx is not tied up.
      
      -- x86 FP: do sin, cos, tan in-line so we get the same answers as gcc.
      
      -- Moved a little code around to remove recursive dependencies.
      
      -- Fix a subtle bug in x86 regUsage, which could cause underestimation
         of live ranges.
      c39373f1
    • sewardj's avatar
      [project @ 2000-01-28 09:40:05 by sewardj] · 8252a068
      sewardj authored
      Commit all changes prior to addressing the x86 spilling situation in
      the register allocator.
      
      -- Fix nonsensical x86 addressing mode hacks in mangleIndexTree
         and getAmode.
      
      -- Make char-sized loads work properly, using MOVZBL.
      
      -- In assignIntCode, use primRep on the assign node to determine
         the size of data transfer, not the size of the source.
      
      -- Redo Integer primitives to be in line with current representation
         of Integers.
      8252a068
  14. 26 Jan, 2000 1 commit
  15. 25 Jan, 2000 4 commits
    • sewardj's avatar
      [project @ 2000-01-25 20:08:33 by sewardj] · db0b3140
      sewardj authored
      Print a useful panic msg if getRegister(x86) can't reduce a tree.
      db0b3140
    • sewardj's avatar
      [project @ 2000-01-25 19:33:32 by sewardj] · 7ed63dba
      sewardj authored
      Handle float args correctly for x86 ccalls.
      7ed63dba
    • sewardj's avatar
      [project @ 2000-01-25 19:18:42 by sewardj] · 172e212b
      sewardj authored
      Disable a dubious looking clause for trivialCode (x86), which was
      generating bad code for some subtracts.
      172e212b
    • sewardj's avatar
      [project @ 2000-01-25 10:22:55 by sewardj] · b539a820
      sewardj authored
      genCCall for x86, as supplied, used PUSH et al to move args onto the C
      stack ready for the call.  Reasonable as this seems, it causes a
      problem with spill code, since the spiller spills relative to %esp and
      assumes that %esp doesn't move.  If the args of a ccall involved any
      spilled values, the resulting code would be wrong.
      
      The One True Way is to do it like a RISC: move args to the stack
      without adjusting %esp for each argument, then adjust it all at once
      immediately prior to the call insn and un-adjust it immediately
      afterwards.  genCCall now does this.  In general, push/pop and other
      C-stack effecting operations should not be generated for the same
      reason.
      b539a820
  16. 24 Jan, 2000 1 commit
    • sewardj's avatar
      [project @ 2000-01-24 17:24:23 by sewardj] · e2a7f079
      sewardj authored
      Major reworking of the x86 floating point code generation.
      
      Intel, in their infinite wisdom, selected a stack model for floating
      point registers on x86.  That might have made sense back in 1979 --
      nowadays we can see it for the nonsense it really is.  A stack model
      fits poorly with the existing nativeGen infrastructure, which assumes
      flat integer and FP register sets.  Prior to this commit, nativeGen
      could not generate correct x86 FP code -- to do so would have meant
      somehow working the register-stack paradigm into the register
      allocator and spiller, which sounds very difficult.
      
      We have decided to cheat, and go for a simple fix which requires no
      infrastructure modifications, at the expense of generating ropey but
      correct FP code.  All notions of the x86 FP stack and its insns have
      been removed.  Instead, we pretend (to the instruction selector and
      register allocator) that x86 has six floating point registers, %fake0
      .. %fake5, which can be used in the usual flat manner.  We further
      claim that x86 has floating point instructions very similar to SPARC
      and Alpha, that is, a simple 3-operand register-register arrangement.
      Code generation and register allocation proceed on this basis.
      
      When we come to print out the final assembly, our convenient fiction
      is converted to dismal reality.  Each fake instruction is
      independently converted to a series of real x86 instructions.
      %fake0 .. %fake5 are mapped to %st(0) .. %st(5).  To do reg-reg
      arithmetic operations, the two operands are pushed onto the top of the
      FP stack, the operation done, and the result copied back into the
      relevant register.  There are only six %fake registers because 2 are
      needed for the translation, and x86 has 8 in total.
      
      The translation is inefficient but is simple and it works.  A cleverer
      translation would handle a sequence of insns, simulating the FP stack
      contents, would not impose a fixed mapping from %fake to %st regs, and
      hopefully could avoid most of the redundant reg-reg moves of the
      current translation.
      e2a7f079
  17. 20 Jan, 2000 1 commit
  18. 19 Jan, 2000 2 commits
  19. 18 Jan, 2000 3 commits
  20. 13 Jan, 2000 1 commit
  21. 22 Dec, 1999 1 commit
  22. 20 Dec, 1999 1 commit
  23. 01 Mar, 1999 1 commit
  24. 25 Jan, 1999 1 commit
  25. 18 Dec, 1998 1 commit
    • simonpj's avatar
      [project @ 1998-12-18 17:40:31 by simonpj] · 7e602b0a
      simonpj authored
      Another big commit from Simon.  Actually, the last one
      didn't all go into the main trunk; because of a CVS glitch it
      ended up in the wrong branch.
      
      So this commit includes:
      
      * Scoped type variables
      * Warnings for unused variables should work now (they didn't before)
      * Simplifier improvements:
      	- Much better treatment of strict arguments
      	- Better treatment of bottoming Ids
      	- No need for w/w split for fns that are merely strict
      	- Fewer iterations needed, I hope
      * Less gratuitous renaming in interface files and abs C
      * OccName is a separate module, and is an abstract data type
      
      I think the whole Prelude and Exts libraries compile correctly.
      Something isn't quite right about typechecking existentials though.
      7e602b0a
  26. 02 Dec, 1998 1 commit
  27. 19 Aug, 1998 1 commit
  28. 14 Aug, 1998 1 commit
    • sof's avatar
      [project @ 1998-08-14 12:00:22 by sof] · 91b4fb8d
      sof authored
      StCall now takes extra callconv arg; StixPrim.primCode doesn't flush stdout and stderr anymore (it's done in the .hc code)
      91b4fb8d
  29. 07 Apr, 1998 1 commit
  30. 21 Jan, 1998 1 commit
  31. 08 Jan, 1998 1 commit
    • simonm's avatar
      [project @ 1998-01-08 18:03:08 by simonm] · 9dd6e1c2
      simonm authored
      The Great Multi-Parameter Type Classes Merge.
      
      Notes from Simon (abridged):
      
      * Multi-parameter type classes are fully implemented.
      * Error messages from the type checker should be noticeably improved
      * Warnings for unused bindings (-fwarn-unused-names)
      * many other minor bug fixes.
      
      Internally there are the following changes
      
      * Removal of Haskell 1.2 compatibility.
      * Dramatic clean-up of the PprStyle stuff.
      * The type Type has been substantially changed.
      * The dictionary for each class is represented by a new
        data type for that purpose, rather than by a tuple.
      9dd6e1c2
  32. 20 Nov, 1997 1 commit