Commit graph

283 commits

Author SHA1 Message Date
Bill Currie
85e6dd965f Treat aliases of the same basic type as no-ops.
At the statement level, all pointer types are the same, so just return the
op obtained from the sub-expression when the low-level type of the alias
expression matches the low-level type of the type of type sub-expression
operand.

With this, the alias of a value code can be removed (I always thought it
was wrong), which is what broke calling obj_msgSend_super (type &.super
param lost the &).

Now I have to deal with pointer values in the optimizer :/
2012-12-11 20:44:40 +09:00
Bill Currie
7607c7d649 Resurrect alias operands.
It turns out they are necessary for the code output from dags. This fixes
the ice for *to = *from++;
2012-12-11 15:52:37 +09:00
Bill Currie
6b4efaa3e4 Link temp aliases to their main def.
This fixes the kill sets not building properly.
2012-12-11 12:57:37 +09:00
Bill Currie
b5a72320bb Make alias defs and temps more obvious in dumps. 2012-12-11 12:26:48 +09:00
Bill Currie
eb8fd55677 Move set.c into libQFutil.
Also move the ALLOC/FREE macros from qfcc.h to QF/alloc.h (needed to for
set.c).

Both modules are more generally useful than just for qfcc (eg, set
builtins for ruamoko).
2012-12-06 20:52:53 +09:00
Bill Currie
b6ae9867c2 Fully connect temps and their aliases. 2012-12-06 09:40:16 +09:00
Bill Currie
34e3ac1468 Fix jumpb's operand types.
Aliasing the jump table to an integer broke statement_get_targetlist with
the new alias def handling, and was really wrong anyway. I probably did
that due to being fed up with things and wanting to get qfcc working again
rather than spending time getting jumpb right.
2012-12-05 22:20:55 +09:00
Bill Currie
3f3b501c58 Move flowvar/deflabel from symbol_t to def_t.
With the need to handle aliasing in the optimizer, it has become apparent
that having the flow data attached to symbols is not nearly as useful as
having it attached to defs (which are views of the actual variables).

This also involves a bit of a cleanup of operand types: op_pointer and
op_alias are gone (this seems to greatly simplify the optimizer)

There is a bit of a problem with enums in switch statements, but this might
actually be a sign that something is not quite right in the switch code
(other than enums not being recognized as ints for jump table
optimization).
2012-12-05 19:47:22 +09:00
Bill Currie
98a0afa38f Add and use FREE() to complement ALLOC().
Now it will be easy to test memory access with valgrind (just compile with
DEBUG_QFCC_MEMORY defined).
2012-12-04 13:23:31 +09:00
Bill Currie
5725c5124c Rename the storage_class_t enum values.
With the intoduction of the statement type enum came a prefix clash. As
"st" makes sense for "statement type", I decided that "storage class"
should be "sc". Although there haven't been any problems as of yet, I
decided it would be a good idea to clean up the clash now. It also helps
avoid confusion (I was a bit surprised after working with st_assign etc to
be reminded of st_extern etc).
2012-12-02 10:11:30 +09:00
Bill Currie
d47fa0fc89 Make the new optimizations optional.
The usual -O :) (no numbers yet, though). Alternatively, -C [no-]optimize
may be used.
2012-12-01 11:13:45 +09:00
Bill Currie
848493379d Support calls through function temps.
I had forgotten function vars stored in ents and objects would use a temp
when calling the function.
2012-12-01 11:10:47 +09:00
Bill Currie
554b2e4710 Add flow analysis to determin the type of .return.
It doesn't quite work yet, but...

It has proven necessary to know what type .return has at any point in the
function. The segfault in ctf is caused by the return statement added to
the end of the void function messing with the expr pointer stored in the
daglabel for .return. While this is actually by design (though the
statement really should have a valid expr pointer rather than), it actually
highlights a bigger problem: there's no stable knowledge of the current
type of .return. This is not a problem in expression statements as the
dagnodes for expression statements store the desired types of all operands.
However, when assigning from .return to attached variables in a leaf node,
the type of .return is not stored anywhere but the expression last
accessing .return.
2012-11-30 17:15:05 +09:00
Bill Currie
93f53605ed Move and rename statement related flow_is_* and flow_get_*
They really should have been in statements.[ch] in the first place
(actually, they sort of were: is_goto etc, so some redundant code has been
removed, too).
2012-11-30 14:06:52 +09:00
Bill Currie
c4ba294433 Fix the icky fixme :) 2012-11-27 20:32:52 +09:00
Bill Currie
31b07bcbbf Rewrite expr_alias().
Modifying the existing alias chain proved to be a bad idea (in retrospect,
I should have known better:P). Instead, just walk down any existing alias
chain to the root operand and build a new alias from that.
2012-11-27 18:33:41 +09:00
Bill Currie
d6b38dd0ee Add an option to control expr tree dumping.
About bloody time :P
2012-11-26 21:00:28 +09:00
Bill Currie
8e225cd726 Fix a missing label use count decrement.
if statements in dead code weren't being removed due to the label.
2012-11-26 16:13:59 +09:00
Bill Currie
578ad07487 Fix yet another empty block issue.
I think I need to rework all the code in there, but this will do for now.
2012-11-25 15:01:36 +09:00
Bill Currie
4f8b3b5692 More empty block checks. 2012-11-24 19:06:10 +09:00
Bill Currie
6e7aaac1b9 Fix the wording of a comment. 2012-11-24 19:06:01 +09:00
Bill Currie
7f229b7682 Remove execessive html quoting.
Heh, I must have put that in long before I did the quoting functions.
2012-11-24 15:42:21 +09:00
Bill Currie
f4604d9db5 Remove gotos that go to the following statement.
eg:
	goto foo:
foo:
	//some code
2012-11-24 15:08:48 +09:00
Bill Currie
0dea564cb4 Be more careful of empty sblocks.
Accessing the final statement of an sblock via tail doesn't work in an
empty sblock because tail points to sblock->statements and thus the cast is
invalid. This bug has be lurking for a long time, but for some reason the
cse stuff tickled it (thankfully!!!).
2012-11-19 16:11:07 +09:00
Bill Currie
d1252813ce Use low_level_type instead of extract_type.
extract_type doesn't understand enums (by design?). qwaq's types.r now
compiles.
2012-11-19 13:49:34 +09:00
Bill Currie
f2cc82469a Use the correct field when dechaining aliases.
op_type and type always confuse me :P
2012-11-19 12:53:08 +09:00
Bill Currie
e70b59b925 Don't null the def pointer when freeing a temp.
It makes debugging more difficult.
2012-11-19 11:02:31 +09:00
Bill Currie
0c3aeb30aa Reuse tempary variables.
Now that I've got nice code, it was worth doing. Unfortunatly, bsearch
style switch statements have problems.
switch.r:14: BUG: temp users went negative: <tmp 0x21b6840:-1>
switch.r:14: BUG: temp users went negative: <tmp 0x21b6840:-2>
switch.r:14: BUG: temp users went negative: <tmp 0x21b6840:-3>
switch.r:14: BUG: temp users went negative: <tmp 0x21b67d0:-1>
2012-11-18 19:10:18 +09:00
Bill Currie
1100efba54 Nuke find_operands in favor of flow_analyze_statement.
flow_analyze_statement uses the statement type to quickly determin which
operands are inputs and which are outputs. It takes (optional) sets for
used variables, defined variables and killed variables (only partially
working, but I don't actually use kill sets yet). It also takes an optional
array for storing the operands: index 0 is the output, 1-3 are the inputs.
flow_analyze_statement clears any given sets on entry.

Live variable analysis now uses the sets rather than individual vars. Much
cleaner code :).

Dags are completely broken.
2012-11-16 19:33:37 +09:00
Bill Currie
001e1ac059 Classify statements into broad types.
The types are expression, assignment, pointer assignment (ie, write to a
dereferenced pointer), move (special case of pointer assignment), state,
function call/return, and flow control. With this classification, it will
be easier (less code:) to determine which operands are inputs and which are
outputs.
2012-11-16 16:16:06 +09:00
Bill Currie
b8b626ee81 Change the int<->float conversion opcode string.
Using "=" was rather confusing, so changing it to "<CONV>" seems to be a
good idea. As the string is used only for selecting opcodes at compile
time, only qfcc is affected.
2012-11-16 14:45:11 +09:00
Bill Currie
c1a5c1a7b2 Create alias_operand (). 2012-11-15 15:52:30 +09:00
Bill Currie
095210893f Ensure alias operands are never nested.
No more than one level of aliasing is ever needed, so strip off any
intervening aliases that show up.
2012-11-15 15:18:00 +09:00
Bill Currie
1c32ac8ce6 Expose new_statement, too. 2012-11-15 13:44:09 +09:00
Bill Currie
802e1981bb Expose some statements functions needed for code gen. 2012-11-15 13:44:09 +09:00
Bill Currie
c43a8331cf Expose dump_dot_sblock. 2012-11-15 13:44:09 +09:00
Bill Currie
c358a0e77e Create a function to generalize dot dumping.
Now, any time a graph is wanted, the file can be consistently named without
a lot of messy code.
2012-11-15 13:44:08 +09:00
Bill Currie
5051c922a5 Ensure alias operands are properly freed. 2012-11-15 13:44:08 +09:00
Bill Currie
3298e4d67e Ensure find_operands sets the operands to known values.
This fixes the last of the bogus live variables.
2012-11-15 13:44:08 +09:00
Bill Currie
c00e666668 Expose find_operands.
It has proven to be a generally useful function, not just for dags.
2012-11-15 13:44:08 +09:00
Bill Currie
7404aacab7 Resurrect dags building and printing.
However, this time it's done after the statement recording (so the
statement numbers are set).
2012-11-15 13:44:08 +09:00
Bill Currie
8844ac61a2 Rename dump_flow to dump_sblock and move to dot_sblock.c 2012-11-15 13:44:07 +09:00
Bill Currie
8b374305d2 Rename dot_flow.c and print_flow.
They're now dot_sblock.c and print_sblock. The new names both better
reflect their purpose and free up "flow" for outputting the real flow
analysis graphs.
2012-11-15 13:44:07 +09:00
Bill Currie
7853bf1859 Calculate a node's successors and predecessors.
The dot graphs are a little odd (arrow heads on the wrong end of the
predecessor edges), but things seem to be correct.
2012-11-15 13:44:06 +09:00
Bill Currie
a22260030a Use value for pointer operands.
This allows daglabels on pointer operands without a redundant daglabel
pointer.
2012-11-15 13:44:06 +09:00
Bill Currie
28ce35f1c1 Make values independent objects.
values are now uniquely allocated (for the current object file). With
this, constants in dags will work.
2012-11-15 13:44:06 +09:00
Bill Currie
dbf1aa8f72 Attach dags to statement blocks.
Now, if a dag is attached to a statement block, it will be included in the
flowgraph with that statement block.
2012-11-15 13:44:06 +09:00
Bill Currie
9bc65ffedb Start actually trying to build dags.
Temporary variables aren't being handled correctly (treated as constants),
but it looks like a good start.
2012-11-15 13:44:05 +09:00
Bill Currie
6ff2644ab5 Fix simple pointer dereferences.
It turns out no code was being generated for x = *y. Ouch. I suspect I need
to take a better look at expr_deref at some time in the not too distant
future.

Conflicts:
	tools/qfcc/source/statements.c
2012-11-09 12:32:35 +09:00
Bill Currie
9095e1eabc Rework build_switch to use initialize_def.
This required support for label reference expressions, whose purpose is to
represent the address of a label.
2012-11-09 12:22:34 +09:00
Bill Currie
61ef901254 Tweak some FIXMEs. 2012-11-08 17:03:02 +09:00
Bill Currie
5c79953a7e Put quotes around strings for statement operands.
This makes reading output a bit easier (especially if the string is empty
or just whitespace).
2012-10-30 12:31:28 +09:00
Bill Currie
034139b806 Move some code around so it's more accessible. 2012-10-27 11:43:29 +09:00
Bill Currie
56410ddc58 Prevent merged if/goto losing its way.
When mering if/goto (ie, if skipping a goto), the rest of the dead code
remover is used to delete the goto. That part of the code unuses the goto's
label. The if was getting the goto's label without the lable's used count
being incremented (the usaged temporarily increases by one). I have no idea
why the problem showed up randomly, but this seems to fix it (it fixes /a/
bug, anyway).
2012-05-04 22:35:20 +09:00
Bill Currie
953e789db2 Handle movement of the final block.
Moving a final block caused segfaults and weird flow graph corruptions.
2012-05-04 19:48:32 +09:00
Bill Currie
5df25133b3 Implement code movement for unconditional jumps.
That is, when the destination of the jump is reachable via only the jump.
2012-05-04 18:00:05 +09:00
Bill Currie
33bfac0508 Process all basic blocks for jump threading.
I'd copied the for loop from the dead block removal code, but jump
threading doesn't need to look at the following block...
2012-05-04 14:10:30 +09:00
Bill Currie
f169a7732d Factor out label unuse.
I expect to need this more often in the future.
2012-05-04 14:01:39 +09:00
Bill Currie
75aa28cfac Mark all subsequent blocks as reachable after if/goto merge.
If an if/goto merge is done in the first dead block pass, no blocks after
the merge have their rechable flag set because they've never been tested.
2012-05-04 10:58:18 +09:00
Bill Currie
8ddd58f951 Fix the dropping of the block after the merged if/goto.
The naive implementation of the if/goto merging was letting the old target
of the if get dropped because the block would lose its label and thus be
judged unreachable because the preceeding goto block was still in the list.
Instead, when the if/goto are "merged", mark the goto block as unreachable,
the following block as reachable, and break out of the analysis loop to
force the removal of the goto block. Since the dead block removal function
loops until no action is taken, all other dead blocks will be removed.
2012-05-04 10:07:55 +09:00
Bill Currie
e866619de6 Output basic block flow diagrams to files.
The output can be controlled via --block-dot (not yet documented). The
files a named <sourcefile>.<function>.<stage>.dot. Currently, stage will be
one of "initial" (after expression to statement conversion), "thread"
(after jump threading), "dead" (after dead block removal), "final" (final
state before actual code emission).
2012-05-04 09:45:51 +09:00
Bill Currie
3da44ace52 Merge if and goto blocks when if only skips over the goto. 2012-05-03 22:21:32 +09:00
Bill Currie
6afdfb5fac Unuse label expressions that are no longer necessary. 2012-05-03 22:20:00 +09:00
Bill Currie
402a578bf8 Add some more helper functions.
Things were getting messy with the strcmps.
2012-05-03 22:17:23 +09:00
Bill Currie
88bed3644e Rename some helper functions. 2012-05-03 22:11:52 +09:00
Bill Currie
6900907129 Remove dead labels when jump threading.
This lets the dead block removal do a better job.
2012-05-03 19:32:44 +09:00
Bill Currie
ab73a267cd Do not unconditionally remove labels from blocks.
Labels can be shared between multiple flow-control instructions, so use the
label's used counter to determine when to remove the label. This was
causing problems with the jump threading.
2012-05-03 19:22:57 +09:00
Bill Currie
43b5edf46b Implement jump threading.
First real optimization :)
2012-05-03 17:42:58 +09:00
Bill Currie
bc1b483525 Nuke the rcsid stuff.
It's pretty useless in git.
2012-04-22 10:56:32 +09:00
Bill Currie
c7612dcd99 Make statement dumps a little more informative. 2011-04-10 09:08:46 +09:00
Bill Currie
55cc0f9206 Bring back the unsigned type (PROGS version bump)
This is only low-level support (the unsigned keyword still does not work),
but sufficient to make switch statements using jump tables work.
2011-04-09 10:07:47 +09:00
Bill Currie
237f11c472 Fix cast expressions.
Casting between ints and floats needs special treatment to get the
conversion operator, but other casts need to be aliases.
2011-04-08 13:55:26 +09:00
Bill Currie
8d3508cf20 Allocate space for temp defs using size rather than type.
Statement operands throw away the high level type information, so store
type size in the operand and use this size for allocating space for temps
rather than using the low-level type.
2011-03-23 21:32:14 +09:00
Bill Currie
5aa0b34570 Add the cast statement to the statement block.
*sob*
2011-03-10 20:43:53 +09:00
Bill Currie
2129eaaf20 Dereference moves need movepi rather than movei. 2011-03-10 19:29:23 +09:00
Bill Currie
39278ba8cc Explicitly select between direct and indirect moves. 2011-03-09 10:30:57 +09:00
Bill Currie
5a78758781 Support return in void functions in v6 code. 2011-03-07 13:52:28 +09:00
Bill Currie
17a9dff769 Avoid freeing an operand twice.
Due to the way operands are used, they can be freed twice in dead-statement
removal. Detect the double-free and ignore it.
2011-03-06 11:19:09 +09:00
Bill Currie
ee9045c377 Emit code for jump tables.
With this, the entirety of the ruamoko tree builds (though the progs will
be broken in various ways: mostly unrelocated references).
2011-03-03 19:09:00 +09:00
Bill Currie
4324486ae6 Give - unary expressions special treatment.
The progs engine has no neg instruction, so need to implement -val as
nil - val
2011-03-03 18:13:30 +09:00
Bill Currie
f9e177efd6 Obtain the label to be removed from the correct place.
This fixes the undetected dead block after "if return else return".
2011-03-03 17:50:46 +09:00
Bill Currie
ed901bd48f Drop unused labels rather than adding them to the statement block.
However, even unused labels create a new statement block if necessary.
2011-03-03 17:35:06 +09:00
Bill Currie
c5ecc170b6 Give labels a usage count to detect unused labels. 2011-03-03 15:28:49 +09:00
Bill Currie
d937172243 Create and use alias operands for alias expressions.
This avoids the alias expression modifying the operand used in other
expressions.
2011-03-03 13:46:07 +09:00
Bill Currie
022fde666f Implement unary expression statements. 2011-03-03 13:10:07 +09:00
Bill Currie
45de7327dc Implement alias expressions (finally).
Alias expressions are like cast expressions, but never do any conversions.
2011-03-03 11:06:10 +09:00
Bill Currie
497db3ac81 Fix the return symbol extraction when appending a return statement.
The code is still icky, though :P
2011-02-22 09:20:52 +09:00
Bill Currie
bcaf3687c5 Fix loading structs into params via an offset pointer.
For certain values of "fix" :/. The code is ugly, but it does the right
thing: calculate the effect address and use the resulting pointer in a
move instruction.
2011-02-14 23:10:45 +09:00
Bill Currie
179c1f7058 Support move statements (structure copy). 2011-02-11 22:29:57 +09:00
Bill Currie
370f0b97ed Produce cleaner output for a = b op c. 2011-02-11 22:29:57 +09:00
Bill Currie
d93d8d7d46 Remove the dirty hack used for accessing params and the return value.
Instead of using the equivalent of *(float*)&.return, now use the
equivalent of (float).return. No conversion is done in the "cast".

NOTE: this sort of cast should be separated from normal casts.
2011-02-11 22:29:38 +09:00
Bill Currie
7d2a95ee40 Mark a few problem spots. 2011-02-11 22:29:37 +09:00
Bill Currie
6f625e426f Use the correct type when deferencing an offset pointer. 2011-02-10 14:26:12 +09:00
Bill Currie
006c16807d Add the statement for based loads.
Oops :P
2011-02-09 22:40:16 +09:00
Bill Currie
0d5ab6600d Store the source expression in a statement.
This makes problem reporting more informative.
2011-02-08 18:18:34 +09:00
Bill Currie
3c849b970b Handle union access now that they're detected properly. 2011-02-08 14:45:48 +09:00
Bill Currie
3b080fcbb0 Fix an uninitialized variable. 2011-02-08 13:27:37 +09:00
Bill Currie
65a07ada1c Implement offset dereferences. 2011-02-07 14:56:29 +09:00
Bill Currie
d2b464053c Fix assignment sub-expressions. 2011-02-07 14:43:07 +09:00
Bill Currie
ef2ad46f7a Convert complex types to a suitable low-level type.
This takes care of moving structures etc around.
2011-02-07 10:55:09 +09:00
Bill Currie
b629c12b31 Do not change the type of the return operand.
Doing so made a mess of returning expressions. It was probably a holdover
from before getting instructions with void operand types working.
2011-02-07 10:21:54 +09:00
Bill Currie
e4ac92b5f2 Auto-cast between enums and the default type. 2011-02-06 20:08:16 +09:00
Bill Currie
c53001800a Create a struct for representing specifiers.
The specifiers are yet to come (next few commits), but this will be
necessary when they do.
2011-02-01 21:15:51 +09:00
Bill Currie
e7424e1496 Don't segfault on bare return statements.
I will probably need to do something about the required operand for v6
progs, but this will do for now.
2011-01-30 21:43:56 +09:00
Bill Currie
834417b8c8 Add "debug" diagnotic printing, and use it.
Debug diagnostics are silent for verbosity levels less than 1.
2011-01-28 13:28:45 +09:00
Bill Currie
a37bdd9fb5 Free removed sblocks. 2011-01-28 13:23:20 +09:00
Bill Currie
80424f6ad5 Ensure functions are always properly terminated.
Control that reaches the end of a function must see a return statement.
2011-01-28 13:14:30 +09:00
Bill Currie
9159daf99d Do simple unreachable block analysis and dead block removal. 2011-01-28 11:45:04 +09:00
Bill Currie
90a2738459 Add the label to the block to which it refers. 2011-01-28 11:41:53 +09:00
Bill Currie
4738c767a2 Fix branch label handling.
Conditional branches and goto now go to the correct location.
2011-01-27 21:11:32 +09:00
Bill Currie
71b5decbe8 Get assignments to .return working.
I really do not like the mechanism I currently use for handling pointer
derefences vs pointer assignments, but this will have to do for now until
I can get qfcc producing code again.
2011-01-27 15:44:11 +09:00
Bill Currie
56106892c8 The & operator produces a pointer, not void. 2011-01-27 15:44:10 +09:00
Bill Currie
6ce3c5a59a Get statments being emitted to the code segment.
The first function seems to work fine, but there's a problems with the
scope of params causing params to get their knickers in a twist (tangled
linked list).
2011-01-25 15:46:48 +09:00
Bill Currie
fd3b594ca5 Move label relocs to the relevant statement block. 2011-01-25 15:45:31 +09:00
Bill Currie
0624408317 Move the diagnostic functions into their own file. 2011-01-24 21:54:57 +09:00
Bill Currie
d618e51dc8 Move save_string and make_string into strpool
Might not be the perfect place, but at least they're strongly related.
2011-01-24 21:32:48 +09:00
Bill Currie
a79b6f0a6c Partially implement casts. 2011-01-23 11:53:08 +09:00
Bill Currie
55d3d17807 Add a missing break.
"return" falling through to "goto" was bad news :)
2011-01-22 15:52:01 +09:00
Bill Currie
3b462e16cf Produce flow diagrams of the basic blocks. 2011-01-22 11:40:53 +09:00
Bill Currie
bcb2667b73 Possibly get vector calls working. 2011-01-21 19:40:46 +09:00
Bill Currie
52b561f7cb Nuke bind expressions.
Since I'm planning on implementing CSE and other optimizations, they're
rather redundant (and I'm having trouble getting them to work).
2011-01-21 19:07:58 +09:00
Bill Currie
977c48d728 Make operator type overrides clear. 2011-01-21 15:57:53 +09:00
Bill Currie
aec9f256a7 Get calls mostly working.
Bind seems to be broken, but parameters seem to be being set correctly.
2011-01-21 15:54:53 +09:00
Bill Currie
96fae582e3 Implement bind expressions. 2011-01-21 11:27:40 +09:00
Bill Currie
4a24393d8d Temp expressions now use operands instead of defs. 2011-01-21 11:26:43 +09:00
Bill Currie
2998e578fb Get very basic deref assignments working.
More complicated expressions will not work yet.
2011-01-21 10:59:16 +09:00
Bill Currie
ff6e2584da Handle block sub-expressions that produce results. 2011-01-21 10:57:47 +09:00
Bill Currie
16e013ff5d Allow the operand to override the symbol's type. 2011-01-21 10:56:32 +09:00
Bill Currie
3f2793ef72 Get a lot of statements being generated. 2011-01-20 23:26:13 +09:00
Bill Currie
e45ea4b2ae Move the statement printing near the top of the file. 2011-01-20 18:07:24 +09:00
Bill Currie
0594609b3a Get the label from the right expression. 2011-01-19 22:25:43 +09:00
Bill Currie
5deda9c9b9 Clean out ex_def as ex_symbol replaces it. 2011-01-19 22:25:04 +09:00
Bill Currie
b5424bca7d Start work on getting expressions converted to internal statements. 2011-01-19 15:47:45 +09:00