Path: utzoo!attcan!uunet!cs.utexas.edu!rice!titan.rice.edu!preston From: preston@titan.rice.edu (Preston Briggs) Newsgroups: comp.arch Subject: Re: speculative execution Message-ID: <1990Oct11.191126.21408@rice.edu> Date: 11 Oct 90 19:11:26 GMT References: <1990Oct10.164353.21070@rice.edu> <2321@charon.cwi.nl> Sender: news@rice.edu (News) Organization: Rice University, Houston Lines: 85 I suggested the trickiness of hoisting pipeline filling instructions above a conditional. The result looked like this >>> int-1, pfmul.ss f3,f4,f0 <--- These floats hoisted from >>> int-2, pfmul.ss f0,f0,f0 <--- from the if >>> int-3, pfmul.ss f0,f0,f0 >>> if (something) { >>> pfmul.ss f0,f0,f5 >>> } >>> fst.l f5,somewhere >>> The true path get much shorter. >>> No increase in the path length of the false path. >>> And no extra register required. >philip@beeblebrox.dle.dg.com (Philip Gladstone) writes: >> It seems to me that it is very difficult to spot when this is legal or not. >> It is assumed in this example that none of the hoisted instructions >> will cause any problems if they are executed when the programmer did >> not intend them to be executed. But we *can* check for legality. Generally, I must not overwrite any registers or memory locations that are live on the other path. Further, I should trigger no traps. This means being careful about loads, etc... and dik@cwi.nl (Dik T. Winter) writes: [says that I'm reasonably ok on result traps] >There is another aspect: after >the three pfmul instructions the pipeline is filled in an indeterminate >state if the false path is to be taken. There might be an overflow status >or somesuch pending in the last stage, and that must be cleared. The pipe would have to be drained, but we must always drain the pipe anyway. So, if at some later point in the program, I perform a multiply, the first 3 pfmul's must direct their (unspecified) values into f0. But we always have to do this anyway. And, as you point out, a scalar (non-pipelined) multiply will overwrite the pipe. So, if we'd had an if-then-else instead, we might get this result. int-1, pfmul.ss f3,f4,f0 <--- These floats hoisted from int-2, pfmul.ss f0,f0,f0 <--- from the then clause int-3, pfmul.ss f0,f0,f0 if (something) { pfmul.ss f0,f0,f5 } else { pfmul.ss f7,f8,f0 -- draining the pipe pfmul.ss f0,f0,f0 pfmul.ss f0,f0,f0 pfmul.ss f0,f0,f5 } fst.l f5,somewhere The point is that the else clause is unchanged. Actually, we could build this form int-1, pfmul.ss f3,f4,f0 <--- These floats hoisted from int-2, pfmul.ss f7,f8,f0 <--- from the then clause int-3, pfmul.ss f0,f0,f0 if (something) { pfmul.ss f0,f0,f5 } else { pfmul.ss f0,f0,f0 pfmul.ss f0,f0,f5 } fst.l f5,somewhere Note also that the scalar multiply doesn't "clear the pipe"; it just overwrites it with new junk. We need to be careful to drain this new junk to avoid traps. Recently I tried to use the "r2pt.ss f10,f0,f0" instruction to set the KR register to f10. Unfortunately, this may provoke a source exception trap from the adder if the multiply pipeline is not in some nice state. -- Preston Briggs looking for the great leap forward preston@titan.rice.edu