Skip to content

Commit 9b6d12a

Browse files
authored
Support 32 byte alignment of code on xarch (#2249)
* Support 32 byte alignment of code on xarch Update jit and runtime to allow jit to ask for code to be 32 byte aligned. Request 32 byte alignment for Tier1 methods on x86/x64. Add minimal crossgen support; one can imagine requesting or choosing 32 byte alignment for crossgenned code, but that is left as future work. This should provide some measure of performance stability, in particular for microbenchmarks or other code where performance depends crucially on a few branches. It may or may not improve performance. If/when there are regressions we can contemplate updating the jit to add intra-method padding to address alignment sensitive code layout (e.g. dotnet/coreclr#11607). This will require a jit GUID update in addition to the changes here. * restrict to larger methods with loops; don't update zapper * new jit GUID * fix target ifdef name
1 parent d4b06b1 commit 9b6d12a

File tree

7 files changed

+45
-14
lines changed

7 files changed

+45
-14
lines changed

src/coreclr/src/inc/corinfo.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,11 @@ TODO: Talk about initializing strutures before use
217217
#endif
218218
#endif
219219

220-
SELECTANY const GUID JITEEVersionIdentifier = { /* 13028353-152c-4886-b05b-fa76ee8169cf */
221-
0x13028353,
222-
0x152c,
223-
0x4886,
224-
{0xb0, 0x5b, 0xfa, 0x76, 0xee, 0x81, 0x69, 0xcf}
220+
SELECTANY const GUID JITEEVersionIdentifier = { /* 96fc0c0a-9f77-450d-9663-ee33ae0fcae8 */
221+
0x96fc0c0a,
222+
0x9f77,
223+
0x450d,
224+
{0x96, 0x63, 0xee, 0x33, 0xae, 0x0f, 0xca, 0xe8}
225225
};
226226

227227
//////////////////////////////////////////////////////////////////////////////////////////////////////////

src/coreclr/src/inc/corjit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ enum CorJitAllocMemFlag
179179
CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN = 0x00000000, // The code will be use the normal alignment
180180
CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN = 0x00000001, // The code will be 16-byte aligned
181181
CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN = 0x00000002, // The read-only data will be 16-byte aligned
182+
CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN = 0x00000004, // The code will be 32-byte aligned
183+
CORJIT_ALLOCMEM_FLG_RODATA_32BYTE_ALIGN = 0x00000008, // The read-only data will be 32-byte aligned
182184
};
183185

184186
inline CorJitAllocMemFlag operator |(CorJitAllocMemFlag a, CorJitAllocMemFlag b)

src/coreclr/src/jit/emit.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4615,6 +4615,16 @@ unsigned emitter::emitEndCodeGen(Compiler* comp,
46154615
}
46164616
#endif
46174617

4618+
#ifdef TARGET_XARCH
4619+
// For x64/x86, align Tier1 methods to 32 byte boundaries if
4620+
// they are larger than 16 bytes and contain a loop.
4621+
//
4622+
if (emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER1) && (emitTotalHotCodeSize > 16) && emitComp->fgHasLoops)
4623+
{
4624+
allocMemFlag = CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN;
4625+
}
4626+
#endif
4627+
46184628
if (emitConsDsc.align16)
46194629
{
46204630
allocMemFlag = static_cast<CorJitAllocMemFlag>(allocMemFlag | CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN);

src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ public enum CorJitAllocMemFlag
764764
CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN = 0x00000000, // The code will be use the normal alignment
765765
CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN = 0x00000001, // The code will be 16-byte aligned
766766
CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN = 0x00000002, // The read-only data will be 16-byte aligned
767+
CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN = 0x00000004, // The code will be 32-byte aligned
768+
CORJIT_ALLOCMEM_FLG_RODATA_32BYTE_ALIGN = 0x00000008, // The read-only data will be 32-byte aligned
767769
}
768770

769771
public enum CorJitFuncKind

src/coreclr/src/tools/crossgen2/jitinterface/jitwrapper.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ class CORJIT_FLAGS
2727
uint64_t corJitFlags;
2828
};
2929

30-
static const GUID JITEEVersionIdentifier = { /* 13028353-152c-4886-b05b-fa76ee8169cf */
31-
0x13028353,
32-
0x152c,
33-
0x4886,
34-
{0xb0, 0x5b, 0xfa, 0x76, 0xee, 0x81, 0x69, 0xcf}
30+
static const GUID JITEEVersionIdentifier = { /* 96fc0c0a-9f77-450d-9663-ee33ae0fcae8 */
31+
0x96fc0c0a,
32+
0x9f77,
33+
0x450d,
34+
{0x96, 0x63, 0xee, 0x33, 0xae, 0x0f, 0xca, 0xe8}
3535
};
3636

3737
class Jit

src/coreclr/src/vm/codeman.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2551,7 +2551,11 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t re
25512551

25522552
unsigned alignment = CODE_SIZE_ALIGN;
25532553

2554-
if ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN) != 0)
2554+
if ((flag & CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN) != 0)
2555+
{
2556+
alignment = max(alignment, 32);
2557+
}
2558+
else if ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN) != 0)
25552559
{
25562560
alignment = max(alignment, 16);
25572561
}

src/coreclr/src/vm/jitinterface.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12065,7 +12065,11 @@ void CEEJitInfo::allocMem (
1206512065
S_SIZE_T totalSize = S_SIZE_T(codeSize);
1206612066

1206712067
size_t roDataAlignment = sizeof(void*);
12068-
if ((flag & CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN)!= 0)
12068+
if ((flag & CORJIT_ALLOCMEM_FLG_RODATA_32BYTE_ALIGN)!= 0)
12069+
{
12070+
roDataAlignment = 32;
12071+
}
12072+
else if ((flag & CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN)!= 0)
1206912073
{
1207012074
roDataAlignment = 16;
1207112075
}
@@ -12075,9 +12079,18 @@ void CEEJitInfo::allocMem (
1207512079
}
1207612080
if (roDataSize > 0)
1207712081
{
12078-
size_t codeAlignment = ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN)!= 0)
12079-
? 16 : sizeof(void*);
12082+
size_t codeAlignment = sizeof(void*);
12083+
12084+
if ((flag & CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN) != 0)
12085+
{
12086+
codeAlignment = 32;
12087+
}
12088+
else if ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN) != 0)
12089+
{
12090+
codeAlignment = 16;
12091+
}
1208012092
totalSize.AlignUp(codeAlignment);
12093+
1208112094
if (roDataAlignment > codeAlignment) {
1208212095
// Add padding to align read-only data.
1208312096
totalSize += (roDataAlignment - codeAlignment);

0 commit comments

Comments
 (0)