diff options
author | David Terei <davidterei@gmail.com> | 2011-10-17 14:50:09 -0700 |
---|---|---|
committer | David Terei <davidterei@gmail.com> | 2011-10-17 14:50:09 -0700 |
commit | c726526a03f62802254f4dfcd826e48456bb831e (patch) | |
tree | a73631effcc8baa56ab9f0aeb794d570e0245ad6 | |
parent | 6f43ec8ca0e4edfe9b449e3df10f01d5d3d36331 (diff) | |
download | haskell-c726526a03f62802254f4dfcd826e48456bb831e.tar.gz |
remove some old files
-rw-r--r-- | driver/ordering-passes | 257 | ||||
-rw-r--r-- | driver/test_mangler | 29 |
2 files changed, 0 insertions, 286 deletions
diff --git a/driver/ordering-passes b/driver/ordering-passes deleted file mode 100644 index 305f3f06b4..0000000000 --- a/driver/ordering-passes +++ /dev/null @@ -1,257 +0,0 @@ - Ordering the compiler's passes - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Change notes -~~~~~~~~~~~~ -1 Nov 94 * NB: if float-out is done after strictness, remember to - switch off demandedness flags on floated bindings! -13 Oct 94 * Run Float Inwards once more after strictness-simplify [andre] - 4 Oct 94 * Do simplification between float-in and strictness [andre] - * Ignore-inline-pragmas flag for final simplification [andre] - -Aug 94 Original: Simon, Andy, Andre - - - - -This ordering obeys all the constraints except (5) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - full laziness - simplify with foldr/build - float-in - simplify - strictness - float-in - -[check FFT2 still gets benefits with this ordering] - -================================= - Constraints -================================= - -1. float-in before strictness. -Reason: floating inwards moves definitions inwards to a site at which -the binding might well be strict. - -Example let x = ... in - y = x+1 - in - ... -===> - let y = let x = ... in x+1 - in ... - -The strictness analyser will do a better job of the latter -than the former. - -2. Don't simplify between float-in and strictness, -unless you disable float-let-out-of-let, otherwise -the simiplifier's local floating might undo some -useful floating-in. - -Example let f = let y = .. in \x-> x+y - in ... -===> - let y = ... - f = \x -> x+y - in ... - -This is a bad move, because now y isn't strict. -In the pre-float case, the binding for y is strict. -Mind you, this isn't a very common case, and -it's easy to disable float-let-from-let. - -3. Want full-laziness before foldr/build. -Reason: Give priority to sharing rather than deforestation. - -Example \z -> let xs = build g - in foldr k z xs -===> - let xs = build g - in \x -> foldr k z xs - -In the post-full-laziness case, xs is shared between all -applications of the function. If we did foldr/build -first, we'd have got - - \z -> g k z - -and now we can't share xs. - - -4. Want strictness after foldr/build. -Reason: foldr/build makes new function definitions which -can benefit from strictness analysis. - -Example: sum [1..10] -===> (f/b) - let g x a | x > 10 = a - | otherwise = g (x+1) (a+x) - -Here we clearly want to get strictness analysis on g. - - -5. Want full laziness after strictness -Reason: absence may allow something to be floated out -which would not otherwise be. - -Example \z -> let x = f (a,z) in ... -===> (absence anal + inline wrapper of f) - \z -> let x = f.wrk a in ... -===> (full laziness) - let x= f.wrk a in \z -> ... - -TOO BAD. This doesn't look a common case to me. - - -6. Want float-in after foldr/build. -Reason: Desugaring list comprehensions + foldr/build -gives rise to new float-in opportunities. - -Example ...some list comp... -==> (foldr/build) - let v = h xs in - case ... of - [] -> v - (y:ys) -> ...(t v)... -==> (simplifier) - let v = h xs in - case ... of - [] -> h xs - (y:ys) -> ...(t v)... - -Now v could usefully be floated into the second branch. - -7. Want simplify after float-inwards. -[Occurred in the prelude, compiling ITup2.hs, function dfun.Ord.(*,*)] -This is due to the following (that happens with dictionaries): - -let a1 = case v of (a,b) -> a -in let m1 = \ c -> case c of I# c# -> case c# of 1 -> a1 5 - 2 -> 6 -in let m2 = \ c -> case c of I# c# -> - case c# +# 1# of cc# -> let cc = I# cc# - in m1 cc - in (m1,m2) - -floating inwards will push the definition of a1 into m1 (supposing -it is only used there): - -in let m1 = let a1 = case v of (a,b) -> a - in \ c -> case c of I# c# -> case c# of 1 -> a1 5 - 2 -> 6 -in let m2 = \ c -> case c of I# c# -> - case c# +# 1# of cc# -> let cc = I# cc# - in m1 cc - in (m1,m2) - -if we do strictness analysis now we will not get a worker-wrapper -for m1, because of the "let a1 ..." (notice that a1 is not strict in -its body). - -Not having this worker wrapper might be very bad, because it might -mean that we will have to rebox arguments to m1 if they are -already unboxed, generating extra allocations, as occurs with m2 (cc) -above. - -To solve this problem we have decided to run the simplifier after -float-inwards, so that lets whose body is a HNF are floated out, -undoing the float-inwards transformation in these cases. -We are then back to the original code, which would have a worker-wrapper -for m1 after strictness analysis and would avoid the extra let in m2. - -What we lose in this case are the opportunities for case-floating -that could be presented if, for example, a1 would indeed be demanded (strict) -after the floating inwards. - -The only way of having the best of both is if we have the worker/wrapper -pass explicitly called, and then we could do with - -float-in -strictness analysis -simplify -strictness analysis -worker-wrapper generation - -as we would -a) be able to detect the strictness of m1 after the - first call to the strictness analyser, and exploit it with the simplifier - (in case it was strict). -b) after the call to the simplifier (if m1 was not demanded) - it would be floated out just like we currently do, before stricness - analysis II and worker/wrapperisation. - -The reason to not do worker/wrapperisation twice is to avoid -generating wrappers for wrappers which could happen. - - -8. If full laziness is ever done after strictness, remember to switch off -demandedness flags on floated bindings! This isn't done at the moment. - - -Ignore-inline-pragmas flag for final simplification -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -[Occurred in the prelude, compiling ITup2.hs, function dfun.Ord.(*,*)] -Sometimes (e.g. in dictionary methods) we generate -worker/wrappers for functions but the wrappers are never -inlined. In dictionaries we often have - -dict = let f1 = ... - f2 = ... - ... - in (f1,f2,...) - -and if we create worker/wrappers for f1,...,fn the wrappers will not -be inlined anywhere, and we will have ended up with extra -closures (one for the worker and one for the wrapper) and extra -function calls, as when we access the dictionary we will be acessing -the wrapper, which will call the worker. -The simplifier never inlines workers into wrappers, as the wrappers -themselves have INLINE pragmas attached to them (so that they are always -inlined, and we do not know in advance how many times they will be inlined). - -To solve this problem, in the last call to the simplifier we will -ignore these inline pragmas and handle the workers and the wrappers -as normal definitions. This will allow a worker to be inlined into -the wrapper if it satisfies all the criteria for inlining (e.g. it is -the only occurrence of the worker etc.). - -Run Float Inwards once more after strictness-simplify -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -[Occurred in the prelude, compiling IInt.hs, function const.Int.index.wrk] -When workers are generated after strictness analysis (worker/wrapper), -we generate them with "reboxing" lets, that simply reboxes the unboxed -arguments, as it may be the case that the worker will need the -original boxed value: - -f x y = case x of - (a,b) -> case y of - (c,d) -> case a == c of - True -> (x,x) - False -> ((1,1),(2,2)) - -==> (worker/wrapper) - -f_wrapper x y = case x of - (a,b) -> case y of - (c,d) -> f_worker a b c d - -f_worker a b c d = let x = (a,b) - y = (c,d) - in case a == c of - True -> (x,x) - False -> ((1,1),(2,2)) - -in this case the simplifier will remove the binding for y as it is not -used (we expected this to happen very often, but we do not know how -many "reboxers" are eventually removed and how many are kept), and -will keep the binding for x. But notice that x is only used in *one* -of the branches in the case, but is always being allocated! The -floating inwards pass would push its definition into the True branch. -A similar benefit occurs if it is only used inside a let definition. -These are basically the advantages of floating inwards, but they are -only exposed after the S.A./worker-wrapperisation of the code! As we -also have reasons to float inwards before S.A. we have to run it -twice. - diff --git a/driver/test_mangler b/driver/test_mangler deleted file mode 100644 index 96cf31ca68..0000000000 --- a/driver/test_mangler +++ /dev/null @@ -1,29 +0,0 @@ -#! /usr/bin/perl -# a simple wrapper to test a .s-file mangler -# reads stdin, writes stdout - -push(@INC,"/net/dazdak/BUILDS/gransim-4.04/i386-unknown-linux/ghc/driver"); - -$TargetPlatform = $ARGV[0]; shift; # nice error checking, Will - -require("ghc-asm.prl") || die "require mangler failed!\n"; - -$SpX86Mangling = 1; -$StolenX86Regs = 4; - -open(INP, "> /tmp/mangle1.$$") || die "Can't open tmp file 1\n"; -while (<>) { - print INP $_; -} -close(INP) || die "Can't close tmp file 1"; - -&mangle_asm("/tmp/mangle1.$$", "/tmp/mangle2.$$"); - -open(INP, "< /tmp/mangle2.$$") || die "Can't open tmp file 2\n"; -while (<INP>) { - print STDOUT $_; -} -close(INP) || die "Can't close tmp file 2"; - -unlink("/tmp/mangle1.$$", "/tmp/mangle2.$$"); -exit(0); |