Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
32236ac
Detect inner loop and add 10 bytes of padding at the beginning
kunalspathak Oct 8, 2020
a2ec5d1
generate nop in previous blocks
kunalspathak Oct 9, 2020
89b5812
TODO: figure out if anything needs to be done in optCanonicalizeLoop
kunalspathak Oct 9, 2020
a84b8be
Add COMPlus_JitAlignLoopMinBlockWeight and COMPlus_JitAlignLoopMaxCod…
kunalspathak Oct 9, 2020
a51759a
Reuse AlignLoops flag for dynamic loop alignment
kunalspathak Oct 10, 2020
2f57c78
Detect back edge and count no. of instructions before doing loop alig…
kunalspathak Oct 14, 2020
b4848f8
fix bugs
kunalspathak Oct 15, 2020
fe92c62
propagate the basic block flag
kunalspathak Oct 15, 2020
51c3171
Switch from instrCount to codeSize
kunalspathak Oct 16, 2020
0b227a8
JitAlignLoopWith32BPadding
kunalspathak Oct 16, 2020
a9c9764
Add emitLoopAlign32Bytes()
kunalspathak Oct 23, 2020
7f1f787
wip
kunalspathak Oct 23, 2020
aac18a4
Add logic to avoid emitting nop if not needed
kunalspathak Oct 28, 2020
5c3c40e
fix a condition
kunalspathak Oct 28, 2020
fb91d41
Several things:
kunalspathak Oct 30, 2020
0b8eb78
Added JitAlignLoopAdaptive algorithm
kunalspathak Nov 5, 2020
072a113
wip
kunalspathak Nov 5, 2020
7e1328a
revert emitarm64.cpp changes
kunalspathak Nov 5, 2020
d49e84d
fix errors during merge
kunalspathak Nov 5, 2020
f6b5135
fix build errors
kunalspathak Nov 5, 2020
256aae5
refactoring and cleanup
kunalspathak Nov 6, 2020
26c3c84
refactoring and build errors fix
kunalspathak Nov 7, 2020
6bb1a75
jit format
kunalspathak Nov 7, 2020
03f6ba6
one more build error
kunalspathak Nov 7, 2020
8036061
Add emitLoopAlignAdjustments()
kunalspathak Nov 11, 2020
809fc85
Update emitLoopAlignAdjustments to just include loopSize calc
kunalspathak Nov 11, 2020
5b9b7a0
Remove #ifdef ADAPTIVE_LOOP_ALIGNMENT
kunalspathak Nov 11, 2020
5584d71
Code cleanup
kunalspathak Nov 12, 2020
f66ee24
minor fixes
kunalspathak Nov 12, 2020
f2f935d
Fix issues:
kunalspathak Nov 12, 2020
99ea31f
Other fixes
kunalspathak Nov 12, 2020
8f64963
Remove align_loops flag from coreclr
kunalspathak Dec 4, 2020
1c85c3c
Review feedback
kunalspathak Dec 4, 2020
ef0b149
jit format
kunalspathak Dec 4, 2020
599ad43
Add FEATURE_LOOP_ALIGN
kunalspathak Dec 5, 2020
97fd373
remove special case for align
kunalspathak Dec 9, 2020
37b0cdb
Do not propagate BBF_LOOP_ALIGN in certain cases
kunalspathak Dec 14, 2020
c0cc8af
Introduce instrDescAlign and emitLastAlignedIgNum
kunalspathak Dec 15, 2020
26f7e61
Several changes:
kunalspathak Dec 15, 2020
305b812
jit format
kunalspathak Dec 16, 2020
f8bdfec
fix issue related to needLabel
kunalspathak Dec 16, 2020
a205cc0
align memory correctly in superpmi
kunalspathak Dec 17, 2020
d576e9c
Few more fixes:
kunalspathak Dec 17, 2020
28480d1
minor JITDUMP messages
kunalspathak Dec 18, 2020
bf03842
Review comments
kunalspathak Dec 18, 2020
dae9749
missing check
kunalspathak Dec 18, 2020
a153742
Mark the last align IG the one that has non-zero padding
kunalspathak Dec 18, 2020
ef02fbb
More review comments
kunalspathak Dec 19, 2020
e7e0d68
Propagate BBF_LOOP_ALIGN for compacting blocks
kunalspathak Dec 19, 2020
4b0e64d
Handle ALIGN_LOOP flag for loops that are unrolled
kunalspathak Dec 20, 2020
6fddce8
jit format
kunalspathak Dec 20, 2020
bad5685
Loop size upto last back-edge instead of first back-edge
kunalspathak Dec 21, 2020
8c30a96
Take loop weight in consideration
kunalspathak Dec 21, 2020
f32f560
remove align flag if loop is no longer valid
kunalspathak Jan 4, 2021
23177b0
Adjust loop block weight to 4 instead of 8
kunalspathak Jan 6, 2021
9f3cb2d
missing space after rebase
kunalspathak Jan 6, 2021
74620ed
fix the enum values after rebase
kunalspathak Jan 7, 2021
b100226
review feedback
kunalspathak Jan 9, 2021
dbeb7d6
Add missing #ifdef DEBUG
kunalspathak Jan 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add emitLoopAlignAdjustments()
  • Loading branch information
kunalspathak committed Jan 9, 2021
commit 8036061a2d5d5a7218c27b1d9624f755d4bd2e81
6 changes: 5 additions & 1 deletion src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2258,6 +2258,9 @@ void CodeGen::genGenerateMachineCode()

GetEmitter()->emitJumpDistBind();

/* Perform alignment adjustments */
GetEmitter()->emitLoopAlignAdjustments();

/* The code is now complete and final; it should not change after this. */
}

Expand Down Expand Up @@ -2348,7 +2351,8 @@ void CodeGen::genEmitMachineCode()
printf("\n; Total bytes of code %d, prolog size %d, PerfScore %.2f, instruction count %d, allocated bytes for "
"code %d (MethodHash=%08x) for "
"method %s\n",
codeSize, prologSize, compiler->info.compPerfScore, instrCount, GetEmitter()->emitTotalHotCodeSize,
codeSize, prologSize, compiler->info.compPerfScore, instrCount,
GetEmitter()->emitTotalHotCodeSize + GetEmitter()->emitTotalColdCodeSize,
compiler->info.compMethodHash(), compiler->info.compFullName);
printf("; ============================================================\n\n");
printf(""); // in our logic this causes a flush
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/codegenlinear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ void CodeGen::genCodeForBBlist()
if ((block->bbNext != nullptr) && (block->bbNext->bbFlags & BBF_FIRST_BLOCK_IN_INNERLOOP))
{
assert(ShouldAlignLoops());

#ifndef ADAPTIVE_LOOP_ALIGNMENT
if (verbose)
{
Expand Down
135 changes: 135 additions & 0 deletions src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3665,6 +3665,8 @@ size_t emitter::emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp)
}
#endif // DEBUG_EMIT

//assert(id->idCodeSize() == csz);

/* The instruction size estimate wasn't accurate; remember this */

ig->igFlags |= IGF_UPD_ISZ;
Expand Down Expand Up @@ -4487,6 +4489,139 @@ void emitter::emitJumpDistBind()
#endif // DEBUG
}

void emitter::emitLoopAlignAdjustments()
{
#ifdef TARGET_XARCH

#ifdef ADAPTIVE_LOOP_ALIGNMENT
unsigned alignmentBoundary = DEFAULT_ALIGN_LOOP_BOUNDARY;
#else
unsigned alignmentBoundary = emitComp->opts.compJitAlignLoopBoundary;
#endif
unsigned removeAlignment = 0;
bool skipPadding = false;
int maxBlocksAllowedForLoop = genLog2(alignmentBoundary) - 1;
unsigned maxLoopSize = DEFAULT_ALIGN_LOOP_BOUNDARY * maxBlocksAllowedForLoop;
size_t dst = 0, of = 0;
unsigned minBlocksNeededForLoop = 0, nMaxPaddingBytes = 0, nPaddingBytes = 0, loopSize = 0;
for (insGroup* ig = emitIGlist; ig != nullptr; ig = ig->igNext)
{
ig->igOffs -= removeAlignment;
dst += ig->igSize;

// Below is not needed because we just care about the igSize
// and that gets adjusted in emitJumpDst when we add IGF_UPD_ISZ
//// recalculate the size
//if ((ig->igFlags & IGF_UPD_ISZ) != 0)
//{
// igSize = emitFindOffset(ig, ig->igInsCnt);
// assert(igSize == ig->igSize);
//}
//else
//{
// igSize = ig->igSize;
//}

//if (emitComp->compMethodID == 37683)
//{
// unsigned insNum = ig->igInsCnt;
// instrDesc* id = (instrDesc*)ig->igData;

// /* Walk the instruction list until all are counted */

// while (insNum > 0)
// {
// unsigned currSize = id->idCodeSize();


// printf("[%04XH] size = %d -- ", of, id->idCodeSize());
// of += currSize;

// emitDispIns(id, true, false, false);

// castto(id, BYTE*) += emitSizeOfInsDsc(id);

// insNum--;
// }
//}

//dst += igSize;

if (!(ig->igFlags & IGF_ALIGN_LOOP))
{
continue;
}

// TODO: Add logging for Skip/Add?
// TODO: I am about to align so (dst -= 15)

if ((dst & (alignmentBoundary - 1)) == 0)
{
skipPadding = true;
}
else
{
loopSize = 0;
insGroup* loopHeaderIg = ig->igNext;
for (insGroup* igInLoop = loopHeaderIg; igInLoop; igInLoop = igInLoop->igNext)
{
loopSize += igInLoop->igSize;
if (igInLoop->igLoopBackEdge == loopHeaderIg)
{
break;
}
}

minBlocksNeededForLoop = (loopSize + alignmentBoundary - 1) / alignmentBoundary;
nMaxPaddingBytes = (1 << (maxBlocksAllowedForLoop - minBlocksNeededForLoop + 1)) - 1;
nPaddingBytes = (-(int)dst) & (alignmentBoundary - 1);

if (loopSize > maxLoopSize)
{
skipPadding = true;
}
else if (nPaddingBytes > nMaxPaddingBytes)
{
alignmentBoundary = 16;
nMaxPaddingBytes = 1 << (maxBlocksAllowedForLoop - minBlocksNeededForLoop + 1);
nPaddingBytes = (-(int)dst) & (alignmentBoundary - 1);

if (nPaddingBytes > nMaxPaddingBytes)
{
//skipPadding = true;
}
}
}

if (!skipPadding && (nPaddingBytes > 0))
{
size_t extraBytesNotInLoop =
(32 * minBlocksNeededForLoop) - loopSize; // Still have it at alignmentboundary=32
size_t currentOffset = dst % alignmentBoundary; // TODO: Change to & (boundary - 1)
if (currentOffset <= extraBytesNotInLoop)
{
//skipPadding = true;

// TODO: Detect actual no. of padding bytes.
// TODO: Figure out how to update size of align instructions so they just add padding in emitter.
}
}

if (skipPadding)
{
dst -= 15;
ig->igSize -= 15;
ig->igFlags |= IGF_UPD_ISZ;
removeAlignment += 15;
emitTotalCodeSize -= 15;

// remove the flag
ig->igFlags &= ~IGF_ALIGN_LOOP;
}
}
#endif
}

void emitter::emitCheckFuncletBranch(instrDesc* jmp, insGroup* jmpIG)
{
#ifdef DEBUG
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -1740,6 +1740,7 @@ class emitter
instrDescJmp* emitJumpList; // list of local jumps in method
instrDescJmp* emitJumpLast; // last of local jumps in method
void emitJumpDistBind(); // Bind all the local jumps in method
void emitLoopAlignAdjustments(); // Predict if loop alignment is needed and make appropriate adjustments

void emitCheckFuncletBranch(instrDesc* jmp, insGroup* jmpIG); // Check for illegal branches between funclets

Expand Down
37 changes: 28 additions & 9 deletions src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12632,24 +12632,42 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
{
// Candidate for loop alignment
assert(codeGen->ShouldAlignLoops());
assert(ig->igFlags & IGF_ALIGN_LOOP);

#ifdef ADAPTIVE_LOOP_ALIGNMENT
unsigned alignmentBoundary = DEFAULT_ALIGN_LOOP_BOUNDARY;
#else
unsigned alignmentBoundary = emitComp->opts.compJitAlignLoopBoundary;
#endif
sz = SMALL_IDSC_SIZE;

#if DEBUG
bool displayAlignmentDetails =
(emitComp->opts.disAsm /*&& emitComp->opts.disAddr*/) || emitComp->verbose;
#endif
if ((ig->igFlags & IGF_ALIGN_LOOP) == 0)
{
id->idCodeSize(0);
ig->igFlags |= IGF_UPD_ISZ;
if (displayAlignmentDetails)
{
printf("\t\t;; Skip alignment: 'Big loop.' in (%s)\n", emitComp->info.compFullName);
}
break;
}

// If already at alignment boundary, no need to emit anything.
if (((size_t)dst & (alignmentBoundary - 1)) == 0)
{
id->idCodeSize(0);
ig->igFlags |= IGF_UPD_ISZ;
if (displayAlignmentDetails)
{
printf("\t\t;; Skip alignment: 'Loop already aligned at boundary.' in (%s)\n",
emitComp->info.compMethodName);
}
break;
}

#if DEBUG
bool displayAlignmentDetails = (emitComp->opts.disAsm && emitComp->opts.disAddr) || emitComp->verbose;
#endif

#ifndef ADAPTIVE_LOOP_ALIGNMENT
if (emitComp->opts.compJitAlignLoopAdaptive)
#endif
Expand Down Expand Up @@ -12678,12 +12696,13 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
if (loopSize > maxLoopSize)
{
skipPadding = true;
assert(!"This should have checked before!");
#if DEBUG
if (displayAlignmentDetails)
/*if (displayAlignmentDetails)
{
printf("\t\t;; Skip alignment: 'Loopsize= %d, MaxLoopSize= %d.' in (%s)\n", loopSize,
maxLoopSize, emitComp->info.compFullName);
}
printf("\t\t;; Skip alignment: 'Loopsize= %d, MaxLoopSize= %d, Estimated= %d.' in (%s)\n", loopSize,
maxLoopSize, ig->loopSize, emitComp->info.compFullName);
}*/
#endif
}
else if (nPaddingBytes > nMaxPaddingBytes)
Expand Down
11 changes: 6 additions & 5 deletions src/coreclr/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2546,14 +2546,15 @@ void Compiler::optFindNaturalLoops()
#if defined(TARGET_XARCH)
if (codeGen->ShouldAlignLoops())
{
// An innerloop candidate that might need alignment
if ((optLoopTable[loopInd].lpChild == BasicBlock::NOT_IN_LOOP) && (
#ifdef ADAPTIVE_LOOP_ALIGNMENT
DEFAULT_ALIGN_LOOP_MIN_BLOCK_WEIGHT
unsigned minBlockWeight = DEFAULT_ALIGN_LOOP_MIN_BLOCK_WEIGHT;
#else
opts.compJitAlignLoopMinBlockWeight
unsigned minBlockWeight = opts.compJitAlignLoopMinBlockWeight;
#endif
<= first->getBBWeight(this)))

// An innerloop candidate that might need alignment
if ((optLoopTable[loopInd].lpChild == BasicBlock::NOT_IN_LOOP) &&
minBlockWeight <= first->getBBWeight(this))
{
first->bbFlags |= BBF_FIRST_BLOCK_IN_INNERLOOP;
}
Expand Down