Max Muster via llvm-dev
2018-Apr-09 08:17 UTC
[llvm-dev] Tablegen pattern: How to emit a SDNode in an output pattern?
I'm trying to write a tablegen pattern to that matches a sequence of SDNodes and emits again an SDNode and another instruction. The pattern I've written looks like the folowing: def : Pat<(foo (bar GPR:$rs1), simm12:$imm1), (bar (BAZ GPR:$rs1, simm12:$imm1))>; foo and bar are SDNodes, BAZ is an instruction. In particular, bar is defined as follows: def bar : SDNode<"ISD::BAR", SDTIntUnaryOp>; The basic idea of this pattern is to propagate bar over certain instructions until they reach a sink pattern, which only emits an instruction. However, it seems that SDNodes in output patterns are not supported, because when building LLVM, I get the following error message: error: In anonymous_826: Cannot use 'bar' in an output pattern! What are the limits of tablegen here? What are alternatives to propagate the bar node over instructions to reach the same behavior is the pattern-based approach? Thank you in advance! Cheers, Max -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180409/572e41ac/attachment.html>
Nicolai Hähnle via llvm-dev
2018-Apr-09 10:56 UTC
[llvm-dev] Tablegen pattern: How to emit a SDNode in an output pattern?
Hi Max, On 09.04.2018 10:17, Max Muster via llvm-dev wrote:> I'm trying to write a tablegen pattern to that matches a sequence of > SDNodes and emits again an SDNode and another instruction. > The pattern I've written looks like the folowing: > > def : Pat<(foo (bar GPR:$rs1), simm12:$imm1), > (bar (BAZ GPR:$rs1, simm12:$imm1))>; > > foo and bar are SDNodes, BAZ is an instruction. In particular, bar is > defined as follows: > > def bar : SDNode<"ISD::BAR", SDTIntUnaryOp>; > > The basic idea of this pattern is to propagate bar over certain > instructions until they reach a sink pattern, which only emits an > instruction. > However, it seems that SDNodes in output patterns are not supported, > because when building LLVM, I get the following error message: > > error: In anonymous_826: Cannot use 'bar' in an output pattern! > > What are the limits of tablegen here?This is technically not a limit of TableGen per se, but a limit of the DAG selection machinery. The -gen-dag-isel backend of TableGen generates a bytecode which is interpreted by the machinery in SelectionDAGISel::SelectCodeCommon, which is expected to generate machine nodes directly -- what you're trying to do would require some sort of recursion / iteration.> What are alternatives to propagate the bar node over instructions to > reach the same behavior is the pattern-based approach?It looks a bit like you want a kind of instcombine either before or after the instruction selection, but overall it's hard to say without a concrete problem description. Cheers, Nicolai> > Thank you in advance! > Cheers, > Max > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-- Lerne, wie die Welt wirklich ist, Aber vergiss niemals, wie sie sein sollte.
via llvm-dev
2018-Apr-09 17:15 UTC
[llvm-dev] Tablegen pattern: How to emit a SDNode in an output pattern?
> On Apr 9, 2018, at 1:17 AM, Max Muster via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > I'm trying to write a tablegen pattern to that matches a sequence of SDNodes and emits again an SDNode and another instruction. > The pattern I've written looks like the folowing: > > def : Pat<(foo (bar GPR:$rs1), simm12:$imm1), > (bar (BAZ GPR:$rs1, simm12:$imm1))>; > > foo and bar are SDNodes, BAZ is an instruction. In particular, bar is defined as follows: > > def bar : SDNode<"ISD::BAR", SDTIntUnaryOp>; > > The basic idea of this pattern is to propagate bar over certain instructions until they reach a sink pattern, which only emits an instruction. > However, it seems that SDNodes in output patterns are not supported, because when building LLVM, I get the following error message: > > error: In anonymous_826: Cannot use 'bar' in an output pattern! > > What are the limits of tablegen here? > What are alternatives to propagate the bar node over instructions to reach the same behavior is the pattern-based approach? > > Thank you in advance!Firstly, are you sure you can’t do this in combine() or in preprocessiseldag()? Most of the time you may find it better to do things there (we use the latter for cases where the optimization may interfere with DAG canonicalization, and so we need to do it late). Secondly, if you do need to do it in Select(), you can write custom C++ code in Select() for that purpose. It gets a little finicky because you will have to reposition the new DAG nodes you create in order to put them in order. For example, see the following function: inline void InsertDAGNode(SelectionDAG &DAG, SDValue Pos, SDValue N) { if (N->getNodeId() == -1 || (SelectionDAGISel::getUninvalidatedNodeId(N.getNode()) > SelectionDAGISel::getUninvalidatedNodeId(Pos.getNode()))) { DAG.RepositionNode(Pos->getIterator(), N.getNode()); // Mark Node as invalid for pruning as after this it may be a successor to a // selected node but otherwise be in the same position of Pos. // Conservatively mark it with the same -abs(Id) to assure node id // invariant is preserved. N->setNodeId(Pos->getNodeId()); SelectionDAGISel::InvalidateNodeId(N.getNode()); } } I have no idea how “bad” this is, but we use it internally. —escha