diff options
author | Rob Clark <[email protected]> | 2015-02-04 16:07:44 -0500 |
---|---|---|
committer | Rob Clark <[email protected]> | 2015-03-08 17:42:43 -0400 |
commit | 17754b70d78649f29e25dfe938de91d64dbf5ebf (patch) | |
tree | 6f63a5d88a8dc20e2e144cab89b923dbc12007b1 /src/gallium/drivers/freedreno/ir3/ir3.h | |
parent | f8f7548f466509bf881db1826ef6dd23ffe2acdf (diff) |
freedreno/ir3: drop deref nodes
The meta-deref instruction doesn't really do what we need for relative
destination. Instead, since each instruction can reference at most a
single address value, track the dependency on the address register via
instr->address. This lets us express the dependency regardless of
whether it is used for dst and/or src.
The foreach_ssa_src{_n} iterator macros now also iterates the address
register so, at least in SSA form, the address register behaves as an
additional virtual src to the instruction. Which is pretty much what
we want, as far as scheduling/etc.
TODO:
For now, the foreach_src{_n} iterators are unchanged. We could wrap
the address in an ir3_register and make the foreach_src_{_n} iterators
behave the same way. But that seems unnecessary at this point, since
we mainly care about the address dependency when in SSA form.
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/ir3/ir3.h')
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3.h | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index 3d3ad07c330..30932854884 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -79,18 +79,19 @@ struct ir3_register { * the component is in the low two bits of the reg #, so * rN.x becomes: (N << 2) | x */ - int num; + int num; /* immediate: */ - int iim_val; - float fim_val; + int iim_val; + float fim_val; /* relative: */ - int offset; - /* for IR3_REG_SSA, src registers contain ptr back to - * assigning instruction. - */ - struct ir3_instruction *instr; + int offset; }; + /* for IR3_REG_SSA, src registers contain ptr back to + * assigning instruction. + */ + struct ir3_instruction *instr; + union { /* used for cat5 instructions, but also for internal/IR level * tracking of what registers are read/written by an instruction. @@ -209,9 +210,6 @@ struct ir3_instruction { struct { struct ir3_block *block; } inout; - struct { - int off; /* offset relative to addr reg */ - } deref; /* XXX keep this as big as all other union members! */ uint32_t info[3]; @@ -260,6 +258,12 @@ struct ir3_instruction { struct ir3_instruction *left, *right; uint16_t left_cnt, right_cnt; } cp; + + /* an instruction can reference at most one address register amongst + * it's src/dst registers. Beyond that, you need to insert mov's. + */ + struct ir3_instruction *address; + struct ir3_instruction *next; #ifdef DEBUG uint32_t serialno; @@ -445,11 +449,6 @@ static inline bool is_meta(struct ir3_instruction *instr) return (instr->category == -1); } -static inline bool is_addr(struct ir3_instruction *instr) -{ - return is_meta(instr) && (instr->opc == OPC_META_DEREF); -} - static inline bool writes_addr(struct ir3_instruction *instr) { if (instr->regs_count > 0) { @@ -499,11 +498,15 @@ static inline bool reg_gpr(struct ir3_register *r) static inline unsigned __ssa_src_cnt(struct ir3_instruction *instr) { + if (instr->address) + return instr->regs_count + 1; return instr->regs_count; } static inline struct ir3_instruction * __ssa_src_n(struct ir3_instruction *instr, unsigned n) { + if (n == (instr->regs_count + 0)) + return instr->address; return ssa(instr->regs[n]); } |