Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Tue, May 24, 2016 at 3:41 PM, Rob Clarkwrote: > On Mon, May 16, 2016 at 3:16 PM, Jason Ekstrand wrote: >> On Mon, May 16, 2016 at 9:09 AM, Rob Clark wrote: >>> >>> On Mon, May 16, 2016 at 10:45 AM, Jason Ekstrand >>> wrote: >>> > >>> > On May 16, 2016 7:29 AM, "Rob Clark" wrote: >>> >> >>> >> On Sat, May 14, 2016 at 4:03 PM, Jason Ekstrand >>> >> wrote: >>> >> > >>> >> > >>> >> > On Sat, May 14, 2016 at 12:20 PM, Rob Clark >>> >> > wrote: >>> >> >> >>> >> >> On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrand >>> >> >> >>> >> >> wrote: >>> >> >> > >>> >> >> > >>> >> >> > On Tue, May 10, 2016 at 11:57 AM, Rob Clark >>> >> >> > wrote: >>> >> >> >> >>> >> >> >> From: Rob Clark >>> >> >> >> >>> >> >> >> Some optimizations, like converting integer multiply/divide into >>> >> >> >> left/ >>> >> >> >> right shifts, have additional constraints on the search >>> >> >> >> expression. >>> >> >> >> Like requiring that a variable is a constant power of two. >>> >> >> >> Support >>> >> >> >> these cases by allowing a fxn name to be appended to the search >>> >> >> >> var >>> >> >> >> expression (ie. "a#32(is_power_of_two)"). >>> >> >> >> >>> >> >> >> TODO update doc/comment explaining search var syntax >>> >> >> >> TODO the eagle-eyed viewer might have noticed that this could >>> >> >> >> also >>> >> >> >> replace the existing const syntax (ie. "#a"). Not sure if we >>> >> >> >> should >>> >> >> >> keep that.. we could make it syntactic sugar (ie '#' >>> >> >> >> automatically >>> >> >> >> sets >>> >> >> >> the cond fxn ptr to 'is_const') or just get rid of it entirely? >>> >> >> >> Maybe >>> >> >> >> that is a follow-on clean-up patch? >>> >> >> >> >>> >> >> >> Signed-off-by: Rob Clark >>> >> >> >> --- >>> >> >> >> src/compiler/nir/nir_algebraic.py | 8 +++-- >>> >> >> >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ >>> >> >> >> src/compiler/nir/nir_search.c | 3 ++ >>> >> >> >> src/compiler/nir/nir_search.h | 10 ++ >>> >> >> >> src/compiler/nir/nir_search_helpers.h | 66 >>> >> >> >> +++ >>> >> >> >> 5 files changed, 90 insertions(+), 2 deletions(-) >>> >> >> >> create mode 100644 src/compiler/nir/nir_search_helpers.h >>> >> >> >> >>> >> >> >> diff --git a/src/compiler/nir/nir_algebraic.py >>> >> >> >> b/src/compiler/nir/nir_algebraic.py >>> >> >> >> index 285f853..19ac6ee 100644 >>> >> >> >> --- a/src/compiler/nir/nir_algebraic.py >>> >> >> >> +++ b/src/compiler/nir/nir_algebraic.py >>> >> >> >> @@ -76,6 +76,7 @@ class Value(object): >>> >> >> >> return Constant(val, name_base) >>> >> >> >> >>> >> >> >> __template = mako.template.Template(""" >>> >> >> >> +#include "compiler/nir/nir_search_helpers.h" >>> >> >> >> static const ${val.c_type} ${val.name} = { >>> >> >> >> { ${val.type_enum}, ${val.bit_size} }, >>> >> >> >> % if isinstance(val, Constant): >>> >> >> >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { >>> >> >> >> ${val.index}, /* ${val.var_name} */ >>> >> >> >> ${'true' if val.is_constant else 'false'}, >>> >> >> >> ${val.type() or 'nir_type_invalid' }, >>> >> >> >> + ${val.cond if val.cond else 'NULL'}, >>> >> >> >> % elif isinstance(val, Expression): >>> >> >> >> ${'true' if val.inexact else 'false'}, >>> >> >> >> nir_op_${val.opcode}, >>> >> >> >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { >>> >> >> >> Variable=Variable, >>> >> >> >> Expression=Expression) >>> >> >> >> >>> >> >> >> -_constant_re = >>> >> >> >> re.compile(r"(?P[^@]+)(?:@(?P\d+))?") >>> >> >> >> +_constant_re = >>> >> >> >> re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") >>> >> >> > >>> >> >> > >>> >> >> > Spurious change? >>> >> >> > >>> >> >> >>> >> >> I thought it needed to avoid matching something like >>> >> >> a(is_power_of_two).. but it seems to work with that hunk reverted so >>> >> >> I >>> >> >> guess I can drop it.. >>> >> >> >>> >> >> >> >>> >> >> >> >>> >> >> >> class Constant(Value): >>> >> >> >> def __init__(self, val, name): >>> >> >> >> @@ -150,7 +152,8 @@ class Constant(Value): >>> >> >> >> return "nir_type_float" >>> >> >> >> >>> >> >> >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" >>> >> >> >> - >>> >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") >>> >> >> >> + >>> >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" >>> >> >> >> + r"(?P\([^\)]+\))?") >>> >> >> >> >>> >> >> >> class Variable(Value): >>> >> >> >> def __init__(self, val, name, varset): >>> >> >> >> @@ -161,6 +164,7 @@ class Variable(Value): >>> >> >> >> >>> >> >> >>self.var_name = m.group('name') >>> >> >> >>self.is_constant =
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Mon, May 16, 2016 at 3:16 PM, Jason Ekstrandwrote: > On Mon, May 16, 2016 at 9:09 AM, Rob Clark wrote: >> >> On Mon, May 16, 2016 at 10:45 AM, Jason Ekstrand >> wrote: >> > >> > On May 16, 2016 7:29 AM, "Rob Clark" wrote: >> >> >> >> On Sat, May 14, 2016 at 4:03 PM, Jason Ekstrand >> >> wrote: >> >> > >> >> > >> >> > On Sat, May 14, 2016 at 12:20 PM, Rob Clark >> >> > wrote: >> >> >> >> >> >> On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrand >> >> >> >> >> >> wrote: >> >> >> > >> >> >> > >> >> >> > On Tue, May 10, 2016 at 11:57 AM, Rob Clark >> >> >> > wrote: >> >> >> >> >> >> >> >> From: Rob Clark >> >> >> >> >> >> >> >> Some optimizations, like converting integer multiply/divide into >> >> >> >> left/ >> >> >> >> right shifts, have additional constraints on the search >> >> >> >> expression. >> >> >> >> Like requiring that a variable is a constant power of two. >> >> >> >> Support >> >> >> >> these cases by allowing a fxn name to be appended to the search >> >> >> >> var >> >> >> >> expression (ie. "a#32(is_power_of_two)"). >> >> >> >> >> >> >> >> TODO update doc/comment explaining search var syntax >> >> >> >> TODO the eagle-eyed viewer might have noticed that this could >> >> >> >> also >> >> >> >> replace the existing const syntax (ie. "#a"). Not sure if we >> >> >> >> should >> >> >> >> keep that.. we could make it syntactic sugar (ie '#' >> >> >> >> automatically >> >> >> >> sets >> >> >> >> the cond fxn ptr to 'is_const') or just get rid of it entirely? >> >> >> >> Maybe >> >> >> >> that is a follow-on clean-up patch? >> >> >> >> >> >> >> >> Signed-off-by: Rob Clark >> >> >> >> --- >> >> >> >> src/compiler/nir/nir_algebraic.py | 8 +++-- >> >> >> >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ >> >> >> >> src/compiler/nir/nir_search.c | 3 ++ >> >> >> >> src/compiler/nir/nir_search.h | 10 ++ >> >> >> >> src/compiler/nir/nir_search_helpers.h | 66 >> >> >> >> +++ >> >> >> >> 5 files changed, 90 insertions(+), 2 deletions(-) >> >> >> >> create mode 100644 src/compiler/nir/nir_search_helpers.h >> >> >> >> >> >> >> >> diff --git a/src/compiler/nir/nir_algebraic.py >> >> >> >> b/src/compiler/nir/nir_algebraic.py >> >> >> >> index 285f853..19ac6ee 100644 >> >> >> >> --- a/src/compiler/nir/nir_algebraic.py >> >> >> >> +++ b/src/compiler/nir/nir_algebraic.py >> >> >> >> @@ -76,6 +76,7 @@ class Value(object): >> >> >> >> return Constant(val, name_base) >> >> >> >> >> >> >> >> __template = mako.template.Template(""" >> >> >> >> +#include "compiler/nir/nir_search_helpers.h" >> >> >> >> static const ${val.c_type} ${val.name} = { >> >> >> >> { ${val.type_enum}, ${val.bit_size} }, >> >> >> >> % if isinstance(val, Constant): >> >> >> >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { >> >> >> >> ${val.index}, /* ${val.var_name} */ >> >> >> >> ${'true' if val.is_constant else 'false'}, >> >> >> >> ${val.type() or 'nir_type_invalid' }, >> >> >> >> + ${val.cond if val.cond else 'NULL'}, >> >> >> >> % elif isinstance(val, Expression): >> >> >> >> ${'true' if val.inexact else 'false'}, >> >> >> >> nir_op_${val.opcode}, >> >> >> >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { >> >> >> >> Variable=Variable, >> >> >> >> Expression=Expression) >> >> >> >> >> >> >> >> -_constant_re = >> >> >> >> re.compile(r"(?P[^@]+)(?:@(?P\d+))?") >> >> >> >> +_constant_re = >> >> >> >> re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") >> >> >> > >> >> >> > >> >> >> > Spurious change? >> >> >> > >> >> >> >> >> >> I thought it needed to avoid matching something like >> >> >> a(is_power_of_two).. but it seems to work with that hunk reverted so >> >> >> I >> >> >> guess I can drop it.. >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> class Constant(Value): >> >> >> >> def __init__(self, val, name): >> >> >> >> @@ -150,7 +152,8 @@ class Constant(Value): >> >> >> >> return "nir_type_float" >> >> >> >> >> >> >> >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" >> >> >> >> - >> >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") >> >> >> >> + >> >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" >> >> >> >> + r"(?P\([^\)]+\))?") >> >> >> >> >> >> >> >> class Variable(Value): >> >> >> >> def __init__(self, val, name, varset): >> >> >> >> @@ -161,6 +164,7 @@ class Variable(Value): >> >> >> >> >> >> >> >>self.var_name = m.group('name') >> >> >> >>self.is_constant = m.group('const') is not None >> >> >> >> + self.cond = m.group('cond') >> >> >> >>self.required_type = m.group('type') >> >> >> >>self.bit_size = int(m.group('bits')) if
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Mon, May 16, 2016 at 9:09 AM, Rob Clarkwrote: > On Mon, May 16, 2016 at 10:45 AM, Jason Ekstrand > wrote: > > > > On May 16, 2016 7:29 AM, "Rob Clark" wrote: > >> > >> On Sat, May 14, 2016 at 4:03 PM, Jason Ekstrand > >> wrote: > >> > > >> > > >> > On Sat, May 14, 2016 at 12:20 PM, Rob Clark > wrote: > >> >> > >> >> On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrand < > ja...@jlekstrand.net> > >> >> wrote: > >> >> > > >> >> > > >> >> > On Tue, May 10, 2016 at 11:57 AM, Rob Clark > >> >> > wrote: > >> >> >> > >> >> >> From: Rob Clark > >> >> >> > >> >> >> Some optimizations, like converting integer multiply/divide into > >> >> >> left/ > >> >> >> right shifts, have additional constraints on the search > expression. > >> >> >> Like requiring that a variable is a constant power of two. > Support > >> >> >> these cases by allowing a fxn name to be appended to the search > var > >> >> >> expression (ie. "a#32(is_power_of_two)"). > >> >> >> > >> >> >> TODO update doc/comment explaining search var syntax > >> >> >> TODO the eagle-eyed viewer might have noticed that this could also > >> >> >> replace the existing const syntax (ie. "#a"). Not sure if we > should > >> >> >> keep that.. we could make it syntactic sugar (ie '#' automatically > >> >> >> sets > >> >> >> the cond fxn ptr to 'is_const') or just get rid of it entirely? > >> >> >> Maybe > >> >> >> that is a follow-on clean-up patch? > >> >> >> > >> >> >> Signed-off-by: Rob Clark > >> >> >> --- > >> >> >> src/compiler/nir/nir_algebraic.py | 8 +++-- > >> >> >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ > >> >> >> src/compiler/nir/nir_search.c | 3 ++ > >> >> >> src/compiler/nir/nir_search.h | 10 ++ > >> >> >> src/compiler/nir/nir_search_helpers.h | 66 > >> >> >> +++ > >> >> >> 5 files changed, 90 insertions(+), 2 deletions(-) > >> >> >> create mode 100644 src/compiler/nir/nir_search_helpers.h > >> >> >> > >> >> >> diff --git a/src/compiler/nir/nir_algebraic.py > >> >> >> b/src/compiler/nir/nir_algebraic.py > >> >> >> index 285f853..19ac6ee 100644 > >> >> >> --- a/src/compiler/nir/nir_algebraic.py > >> >> >> +++ b/src/compiler/nir/nir_algebraic.py > >> >> >> @@ -76,6 +76,7 @@ class Value(object): > >> >> >> return Constant(val, name_base) > >> >> >> > >> >> >> __template = mako.template.Template(""" > >> >> >> +#include "compiler/nir/nir_search_helpers.h" > >> >> >> static const ${val.c_type} ${val.name} = { > >> >> >> { ${val.type_enum}, ${val.bit_size} }, > >> >> >> % if isinstance(val, Constant): > >> >> >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { > >> >> >> ${val.index}, /* ${val.var_name} */ > >> >> >> ${'true' if val.is_constant else 'false'}, > >> >> >> ${val.type() or 'nir_type_invalid' }, > >> >> >> + ${val.cond if val.cond else 'NULL'}, > >> >> >> % elif isinstance(val, Expression): > >> >> >> ${'true' if val.inexact else 'false'}, > >> >> >> nir_op_${val.opcode}, > >> >> >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { > >> >> >> Variable=Variable, > >> >> >> Expression=Expression) > >> >> >> > >> >> >> -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") > >> >> >> +_constant_re = > re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") > >> >> > > >> >> > > >> >> > Spurious change? > >> >> > > >> >> > >> >> I thought it needed to avoid matching something like > >> >> a(is_power_of_two).. but it seems to work with that hunk reverted so > I > >> >> guess I can drop it.. > >> >> > >> >> >> > >> >> >> > >> >> >> class Constant(Value): > >> >> >> def __init__(self, val, name): > >> >> >> @@ -150,7 +152,8 @@ class Constant(Value): > >> >> >> return "nir_type_float" > >> >> >> > >> >> >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" > >> >> >> - > >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") > >> >> >> + > >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" > >> >> >> + r"(?P\([^\)]+\))?") > >> >> >> > >> >> >> class Variable(Value): > >> >> >> def __init__(self, val, name, varset): > >> >> >> @@ -161,6 +164,7 @@ class Variable(Value): > >> >> >> > >> >> >>self.var_name = m.group('name') > >> >> >>self.is_constant = m.group('const') is not None > >> >> >> + self.cond = m.group('cond') > >> >> >>self.required_type = m.group('type') > >> >> >>self.bit_size = int(m.group('bits')) if m.group('bits') > else > >> >> >> 0 > >> >> >> > >> >> >> diff --git a/src/compiler/nir/nir_opt_algebraic.py > >> >> >> b/src/compiler/nir/nir_opt_algebraic.py > >> >> >> index 0a95725..952a91a 100644 > >> >> >> --- a/src/compiler/nir/nir_opt_algebraic.py > >> >> >> +++
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Mon, May 16, 2016 at 10:45 AM, Jason Ekstrandwrote: > > On May 16, 2016 7:29 AM, "Rob Clark" wrote: >> >> On Sat, May 14, 2016 at 4:03 PM, Jason Ekstrand >> wrote: >> > >> > >> > On Sat, May 14, 2016 at 12:20 PM, Rob Clark wrote: >> >> >> >> On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrand >> >> wrote: >> >> > >> >> > >> >> > On Tue, May 10, 2016 at 11:57 AM, Rob Clark >> >> > wrote: >> >> >> >> >> >> From: Rob Clark >> >> >> >> >> >> Some optimizations, like converting integer multiply/divide into >> >> >> left/ >> >> >> right shifts, have additional constraints on the search expression. >> >> >> Like requiring that a variable is a constant power of two. Support >> >> >> these cases by allowing a fxn name to be appended to the search var >> >> >> expression (ie. "a#32(is_power_of_two)"). >> >> >> >> >> >> TODO update doc/comment explaining search var syntax >> >> >> TODO the eagle-eyed viewer might have noticed that this could also >> >> >> replace the existing const syntax (ie. "#a"). Not sure if we should >> >> >> keep that.. we could make it syntactic sugar (ie '#' automatically >> >> >> sets >> >> >> the cond fxn ptr to 'is_const') or just get rid of it entirely? >> >> >> Maybe >> >> >> that is a follow-on clean-up patch? >> >> >> >> >> >> Signed-off-by: Rob Clark >> >> >> --- >> >> >> src/compiler/nir/nir_algebraic.py | 8 +++-- >> >> >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ >> >> >> src/compiler/nir/nir_search.c | 3 ++ >> >> >> src/compiler/nir/nir_search.h | 10 ++ >> >> >> src/compiler/nir/nir_search_helpers.h | 66 >> >> >> +++ >> >> >> 5 files changed, 90 insertions(+), 2 deletions(-) >> >> >> create mode 100644 src/compiler/nir/nir_search_helpers.h >> >> >> >> >> >> diff --git a/src/compiler/nir/nir_algebraic.py >> >> >> b/src/compiler/nir/nir_algebraic.py >> >> >> index 285f853..19ac6ee 100644 >> >> >> --- a/src/compiler/nir/nir_algebraic.py >> >> >> +++ b/src/compiler/nir/nir_algebraic.py >> >> >> @@ -76,6 +76,7 @@ class Value(object): >> >> >> return Constant(val, name_base) >> >> >> >> >> >> __template = mako.template.Template(""" >> >> >> +#include "compiler/nir/nir_search_helpers.h" >> >> >> static const ${val.c_type} ${val.name} = { >> >> >> { ${val.type_enum}, ${val.bit_size} }, >> >> >> % if isinstance(val, Constant): >> >> >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { >> >> >> ${val.index}, /* ${val.var_name} */ >> >> >> ${'true' if val.is_constant else 'false'}, >> >> >> ${val.type() or 'nir_type_invalid' }, >> >> >> + ${val.cond if val.cond else 'NULL'}, >> >> >> % elif isinstance(val, Expression): >> >> >> ${'true' if val.inexact else 'false'}, >> >> >> nir_op_${val.opcode}, >> >> >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { >> >> >> Variable=Variable, >> >> >> Expression=Expression) >> >> >> >> >> >> -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") >> >> >> +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") >> >> > >> >> > >> >> > Spurious change? >> >> > >> >> >> >> I thought it needed to avoid matching something like >> >> a(is_power_of_two).. but it seems to work with that hunk reverted so I >> >> guess I can drop it.. >> >> >> >> >> >> >> >> >> >> >> class Constant(Value): >> >> >> def __init__(self, val, name): >> >> >> @@ -150,7 +152,8 @@ class Constant(Value): >> >> >> return "nir_type_float" >> >> >> >> >> >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" >> >> >> - >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") >> >> >> + >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" >> >> >> + r"(?P\([^\)]+\))?") >> >> >> >> >> >> class Variable(Value): >> >> >> def __init__(self, val, name, varset): >> >> >> @@ -161,6 +164,7 @@ class Variable(Value): >> >> >> >> >> >>self.var_name = m.group('name') >> >> >>self.is_constant = m.group('const') is not None >> >> >> + self.cond = m.group('cond') >> >> >>self.required_type = m.group('type') >> >> >>self.bit_size = int(m.group('bits')) if m.group('bits') else >> >> >> 0 >> >> >> >> >> >> diff --git a/src/compiler/nir/nir_opt_algebraic.py >> >> >> b/src/compiler/nir/nir_opt_algebraic.py >> >> >> index 0a95725..952a91a 100644 >> >> >> --- a/src/compiler/nir/nir_opt_algebraic.py >> >> >> +++ b/src/compiler/nir/nir_opt_algebraic.py >> >> >> @@ -62,6 +62,11 @@ d = 'd' >> >> >> # constructed value should have that bit-size. >> >> >> >> >> >> optimizations = [ >> >> >> + >> >> >> + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', >> >> >> b))), >> >> >> + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a,
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On May 16, 2016 7:29 AM, "Rob Clark"wrote: > > On Sat, May 14, 2016 at 4:03 PM, Jason Ekstrand wrote: > > > > > > On Sat, May 14, 2016 at 12:20 PM, Rob Clark wrote: > >> > >> On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrand > >> wrote: > >> > > >> > > >> > On Tue, May 10, 2016 at 11:57 AM, Rob Clark wrote: > >> >> > >> >> From: Rob Clark > >> >> > >> >> Some optimizations, like converting integer multiply/divide into left/ > >> >> right shifts, have additional constraints on the search expression. > >> >> Like requiring that a variable is a constant power of two. Support > >> >> these cases by allowing a fxn name to be appended to the search var > >> >> expression (ie. "a#32(is_power_of_two)"). > >> >> > >> >> TODO update doc/comment explaining search var syntax > >> >> TODO the eagle-eyed viewer might have noticed that this could also > >> >> replace the existing const syntax (ie. "#a"). Not sure if we should > >> >> keep that.. we could make it syntactic sugar (ie '#' automatically sets > >> >> the cond fxn ptr to 'is_const') or just get rid of it entirely? Maybe > >> >> that is a follow-on clean-up patch? > >> >> > >> >> Signed-off-by: Rob Clark > >> >> --- > >> >> src/compiler/nir/nir_algebraic.py | 8 +++-- > >> >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ > >> >> src/compiler/nir/nir_search.c | 3 ++ > >> >> src/compiler/nir/nir_search.h | 10 ++ > >> >> src/compiler/nir/nir_search_helpers.h | 66 > >> >> +++ > >> >> 5 files changed, 90 insertions(+), 2 deletions(-) > >> >> create mode 100644 src/compiler/nir/nir_search_helpers.h > >> >> > >> >> diff --git a/src/compiler/nir/nir_algebraic.py > >> >> b/src/compiler/nir/nir_algebraic.py > >> >> index 285f853..19ac6ee 100644 > >> >> --- a/src/compiler/nir/nir_algebraic.py > >> >> +++ b/src/compiler/nir/nir_algebraic.py > >> >> @@ -76,6 +76,7 @@ class Value(object): > >> >> return Constant(val, name_base) > >> >> > >> >> __template = mako.template.Template(""" > >> >> +#include "compiler/nir/nir_search_helpers.h" > >> >> static const ${val.c_type} ${val.name} = { > >> >> { ${val.type_enum}, ${val.bit_size} }, > >> >> % if isinstance(val, Constant): > >> >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { > >> >> ${val.index}, /* ${val.var_name} */ > >> >> ${'true' if val.is_constant else 'false'}, > >> >> ${val.type() or 'nir_type_invalid' }, > >> >> + ${val.cond if val.cond else 'NULL'}, > >> >> % elif isinstance(val, Expression): > >> >> ${'true' if val.inexact else 'false'}, > >> >> nir_op_${val.opcode}, > >> >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { > >> >> Variable=Variable, > >> >> Expression=Expression) > >> >> > >> >> -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") > >> >> +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") > >> > > >> > > >> > Spurious change? > >> > > >> > >> I thought it needed to avoid matching something like > >> a(is_power_of_two).. but it seems to work with that hunk reverted so I > >> guess I can drop it.. > >> > >> >> > >> >> > >> >> class Constant(Value): > >> >> def __init__(self, val, name): > >> >> @@ -150,7 +152,8 @@ class Constant(Value): > >> >> return "nir_type_float" > >> >> > >> >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" > >> >> - > >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") > >> >> + > >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" > >> >> + r"(?P\([^\)]+\))?") > >> >> > >> >> class Variable(Value): > >> >> def __init__(self, val, name, varset): > >> >> @@ -161,6 +164,7 @@ class Variable(Value): > >> >> > >> >>self.var_name = m.group('name') > >> >>self.is_constant = m.group('const') is not None > >> >> + self.cond = m.group('cond') > >> >>self.required_type = m.group('type') > >> >>self.bit_size = int(m.group('bits')) if m.group('bits') else 0 > >> >> > >> >> diff --git a/src/compiler/nir/nir_opt_algebraic.py > >> >> b/src/compiler/nir/nir_opt_algebraic.py > >> >> index 0a95725..952a91a 100644 > >> >> --- a/src/compiler/nir/nir_opt_algebraic.py > >> >> +++ b/src/compiler/nir/nir_opt_algebraic.py > >> >> @@ -62,6 +62,11 @@ d = 'd' > >> >> # constructed value should have that bit-size. > >> >> > >> >> optimizations = [ > >> >> + > >> >> + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', > >> >> b))), > >> >> + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a, ('find_lsb', > >> >> b))), > >> >> + (('umod', a, '#b(is_power_of_two)'),('iand', a, ('isub', b, > >> >> 1))), > >> >> + > >> >> (('fneg', ('fneg', a)), a), > >> >> (('ineg', ('ineg', a)), a), > >> >> (('fabs', ('fabs', a)),
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Mon, May 16, 2016 at 10:45 AM, Jason Ekstrandwrote: > > On May 16, 2016 7:29 AM, "Rob Clark" wrote: >> >> On Sat, May 14, 2016 at 4:03 PM, Jason Ekstrand >> wrote: >> > >> > >> > On Sat, May 14, 2016 at 12:20 PM, Rob Clark wrote: >> >> >> >> On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrand >> >> wrote: >> >> > >> >> > >> >> > On Tue, May 10, 2016 at 11:57 AM, Rob Clark >> >> > wrote: >> >> >> >> >> >> From: Rob Clark >> >> >> >> >> >> Some optimizations, like converting integer multiply/divide into >> >> >> left/ >> >> >> right shifts, have additional constraints on the search expression. >> >> >> Like requiring that a variable is a constant power of two. Support >> >> >> these cases by allowing a fxn name to be appended to the search var >> >> >> expression (ie. "a#32(is_power_of_two)"). >> >> >> >> >> >> TODO update doc/comment explaining search var syntax >> >> >> TODO the eagle-eyed viewer might have noticed that this could also >> >> >> replace the existing const syntax (ie. "#a"). Not sure if we should >> >> >> keep that.. we could make it syntactic sugar (ie '#' automatically >> >> >> sets >> >> >> the cond fxn ptr to 'is_const') or just get rid of it entirely? >> >> >> Maybe >> >> >> that is a follow-on clean-up patch? >> >> >> >> >> >> Signed-off-by: Rob Clark >> >> >> --- >> >> >> src/compiler/nir/nir_algebraic.py | 8 +++-- >> >> >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ >> >> >> src/compiler/nir/nir_search.c | 3 ++ >> >> >> src/compiler/nir/nir_search.h | 10 ++ >> >> >> src/compiler/nir/nir_search_helpers.h | 66 >> >> >> +++ >> >> >> 5 files changed, 90 insertions(+), 2 deletions(-) >> >> >> create mode 100644 src/compiler/nir/nir_search_helpers.h >> >> >> >> >> >> diff --git a/src/compiler/nir/nir_algebraic.py >> >> >> b/src/compiler/nir/nir_algebraic.py >> >> >> index 285f853..19ac6ee 100644 >> >> >> --- a/src/compiler/nir/nir_algebraic.py >> >> >> +++ b/src/compiler/nir/nir_algebraic.py >> >> >> @@ -76,6 +76,7 @@ class Value(object): >> >> >> return Constant(val, name_base) >> >> >> >> >> >> __template = mako.template.Template(""" >> >> >> +#include "compiler/nir/nir_search_helpers.h" >> >> >> static const ${val.c_type} ${val.name} = { >> >> >> { ${val.type_enum}, ${val.bit_size} }, >> >> >> % if isinstance(val, Constant): >> >> >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { >> >> >> ${val.index}, /* ${val.var_name} */ >> >> >> ${'true' if val.is_constant else 'false'}, >> >> >> ${val.type() or 'nir_type_invalid' }, >> >> >> + ${val.cond if val.cond else 'NULL'}, >> >> >> % elif isinstance(val, Expression): >> >> >> ${'true' if val.inexact else 'false'}, >> >> >> nir_op_${val.opcode}, >> >> >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { >> >> >> Variable=Variable, >> >> >> Expression=Expression) >> >> >> >> >> >> -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") >> >> >> +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") >> >> > >> >> > >> >> > Spurious change? >> >> > >> >> >> >> I thought it needed to avoid matching something like >> >> a(is_power_of_two).. but it seems to work with that hunk reverted so I >> >> guess I can drop it.. >> >> >> >> >> >> >> >> >> >> >> class Constant(Value): >> >> >> def __init__(self, val, name): >> >> >> @@ -150,7 +152,8 @@ class Constant(Value): >> >> >> return "nir_type_float" >> >> >> >> >> >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" >> >> >> - >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") >> >> >> + >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" >> >> >> + r"(?P\([^\)]+\))?") >> >> >> >> >> >> class Variable(Value): >> >> >> def __init__(self, val, name, varset): >> >> >> @@ -161,6 +164,7 @@ class Variable(Value): >> >> >> >> >> >>self.var_name = m.group('name') >> >> >>self.is_constant = m.group('const') is not None >> >> >> + self.cond = m.group('cond') >> >> >>self.required_type = m.group('type') >> >> >>self.bit_size = int(m.group('bits')) if m.group('bits') else >> >> >> 0 >> >> >> >> >> >> diff --git a/src/compiler/nir/nir_opt_algebraic.py >> >> >> b/src/compiler/nir/nir_opt_algebraic.py >> >> >> index 0a95725..952a91a 100644 >> >> >> --- a/src/compiler/nir/nir_opt_algebraic.py >> >> >> +++ b/src/compiler/nir/nir_opt_algebraic.py >> >> >> @@ -62,6 +62,11 @@ d = 'd' >> >> >> # constructed value should have that bit-size. >> >> >> >> >> >> optimizations = [ >> >> >> + >> >> >> + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', >> >> >> b))), >> >> >> + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a,
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Mon, May 16, 2016 at 10:45 AM, Jason Ekstrandwrote: > > On May 16, 2016 7:29 AM, "Rob Clark" wrote: >> >> On Sat, May 14, 2016 at 4:03 PM, Jason Ekstrand >> wrote: >> > >> > >> > On Sat, May 14, 2016 at 12:20 PM, Rob Clark wrote: >> >> >> >> On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrand >> >> wrote: >> >> > >> >> > >> >> > On Tue, May 10, 2016 at 11:57 AM, Rob Clark >> >> > wrote: >> >> >> >> >> >> From: Rob Clark >> >> >> >> >> >> Some optimizations, like converting integer multiply/divide into >> >> >> left/ >> >> >> right shifts, have additional constraints on the search expression. >> >> >> Like requiring that a variable is a constant power of two. Support >> >> >> these cases by allowing a fxn name to be appended to the search var >> >> >> expression (ie. "a#32(is_power_of_two)"). >> >> >> >> >> >> TODO update doc/comment explaining search var syntax >> >> >> TODO the eagle-eyed viewer might have noticed that this could also >> >> >> replace the existing const syntax (ie. "#a"). Not sure if we should >> >> >> keep that.. we could make it syntactic sugar (ie '#' automatically >> >> >> sets >> >> >> the cond fxn ptr to 'is_const') or just get rid of it entirely? >> >> >> Maybe >> >> >> that is a follow-on clean-up patch? >> >> >> >> >> >> Signed-off-by: Rob Clark >> >> >> --- >> >> >> src/compiler/nir/nir_algebraic.py | 8 +++-- >> >> >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ >> >> >> src/compiler/nir/nir_search.c | 3 ++ >> >> >> src/compiler/nir/nir_search.h | 10 ++ >> >> >> src/compiler/nir/nir_search_helpers.h | 66 >> >> >> +++ >> >> >> 5 files changed, 90 insertions(+), 2 deletions(-) >> >> >> create mode 100644 src/compiler/nir/nir_search_helpers.h >> >> >> >> >> >> diff --git a/src/compiler/nir/nir_algebraic.py >> >> >> b/src/compiler/nir/nir_algebraic.py >> >> >> index 285f853..19ac6ee 100644 >> >> >> --- a/src/compiler/nir/nir_algebraic.py >> >> >> +++ b/src/compiler/nir/nir_algebraic.py >> >> >> @@ -76,6 +76,7 @@ class Value(object): >> >> >> return Constant(val, name_base) >> >> >> >> >> >> __template = mako.template.Template(""" >> >> >> +#include "compiler/nir/nir_search_helpers.h" >> >> >> static const ${val.c_type} ${val.name} = { >> >> >> { ${val.type_enum}, ${val.bit_size} }, >> >> >> % if isinstance(val, Constant): >> >> >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { >> >> >> ${val.index}, /* ${val.var_name} */ >> >> >> ${'true' if val.is_constant else 'false'}, >> >> >> ${val.type() or 'nir_type_invalid' }, >> >> >> + ${val.cond if val.cond else 'NULL'}, >> >> >> % elif isinstance(val, Expression): >> >> >> ${'true' if val.inexact else 'false'}, >> >> >> nir_op_${val.opcode}, >> >> >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { >> >> >> Variable=Variable, >> >> >> Expression=Expression) >> >> >> >> >> >> -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") >> >> >> +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") >> >> > >> >> > >> >> > Spurious change? >> >> > >> >> >> >> I thought it needed to avoid matching something like >> >> a(is_power_of_two).. but it seems to work with that hunk reverted so I >> >> guess I can drop it.. >> >> >> >> >> >> >> >> >> >> >> class Constant(Value): >> >> >> def __init__(self, val, name): >> >> >> @@ -150,7 +152,8 @@ class Constant(Value): >> >> >> return "nir_type_float" >> >> >> >> >> >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" >> >> >> - >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") >> >> >> + >> >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" >> >> >> + r"(?P\([^\)]+\))?") >> >> >> >> >> >> class Variable(Value): >> >> >> def __init__(self, val, name, varset): >> >> >> @@ -161,6 +164,7 @@ class Variable(Value): >> >> >> >> >> >>self.var_name = m.group('name') >> >> >>self.is_constant = m.group('const') is not None >> >> >> + self.cond = m.group('cond') >> >> >>self.required_type = m.group('type') >> >> >>self.bit_size = int(m.group('bits')) if m.group('bits') else >> >> >> 0 >> >> >> >> >> >> diff --git a/src/compiler/nir/nir_opt_algebraic.py >> >> >> b/src/compiler/nir/nir_opt_algebraic.py >> >> >> index 0a95725..952a91a 100644 >> >> >> --- a/src/compiler/nir/nir_opt_algebraic.py >> >> >> +++ b/src/compiler/nir/nir_opt_algebraic.py >> >> >> @@ -62,6 +62,11 @@ d = 'd' >> >> >> # constructed value should have that bit-size. >> >> >> >> >> >> optimizations = [ >> >> >> + >> >> >> + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', >> >> >> b))), >> >> >> + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a,
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Sat, May 14, 2016 at 4:03 PM, Jason Ekstrandwrote: > > > On Sat, May 14, 2016 at 12:20 PM, Rob Clark wrote: >> >> On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrand >> wrote: >> > >> > >> > On Tue, May 10, 2016 at 11:57 AM, Rob Clark wrote: >> >> >> >> From: Rob Clark >> >> >> >> Some optimizations, like converting integer multiply/divide into left/ >> >> right shifts, have additional constraints on the search expression. >> >> Like requiring that a variable is a constant power of two. Support >> >> these cases by allowing a fxn name to be appended to the search var >> >> expression (ie. "a#32(is_power_of_two)"). >> >> >> >> TODO update doc/comment explaining search var syntax >> >> TODO the eagle-eyed viewer might have noticed that this could also >> >> replace the existing const syntax (ie. "#a"). Not sure if we should >> >> keep that.. we could make it syntactic sugar (ie '#' automatically sets >> >> the cond fxn ptr to 'is_const') or just get rid of it entirely? Maybe >> >> that is a follow-on clean-up patch? >> >> >> >> Signed-off-by: Rob Clark >> >> --- >> >> src/compiler/nir/nir_algebraic.py | 8 +++-- >> >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ >> >> src/compiler/nir/nir_search.c | 3 ++ >> >> src/compiler/nir/nir_search.h | 10 ++ >> >> src/compiler/nir/nir_search_helpers.h | 66 >> >> +++ >> >> 5 files changed, 90 insertions(+), 2 deletions(-) >> >> create mode 100644 src/compiler/nir/nir_search_helpers.h >> >> >> >> diff --git a/src/compiler/nir/nir_algebraic.py >> >> b/src/compiler/nir/nir_algebraic.py >> >> index 285f853..19ac6ee 100644 >> >> --- a/src/compiler/nir/nir_algebraic.py >> >> +++ b/src/compiler/nir/nir_algebraic.py >> >> @@ -76,6 +76,7 @@ class Value(object): >> >> return Constant(val, name_base) >> >> >> >> __template = mako.template.Template(""" >> >> +#include "compiler/nir/nir_search_helpers.h" >> >> static const ${val.c_type} ${val.name} = { >> >> { ${val.type_enum}, ${val.bit_size} }, >> >> % if isinstance(val, Constant): >> >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { >> >> ${val.index}, /* ${val.var_name} */ >> >> ${'true' if val.is_constant else 'false'}, >> >> ${val.type() or 'nir_type_invalid' }, >> >> + ${val.cond if val.cond else 'NULL'}, >> >> % elif isinstance(val, Expression): >> >> ${'true' if val.inexact else 'false'}, >> >> nir_op_${val.opcode}, >> >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { >> >> Variable=Variable, >> >> Expression=Expression) >> >> >> >> -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") >> >> +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") >> > >> > >> > Spurious change? >> > >> >> I thought it needed to avoid matching something like >> a(is_power_of_two).. but it seems to work with that hunk reverted so I >> guess I can drop it.. >> >> >> >> >> >> >> class Constant(Value): >> >> def __init__(self, val, name): >> >> @@ -150,7 +152,8 @@ class Constant(Value): >> >> return "nir_type_float" >> >> >> >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" >> >> - >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") >> >> + >> >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" >> >> + r"(?P\([^\)]+\))?") >> >> >> >> class Variable(Value): >> >> def __init__(self, val, name, varset): >> >> @@ -161,6 +164,7 @@ class Variable(Value): >> >> >> >>self.var_name = m.group('name') >> >>self.is_constant = m.group('const') is not None >> >> + self.cond = m.group('cond') >> >>self.required_type = m.group('type') >> >>self.bit_size = int(m.group('bits')) if m.group('bits') else 0 >> >> >> >> diff --git a/src/compiler/nir/nir_opt_algebraic.py >> >> b/src/compiler/nir/nir_opt_algebraic.py >> >> index 0a95725..952a91a 100644 >> >> --- a/src/compiler/nir/nir_opt_algebraic.py >> >> +++ b/src/compiler/nir/nir_opt_algebraic.py >> >> @@ -62,6 +62,11 @@ d = 'd' >> >> # constructed value should have that bit-size. >> >> >> >> optimizations = [ >> >> + >> >> + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', >> >> b))), >> >> + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a, ('find_lsb', >> >> b))), >> >> + (('umod', a, '#b(is_power_of_two)'),('iand', a, ('isub', b, >> >> 1))), >> >> + >> >> (('fneg', ('fneg', a)), a), >> >> (('ineg', ('ineg', a)), a), >> >> (('fabs', ('fabs', a)), ('fabs', a)), >> >> diff --git a/src/compiler/nir/nir_search.c >> >> b/src/compiler/nir/nir_search.c >> >> index 2c2fd92..b21fb2c 100644 >> >> --- a/src/compiler/nir/nir_search.c >> >> +++ b/src/compiler/nir/nir_search.c >> >> @@ -127,6 +127,9 @@ match_value(const nir_search_value *value, >> >>
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Sat, May 14, 2016 at 12:20 PM, Rob Clarkwrote: > On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrand > wrote: > > > > > > On Tue, May 10, 2016 at 11:57 AM, Rob Clark wrote: > >> > >> From: Rob Clark > >> > >> Some optimizations, like converting integer multiply/divide into left/ > >> right shifts, have additional constraints on the search expression. > >> Like requiring that a variable is a constant power of two. Support > >> these cases by allowing a fxn name to be appended to the search var > >> expression (ie. "a#32(is_power_of_two)"). > >> > >> TODO update doc/comment explaining search var syntax > >> TODO the eagle-eyed viewer might have noticed that this could also > >> replace the existing const syntax (ie. "#a"). Not sure if we should > >> keep that.. we could make it syntactic sugar (ie '#' automatically sets > >> the cond fxn ptr to 'is_const') or just get rid of it entirely? Maybe > >> that is a follow-on clean-up patch? > >> > >> Signed-off-by: Rob Clark > >> --- > >> src/compiler/nir/nir_algebraic.py | 8 +++-- > >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ > >> src/compiler/nir/nir_search.c | 3 ++ > >> src/compiler/nir/nir_search.h | 10 ++ > >> src/compiler/nir/nir_search_helpers.h | 66 > >> +++ > >> 5 files changed, 90 insertions(+), 2 deletions(-) > >> create mode 100644 src/compiler/nir/nir_search_helpers.h > >> > >> diff --git a/src/compiler/nir/nir_algebraic.py > >> b/src/compiler/nir/nir_algebraic.py > >> index 285f853..19ac6ee 100644 > >> --- a/src/compiler/nir/nir_algebraic.py > >> +++ b/src/compiler/nir/nir_algebraic.py > >> @@ -76,6 +76,7 @@ class Value(object): > >> return Constant(val, name_base) > >> > >> __template = mako.template.Template(""" > >> +#include "compiler/nir/nir_search_helpers.h" > >> static const ${val.c_type} ${val.name} = { > >> { ${val.type_enum}, ${val.bit_size} }, > >> % if isinstance(val, Constant): > >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { > >> ${val.index}, /* ${val.var_name} */ > >> ${'true' if val.is_constant else 'false'}, > >> ${val.type() or 'nir_type_invalid' }, > >> + ${val.cond if val.cond else 'NULL'}, > >> % elif isinstance(val, Expression): > >> ${'true' if val.inexact else 'false'}, > >> nir_op_${val.opcode}, > >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { > >> Variable=Variable, > >> Expression=Expression) > >> > >> -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") > >> +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") > > > > > > Spurious change? > > > > I thought it needed to avoid matching something like > a(is_power_of_two).. but it seems to work with that hunk reverted so I > guess I can drop it.. > > >> > >> > >> class Constant(Value): > >> def __init__(self, val, name): > >> @@ -150,7 +152,8 @@ class Constant(Value): > >> return "nir_type_float" > >> > >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" > >> - > >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") > >> + > >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" > >> + r"(?P\([^\)]+\))?") > >> > >> class Variable(Value): > >> def __init__(self, val, name, varset): > >> @@ -161,6 +164,7 @@ class Variable(Value): > >> > >>self.var_name = m.group('name') > >>self.is_constant = m.group('const') is not None > >> + self.cond = m.group('cond') > >>self.required_type = m.group('type') > >>self.bit_size = int(m.group('bits')) if m.group('bits') else 0 > >> > >> diff --git a/src/compiler/nir/nir_opt_algebraic.py > >> b/src/compiler/nir/nir_opt_algebraic.py > >> index 0a95725..952a91a 100644 > >> --- a/src/compiler/nir/nir_opt_algebraic.py > >> +++ b/src/compiler/nir/nir_opt_algebraic.py > >> @@ -62,6 +62,11 @@ d = 'd' > >> # constructed value should have that bit-size. > >> > >> optimizations = [ > >> + > >> + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', > b))), > >> + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a, ('find_lsb', > b))), > >> + (('umod', a, '#b(is_power_of_two)'),('iand', a, ('isub', b, > 1))), > >> + > >> (('fneg', ('fneg', a)), a), > >> (('ineg', ('ineg', a)), a), > >> (('fabs', ('fabs', a)), ('fabs', a)), > >> diff --git a/src/compiler/nir/nir_search.c > b/src/compiler/nir/nir_search.c > >> index 2c2fd92..b21fb2c 100644 > >> --- a/src/compiler/nir/nir_search.c > >> +++ b/src/compiler/nir/nir_search.c > >> @@ -127,6 +127,9 @@ match_value(const nir_search_value *value, > >> nir_alu_instr *instr, unsigned src, > >> instr->src[src].src.ssa->parent_instr->type != > >> nir_instr_type_load_const) > >> return false; > >> > >> + if (var->cond && !var->cond(instr, src,
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Thu, May 12, 2016 at 10:55 PM, Jason Ekstrandwrote: > > > On Tue, May 10, 2016 at 11:57 AM, Rob Clark wrote: >> >> From: Rob Clark >> >> Some optimizations, like converting integer multiply/divide into left/ >> right shifts, have additional constraints on the search expression. >> Like requiring that a variable is a constant power of two. Support >> these cases by allowing a fxn name to be appended to the search var >> expression (ie. "a#32(is_power_of_two)"). >> >> TODO update doc/comment explaining search var syntax >> TODO the eagle-eyed viewer might have noticed that this could also >> replace the existing const syntax (ie. "#a"). Not sure if we should >> keep that.. we could make it syntactic sugar (ie '#' automatically sets >> the cond fxn ptr to 'is_const') or just get rid of it entirely? Maybe >> that is a follow-on clean-up patch? >> >> Signed-off-by: Rob Clark >> --- >> src/compiler/nir/nir_algebraic.py | 8 +++-- >> src/compiler/nir/nir_opt_algebraic.py | 5 +++ >> src/compiler/nir/nir_search.c | 3 ++ >> src/compiler/nir/nir_search.h | 10 ++ >> src/compiler/nir/nir_search_helpers.h | 66 >> +++ >> 5 files changed, 90 insertions(+), 2 deletions(-) >> create mode 100644 src/compiler/nir/nir_search_helpers.h >> >> diff --git a/src/compiler/nir/nir_algebraic.py >> b/src/compiler/nir/nir_algebraic.py >> index 285f853..19ac6ee 100644 >> --- a/src/compiler/nir/nir_algebraic.py >> +++ b/src/compiler/nir/nir_algebraic.py >> @@ -76,6 +76,7 @@ class Value(object): >> return Constant(val, name_base) >> >> __template = mako.template.Template(""" >> +#include "compiler/nir/nir_search_helpers.h" >> static const ${val.c_type} ${val.name} = { >> { ${val.type_enum}, ${val.bit_size} }, >> % if isinstance(val, Constant): >> @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { >> ${val.index}, /* ${val.var_name} */ >> ${'true' if val.is_constant else 'false'}, >> ${val.type() or 'nir_type_invalid' }, >> + ${val.cond if val.cond else 'NULL'}, >> % elif isinstance(val, Expression): >> ${'true' if val.inexact else 'false'}, >> nir_op_${val.opcode}, >> @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { >> Variable=Variable, >> Expression=Expression) >> >> -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") >> +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") > > > Spurious change? > I thought it needed to avoid matching something like a(is_power_of_two).. but it seems to work with that hunk reverted so I guess I can drop it.. >> >> >> class Constant(Value): >> def __init__(self, val, name): >> @@ -150,7 +152,8 @@ class Constant(Value): >> return "nir_type_float" >> >> _var_name_re = re.compile(r"(?P#)?(?P\w+)" >> - >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") >> + >> r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" >> + r"(?P\([^\)]+\))?") >> >> class Variable(Value): >> def __init__(self, val, name, varset): >> @@ -161,6 +164,7 @@ class Variable(Value): >> >>self.var_name = m.group('name') >>self.is_constant = m.group('const') is not None >> + self.cond = m.group('cond') >>self.required_type = m.group('type') >>self.bit_size = int(m.group('bits')) if m.group('bits') else 0 >> >> diff --git a/src/compiler/nir/nir_opt_algebraic.py >> b/src/compiler/nir/nir_opt_algebraic.py >> index 0a95725..952a91a 100644 >> --- a/src/compiler/nir/nir_opt_algebraic.py >> +++ b/src/compiler/nir/nir_opt_algebraic.py >> @@ -62,6 +62,11 @@ d = 'd' >> # constructed value should have that bit-size. >> >> optimizations = [ >> + >> + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', b))), >> + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a, ('find_lsb', b))), >> + (('umod', a, '#b(is_power_of_two)'),('iand', a, ('isub', b, 1))), >> + >> (('fneg', ('fneg', a)), a), >> (('ineg', ('ineg', a)), a), >> (('fabs', ('fabs', a)), ('fabs', a)), >> diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c >> index 2c2fd92..b21fb2c 100644 >> --- a/src/compiler/nir/nir_search.c >> +++ b/src/compiler/nir/nir_search.c >> @@ -127,6 +127,9 @@ match_value(const nir_search_value *value, >> nir_alu_instr *instr, unsigned src, >> instr->src[src].src.ssa->parent_instr->type != >> nir_instr_type_load_const) >> return false; >> >> + if (var->cond && !var->cond(instr, src, num_components, >> new_swizzle)) >> +return false; >> + >> if (var->type != nir_type_invalid) { >> if (instr->src[src].src.ssa->parent_instr->type != >> nir_instr_type_alu) >> return false; >> diff --git a/src/compiler/nir/nir_search.h b/src/compiler/nir/nir_search.h >>
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Thu, May 12, 2016 at 8:12 PM, Matt Turnerwrote: > On Tue, May 10, 2016 at 11:57 AM, Rob Clark wrote: > > From: Rob Clark > > > > Some optimizations, like converting integer multiply/divide into left/ > > right shifts, have additional constraints on the search expression. > > Like requiring that a variable is a constant power of two. Support > > these cases by allowing a fxn name to be appended to the search var > > expression (ie. "a#32(is_power_of_two)"). > > > > TODO update doc/comment explaining search var syntax > > TODO the eagle-eyed viewer might have noticed that this could also > > replace the existing const syntax (ie. "#a"). Not sure if we should > > keep that.. we could make it syntactic sugar (ie '#' automatically sets > > the cond fxn ptr to 'is_const') or just get rid of it entirely? Maybe > > that is a follow-on clean-up patch? > > > > Signed-off-by: Rob Clark > > --- > > src/compiler/nir/nir_algebraic.py | 8 +++-- > > src/compiler/nir/nir_opt_algebraic.py | 5 +++ > > src/compiler/nir/nir_search.c | 3 ++ > > src/compiler/nir/nir_search.h | 10 ++ > > src/compiler/nir/nir_search_helpers.h | 66 > +++ > > 5 files changed, 90 insertions(+), 2 deletions(-) > > create mode 100644 src/compiler/nir/nir_search_helpers.h > > > > diff --git a/src/compiler/nir/nir_algebraic.py > b/src/compiler/nir/nir_algebraic.py > > index 285f853..19ac6ee 100644 > > --- a/src/compiler/nir/nir_algebraic.py > > +++ b/src/compiler/nir/nir_algebraic.py > > @@ -76,6 +76,7 @@ class Value(object): > > return Constant(val, name_base) > > > > __template = mako.template.Template(""" > > +#include "compiler/nir/nir_search_helpers.h" > > static const ${val.c_type} ${val.name} = { > > { ${val.type_enum}, ${val.bit_size} }, > > % if isinstance(val, Constant): > > @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { > > ${val.index}, /* ${val.var_name} */ > > ${'true' if val.is_constant else 'false'}, > > ${val.type() or 'nir_type_invalid' }, > > + ${val.cond if val.cond else 'NULL'}, > > % elif isinstance(val, Expression): > > ${'true' if val.inexact else 'false'}, > > nir_op_${val.opcode}, > > @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { > > Variable=Variable, > > Expression=Expression) > > > > -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") > > +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") > > > > class Constant(Value): > > def __init__(self, val, name): > > @@ -150,7 +152,8 @@ class Constant(Value): > > return "nir_type_float" > > > > _var_name_re = re.compile(r"(?P#)?(?P\w+)" > > - > r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") > > + > r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" > > + r"(?P\([^\)]+\))?") > > > > class Variable(Value): > > def __init__(self, val, name, varset): > > @@ -161,6 +164,7 @@ class Variable(Value): > > > >self.var_name = m.group('name') > >self.is_constant = m.group('const') is not None > > + self.cond = m.group('cond') > >self.required_type = m.group('type') > >self.bit_size = int(m.group('bits')) if m.group('bits') else 0 > > > > diff --git a/src/compiler/nir/nir_opt_algebraic.py > b/src/compiler/nir/nir_opt_algebraic.py > > index 0a95725..952a91a 100644 > > --- a/src/compiler/nir/nir_opt_algebraic.py > > +++ b/src/compiler/nir/nir_opt_algebraic.py > > @@ -62,6 +62,11 @@ d = 'd' > > # constructed value should have that bit-size. > > > > optimizations = [ > > + > > + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', > b))), > > + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a, ('find_lsb', > b))), > > + (('umod', a, '#b(is_power_of_two)'),('iand', a, ('isub', b, 1))), > > + > > (('fneg', ('fneg', a)), a), > > (('ineg', ('ineg', a)), a), > > (('fabs', ('fabs', a)), ('fabs', a)), > > diff --git a/src/compiler/nir/nir_search.c > b/src/compiler/nir/nir_search.c > > index 2c2fd92..b21fb2c 100644 > > --- a/src/compiler/nir/nir_search.c > > +++ b/src/compiler/nir/nir_search.c > > @@ -127,6 +127,9 @@ match_value(const nir_search_value *value, > nir_alu_instr *instr, unsigned src, > > instr->src[src].src.ssa->parent_instr->type != > nir_instr_type_load_const) > > return false; > > > > + if (var->cond && !var->cond(instr, src, num_components, > new_swizzle)) > > +return false; > > + > > if (var->type != nir_type_invalid) { > > if (instr->src[src].src.ssa->parent_instr->type != > nir_instr_type_alu) > > return false; > > diff --git a/src/compiler/nir/nir_search.h > b/src/compiler/nir/nir_search.h > > index a500feb..f55d797 100644 > > --- a/src/compiler/nir/nir_search.h > > +++
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Tue, May 10, 2016 at 11:57 AM, Rob Clarkwrote: > From: Rob Clark > > Some optimizations, like converting integer multiply/divide into left/ > right shifts, have additional constraints on the search expression. > Like requiring that a variable is a constant power of two. Support > these cases by allowing a fxn name to be appended to the search var > expression (ie. "a#32(is_power_of_two)"). > > TODO update doc/comment explaining search var syntax > TODO the eagle-eyed viewer might have noticed that this could also > replace the existing const syntax (ie. "#a"). Not sure if we should > keep that.. we could make it syntactic sugar (ie '#' automatically sets > the cond fxn ptr to 'is_const') or just get rid of it entirely? Maybe > that is a follow-on clean-up patch? > > Signed-off-by: Rob Clark > --- > src/compiler/nir/nir_algebraic.py | 8 +++-- > src/compiler/nir/nir_opt_algebraic.py | 5 +++ > src/compiler/nir/nir_search.c | 3 ++ > src/compiler/nir/nir_search.h | 10 ++ > src/compiler/nir/nir_search_helpers.h | 66 > +++ > 5 files changed, 90 insertions(+), 2 deletions(-) > create mode 100644 src/compiler/nir/nir_search_helpers.h > > diff --git a/src/compiler/nir/nir_algebraic.py > b/src/compiler/nir/nir_algebraic.py > index 285f853..19ac6ee 100644 > --- a/src/compiler/nir/nir_algebraic.py > +++ b/src/compiler/nir/nir_algebraic.py > @@ -76,6 +76,7 @@ class Value(object): > return Constant(val, name_base) > > __template = mako.template.Template(""" > +#include "compiler/nir/nir_search_helpers.h" > static const ${val.c_type} ${val.name} = { > { ${val.type_enum}, ${val.bit_size} }, > % if isinstance(val, Constant): > @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { > ${val.index}, /* ${val.var_name} */ > ${'true' if val.is_constant else 'false'}, > ${val.type() or 'nir_type_invalid' }, > + ${val.cond if val.cond else 'NULL'}, > % elif isinstance(val, Expression): > ${'true' if val.inexact else 'false'}, > nir_op_${val.opcode}, > @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { > Variable=Variable, > Expression=Expression) > > -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") > +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") > > class Constant(Value): > def __init__(self, val, name): > @@ -150,7 +152,8 @@ class Constant(Value): > return "nir_type_float" > > _var_name_re = re.compile(r"(?P#)?(?P\w+)" > - > r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") > + > r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" > + r"(?P\([^\)]+\))?") > > class Variable(Value): > def __init__(self, val, name, varset): > @@ -161,6 +164,7 @@ class Variable(Value): > >self.var_name = m.group('name') >self.is_constant = m.group('const') is not None > + self.cond = m.group('cond') >self.required_type = m.group('type') >self.bit_size = int(m.group('bits')) if m.group('bits') else 0 > > diff --git a/src/compiler/nir/nir_opt_algebraic.py > b/src/compiler/nir/nir_opt_algebraic.py > index 0a95725..952a91a 100644 > --- a/src/compiler/nir/nir_opt_algebraic.py > +++ b/src/compiler/nir/nir_opt_algebraic.py > @@ -62,6 +62,11 @@ d = 'd' > # constructed value should have that bit-size. > > optimizations = [ > + > + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', b))), > + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a, ('find_lsb', b))), > + (('umod', a, '#b(is_power_of_two)'),('iand', a, ('isub', b, 1))), > + > (('fneg', ('fneg', a)), a), > (('ineg', ('ineg', a)), a), > (('fabs', ('fabs', a)), ('fabs', a)), > diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c > index 2c2fd92..b21fb2c 100644 > --- a/src/compiler/nir/nir_search.c > +++ b/src/compiler/nir/nir_search.c > @@ -127,6 +127,9 @@ match_value(const nir_search_value *value, nir_alu_instr > *instr, unsigned src, > instr->src[src].src.ssa->parent_instr->type != > nir_instr_type_load_const) > return false; > > + if (var->cond && !var->cond(instr, src, num_components, > new_swizzle)) > +return false; > + > if (var->type != nir_type_invalid) { > if (instr->src[src].src.ssa->parent_instr->type != > nir_instr_type_alu) > return false; > diff --git a/src/compiler/nir/nir_search.h b/src/compiler/nir/nir_search.h > index a500feb..f55d797 100644 > --- a/src/compiler/nir/nir_search.h > +++ b/src/compiler/nir/nir_search.h > @@ -68,6 +68,16 @@ typedef struct { > * never match anything. > */ > nir_alu_type type; > + > + /** Optional condition fxn ptr Can we write out "function"?
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Tue, May 10, 2016 at 11:57 AM, Rob Clarkwrote: > From: Rob Clark > > Some optimizations, like converting integer multiply/divide into left/ > right shifts, have additional constraints on the search expression. > Like requiring that a variable is a constant power of two. Support > these cases by allowing a fxn name to be appended to the search var > expression (ie. "a#32(is_power_of_two)"). > > TODO update doc/comment explaining search var syntax > TODO the eagle-eyed viewer might have noticed that this could also > replace the existing const syntax (ie. "#a"). Not sure if we should > keep that.. we could make it syntactic sugar (ie '#' automatically sets > the cond fxn ptr to 'is_const') or just get rid of it entirely? Maybe > that is a follow-on clean-up patch? > > Signed-off-by: Rob Clark > --- > src/compiler/nir/nir_algebraic.py | 8 +++-- > src/compiler/nir/nir_opt_algebraic.py | 5 +++ > src/compiler/nir/nir_search.c | 3 ++ > src/compiler/nir/nir_search.h | 10 ++ > src/compiler/nir/nir_search_helpers.h | 66 > +++ > 5 files changed, 90 insertions(+), 2 deletions(-) > create mode 100644 src/compiler/nir/nir_search_helpers.h > > diff --git a/src/compiler/nir/nir_algebraic.py > b/src/compiler/nir/nir_algebraic.py > index 285f853..19ac6ee 100644 > --- a/src/compiler/nir/nir_algebraic.py > +++ b/src/compiler/nir/nir_algebraic.py > @@ -76,6 +76,7 @@ class Value(object): > return Constant(val, name_base) > > __template = mako.template.Template(""" > +#include "compiler/nir/nir_search_helpers.h" > static const ${val.c_type} ${val.name} = { > { ${val.type_enum}, ${val.bit_size} }, > % if isinstance(val, Constant): > @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { > ${val.index}, /* ${val.var_name} */ > ${'true' if val.is_constant else 'false'}, > ${val.type() or 'nir_type_invalid' }, > + ${val.cond if val.cond else 'NULL'}, > % elif isinstance(val, Expression): > ${'true' if val.inexact else 'false'}, > nir_op_${val.opcode}, > @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { > Variable=Variable, > Expression=Expression) > > -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") > +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") > Spurious change? > > class Constant(Value): > def __init__(self, val, name): > @@ -150,7 +152,8 @@ class Constant(Value): > return "nir_type_float" > > _var_name_re = re.compile(r"(?P#)?(?P\w+)" > - > r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") > + > r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" > + r"(?P\([^\)]+\))?") > > class Variable(Value): > def __init__(self, val, name, varset): > @@ -161,6 +164,7 @@ class Variable(Value): > >self.var_name = m.group('name') >self.is_constant = m.group('const') is not None > + self.cond = m.group('cond') >self.required_type = m.group('type') >self.bit_size = int(m.group('bits')) if m.group('bits') else 0 > > diff --git a/src/compiler/nir/nir_opt_algebraic.py > b/src/compiler/nir/nir_opt_algebraic.py > index 0a95725..952a91a 100644 > --- a/src/compiler/nir/nir_opt_algebraic.py > +++ b/src/compiler/nir/nir_opt_algebraic.py > @@ -62,6 +62,11 @@ d = 'd' > # constructed value should have that bit-size. > > optimizations = [ > + > + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', b))), > + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a, ('find_lsb', b))), > + (('umod', a, '#b(is_power_of_two)'),('iand', a, ('isub', b, 1))), > + > (('fneg', ('fneg', a)), a), > (('ineg', ('ineg', a)), a), > (('fabs', ('fabs', a)), ('fabs', a)), > diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c > index 2c2fd92..b21fb2c 100644 > --- a/src/compiler/nir/nir_search.c > +++ b/src/compiler/nir/nir_search.c > @@ -127,6 +127,9 @@ match_value(const nir_search_value *value, > nir_alu_instr *instr, unsigned src, > instr->src[src].src.ssa->parent_instr->type != > nir_instr_type_load_const) > return false; > > + if (var->cond && !var->cond(instr, src, num_components, > new_swizzle)) > +return false; > + > if (var->type != nir_type_invalid) { > if (instr->src[src].src.ssa->parent_instr->type != > nir_instr_type_alu) > return false; > diff --git a/src/compiler/nir/nir_search.h b/src/compiler/nir/nir_search.h > index a500feb..f55d797 100644 > --- a/src/compiler/nir/nir_search.h > +++ b/src/compiler/nir/nir_search.h > @@ -68,6 +68,16 @@ typedef struct { > * never match anything. > */ > nir_alu_type type; > + > + /** Optional condition fxn ptr > +* > +* This is only allowed in search expressions, and allows additional > +* constraints
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Tuesday, May 10, 2016 2:57:03 PM PDT Rob Clark wrote: > From: Rob Clark> > Some optimizations, like converting integer multiply/divide into left/ > right shifts, have additional constraints on the search expression. > Like requiring that a variable is a constant power of two. Support > these cases by allowing a fxn name to be appended to the search var > expression (ie. "a#32(is_power_of_two)"). > > TODO update doc/comment explaining search var syntax > TODO the eagle-eyed viewer might have noticed that this could also > replace the existing const syntax (ie. "#a"). Not sure if we should > keep that.. we could make it syntactic sugar (ie '#' automatically sets > the cond fxn ptr to 'is_const') or just get rid of it entirely? Maybe > that is a follow-on clean-up patch? > > Signed-off-by: Rob Clark > --- > src/compiler/nir/nir_algebraic.py | 8 +++-- > src/compiler/nir/nir_opt_algebraic.py | 5 +++ > src/compiler/nir/nir_search.c | 3 ++ > src/compiler/nir/nir_search.h | 10 ++ > src/compiler/nir/nir_search_helpers.h | 66 ++ + > 5 files changed, 90 insertions(+), 2 deletions(-) > create mode 100644 src/compiler/nir/nir_search_helpers.h > > diff --git a/src/compiler/nir/nir_algebraic.py b/src/compiler/nir/ nir_algebraic.py > index 285f853..19ac6ee 100644 > --- a/src/compiler/nir/nir_algebraic.py > +++ b/src/compiler/nir/nir_algebraic.py > @@ -76,6 +76,7 @@ class Value(object): > return Constant(val, name_base) > > __template = mako.template.Template(""" > +#include "compiler/nir/nir_search_helpers.h" > static const ${val.c_type} ${val.name} = { > { ${val.type_enum}, ${val.bit_size} }, > % if isinstance(val, Constant): > @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { > ${val.index}, /* ${val.var_name} */ > ${'true' if val.is_constant else 'false'}, > ${val.type() or 'nir_type_invalid' }, > + ${val.cond if val.cond else 'NULL'}, > % elif isinstance(val, Expression): > ${'true' if val.inexact else 'false'}, > nir_op_${val.opcode}, > @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { > Variable=Variable, > Expression=Expression) > > -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") > +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") > > class Constant(Value): > def __init__(self, val, name): > @@ -150,7 +152,8 @@ class Constant(Value): > return "nir_type_float" > > _var_name_re = re.compile(r"(?P#)?(?P\w+)" > - r"(?:@(?Pint|uint|bool|float)?(?P\d +)?)?") > + r"(?:@(?Pint|uint|bool|float)?(?P\d +)?)?" > + r"(?P\([^\)]+\))?") > > class Variable(Value): > def __init__(self, val, name, varset): > @@ -161,6 +164,7 @@ class Variable(Value): > >self.var_name = m.group('name') >self.is_constant = m.group('const') is not None > + self.cond = m.group('cond') >self.required_type = m.group('type') >self.bit_size = int(m.group('bits')) if m.group('bits') else 0 > > diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/ nir_opt_algebraic.py > index 0a95725..952a91a 100644 > --- a/src/compiler/nir/nir_opt_algebraic.py > +++ b/src/compiler/nir/nir_opt_algebraic.py > @@ -62,6 +62,11 @@ d = 'd' > # constructed value should have that bit-size. > > optimizations = [ > + > + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', b))), > + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a, ('find_lsb', b))), > + (('umod', a, '#b(is_power_of_two)'),('iand', a, ('isub', b, 1))), > + > (('fneg', ('fneg', a)), a), > (('ineg', ('ineg', a)), a), > (('fabs', ('fabs', a)), ('fabs', a)), > diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c > index 2c2fd92..b21fb2c 100644 > --- a/src/compiler/nir/nir_search.c > +++ b/src/compiler/nir/nir_search.c > @@ -127,6 +127,9 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src, > instr->src[src].src.ssa->parent_instr->type != nir_instr_type_load_const) > return false; > > + if (var->cond && !var->cond(instr, src, num_components, new_swizzle)) > +return false; > + > if (var->type != nir_type_invalid) { > if (instr->src[src].src.ssa->parent_instr->type != nir_instr_type_alu) > return false; > diff --git a/src/compiler/nir/nir_search.h b/src/compiler/nir/nir_search.h > index a500feb..f55d797 100644 > --- a/src/compiler/nir/nir_search.h > +++ b/src/compiler/nir/nir_search.h > @@ -68,6 +68,16 @@ typedef struct { > * never match anything. > */ > nir_alu_type type; > + > + /** Optional condition fxn ptr > +* > +* This is only allowed in search expressions, and allows
[Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
From: Rob ClarkSome optimizations, like converting integer multiply/divide into left/ right shifts, have additional constraints on the search expression. Like requiring that a variable is a constant power of two. Support these cases by allowing a fxn name to be appended to the search var expression (ie. "a#32(is_power_of_two)"). TODO update doc/comment explaining search var syntax TODO the eagle-eyed viewer might have noticed that this could also replace the existing const syntax (ie. "#a"). Not sure if we should keep that.. we could make it syntactic sugar (ie '#' automatically sets the cond fxn ptr to 'is_const') or just get rid of it entirely? Maybe that is a follow-on clean-up patch? Signed-off-by: Rob Clark --- src/compiler/nir/nir_algebraic.py | 8 +++-- src/compiler/nir/nir_opt_algebraic.py | 5 +++ src/compiler/nir/nir_search.c | 3 ++ src/compiler/nir/nir_search.h | 10 ++ src/compiler/nir/nir_search_helpers.h | 66 +++ 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 src/compiler/nir/nir_search_helpers.h diff --git a/src/compiler/nir/nir_algebraic.py b/src/compiler/nir/nir_algebraic.py index 285f853..19ac6ee 100644 --- a/src/compiler/nir/nir_algebraic.py +++ b/src/compiler/nir/nir_algebraic.py @@ -76,6 +76,7 @@ class Value(object): return Constant(val, name_base) __template = mako.template.Template(""" +#include "compiler/nir/nir_search_helpers.h" static const ${val.c_type} ${val.name} = { { ${val.type_enum}, ${val.bit_size} }, % if isinstance(val, Constant): @@ -84,6 +85,7 @@ static const ${val.c_type} ${val.name} = { ${val.index}, /* ${val.var_name} */ ${'true' if val.is_constant else 'false'}, ${val.type() or 'nir_type_invalid' }, + ${val.cond if val.cond else 'NULL'}, % elif isinstance(val, Expression): ${'true' if val.inexact else 'false'}, nir_op_${val.opcode}, @@ -113,7 +115,7 @@ static const ${val.c_type} ${val.name} = { Variable=Variable, Expression=Expression) -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") +_constant_re = re.compile(r"(?P[^@\(]+)(?:@(?P\d+))?") class Constant(Value): def __init__(self, val, name): @@ -150,7 +152,8 @@ class Constant(Value): return "nir_type_float" _var_name_re = re.compile(r"(?P#)?(?P\w+)" - r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") + r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?" + r"(?P\([^\)]+\))?") class Variable(Value): def __init__(self, val, name, varset): @@ -161,6 +164,7 @@ class Variable(Value): self.var_name = m.group('name') self.is_constant = m.group('const') is not None + self.cond = m.group('cond') self.required_type = m.group('type') self.bit_size = int(m.group('bits')) if m.group('bits') else 0 diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index 0a95725..952a91a 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -62,6 +62,11 @@ d = 'd' # constructed value should have that bit-size. optimizations = [ + + (('imul', a, '#b@32(is_power_of_two)'), ('ishl', a, ('find_lsb', b))), + (('udiv', a, '#b@32(is_power_of_two)'), ('ushr', a, ('find_lsb', b))), + (('umod', a, '#b(is_power_of_two)'),('iand', a, ('isub', b, 1))), + (('fneg', ('fneg', a)), a), (('ineg', ('ineg', a)), a), (('fabs', ('fabs', a)), ('fabs', a)), diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c index 2c2fd92..b21fb2c 100644 --- a/src/compiler/nir/nir_search.c +++ b/src/compiler/nir/nir_search.c @@ -127,6 +127,9 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src, instr->src[src].src.ssa->parent_instr->type != nir_instr_type_load_const) return false; + if (var->cond && !var->cond(instr, src, num_components, new_swizzle)) +return false; + if (var->type != nir_type_invalid) { if (instr->src[src].src.ssa->parent_instr->type != nir_instr_type_alu) return false; diff --git a/src/compiler/nir/nir_search.h b/src/compiler/nir/nir_search.h index a500feb..f55d797 100644 --- a/src/compiler/nir/nir_search.h +++ b/src/compiler/nir/nir_search.h @@ -68,6 +68,16 @@ typedef struct { * never match anything. */ nir_alu_type type; + + /** Optional condition fxn ptr +* +* This is only allowed in search expressions, and allows additional +* constraints to be placed on the match. Typically used for 'is_constant' +* variables to require, for example, power-of-two in order for the search +* to match. +*/ + bool (*cond)(nir_alu_instr *instr, unsigned src, +unsigned num_components, const
Re: [Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
On Mon, May 9, 2016 at 12:52 PM, Rob Clarkwrote: > From: Rob Clark > > It was kinda sad that we couldn't optimize imul/idiv by power-of-two. > So I bashed my head against python for a while and this is what I came > up with. In the search expression, you can use "#a^2" to only match > constants which are a power of two. The rest is taken care of w/ normal > replacement expression. > > Signed-off-by: Rob Clark > --- > src/compiler/nir/nir_algebraic.py | 9 +++-- > src/compiler/nir/nir_opt_algebraic.py | 5 + > src/compiler/nir/nir_search.c | 26 ++ > src/compiler/nir/nir_search.h | 7 +++ > 4 files changed, 45 insertions(+), 2 deletions(-) > > diff --git a/src/compiler/nir/nir_algebraic.py > b/src/compiler/nir/nir_algebraic.py > index 285f853..9bfd3f2 100644 > --- a/src/compiler/nir/nir_algebraic.py > +++ b/src/compiler/nir/nir_algebraic.py > @@ -83,6 +83,7 @@ static const ${val.c_type} ${val.name} = { > % elif isinstance(val, Variable): > ${val.index}, /* ${val.var_name} */ > ${'true' if val.is_constant else 'false'}, > + ${'true' if val.is_power_of_two else 'false'}, > ${val.type() or 'nir_type_invalid' }, > % elif isinstance(val, Expression): > ${'true' if val.inexact else 'false'}, > @@ -113,7 +114,7 @@ static const ${val.c_type} ${val.name} = { > Variable=Variable, > Expression=Expression) > > -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") > +_constant_re = > re.compile(r"(?P[^@\^]+)(?P\^2)?(?:@(?P\d+))?") > > class Constant(Value): > def __init__(self, val, name): > @@ -123,6 +124,7 @@ class Constant(Value): > m = _constant_re.match(val) > self.value = ast.literal_eval(m.group('value')) > self.bit_size = int(m.group('bits')) if m.group('bits') else 0 > + self.power_of_two = m.group('PoT') is not None >else: > self.value = val > self.bit_size = 0 > @@ -149,7 +151,7 @@ class Constant(Value): >elif isinstance(self.value, float): > return "nir_type_float" > > -_var_name_re = re.compile(r"(?P#)?(?P\w+)" > +_var_name_re = re.compile(r"(?P#)?(?P\w+)(?P\^2)?" > > r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") > > class Variable(Value): > @@ -161,6 +163,9 @@ class Variable(Value): > >self.var_name = m.group('name') >self.is_constant = m.group('const') is not None > + self.is_power_of_two = m.group('PoT') is not None > + if self.is_power_of_two: > + assert self.is_constant >self.required_type = m.group('type') >self.bit_size = int(m.group('bits')) if m.group('bits') else 0 > > diff --git a/src/compiler/nir/nir_opt_algebraic.py > b/src/compiler/nir/nir_opt_algebraic.py > index 0a95725..c92e76d 100644 > --- a/src/compiler/nir/nir_opt_algebraic.py > +++ b/src/compiler/nir/nir_opt_algebraic.py > @@ -62,6 +62,11 @@ d = 'd' > # constructed value should have that bit-size. > > optimizations = [ > + > + (('imul', a, '#b^2@32'), ('ishl', a, ('find_lsb', b))), > + (('udiv', a, '#b^2@32'), ('ishr', a, ('find_lsb', b))), ushr (A little frightening that there aren't tests that are hit by this...) > + (('umod', a, '#b^2'),('iand', a, ('isub', b, 1))), > + > (('fneg', ('fneg', a)), a), > (('ineg', ('ineg', a)), a), > (('fabs', ('fabs', a)), ('fabs', a)), > diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c > index 2c2fd92..6578088 100644 > --- a/src/compiler/nir/nir_search.c > +++ b/src/compiler/nir/nir_search.c > @@ -70,6 +70,13 @@ alu_instr_is_bool(nir_alu_instr *instr) > } > } > > +/* helper for this somewhere? */ > +static bool > +is_power_of_two(unsigned int x) > +{ > + return ((x != 0) && !(x & (x - 1))); > +} > + > static bool > match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned > src, > unsigned num_components, const uint8_t *swizzle, > @@ -127,6 +134,25 @@ match_value(const nir_search_value *value, nir_alu_instr > *instr, unsigned src, > instr->src[src].src.ssa->parent_instr->type != > nir_instr_type_load_const) > return false; > > + if (var->is_power_of_two) { > +assert(var->is_constant); > +nir_const_value *val = > nir_src_as_const_value(instr->src[src].src); > +for (unsigned i = 0; i < num_components; i++) { > + switch (nir_op_infos[instr->op].input_types[src]) { > + case nir_type_int: > + if (!is_power_of_two(val->i32[new_swizzle[i]])) > + return false; > + break; > + case nir_type_uint: > + if (!is_power_of_two(val->u32[new_swizzle[i]])) > + return false; > + break; > + default: > +
[Mesa-dev] [PATCH 2/3] nir/algebraic: support for power-of-two optimizations
From: Rob ClarkIt was kinda sad that we couldn't optimize imul/idiv by power-of-two. So I bashed my head against python for a while and this is what I came up with. In the search expression, you can use "#a^2" to only match constants which are a power of two. The rest is taken care of w/ normal replacement expression. Signed-off-by: Rob Clark --- src/compiler/nir/nir_algebraic.py | 9 +++-- src/compiler/nir/nir_opt_algebraic.py | 5 + src/compiler/nir/nir_search.c | 26 ++ src/compiler/nir/nir_search.h | 7 +++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/compiler/nir/nir_algebraic.py b/src/compiler/nir/nir_algebraic.py index 285f853..9bfd3f2 100644 --- a/src/compiler/nir/nir_algebraic.py +++ b/src/compiler/nir/nir_algebraic.py @@ -83,6 +83,7 @@ static const ${val.c_type} ${val.name} = { % elif isinstance(val, Variable): ${val.index}, /* ${val.var_name} */ ${'true' if val.is_constant else 'false'}, + ${'true' if val.is_power_of_two else 'false'}, ${val.type() or 'nir_type_invalid' }, % elif isinstance(val, Expression): ${'true' if val.inexact else 'false'}, @@ -113,7 +114,7 @@ static const ${val.c_type} ${val.name} = { Variable=Variable, Expression=Expression) -_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") +_constant_re = re.compile(r"(?P[^@\^]+)(?P\^2)?(?:@(?P\d+))?") class Constant(Value): def __init__(self, val, name): @@ -123,6 +124,7 @@ class Constant(Value): m = _constant_re.match(val) self.value = ast.literal_eval(m.group('value')) self.bit_size = int(m.group('bits')) if m.group('bits') else 0 + self.power_of_two = m.group('PoT') is not None else: self.value = val self.bit_size = 0 @@ -149,7 +151,7 @@ class Constant(Value): elif isinstance(self.value, float): return "nir_type_float" -_var_name_re = re.compile(r"(?P#)?(?P\w+)" +_var_name_re = re.compile(r"(?P#)?(?P\w+)(?P\^2)?" r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") class Variable(Value): @@ -161,6 +163,9 @@ class Variable(Value): self.var_name = m.group('name') self.is_constant = m.group('const') is not None + self.is_power_of_two = m.group('PoT') is not None + if self.is_power_of_two: + assert self.is_constant self.required_type = m.group('type') self.bit_size = int(m.group('bits')) if m.group('bits') else 0 diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index 0a95725..c92e76d 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -62,6 +62,11 @@ d = 'd' # constructed value should have that bit-size. optimizations = [ + + (('imul', a, '#b^2@32'), ('ishl', a, ('find_lsb', b))), + (('udiv', a, '#b^2@32'), ('ishr', a, ('find_lsb', b))), + (('umod', a, '#b^2'),('iand', a, ('isub', b, 1))), + (('fneg', ('fneg', a)), a), (('ineg', ('ineg', a)), a), (('fabs', ('fabs', a)), ('fabs', a)), diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c index 2c2fd92..6578088 100644 --- a/src/compiler/nir/nir_search.c +++ b/src/compiler/nir/nir_search.c @@ -70,6 +70,13 @@ alu_instr_is_bool(nir_alu_instr *instr) } } +/* helper for this somewhere? */ +static bool +is_power_of_two(unsigned int x) +{ + return ((x != 0) && !(x & (x - 1))); +} + static bool match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src, unsigned num_components, const uint8_t *swizzle, @@ -127,6 +134,25 @@ match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src, instr->src[src].src.ssa->parent_instr->type != nir_instr_type_load_const) return false; + if (var->is_power_of_two) { +assert(var->is_constant); +nir_const_value *val = nir_src_as_const_value(instr->src[src].src); +for (unsigned i = 0; i < num_components; i++) { + switch (nir_op_infos[instr->op].input_types[src]) { + case nir_type_int: + if (!is_power_of_two(val->i32[new_swizzle[i]])) + return false; + break; + case nir_type_uint: + if (!is_power_of_two(val->u32[new_swizzle[i]])) + return false; + break; + default: + return false; + } +} + } + if (var->type != nir_type_invalid) { if (instr->src[src].src.ssa->parent_instr->type != nir_instr_type_alu) return false; diff --git a/src/compiler/nir/nir_search.h b/src/compiler/nir/nir_search.h index a500feb..32ed538 100644 --- a/src/compiler/nir/nir_search.h