@@ -1023,9 +1023,9 @@ void emitter::emitBegFN(bool hasFramePtr
1023
1023
emitIGbuffSize = 0 ;
1024
1024
1025
1025
#if FEATURE_LOOP_ALIGN
1026
- emitLastAlignedIgNum = 0 ;
1027
- emitLastInnerLoopStartIgNum = 0 ;
1028
- emitLastInnerLoopEndIgNum = 0 ;
1026
+ emitLastAlignedIgNum = 0 ;
1027
+ emitLastLoopStart = 0 ;
1028
+ emitLastLoopEnd = 0 ;
1029
1029
#endif
1030
1030
1031
1031
/* Record stack frame info (the temp size is just an estimate) */
@@ -4820,58 +4820,112 @@ unsigned emitter::getLoopSize(insGroup* igLoopHeader, unsigned maxLoopSize DEBUG
4820
4820
// if currIG has back-edge to dstIG.
4821
4821
//
4822
4822
// Notes:
4823
- // If the current loop encloses a loop that is already marked as align, then remove
4824
- // the alignment flag present on IG before dstIG.
4823
+ // Despite we align only inner most loop, we might see intersected loops because of control flow
4824
+ // re-arrangement like adding a split edge in LSRA.
4825
+ //
4826
+ // If there is an intersection of current loop with last loop that is already marked as align,
4827
+ // then *do not align* one of the loop that completely encloses the other one. Or if they both intersect,
4828
+ // then *do not align* either of them because since the flow is complicated enough that aligning one of them
4829
+ // will not improve the performance.
4825
4830
//
4826
4831
void emitter::emitSetLoopBackEdge (BasicBlock* loopTopBlock)
4827
4832
{
4828
- insGroup* dstIG = (insGroup*)loopTopBlock->bbEmitCookie ;
4833
+ insGroup* dstIG = (insGroup*)loopTopBlock->bbEmitCookie ;
4834
+ bool alignCurrentLoop = true ;
4835
+ bool alignLastLoop = true ;
4829
4836
4830
4837
// With (dstIG != nullptr), ensure that only back edges are tracked.
4831
4838
// If there is forward jump, dstIG is not yet generated.
4832
4839
//
4833
4840
// We don't rely on (block->bbJumpDest->bbNum <= block->bbNum) because the basic
4834
4841
// block numbering is not guaranteed to be sequential.
4835
-
4836
4842
if ((dstIG != nullptr ) && (dstIG->igNum <= emitCurIG->igNum ))
4837
4843
{
4838
4844
unsigned currLoopStart = dstIG->igNum ;
4839
4845
unsigned currLoopEnd = emitCurIG->igNum ;
4840
4846
4841
4847
// Only mark back-edge if current loop starts after the last inner loop ended.
4842
- if (emitLastInnerLoopEndIgNum < currLoopStart)
4848
+ if (emitLastLoopEnd < currLoopStart)
4843
4849
{
4844
4850
emitCurIG->igLoopBackEdge = dstIG;
4845
4851
4846
4852
JITDUMP (" ** IG%02u jumps back to IG%02u forming a loop.\n " , currLoopEnd, currLoopStart);
4847
4853
4848
- emitLastInnerLoopStartIgNum = currLoopStart;
4849
- emitLastInnerLoopEndIgNum = currLoopEnd;
4854
+ emitLastLoopStart = currLoopStart;
4855
+ emitLastLoopEnd = currLoopEnd;
4856
+ }
4857
+ else if (currLoopStart == emitLastLoopStart)
4858
+ {
4859
+ // Note: If current and last loop starts at same point,
4860
+ // retain the alignment flag of the smaller loop.
4861
+ // |
4862
+ // .---->|<----.
4863
+ // last | | |
4864
+ // loop | | | current
4865
+ // .---->| | loop
4866
+ // | |
4867
+ // |-----.
4868
+ //
4869
+ }
4870
+ else if ((currLoopStart < emitLastLoopStart) && (emitLastLoopEnd < currLoopEnd))
4871
+ {
4872
+ // if current loop completely encloses last loop,
4873
+ // then current loop should not be aligned.
4874
+ alignCurrentLoop = false ;
4875
+ }
4876
+ else if ((emitLastLoopStart < currLoopStart) && (currLoopEnd < emitLastLoopEnd))
4877
+ {
4878
+ // if last loop completely encloses current loop,
4879
+ // then last loop should not be aligned.
4880
+ alignLastLoop = false ;
4881
+ }
4882
+ else
4883
+ {
4884
+ // The loops intersect and should not align either of the loops
4885
+ alignLastLoop = false ;
4886
+ alignCurrentLoop = false ;
4850
4887
}
4851
- // Otherwise, mark the dstIG->prevIG as no alignment needed.
4852
- //
4853
- // Note: If current loop's back-edge target is same as emitLastInnerLoopStartIgNum,
4854
- // retain the alignment flag of dstIG->prevIG so the loop
4855
- // (emitLastInnerLoopStartIgNum ~ emitLastInnerLoopEndIgNum) is still aligned.
4856
- else if (emitLastInnerLoopStartIgNum != currLoopStart)
4857
- {
4858
- // Find the IG before dstIG...
4859
- instrDescAlign* alignInstr = emitAlignList;
4860
- while ((alignInstr != nullptr ) && (alignInstr->idaIG ->igNext != dstIG))
4861
- {
4862
- alignInstr = alignInstr->idaNext ;
4863
- }
4864
4888
4865
- // ...and clear the IGF_LOOP_ALIGN flag
4866
- if (alignInstr != nullptr )
4889
+ if (!alignLastLoop || !alignCurrentLoop)
4890
+ {
4891
+ instrDescAlign* alignInstr = emitAlignList;
4892
+ bool markedLastLoop = alignLastLoop;
4893
+ bool markedCurrLoop = alignCurrentLoop;
4894
+ while ((alignInstr != nullptr ))
4867
4895
{
4868
- assert (alignInstr->idaIG ->igNext == dstIG);
4869
- alignInstr->idaIG ->igFlags &= ~IGF_LOOP_ALIGN;
4896
+ // Find the IG before current loop and clear the IGF_LOOP_ALIGN flag
4897
+ if (!alignCurrentLoop && (alignInstr->idaIG ->igNext == dstIG))
4898
+ {
4899
+ assert (!markedCurrLoop);
4900
+ alignInstr->idaIG ->igFlags &= ~IGF_LOOP_ALIGN;
4901
+ markedCurrLoop = true ;
4902
+ JITDUMP (" ** Skip alignment for current loop IG%02u ~ IG%02u because it encloses an aligned loop "
4903
+ " IG%02u ~ IG%02u.\n " ,
4904
+ currLoopStart, currLoopEnd, emitLastLoopStart, emitLastLoopEnd);
4905
+ }
4906
+
4907
+ // Find the IG before the last loop and clear the IGF_LOOP_ALIGN flag
4908
+ if (!alignLastLoop && (alignInstr->idaIG ->igNext != nullptr ) &&
4909
+ (alignInstr->idaIG ->igNext ->igNum == emitLastLoopStart))
4910
+ {
4911
+ assert (!markedLastLoop);
4912
+ assert (alignInstr->idaIG ->isLoopAlign ());
4913
+ alignInstr->idaIG ->igFlags &= ~IGF_LOOP_ALIGN;
4914
+ markedLastLoop = true ;
4915
+ JITDUMP (" ** Skip alignment for aligned loop IG%02u ~ IG%02u because it encloses the current loop "
4916
+ " IG%02u ~ IG%02u.\n " ,
4917
+ emitLastLoopStart, emitLastLoopEnd, currLoopStart, currLoopEnd);
4918
+ }
4919
+
4920
+ if (markedLastLoop && markedCurrLoop)
4921
+ {
4922
+ break ;
4923
+ }
4924
+
4925
+ alignInstr = alignInstr->idaNext ;
4870
4926
}
4871
4927
4872
- JITDUMP (
4873
- " ** Skip alignment for loop IG%02u ~ IG%02u, because it encloses an aligned loop IG%02u ~ IG%02u.\n " ,
4874
- currLoopStart, currLoopEnd, emitLastInnerLoopStartIgNum, emitLastInnerLoopEndIgNum);
4928
+ assert (markedLastLoop && markedCurrLoop);
4875
4929
}
4876
4930
}
4877
4931
}
0 commit comments