[Mesa-dev] [PATCH 07/10] intel/fs: Introduce regioning lowering pass.
Francisco Jerez
currojerez at riseup.net
Sat Jan 5 21:50:54 UTC 2019
Francisco Jerez <currojerez at riseup.net> writes:
> Iago Toral <itoral at igalia.com> writes:
>
>> On Sat, 2018-12-29 at 12:39 -0800, Francisco Jerez wrote:
>>> This legalization pass is meant to handle situations where the source
>>> or destination regioning controls of an instruction are unsupported
>>> by
>>> the hardware and need to be lowered away into separate instructions.
>>> This should be more reliable and future-proof than the current
>>> approach of handling CHV/BXT restrictions manually all over the
>>> visitor. The same mechanism is leveraged to lower unsupported type
>>> conversions easily, which obsoletes the lower_conversions pass.
>>> ---
>>> src/intel/Makefile.sources | 1 +
>>> src/intel/compiler/brw_fs.cpp | 5 +-
>>> src/intel/compiler/brw_fs.h | 21 +-
>>> src/intel/compiler/brw_fs_lower_regioning.cpp | 382
>>> ++++++++++++++++++
>>> src/intel/compiler/brw_ir_fs.h | 10 +
>>> src/intel/compiler/meson.build | 1 +
>>> 6 files changed, 401 insertions(+), 19 deletions(-)
>>> create mode 100644 src/intel/compiler/brw_fs_lower_regioning.cpp
>>>
>>> diff --git a/src/intel/Makefile.sources b/src/intel/Makefile.sources
>>> index 5e7d32293b7..6b9874d2b80 100644
>>> --- a/src/intel/Makefile.sources
>>> +++ b/src/intel/Makefile.sources
>>> @@ -64,6 +64,7 @@ COMPILER_FILES = \
>>> compiler/brw_fs_live_variables.h \
>>> compiler/brw_fs_lower_conversions.cpp \
>>> compiler/brw_fs_lower_pack.cpp \
>>> + compiler/brw_fs_lower_regioning.cpp \
>>> compiler/brw_fs_nir.cpp \
>>> compiler/brw_fs_reg_allocate.cpp \
>>> compiler/brw_fs_register_coalesce.cpp \
>>> diff --git a/src/intel/compiler/brw_fs.cpp
>>> b/src/intel/compiler/brw_fs.cpp
>>> index 889509badab..caa7a798332 100644
>>> --- a/src/intel/compiler/brw_fs.cpp
>>> +++ b/src/intel/compiler/brw_fs.cpp
>>> @@ -6471,7 +6471,10 @@ fs_visitor::optimize()
>>> OPT(dead_code_eliminate);
>>> }
>>>
>>> - if (OPT(lower_conversions)) {
>>> + progress = false;
>>> + OPT(lower_conversions);
>>> + OPT(lower_regioning);
>>> + if (progress) {
>>> OPT(opt_copy_propagation);
>>> OPT(dead_code_eliminate);
>>> OPT(lower_simd_width);
>>> diff --git a/src/intel/compiler/brw_fs.h
>>> b/src/intel/compiler/brw_fs.h
>>> index dc36ecc21ac..36825754931 100644
>>> --- a/src/intel/compiler/brw_fs.h
>>> +++ b/src/intel/compiler/brw_fs.h
>>> @@ -164,6 +164,7 @@ public:
>>> void lower_uniform_pull_constant_loads();
>>> bool lower_load_payload();
>>> bool lower_pack();
>>> + bool lower_regioning();
>>> bool lower_conversions();
>>> bool lower_logical_sends();
>>> bool lower_integer_multiplication();
>>> @@ -536,24 +537,8 @@ namespace brw {
>>> }
>>> }
>>>
>>> - /**
>>> - * Remove any modifiers from the \p i-th source region of the
>>> instruction,
>>> - * including negate, abs and any implicit type conversion to the
>>> execution
>>> - * type. Instead any source modifiers will be implemented as a
>>> separate
>>> - * MOV instruction prior to the original instruction.
>>> - */
>>> - inline bool
>>> - lower_src_modifiers(fs_visitor *v, bblock_t *block, fs_inst
>>> *inst, unsigned i)
>>> - {
>>> - assert(inst->components_read(i) == 1);
>>> - const fs_builder ibld(v, block, inst);
>>> - const fs_reg tmp = ibld.vgrf(get_exec_type(inst));
>>> -
>>> - ibld.MOV(tmp, inst->src[i]);
>>> - inst->src[i] = tmp;
>>> -
>>> - return true;
>>> - }
>>> + bool
>>> + lower_src_modifiers(fs_visitor *v, bblock_t *block, fs_inst
>>> *inst, unsigned i);
>>> }
>>>
>>> void shuffle_from_32bit_read(const brw::fs_builder &bld,
>>> diff --git a/src/intel/compiler/brw_fs_lower_regioning.cpp
>>> b/src/intel/compiler/brw_fs_lower_regioning.cpp
>>> new file mode 100644
>>> index 00000000000..9578622401d
>>> --- /dev/null
>>> +++ b/src/intel/compiler/brw_fs_lower_regioning.cpp
>>> @@ -0,0 +1,382 @@
>>> +/*
>>> + * Copyright © 2018 Intel Corporation
>>> + *
>>> + * Permission is hereby granted, free of charge, to any person
>>> obtaining a
>>> + * copy of this software and associated documentation files (the
>>> "Software"),
>>> + * to deal in the Software without restriction, including without
>>> limitation
>>> + * the rights to use, copy, modify, merge, publish, distribute,
>>> sublicense,
>>> + * and/or sell copies of the Software, and to permit persons to whom
>>> the
>>> + * Software is furnished to do so, subject to the following
>>> conditions:
>>> + *
>>> + * The above copyright notice and this permission notice (including
>>> the next
>>> + * paragraph) shall be included in all copies or substantial
>>> portions of the
>>> + * Software.
>>> + *
>>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>>> EXPRESS OR
>>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>>> MERCHANTABILITY,
>>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
>>> EVENT SHALL
>>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
>>> OR OTHER
>>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
>>> ARISING
>>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>>> OTHER DEALINGS
>>> + * IN THE SOFTWARE.
>>> + */
>>> +
>>> +#include "brw_fs.h"
>>> +#include "brw_cfg.h"
>>> +#include "brw_fs_builder.h"
>>> +
>>> +using namespace brw;
>>> +
>>> +namespace {
>>> + /* From the SKL PRM Vol 2a, "Move":
>>> + *
>>> + * "A mov with the same source and destination type, no source
>>> modifier,
>>> + * and no saturation is a raw move. A packed byte destination
>>> region (B
>>> + * or UB type with HorzStride == 1 and ExecSize > 1) can only be
>>> written
>>> + * using raw move."
>>> + */
>>> + bool
>>> + is_byte_raw_mov(const fs_inst *inst)
>>> + {
>>> + return type_sz(inst->dst.type) == 1 &&
>>> + inst->opcode == BRW_OPCODE_MOV &&
>>> + inst->src[0].type == inst->dst.type &&
>>> + !inst->saturate &&
>>> + !inst->src[0].negate &&
>>> + !inst->src[0].abs;
>>> + }
>>> +
>>> + /*
>>> + * Return an acceptable byte stride for the destination of an
>>> instruction
>>> + * that requires it to have some particular alignment.
>>> + */
>>> + unsigned
>>> + required_dst_byte_stride(const fs_inst *inst)
>>> + {
>>> + if (type_sz(inst->dst.type) < get_exec_type_size(inst) &&
>>> + !is_byte_raw_mov(inst)) {
>>> + return get_exec_type_size(inst);
>>> + } else {
>>> + unsigned stride = inst->dst.stride * type_sz(inst-
>>> >dst.type);
>>> +
>>> + for (unsigned i = 0; i < inst->sources; i++) {
>>> + if (!is_uniform(inst->src[i]))
>>> + stride = MAX2(stride, inst->src[i].stride *
>>> + type_sz(inst->src[i].type));
>>> + }
>>> +
>>> + return stride;
>>> + }
>>> + }
>>> +
>>> + /*
>>> + * Return an acceptable byte sub-register offset for the
>>> destination of an
>>> + * instruction that requires it to be aligned to the sub-register
>>> offset of
>>> + * the sources.
>>> + */
>>> + unsigned
>>> + required_dst_byte_offset(const fs_inst *inst)
>>> + {
>>> + for (unsigned i = 0; i < inst->sources; i++) {
>>> + if (!is_uniform(inst->src[i]))
>>> + if (reg_offset(inst->src[i]) % REG_SIZE !=
>>> + reg_offset(inst->dst) % REG_SIZE)
>>> + return 0;
>>> + }
>>> +
>>> + return reg_offset(inst->dst) % REG_SIZE;
>>> + }
>>> +
>>> + /*
>>> + * Return whether the instruction has an unsupported channel bit
>>> layout
>>> + * specified for the i-th source region.
>>> + */
>>> + bool
>>> + has_invalid_src_region(const gen_device_info *devinfo, const
>>> fs_inst *inst,
>>> + unsigned i)
>>> + {
>>> + if (is_unordered(inst)) {
>>> + return false;
>>> + } else {
>>> + const unsigned dst_byte_stride = inst->dst.stride *
>>> type_sz(inst->dst.type);
>>> + const unsigned src_byte_stride = inst->src[i].stride *
>>> + type_sz(inst->src[i].type);
>>> + const unsigned dst_byte_offset = reg_offset(inst->dst) %
>>> REG_SIZE;
>>> + const unsigned src_byte_offset = reg_offset(inst->src[i]) %
>>> REG_SIZE;
>>> +
>>> + return has_dst_aligned_region_restriction(devinfo, inst) &&
>>> + !is_uniform(inst->src[i]) &&
>>> + (src_byte_stride != dst_byte_stride ||
>>> + src_byte_offset != dst_byte_offset);
>>> + }
>>> + }
>>> +
>>> + /*
>>> + * Return whether the instruction has an unsupported channel bit
>>> layout
>>> + * specified for the destination region.
>>> + */
>>> + bool
>>> + has_invalid_dst_region(const gen_device_info *devinfo,
>>> + const fs_inst *inst)
>>> + {
>>> + if (is_unordered(inst)) {
>>> + return false;
>>> + } else {
>>> + const brw_reg_type exec_type = get_exec_type(inst);
>>> + const unsigned dst_byte_offset = reg_offset(inst->dst) %
>>> REG_SIZE;
>>> + const unsigned dst_byte_stride = inst->dst.stride *
>>> type_sz(inst->dst.type);
>>> + const bool is_narrowing_conversion = !is_byte_raw_mov(inst)
>>> &&
>>> + type_sz(inst->dst.type) < type_sz(exec_type);
>>> +
>>> + return (has_dst_aligned_region_restriction(devinfo, inst)
>>> &&
>>> + (required_dst_byte_stride(inst) != dst_byte_stride
>>> ||
>>> + required_dst_byte_offset(inst) !=
>>> dst_byte_offset)) ||
>>> + (is_narrowing_conversion &&
>>> + required_dst_byte_stride(inst) != dst_byte_stride);
>>> + }
>>> + }
>>> +
>>> + /*
>>> + * Return whether the instruction has unsupported source
>>> modifiers
>>> + * specified for the i-th source region.
>>> + */
>>> + bool
>>> + has_invalid_src_modifiers(const gen_device_info *devinfo, const
>>> fs_inst *inst,
>>> + unsigned i)
>>> + {
>>> + return !inst->can_do_source_mods(devinfo) &&
>>> + (inst->src[i].negate || inst->src[i].abs);
>>> + }
>>> +
>>> + /*
>>> + * Return whether the instruction has an unsupported type
>>> conversion
>>> + * specified for the destination.
>>> + */
>>> + bool
>>> + has_invalid_conversion(const gen_device_info *devinfo, const
>>> fs_inst *inst)
>>> + {
>>> + switch (inst->opcode) {
>>> + case BRW_OPCODE_MOV:
>>> + return false;
>>> + case BRW_OPCODE_SEL:
>>> + return inst->dst.type != get_exec_type(inst);
>>> + case SHADER_OPCODE_BROADCAST:
>>> + case SHADER_OPCODE_MOV_INDIRECT:
>>> + /* The source and destination types of these may are hard-
>>> coded to
>>> + * integer at codegen time due to hardware limitations of
>>> 64-bit
>>> + * types.
>>> + */
>>> + return ((devinfo->gen == 7 && !devinfo->is_haswell) ||
>>> + devinfo->is_cherryview ||
>>> gen_device_info_is_9lp(devinfo)) &&
>>> + type_sz(inst->src[0].type) > 4 &&
>>> + inst->dst.type != inst->src[0].type;
>>> + default:
>>> + /* FIXME: We assume the opcodes don't explicitly mentioned
>>> before
>>> + * just work fine with arbitrary conversions.
>>> + */
>>> + return false;
>>> + }
>>> + }
>>> +
>>> + bool
>>> + lower_instruction(fs_visitor *v, bblock_t *block, fs_inst *inst);
>>> +}
>>> +
>>> +namespace brw {
>>> + /**
>>> + * Remove any modifiers from the \p i-th source region of the
>>> instruction,
>>> + * including negate, abs and any implicit type conversion to the
>>> execution
>>> + * type. Instead any source modifiers will be implemented as a
>>> separate
>>> + * MOV instruction prior to the original instruction.
>>> + */
>>> + bool
>>> + lower_src_modifiers(fs_visitor *v, bblock_t *block, fs_inst
>>> *inst, unsigned i)
>>> + {
>>> + assert(inst->components_read(i) == 1);
>>> + const fs_builder ibld(v, block, inst);
>>> + const fs_reg tmp = ibld.vgrf(get_exec_type(inst));
>>> +
>>> + lower_instruction(v, block, ibld.MOV(tmp, inst->src[i]));
>>> + inst->src[i] = tmp;
>>> +
>>> + return true;
>>> + }
>>> +}
>>> +
>>> +namespace {
>>> + /**
>>> + * Remove any modifiers from the destination region of the
>>> instruction,
>>> + * including saturate, conditional mod and any implicit type
>>> conversion
>>> + * from the execution type. Instead any destination modifiers
>>> will be
>>> + * implemented as a separate MOV instruction after the original
>>> + * instruction.
>>> + */
>>> + bool
>>> + lower_dst_modifiers(fs_visitor *v, bblock_t *block, fs_inst
>>> *inst)
>>> + {
>>> + const fs_builder ibld(v, block, inst);
>>> + const brw_reg_type type = get_exec_type(inst);
>>> + /* Not strictly necessary, but if possible use a temporary
>>> with the same
>>> + * channel alignment as the current destination in order to
>>> avoid
>>> + * violating the restrictions enforced later on by
>>> lower_src_region()
>>> + * and lower_dst_region(), which would introduce additional
>>> copy
>>> + * instructions into the program unnecessarily.
>>> + */
>>> + const unsigned stride =
>>> + type_sz(inst->dst.type) * inst->dst.stride <= type_sz(type)
>>> ? 1 :
>>> + type_sz(inst->dst.type) * inst->dst.stride / type_sz(type);
>>> + const fs_reg tmp = horiz_stride(ibld.vgrf(type, stride),
>>> stride);
>>> +
>>> + /* Emit a MOV taking care of all the destination modifiers. */
>>> + fs_inst *mov = ibld.at(block, inst->next).MOV(inst->dst, tmp);
>>> + mov->saturate = inst->saturate;
>>> + mov->conditional_mod = inst->conditional_mod;
>>> + if (inst->opcode != BRW_OPCODE_SEL) {
>>> + mov->predicate = inst->predicate;
>>> + mov->predicate_inverse = inst->predicate_inverse;
>>> + }
>>> + mov->flag_subreg = inst->flag_subreg;
>>> + lower_instruction(v, block, mov);
>>> +
>>> + /* Point the original instruction at the temporary, and clean
>>> up any
>>> + * destination modifiers.
>>> + */
>>> + assert(inst->size_written == inst->dst.component_size(inst-
>>> >exec_size));
>>> + inst->dst = tmp;
>>> + inst->size_written = inst->dst.component_size(inst-
>>> >exec_size);
>>> + inst->saturate = false;
>>> + inst->conditional_mod = BRW_CONDITIONAL_NONE;
>>
>> I think this is not correct if if inst is a SEL instruction. Here is an
>> example that is causing a regresion for me:
>>
>> With the original lower_conversions pass I have:
>>
>> sel.l(8) vgrf15+0.0:W, vgrf3+0.0:B, vgrf5+0.0:B
>> mov(8) vgrf16+0.0<2>:B, vgrf15+0.0:W
>>
>> Now, with this pass this is turned into:
>>
>> sel(8) vgrf15+0.0:W, vgrf3+0.0:B, vgrf5+0.0:B
>> mov.l.f0.0(8) vgrf16+0.0<2>:B, vgrf15+0.0:W
>>
>> So I guess the SEL instruction no longer works since it is not
>> predicated and we have removed the conditional modifier as well.
>>
>> Maybe only move the conditional modifier to the MOV when the
>> instruction is not a SEL like we do for the predicate?
>>
>
> Yeah good point, the semantics of conditional mods are inconsistent for
> the SEL instruction -- Fixed up locally in the same way predicates are
> handled for SEL in the same function.
>
It just occurred to me that there are a couple other ISA instructions
with non-standard semantics for the conditional mod that need to be
special-cased here as well. I'll reply with a fix in a minute.
>>> + return true;
>>> + }
>>> +
>>> + /**
>>> + * Remove any non-trivial shuffling of data from the \p i-th
>>> source region
>>> + * of the instruction. Instead implement the region as a series
>>> of integer
>>> + * copies into a temporary with the same channel layout as the
>>> destination.
>>> + */
>>> + bool
>>> + lower_src_region(fs_visitor *v, bblock_t *block, fs_inst *inst,
>>> unsigned i)
>>> + {
>>> + assert(inst->components_read(i) == 1);
>>> + const fs_builder ibld(v, block, inst);
>>> + const unsigned stride = type_sz(inst->dst.type) * inst-
>>> >dst.stride /
>>> + type_sz(inst->src[i].type);
>>> + assert(stride > 0);
>>> + const fs_reg tmp = horiz_stride(ibld.vgrf(inst->src[i].type,
>>> stride),
>>> + stride);
>>> +
>>> + /* Emit a series of 32-bit integer copies with any source
>>> modifiers
>>> + * cleaned up (because their semantics are dependent on the
>>> type).
>>> + */
>>> + const brw_reg_type raw_type =
>>> brw_int_type(MIN2(type_sz(tmp.type), 4),
>>> + false);
>>> + const unsigned n = type_sz(tmp.type) / type_sz(raw_type);
>>> + fs_reg raw_src = inst->src[i];
>>> + raw_src.negate = false;
>>> + raw_src.abs = false;
>>> +
>>> + for (unsigned j = 0; j < n; j++)
>>> + ibld.MOV(subscript(tmp, raw_type, j), subscript(raw_src,
>>> raw_type, j));
>>> +
>>> + /* Point the original instruction at the temporary, making
>>> sure to keep
>>> + * any source modifiers in the instruction.
>>> + */
>>> + fs_reg lower_src = tmp;
>>> + lower_src.negate = inst->src[i].negate;
>>> + lower_src.abs = inst->src[i].abs;
>>> + inst->src[i] = lower_src;
>>> +
>>> + return true;
>>> + }
>>> +
>>> + /**
>>> + * Remove any non-trivial shuffling of data from the destination
>>> region of
>>> + * the instruction. Instead implement the region as a series of
>>> integer
>>> + * copies from a temporary with a channel layout compatible with
>>> the
>>> + * sources.
>>> + */
>>> + bool
>>> + lower_dst_region(fs_visitor *v, bblock_t *block, fs_inst *inst)
>>> + {
>>> + const fs_builder ibld(v, block, inst);
>>> + const unsigned stride = required_dst_byte_stride(inst) /
>>> + type_sz(inst->dst.type);
>>> + assert(stride > 0);
>>> + const fs_reg tmp = horiz_stride(ibld.vgrf(inst->dst.type,
>>> stride),
>>> + stride);
>>> +
>>> + /* Emit a series of 32-bit integer copies from the temporary
>>> into the
>>> + * original destination.
>>> + */
>>> + const brw_reg_type raw_type =
>>> brw_int_type(MIN2(type_sz(tmp.type), 4),
>>> + false);
>>> + const unsigned n = type_sz(tmp.type) / type_sz(raw_type);
>>> +
>>> + if (inst->predicate && inst->opcode != BRW_OPCODE_SEL) {
>>> + /* Note that in general we cannot simply predicate the
>>> copies on the
>>> + * same flag register as the original instruction, since it
>>> may have
>>> + * been overwritten by the instruction itself. Instead
>>> initialize
>>> + * the temporary with the previous contents of the
>>> destination
>>> + * register.
>>> + */
>>> + for (unsigned j = 0; j < n; j++)
>>> + ibld.MOV(subscript(tmp, raw_type, j),
>>> + subscript(inst->dst, raw_type, j));
>>> + }
>>> +
>>> + for (unsigned j = 0; j < n; j++)
>>> + ibld.at(block, inst->next).MOV(subscript(inst->dst,
>>> raw_type, j),
>>> + subscript(tmp, raw_type,
>>> j));
>>> +
>>> + /* Point the original instruction at the temporary, making
>>> sure to keep
>>> + * any destination modifiers in the instruction.
>>> + */
>>> + assert(inst->size_written == inst->dst.component_size(inst-
>>> >exec_size));
>>> + inst->dst = tmp;
>>> + inst->size_written = inst->dst.component_size(inst-
>>> >exec_size);
>>> +
>>> + return true;
>>> + }
>>> +
>>> + /**
>>> + * Legalize the source and destination regioning controls of the
>>> specified
>>> + * instruction.
>>> + */
>>> + bool
>>> + lower_instruction(fs_visitor *v, bblock_t *block, fs_inst *inst)
>>> + {
>>> + const gen_device_info *devinfo = v->devinfo;
>>> + bool progress = false;
>>> +
>>> + if (has_invalid_conversion(devinfo, inst))
>>> + progress |= lower_dst_modifiers(v, block, inst);
>>> +
>>> + if (has_invalid_dst_region(devinfo, inst))
>>> + progress |= lower_dst_region(v, block, inst);
>>> +
>>> + for (unsigned i = 0; i < inst->sources; i++) {
>>> + if (has_invalid_src_modifiers(devinfo, inst, i))
>>> + progress |= lower_src_modifiers(v, block, inst, i);
>>> +
>>> + if (has_invalid_src_region(devinfo, inst, i))
>>> + progress |= lower_src_region(v, block, inst, i);
>>> + }
>>> +
>>> + return progress;
>>> + }
>>> +}
>>> +
>>> +bool
>>> +fs_visitor::lower_regioning()
>>> +{
>>> + bool progress = false;
>>> +
>>> + foreach_block_and_inst(block, fs_inst, inst, cfg)
>>> + progress |= lower_instruction(this, block, inst);
>>> +
>>> + if (progress)
>>> + invalidate_live_intervals();
>>> +
>>> + return progress;
>>> +}
>>> diff --git a/src/intel/compiler/brw_ir_fs.h
>>> b/src/intel/compiler/brw_ir_fs.h
>>> index 5bb92e4cc86..3c23fb375e4 100644
>>> --- a/src/intel/compiler/brw_ir_fs.h
>>> +++ b/src/intel/compiler/brw_ir_fs.h
>>> @@ -486,6 +486,16 @@ get_exec_type_size(const fs_inst *inst)
>>> return type_sz(get_exec_type(inst));
>>> }
>>>
>>> +/**
>>> + * Return whether the instruction isn't an ALU instruction and
>>> cannot be
>>> + * assumed to complete in-order.
>>> + */
>>> +static inline bool
>>> +is_unordered(const fs_inst *inst)
>>> +{
>>> + return inst->mlen || inst->is_send_from_grf() || inst->is_math();
>>> +}
>>> +
>>> /**
>>> * Return whether the following regioning restriction applies to the
>>> specified
>>> * instruction. From the Cherryview PRM Vol 7. "Register Region
>>> diff --git a/src/intel/compiler/meson.build
>>> b/src/intel/compiler/meson.build
>>> index 69ce2eab4cf..4af134b418e 100644
>>> --- a/src/intel/compiler/meson.build
>>> +++ b/src/intel/compiler/meson.build
>>> @@ -57,6 +57,7 @@ libintel_compiler_files = files(
>>> 'brw_fs_live_variables.h',
>>> 'brw_fs_lower_conversions.cpp',
>>> 'brw_fs_lower_pack.cpp',
>>> + 'brw_fs_lower_regioning.cpp',
>>> 'brw_fs_nir.cpp',
>>> 'brw_fs_reg_allocate.cpp',
>>> 'brw_fs_register_coalesce.cpp',
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 227 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20190105/77030f74/attachment-0001.sig>
More information about the mesa-dev
mailing list