Time-stamp: <98/05/12 21:09:50 mitchell>
Frequently Asked Questions
-
(6/4/98) (JF)
In Project 2, the assignment stated we should only make Phi functions for
pseudo registers. This does not seem to
suffice for constant propagation. This is because Suif unnecessarily
loads everything into temps before it loads them into pseudo registers.
If we treat every temp as NONCONSTs (we would have to because they aren't
in SSA form) there would be essentially no instructions that could be
optimized. See the sample code below.
- main() {
- int a,b,c;
- a = 3;
- b = 4;
- c = a + b;
}
- Procedure main:
- ldc (s.32) t4 = 3
- cpy (s.32) r1 = t4
- ldc (s.32) t5 = 4
- cpy (s.32) r2 = t5
- add (s.32) t6 = r1, r2
- cpy (s.32) r3 = t6
- ldc (s.32) t7 = 0
- ret t7
-
You are right, this is a problem with getting initial constants. To
fix it, you need to propagate the initial constant values from the temp
registers to the pseudo registers. You still don't need to add Phi functions
or do renaming for the temp registers.
-
(6/4/98) (JF)
In Project 2, is the algorithm for Sparse Conditional Constant Prop. in
the book correct? Consider the following
example. How does symbolic execution
ever reach the assignment to even3 on the second iteration of the loop?
- You have found a mistake in the algorithm in the book (and perhaps
the paper, but its ambiguous). To fix it, you need to change the Visit_Phi
routine. If the Lattice value of the Phi expression is lowered, then
the outgoing SSA edges from the Phi assignment need to be placed on SSAWL.
-
(5/12/98) (JF)
Is the algorithm for renaming in the SSA article correct?
-
YES. The algorithm assumes all statements are either ordinary
assignments or Phi functions. If A is an ordinary assignment (ie not
a Phi function) then the RHS is dealt with in the first loop. If A
is a Phi function, then the RSH is dealt with in the loop over Succ(X).
-
(5/7/98)
How should we print out variables?
-
I've updated names.c and names.h to add a new
function print_variable(simple_reg *).
-
(5/7/98)
Should still we print out the stuff from the first project for project 2?
-
(4/16/98)
How exactly should I print out the three outputs?
-
The three outputs will be three lists, so you can just print them out
one after the other, just make sure that you print them in this order:
CFG, dominator, loops.
-
(4/15/98) ****NICK MESS-UP ALERT!****
What's the definitive answer on basic block names?
- Oh boy, sorry about this. Check the updated answer below on basic
block names. In short, forget what I said about "first executable
instruction"; let's simply make it the first instruction (which might
be a label instruction, or might not be). I think we've gone full
circle, which means this time it's right, hehe.
-
(4/15/98) ****NOTE: THIS ANSWER HAS CHANGED, AGAIN!****
What about empty basic blocks (those with no instructions)?
- If you strictly follow the definition of maximal basic blocks, you
shouldn't run into any problems. If there is a suif label instruction,
but no jumps to this label, then that label does not start a basic
block. If there are two consecutive labels and distinct jumps to each
of the two labels, then each starts a (different) basic block!!
-
(4/15/98)
Does a RET mark the end of a basic block?
-
A RET is basically a "jump to register". a JMP is a "jump to
label". both transfer control and hence mark the end of a basic block.
Remember, we asked you to add two nodes to the CFG, "entry" and
"exit". So the RET instruction adds an edge from the current basic
block to "exit", whereas a JMP adds an edge from the current basic
block to whatever basic block exists at the label.
-
(4/13/98)
Can I modify doproc.c?
- Sure, you can write whatever code you want and put it in whatever
files you want.
-
(4/13/98)
What do you mean by "concatenation" as far as basic block names?
- Please see the item immediately below this one.
-
(4/13/98, updated 4/15/98) ****IMPORTANT****
What about those darn fall-throughs? simplesuif doesn't give them labels.
- Remember how the original handout specified how to name basic
blocks? The technique we suggested doesn't quite work. (sorry!) Here's a better
way. Assign every basic block a unique name which is
as follows. If the basic block occurs in
a file named filename and in a procedure named
procname and the first instruction
is the nth instruction the
simplesuif stream, then the basic block is given the name
filename_procname_n. Notice this clears up the problem with
fall-throughs not having simplesuif "labels". The implication of this
implementation is that we basically ignore simplesuif labels as far as
naming goes. This is probably as it should be.
-
(4/13/98)
Why?
- Jeeze! The simplesuif instructions you're given obviously must
have labels, right? or else the branches wouldn't go
anywhere. However, there is not a one-to-one relationship between
simplesuif "label instructions" and basic blocks. One of the goals of
this project is to find basic blocks (for the CFG). In this respect,
simplesuif "label instructions" aren't the most important concept
(i.e., they don't suffice to name basic blocks).
-
(4/13/98)
Whassup with the multiway branch?
- I don't think any language construct should require a multiway
branch for correctness, but it's not that much work to handle it,
anyway.
-
(4/13/98)
Can I use the C++ graph implementation in the jumpstart directory?
-
(4/9/98)
Can we make any assumptions about the input to our CFG generator?
I'm wondering if we should handle procedure calls and returns?
-
the only support for "calls and returns" is already in simplesuif;
it supports calls and returns
-
you don't need to create a basic block boundary at a procedure
call, because C and Fortran only allow returns to a single point
("jump to return register"), so:
-
basic block boundary
- load ...
- add ...
- call foo (no boundary before/after here)
- subtract ...
-
basic block boundary
-
you don't need to create an inter-procedural control-flow
graph. that is, if you have "foo calls bar returns to foo", then
the calling basic block from procedure "foo" doesn't need to have
an arrow to the target basic block in procedure "bar", and the
returning basic block(s) in bar don't need to point back to the
calling basic block in "foo".