Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support loop cloning with non-int iteration variables #85552

Open
BruceForstall opened this issue Apr 29, 2023 · 2 comments
Open

Support loop cloning with non-int iteration variables #85552

BruceForstall opened this issue Apr 29, 2023 · 2 comments
Assignees
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI Priority:2 Work that is important, but not critical for the release
Milestone

Comments

@BruceForstall
Copy link
Member

Loops with byte/short iteration variables:

for (byte i = 0; i < 100; i++)
{
    a[i] = 0;
}

create an iteration increment tree with a CAST node:

***** BB03
STMT00003 ( 0x00E[E-] ... 0x012 )
               [000025] -A---+-----                         *  ASG       int
               [000024] D----+-N---                         +--*  LCL_VAR   int    V01 loc0
               [000023] -----+-----                         \--*  CAST      int <- ubyte <- int
               [000022] -----+-----                            \--*  ADD       int
               [000020] -----+-----                               +--*  LCL_VAR   int    V01 loc0
               [000021] -----+-----                               \--*  CNS_INT   int    1

This pattern is not matched by GenTree::IsLclVarUpdateTree().

Loops with long iteration variables:

for (long i = 0; i < 100; i++)
{
    a[i] = 0;
}

create (naturally) an increment constant that is long typed:

STMT00003 ( 0x00B[E-] ... 0x00F )
               [000022] -A---+-----                         *  ASG       long
               [000021] D----+-N---                         +--*  LCL_VAR   long   V01 loc0
               [000020] -----+-----                         \--*  ADD       long
               [000017] -----+-----                            +--*  LCL_VAR   long   V01 loc0
               [000019] -----+-----                            \--*  CNS_INT   long   1

and that is screened out by Compiler::optIsLoopIncrTree():

        if ((incrVal->gtOper != GT_CNS_INT) || (incrVal->TypeGet() != TYP_INT))

category:cq
theme:loop-opt
skill-level:expert
cost:small
impact:small

@BruceForstall BruceForstall added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 29, 2023
@BruceForstall BruceForstall added this to the Future milestone Apr 29, 2023
@BruceForstall BruceForstall self-assigned this Apr 29, 2023
@ghost
Copy link

ghost commented Apr 29, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Loops with byte/short iteration variables:

for (byte i = 0; i < 100; i++)
{
    a[i] = 0;
}

create an iteration increment tree with a CAST node:

***** BB03
STMT00003 ( 0x00E[E-] ... 0x012 )
               [000025] -A---+-----                         *  ASG       int
               [000024] D----+-N---                         +--*  LCL_VAR   int    V01 loc0
               [000023] -----+-----                         \--*  CAST      int <- ubyte <- int
               [000022] -----+-----                            \--*  ADD       int
               [000020] -----+-----                               +--*  LCL_VAR   int    V01 loc0
               [000021] -----+-----                               \--*  CNS_INT   int    1

This pattern is not matched by GenTree::IsLclVarUpdateTree().

Loops with long iteration variables:

for (long i = 0; i < 100; i++)
{
    a[i] = 0;
}

create (naturally) an increment constant that is long typed:

STMT00003 ( 0x00B[E-] ... 0x00F )
               [000022] -A---+-----                         *  ASG       long
               [000021] D----+-N---                         +--*  LCL_VAR   long   V01 loc0
               [000020] -----+-----                         \--*  ADD       long
               [000017] -----+-----                            +--*  LCL_VAR   long   V01 loc0
               [000019] -----+-----                            \--*  CNS_INT   long   1

and that is screened out by Compiler::optIsLoopIncrTree():

        if ((incrVal->gtOper != GT_CNS_INT) || (incrVal->TypeGet() != TYP_INT))

category:cq
theme:loop-opt
skill-level:expert
cost:small
impact:small

Author: BruceForstall
Assignees: BruceForstall
Labels:

area-CodeGen-coreclr

Milestone: Future

@BruceForstall
Copy link
Member Author

BruceForstall commented May 1, 2023

For the long iteration var case, there are (at least) these additional things:

The array length node ARR_LENGTH has a cast on top, which Compiler::optExtractArrIndex() doesn't recognize:

*  COMMA     byref
+--*  BOUNDS_CHECK_Rng void
|  +--*  LCL_VAR   long   V01 loc0
|  \--*  CAST      long <- uint
|     \--*  ARR_LENGTH int
|        \--*  LCL_VAR   ref    V00 arg0
\--*  ARR_ADDR  byref byte[]
   \--*  ADD       byref
      +--*  LCL_VAR   ref    V00 arg0
      \--*  ADD       long
         +--*  LCL_VAR   long   V01 loc0
         \--*  CNS_INT   long   16

The iteration variable is expected to be TYP_INT in Compiler::optCheckIterInLoopTest().

Compiler::optDeriveLoopCloningConditions() requires the initLcl var to be TYP_INT.

LC_Ident constants are assumed to be TYP_INT.

LC_Condition::ToGenTree() assumes TYP_INT.

LC_Array::ToGenTree() uses gtNewArrLen(TYP_INT,...), which is correct, but we need to re-insert the cast up to LONG if necessary.

@JulieLeeMSFT JulieLeeMSFT added the Priority:2 Work that is important, but not critical for the release label May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI Priority:2 Work that is important, but not critical for the release
Projects
None yet
Development

No branches or pull requests

2 participants