Add Apply.inst_predicate().

Compute an instruction predicate from any constant values given as
arguments for the immediate operands in an instruction pattern.

Allows for patterns like icmp.i32(intcc.ugt, x, y) or iadd_imm.i32(x, 1)

Trap these predicates in the legalizer code generator since we can't
actually handle them yet.
This commit is contained in:
Jakob Stoklund Olesen
2017-03-31 10:12:23 -07:00
parent 63a6ade0a5
commit 0403845c40
3 changed files with 36 additions and 1 deletions

View File

@@ -7,11 +7,13 @@ for patern matching an rewriting of cretonne instructions.
from __future__ import absolute_import from __future__ import absolute_import
from . import instructions from . import instructions
from .typevar import TypeVar from .typevar import TypeVar
from .predicates import IsEqual, And
try: try:
from typing import Union, Tuple, Sequence, TYPE_CHECKING # noqa from typing import Union, Tuple, Sequence, TYPE_CHECKING # noqa
if TYPE_CHECKING: if TYPE_CHECKING:
from .operands import ImmediateKind # noqa from .operands import ImmediateKind # noqa
from .predicates import PredNode # noqa
except ImportError: except ImportError:
pass pass
@@ -412,6 +414,32 @@ class Apply(Expr):
method = self.inst.snake_name() method = self.inst.snake_name()
return '{}({})'.format(method, args) return '{}({})'.format(method, args)
def inst_predicate(self):
# type: () -> PredNode
"""
Construct an instruction predicate that verifies the immediate operands
on this instruction.
Immediate operands in a source pattern can be either free variables or
constants like `Enumerator`. We don't currently support constraints on
free variables, but we may in the future.
"""
pred = None # type: PredNode
iform = self.inst.format
# Examine all of the immediate operands.
for ffield, opnum in zip(iform.imm_fields, self.inst.imm_opnums):
arg = self.args[opnum]
# Ignore free variables for now. We may add variable predicates
# later.
if isinstance(arg, Var):
continue
pred = And.combine(pred, IsEqual(ffield, arg))
return pred
class Enumerator(Expr): class Enumerator(Expr):
""" """

View File

@@ -216,7 +216,8 @@ class FieldPredicate(object):
This predicate can be evaluated in the context of an instruction This predicate can be evaluated in the context of an instruction
format. format.
""" """
return self.field.format iform = self.field.format # type: InstructionFormat
return iform
def predicate_leafs(self, leafs): def predicate_leafs(self, leafs):
# type: (Set[PredLeaf]) -> None # type: (Set[PredLeaf]) -> None

View File

@@ -211,6 +211,12 @@ def gen_xform(xform, fmt):
# variables. # variables.
unwrap_inst('inst', xform.src.rtl[0], fmt) unwrap_inst('inst', xform.src.rtl[0], fmt)
# We could support instruction predicates, but not yet. Should we just
# return false if it fails? What about multiple patterns with different
# predicates for the same opcode?
instp = xform.src.rtl[0].expr.inst_predicate()
assert instp is None, "Instruction predicates not supported in legalizer"
# Emit the destination pattern. # Emit the destination pattern.
for dst in xform.dst.rtl: for dst in xform.dst.rtl:
emit_dst_inst(dst, fmt) emit_dst_inst(dst, fmt)