| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
Switch statements introduce a bogus loop with an unconditional break at
the end of the loop, just before the while...so the while is unreachable
and has no immediate dominator.
v2: With less exuberance
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
|
|
|
|
|
|
|
|
|
| |
It is possible to directly predicate the WHILE instruction. In this
case there will be a second successor block because the execution can
resume from the instruction after the loop. This will be used in a
subsequent patch.
Reviewed-by: Matt Turner <[email protected]>
|
|
|
|
| |
More.. like in commit 4d93a07c.
|
|
|
|
|
|
|
|
| |
Coverity sees that the functions immediately below the new assertions
dereference these pointers, but is unaware that an ENDIF always follows
an IF, etc.
Reviewed-by: Jordan Justen <[email protected]>
|
|
|
|
|
|
|
|
| |
The backend_shader class really is a representation of a shader. The fact
that it inherits from ir_visitor is somewhat immaterial.
Reviewed-by: Matt Turner <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
| |
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
| |
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
| |
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
|
|
| |
The fs_visitor's dump_instruction() implementation calls cfg_t()
indirectly through calculate_live_intervals, so if you have an infinite
loop in the CFG code, you can't call cfg::dump(fs_visitor *) to debug
it.
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
| |
start_ip and end_ip are inclusive.
Increases instruction counts in 64 shaders in shader-db, likely
indicative of them previously being misoptimized.
|
|
|
|
|
|
|
|
| |
I used these in the SEL peephole, but they require extra tracking and
fix ups. The SEL peephole can pretty easily find the blocks it needs
without these.
Reviewed-by: Jason Ekstrand <[email protected]>
|
|
|
|
| |
Reviewed-by: Topi Pohjolainen <[email protected]>
|
|
|
|
| |
Reviewed-by: Topi Pohjolainen <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
The dump() methods don't alter the CFG or basic blocks, so we should
mark them as const. This lets you call them even if you have a const
cfg_t - which is the case in certain portions of the code (such as live
interval handling).
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
|
|
|
|
| |
Reviewed-by: Topi Pohjolainen <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
... rather than pointing directly to the associated instruction. This
will let us set the block containing the IF statement's else-pointer to
NULL, when we delete a useless ELSE instruction, as in the case
(+f0) if(8)
...
else(8)
endif(8)
Also, remove the pointer to the ENDIF, since it's unused, and it was
also potentially wrong, in the case of a basic block containing both an
ENDIF and an IF instruction:
endif(8)
cmp.ne.f0(8) ...
(+f0) if(8)
Reviewed-by: Topi Pohjolainen <[email protected]>
|
|
|
|
| |
Reviewed-by: Topi Pohjolainen <[email protected]>
|
|
|
|
| |
Reviewed-by: Topi Pohjolainen <[email protected]>
|
|
|
|
|
| |
Use this as an opportunity to rename 'block_num' to 'num'. block->num is
clear, and block->block_num has always been redundant.
|
|
|
|
|
|
|
|
| |
The next patch adds a foreach_block (block, cfg) macro, which works
better if it provides a direct bblock_t pointer, rather than a
bblock_link pointer that you have to use to find the actual block.
Reviewed-by: Topi Pohjolainen <[email protected]>
|
|
|
|
| |
Acked-by: Ian Romanick <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Threads must terminate with a SEND message to a particular shared function,
such as a URB write or FB write, so the instruction stream really shouldn't
ever end in an IF/ELSE/ENDIF or similar block structure.
However, if the instruction stream (incorrectly) ends in a block structure
the last block's end pointer will not be set, leading to a crash later on in
fs_live_variables::setup_def_use(). It is better to detect this earlier, so
assert on that.
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The DO instruction doesn't exist on Gen6+. Since before this commit, DO
always ended a basic block, if it also happened to start one (e.g., a
while loop inside an if statement) the block containing only the DO
would actually contain no hardware instructions.
Pre-Gen6's WHILE instructions jumps to the instruction following the DO,
so strictly speaking we won't be modeling that properly, but I claim
there is actually no functional difference.
This will simplify an upcoming change where we want to mark the first
hardware instruction in the loop as beginning a block, and the last
instruction before the loop as ending one.
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
|
|
|
| |
In order to remove bblock_link's inheritance of exec_node. Also makes
linked list walk code much nicer.
Acked-by: Eric Anholt <[email protected]>
|
|
|
|
|
|
| |
Reviewed-by: Ian Romanick <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
|
|
|
|
| |
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
| |
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
|
|
|
| |
parent_mem_ctx was unused since db47074a, so remove the two wrappers
around create() and make create() the constructor.
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
|
|
|
| |
make_list is just a one-line wrapper and was confusingly called by
NULL objects. E.g., cur_if == NULL; cur_if->make_list(mem_ctx).
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
| |
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
|
|
| |
Unnecessary since last commit.
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously we made the basic block following an ENDIF instruction a
successor of the basic blocks ending with IF and ELSE. The PRM says that
IF and ELSE instructions jump *to* the ENDIF, rather than over it.
This should be immaterial to dataflow analysis, except for if, break,
endif sequences:
START B1 <-B0 <-B9
0x00000100: cmp.g.f0(8) null g15<8,8,1>F g4<0,1,0>F
0x00000110: (+f0) if(8) 0 0 null 0x00000000UD
END B1 ->B2 ->B4
START B2 <-B1
break
0x00000120: break(8) 0 0 null 0D
END B2 ->B10
START B3
0x00000130: endif(8) 2 null 0x00000002UD
END B3 ->B4
The ENDIF block would have no parents, so dataflow analysis would
generate incorrect results, preventing copy propagation from eliminating
some instructions.
This patch changes the CFG to make ENDIF start rather than end basic
blocks, so that it can be the jump target of the IF and ELSE
instructions.
It helps three programs (including two fs8/fs16 pairs).
total instructions in shared programs: 1561126 -> 1561060 (-0.00%)
instructions in affected programs: 837 -> 771 (-7.89%)
More importantly, it allows copy propagation to handle more cases.
Disabling the register_coalesce() pass before this patch hurts 58
programs, while afterward it only hurts 11 programs.
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
|
|
|
| |
Useful for finding the associated control flow instructions, given a
block ending in one.
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
| |
Reviewed-by: Eric Anholt <[email protected]>
|
|
|
|
|
|
|
|
|
| |
These ralloc contexts belong to a specific object and are being
deallocated manually from the class destructor. Now that we've hooked
up destructors to ralloc there's no reason for them to be children of
any other context, and doing so might to lead to double frees under
some circumstances. The class destructor has all the responsibility
of freeing class memory resources now.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The cfg_t object relies on the memory allocator zeroing out its
contents before it's initialized, which is quite an unusual practice
in the C++ world because it ties objects to some specific allocation
scheme, and gives unpredictable results when an object is created with
a different allocator -- Stack allocation, array allocation, or
aggregation inside a different object are some of the useful
possibilities that come to my mind. Initialize all fields from the
constructor and stop using the zeroing allocator.
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The bblock_t object relies on the memory allocator zeroing out its
contents before it's initialized, which is quite an unusual practice
in the C++ world because it ties objects to some specific allocation
scheme, and gives unpredictable results when an object is created with
a different allocator -- Stack allocation, array allocation, or
aggregation inside a different object are some of the useful
possibilities that come to my mind. Initialize all fields from the
constructor and stop using the zeroing allocator.
v2: Use zero initialization for numeric types instead of default construction.
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
All we really need is a memory context and the instruction list; passing
a backend_visitor is just convenient at times.
This will be necessary two patches from now.
Reviewed-by: Eric Anholt <[email protected]>
Reviewed-by: Paul Berry <[email protected]>
|
|
|
|
| |
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
| |
Note that BRW_PREDICATE_NONE is 0 and BRW_PREDICATE_NORMAL is 1, so that's a
lot like the true/false we had in the FS before.
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
|
| |
fs_bblock_link -> bblock_link
fs_bblock -> bblock_t (to avoid conflicting with all the fs_bblock *bblock)
fs_cfg -> cfg_t (to avoid conflicting with all the fs_cfg *cfg)
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
Reviewed-by: Kenneth Graunke <[email protected]>
|