Open EgorBo opened 2 years ago
Tagging subscribers to this area: @JulieLeeMSFT See info in area-owners.md if you want to be subscribed.
Author: | EgorBo |
---|---|
Assignees: | - |
Labels: | `area-CodeGen-coreclr`, `untriaged` |
Milestone: | - |
I support alternate design 😅
Take my 2 cents in favor of alternative design!
Agreeing with the alternative design option. The less C++ there is powering things we care about, the better! Let's build C# in itself.
As someone who has used pattern matching (F#) for a long time, especially in compilers, the 'match' API is a very interesting idea; a prototype would be worth doing. The thing to check is what the performance implications are since this is not a proper form of pattern matching.
Hi @EgorBo , just curious if there has been any more thoughts / prototype work on this?
On vacation but spent a little bit of time trying to create a prototype.
Based on @EgorBo 's example, it works and looks like this:
GenTree* op;
GenTreeIntCon* cns;
if (tree->Match(&op, &cns) || tree->Match(&cns, &op))
{
// work with op and cns
}
Implementation of this overload of Match
:
template <class T1 = GenTree, class T2 = GenTree>
bool Match(T1** op1, T2** op2)
{
if (OperIsBinary())
{
*op1 = dynamic_cast<T1*>(gtGetOp1());
*op2 = dynamic_cast<T2*>(gtGetOp2());
if ((*op1 != nullptr) && (*op2 != nullptr))
{
return true;
}
*op1 = nullptr;
*op2 = nullptr;
return false;
}
return false;
}
Another example: Before:
if (tree->OperIs(GT_MOD, GT_UMOD) && (op2->IsIntegralConst(1)))
{
// work
}
After:
if (tree->MatchOp2<GT_MOD, GT_UMOD>(1))
{
// work
}
Implementation of this overload of MatchOp2
:
template <genTreeOps... T>
bool MatchOp2(ssize_t cns)
{
static_assert(AllOperIsBinary(T...) && "Not a binary operator!");
return OperIs(T...) && gtGetOp2()->IsIntegralConst(cns);
}
I have more implementations of the other overloads for these functions, but thought I'd share a little bit here.
Today, when we need to recognize simple expressions (nodes/trees), e.g.
a tree must be either "X op CNS" or "CNS op X"
we usually end up with something like this:I'm thinking of proposing a sort of "match" API similar to what is used in LLVM, for example LLVM's equivalent of ^:
So we can adopt it to something like this for RyuJIT:
It's extremely powerful and easy to read once you get used to it, and waaaaaay less verbose.
More LLVM examples:
m_OneUse
as in "single use"Alternative Design
Rewrite JIT to C#/F# 😐
cc @dotnet/jit-contrib @SingleAccretion
category:design theme:ir