From: Francisco Jerez Date: Thu, 19 May 2016 04:54:35 +0000 (-0700) Subject: i965/fs: Define methods to calculate the flag subset read or written by an fs_inst. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=df1aec763eb972c69bc5127be102a9f281ce94f6;p=mesa.git i965/fs: Define methods to calculate the flag subset read or written by an fs_inst. v2: Codestyle fixes (Jason). Reviewed-by: Jason Ekstrand --- diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 98940dae8be..33b3afcfd2d 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -907,19 +907,54 @@ fs_inst::regs_read(int arg) const return 0; } -bool -fs_inst::reads_flag() const +namespace { + /* Return the subset of flag registers that an instruction could + * potentially read or write based on the execution controls and flag + * subregister number of the instruction. + */ + unsigned + flag_mask(const fs_inst *inst) + { + const unsigned start = inst->flag_subreg * 16 + inst->group; + const unsigned end = start + inst->exec_size; + return ((1 << DIV_ROUND_UP(end, 8)) - 1) & ~((1 << (start / 8)) - 1); + } +} + +unsigned +fs_inst::flags_read(const brw_device_info *devinfo) const { - return predicate; + /* XXX - This doesn't consider explicit uses of the flag register as source + * region. + */ + if (predicate == BRW_PREDICATE_ALIGN1_ANYV || + predicate == BRW_PREDICATE_ALIGN1_ALLV) { + /* The vertical predication modes combine corresponding bits from + * f0.0 and f1.0 on Gen7+, and f0.0 and f0.1 on older hardware. + */ + const unsigned shift = devinfo->gen >= 7 ? 4 : 2; + return flag_mask(this) << shift | flag_mask(this); + } else if (predicate) { + return flag_mask(this); + } else { + return 0; + } } -bool -fs_inst::writes_flag() const +unsigned +fs_inst::flags_written() const { - return (conditional_mod && (opcode != BRW_OPCODE_SEL && - opcode != BRW_OPCODE_IF && - opcode != BRW_OPCODE_WHILE)) || - opcode == FS_OPCODE_MOV_DISPATCH_TO_FLAGS; + /* XXX - This doesn't consider explicit uses of the flag register as + * destination region. + */ + if ((conditional_mod && (opcode != BRW_OPCODE_SEL && + opcode != BRW_OPCODE_IF && + opcode != BRW_OPCODE_WHILE)) || + opcode == FS_OPCODE_MOV_DISPATCH_TO_FLAGS) { + return flag_mask(this); + } else { + return 0; + } } /** diff --git a/src/mesa/drivers/dri/i965/brw_ir_fs.h b/src/mesa/drivers/dri/i965/brw_ir_fs.h index 13f4e151433..ca4b40a3a14 100644 --- a/src/mesa/drivers/dri/i965/brw_ir_fs.h +++ b/src/mesa/drivers/dri/i965/brw_ir_fs.h @@ -276,8 +276,29 @@ public: bool has_side_effects() const; bool has_source_and_destination_hazard() const; - bool reads_flag() const; - bool writes_flag() const; + /** + * Return the subset of flag registers read by the instruction as a bitset + * with byte granularity. + */ + unsigned flags_read(const brw_device_info *devinfo) const; + + /** + * Return the subset of flag registers updated by the instruction (either + * partially or fully) as a bitset with byte granularity. + */ + unsigned flags_written() const; + + bool reads_flag() const + { + /* XXX - Will get rid of this hack shortly. */ + const brw_device_info devinfo = {}; + return flags_read(&devinfo); + } + + bool writes_flag() const + { + return flags_written(); + } fs_reg dst; fs_reg *src;