Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Add support for 16 byte aligned constants
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedn committed May 8, 2018
1 parent 6a10505 commit 273bfe3
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7161,7 +7161,7 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode)
if (*bitMask == nullptr)
{
assert(cnsAddr != nullptr);
*bitMask = getEmitter()->emitAnyConst(cnsAddr, genTypeSize(targetType), dblAlign);
*bitMask = getEmitter()->emitAnyConst(cnsAddr, genTypeSize(targetType), emitDataAlignment::Preferred);
}

// We need an additional register for bitmask.
Expand Down
68 changes: 49 additions & 19 deletions src/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4513,6 +4513,11 @@ unsigned emitter::emitEndCodeGen(Compiler* comp,
}
#endif

if (emitConsDsc.align16)
{
allocMemFlag = static_cast<CorJitAllocMemFlag>(allocMemFlag | CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN);
}

#ifdef _TARGET_ARM64_
// For arm64, we want to allocate JIT data always adjacent to code similar to what native compiler does.
// This way allows us to use a single `ldr` to access such data like float constant/jmp table.
Expand Down Expand Up @@ -5174,7 +5179,7 @@ UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum)
* block.
*/

UNATIVE_OFFSET emitter::emitDataGenBeg(UNATIVE_OFFSET size, bool dblAlign, bool codeLtab)
UNATIVE_OFFSET emitter::emitDataGenBeg(UNATIVE_OFFSET size, bool align)
{
unsigned secOffs;
dataSection* secDesc;
Expand All @@ -5189,20 +5194,27 @@ UNATIVE_OFFSET emitter::emitDataGenBeg(UNATIVE_OFFSET size, bool dblAlign, bool

secOffs = emitConsDsc.dsdOffs;

/* Are we require to align this request on an eight byte boundry? */
if (dblAlign && (secOffs % sizeof(double) != 0))
if (align)
{
/* Need to skip 4 bytes to honor dblAlign */
/* Must allocate a dummy 4 byte integer */
int zero = 0;
emitDataGenBeg(4, false, false);
emitDataGenData(0, &zero, 4);
emitDataGenEnd();
assert(size <= 16);

if (size == 16)
{
emitConsDsc.align16 = true;
}

while ((secOffs % size) != 0)
{
/* Need to skip 4 bytes to honor alignment */
/* Must allocate a dummy 4 byte integer */
int zero = 0;
emitDataGenBeg(4, false);
emitDataGenData(0, &zero, 4);
emitDataGenEnd();

/* Get the new secOffs */
secOffs = emitConsDsc.dsdOffs;
/* Now it should be a multiple of 8 */
assert(secOffs % sizeof(double) == 0);
/* Get the new secOffs */
secOffs = emitConsDsc.dsdOffs;
}
}

/* Advance the current offset */
Expand Down Expand Up @@ -5353,7 +5365,7 @@ UNATIVE_OFFSET emitter::emitDataConst(const void* cnsAddr, unsigned cnsSize, boo
dblAlign = false;
}

UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, dblAlign, false);
UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, dblAlign);
emitDataGenData(0, cnsAddr, cnsSize);
emitDataGenEnd();

Expand All @@ -5366,16 +5378,34 @@ UNATIVE_OFFSET emitter::emitDataConst(const void* cnsAddr, unsigned cnsSize, boo
// emitAnyConst: Create a data section constant of arbitrary size.
//
// Arguments:
// cnsAddr - pointer to the data to be placed in the data section
// cnsSize - size of the data
// dblAlign - whether to align the data section to an 8 byte boundary
// cnsAddr - pointer to the data to be placed in the data section
// cnsSize - size of the data
// alignment - indicates how to align the constant
//
// Return Value:
// A field handle representing the data offset to access the constant.
//
CORINFO_FIELD_HANDLE emitter::emitAnyConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign)
CORINFO_FIELD_HANDLE emitter::emitAnyConst(const void* cnsAddr, unsigned cnsSize, emitDataAlignment alignment)
{
UNATIVE_OFFSET cnum = emitDataConst(cnsAddr, cnsSize, dblAlign);
bool align;

switch (alignment)
{
case emitDataAlignment::None:
align = false;
break;
case emitDataAlignment::Preferred:
align = (emitComp->compCodeOpt() != Compiler::SMALL_CODE);
break;
case emitDataAlignment::Required:
default:
align = true;
break;
}

UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, align);
emitDataGenData(0, cnsAddr, cnsSize);
emitDataGenEnd();
return emitComp->eeFindJitDataOffs(cnum);
}

Expand Down
12 changes: 11 additions & 1 deletion src/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,15 @@ class emitLocation
unsigned codePos; // the code position within the IG (see emitCurOffset())
};

#ifndef LEGACY_BACKEND
enum class emitDataAlignment
{
None,
Preferred,
Required
};
#endif

/************************************************************************/
/* The following describes an instruction group */
/************************************************************************/
Expand Down Expand Up @@ -1724,7 +1733,7 @@ class emitter
UNATIVE_OFFSET emitInstCodeSz(instrDesc* id);

#ifndef LEGACY_BACKEND
CORINFO_FIELD_HANDLE emitAnyConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign);
CORINFO_FIELD_HANDLE emitAnyConst(const void* cnsAddr, unsigned cnsSize, emitDataAlignment alignment);
CORINFO_FIELD_HANDLE emitFltOrDblConst(double constValue, emitAttr attr);
regNumber emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src);
regNumber emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src1, GenTree* src2);
Expand Down Expand Up @@ -2173,6 +2182,7 @@ class emitter
dataSection* dsdList;
dataSection* dsdLast;
UNATIVE_OFFSET dsdOffs;
bool align16;
};

dataSecDsc emitConsDsc;
Expand Down
2 changes: 1 addition & 1 deletion src/jit/emitpub.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void emitIns_J(instruction ins, BasicBlock* dst, int instrCount = 0);
/* Emit initialized data sections */
/************************************************************************/

UNATIVE_OFFSET emitDataGenBeg(UNATIVE_OFFSET size, bool dblAlign, bool codeLtab);
UNATIVE_OFFSET emitDataGenBeg(UNATIVE_OFFSET size, bool align);

UNATIVE_OFFSET emitBBTableDataGenBeg(unsigned numEntries, bool relativeAddr);

Expand Down

0 comments on commit 273bfe3

Please sign in to comment.