Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 30 additions & 3 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size,
{
// We will use lea so displacement and not immediate will be relocatable
size = EA_SET_FLG(EA_REMOVE_FLG(size, EA_CNS_RELOC_FLG), EA_DSP_RELOC_FLG);
GetEmitter()->emitIns_R_AI(INS_lea, size, reg, imm DEBUGARG(targetHandle) DEBUGARG(gtFlags));
GetEmitter()->emitIns_R_AI(INS_lea, size, reg, imm, 0 DEBUGARG(targetHandle) DEBUGARG(gtFlags));
}
else
{
Expand Down Expand Up @@ -496,8 +496,35 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
}
}

instGen_Set_Reg_To_Imm(attr, targetReg, cnsVal,
INS_FLAGS_DONT_CARE DEBUGARG(con->GetTargetHandle()) DEBUGARG(con->gtFlags));
#ifdef TARGET_AMD64
if (con->IsIconHandle(GTF_ICON_RELOC_ADDR))
{
assert(m_compiler->IsTargetAbi(CORINFO_NATIVEAOT_ABI));

if (m_compiler->opts.compReloc && genDataIndirAddrCanBeEncodedAsPCRelOffset(cnsVal))
{
emitAttr leaAttr = EA_SET_FLG(EA_REMOVE_FLG(attr, EA_CNS_RELOC_FLG), EA_DSP_RELOC_FLG);
GetEmitter()->emitIns_R_AI(INS_lea, leaAttr, targetReg, cnsVal,
con->GetRelocOffset() DEBUGARG(con->GetTargetHandle())
DEBUGARG(con->gtFlags));
}
else
{
instGen_Set_Reg_To_Imm(attr, targetReg, cnsVal,
INS_FLAGS_DONT_CARE DEBUGARG(con->GetTargetHandle()) DEBUGARG(con->gtFlags));
if (con->GetRelocOffset() != 0)
{
emitAttr addAttr = EA_IS_BYREF(attr) ? EA_BYREF : EA_PTRSIZE;
GetEmitter()->emitIns_R_I(INS_add, addAttr, targetReg, con->GetRelocOffset());
}
}
}
else
#endif // TARGET_AMD64
{
instGen_Set_Reg_To_Imm(attr, targetReg, cnsVal,
INS_FLAGS_DONT_CARE DEBUGARG(con->GetTargetHandle()) DEBUGARG(con->gtFlags));
}
regSet.verifyRegUsed(targetReg);
}
break;
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 @@ -2575,6 +2575,7 @@ class emitter
ssize_t emitGetInsCns(instrDesc* id) const;
ssize_t emitGetInsDsp(instrDesc* id) const;
ssize_t emitGetInsAmd(instrDesc* id) const;
int32_t emitGetInsAmdRelocOffset(const instrDesc* id) const;

ssize_t emitGetInsCIdisp(instrDesc* id) const;
unsigned emitGetInsCIargs(instrDesc* id) const;
Expand Down
15 changes: 15 additions & 0 deletions src/coreclr/jit/emitinl.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,21 @@ inline ssize_t emitter::emitGetInsAmd(instrDesc* id) const
return id->idIsLargeDsp() ? ((instrDescAmd*)id)->idaAmdVal : id->idAddr()->iiaAddrMode.amDisp;
}

inline int32_t emitter::emitGetInsAmdRelocOffset(const instrDesc* id) const
{
assert(id->idIsDspReloc());

if (!id->idIsLargeCns())
{
return 0;
}

assert(id->idIsLargeDsp());
ssize_t offset = ((instrDescCnsAmd*)id)->idacCnsVal;
assert(FitsIn<int32_t>(offset));
return static_cast<int32_t>(offset);
}

inline int emitter::emitGetInsCDinfo(instrDesc* id)
{
if (id->idIsLargeCall())
Expand Down
33 changes: 26 additions & 7 deletions src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9263,17 +9263,36 @@ void emitter::emitIns_R_AR(instruction ins, emitAttr attr, regNumber reg, regNum
emitIns_R_ARX(ins, attr, reg, base, REG_NA, 1, disp);
}

void emitter::emitIns_R_AI(instruction ins,
emitAttr attr,
regNumber ireg,
ssize_t disp DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags))
void emitter::emitIns_R_AI(instruction ins,
emitAttr attr,
regNumber ireg,
ssize_t disp,
int32_t relocOffset DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags))
{
assert((CodeGen::instIsFP(ins) == false) && (EA_SIZE(attr) <= EA_8BYTE) && (ireg != REG_NA));
noway_assert(emitVerifyEncodable(ins, EA_SIZE(attr), ireg));
assert((relocOffset == 0) || EA_IS_DSP_RELOC(attr));

UNATIVE_OFFSET sz;
instrDesc* id = emitNewInstrAmd(attr, disp);
insFormat fmt = emitInsModeFormat(ins, IF_RRD_ARD);
instrDesc* id;
if (relocOffset == 0)
{
id = emitNewInstrAmd(attr, disp);
}
else
{
// IF_RRD_ARD has no immediate, so use the large constant slot for the relocation addend.
instrDescCnsAmd* relocId = emitAllocInstrCnsAmd(attr);
relocId->idSetIsLargeCns();
relocId->idSetIsLargeDsp();
#ifdef DEBUG
relocId->idAddr()->iiaAddrMode.amDisp = AM_DISP_BIG_VAL;
#endif
relocId->idacCnsVal = relocOffset;
relocId->idacAmdVal = disp;
id = relocId;
}
insFormat fmt = emitInsModeFormat(ins, IF_RRD_ARD);

id->idIns(ins);
id->idInsFmt(fmt);
Expand Down Expand Up @@ -14425,7 +14444,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
dst += emitOutputWord(dst, code | 0x0500);
}

INT32 addlDelta = 0;
INT32 addlDelta = (addc == nullptr) ? emitGetInsAmdRelocOffset(id) : 0;
#ifdef TARGET_AMD64
if (addc)
{
Expand Down
9 changes: 5 additions & 4 deletions src/coreclr/jit/emitxarch.h
Original file line number Diff line number Diff line change
Expand Up @@ -1073,10 +1073,11 @@ void emitIns_I_AR(

void emitIns_R_AR(instruction ins, emitAttr attr, regNumber reg, regNumber base, int disp);

void emitIns_R_AI(instruction ins,
emitAttr attr,
regNumber ireg,
ssize_t disp DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY));
void emitIns_R_AI(instruction ins,
emitAttr attr,
regNumber ireg,
ssize_t disp,
int32_t relocOffset = 0 DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY));

void emitIns_AR_R(instruction ins,
emitAttr attr,
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20219,6 +20219,12 @@ UINT64 GenTreeIntConCommon::UnsignedIntegralValue() const
// be encoded as 32-bit offset relative to IP or zero.
bool GenTreeIntConCommon::FitsInAddrBase(Compiler* comp)
{
// The relocation addend is not part of IconValue(), so address containment cannot preserve it.
if (IsIconHandle(GTF_ICON_RELOC_ADDR))
{
return false;
}

#ifdef DEBUG
// Early out if PC-rel encoding of absolute addr is disabled.
if (!comp->opts.compEnablePCRelAddr)
Expand Down
14 changes: 14 additions & 0 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3430,6 +3430,7 @@ struct GenTreeIntCon : public GenTreeIntConCommon
in AOT mode, the handle in that statement does not correspond to the compile
time handle (rather it lets you get a handle at run-time). In that case, we also
need to store a compile time handle, which goes in this gtCompileTimeHandle field.
For GTF_ICON_RELOC_ADDR, this field instead stores the relocation addend.
*/
ssize_t gtCompileTimeHandle;

Expand Down Expand Up @@ -3458,6 +3459,19 @@ struct GenTreeIntCon : public GenTreeIntConCommon
gtCompileTimeHandle = compileTimeHandle;
}

int32_t GetRelocOffset() const
{
assert(IsIconHandle(GTF_ICON_RELOC_ADDR));
assert(FitsIn<int32_t>(gtCompileTimeHandle));
return static_cast<int32_t>(gtCompileTimeHandle);
}

void SetRelocOffset(int32_t offset)
{
assert(IsIconHandle(GTF_ICON_RELOC_ADDR));
gtCompileTimeHandle = offset;
}

// Accessors for the field sequence. See "gtFieldSeq" above.
FieldSeq* GetFieldSeq() const
{
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/handlekinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ HANDLE_KIND(GTF_ICON_FIELD_SEQ , "field seq" , 0)
HANDLE_KIND(GTF_ICON_STATIC_ADDR_PTR , "static base addr cell" , HKF_INVARIANT | HKF_NONNULL) // pointer to a static base address
HANDLE_KIND(GTF_ICON_SECREL_OFFSET , "relative offset in section" , HKF_INVARIANT) // offset in a certain section.
HANDLE_KIND(GTF_ICON_TLSGD_OFFSET , "tls global dynamic offset" , HKF_INVARIANT) // argument to tls_get_addr.
HANDLE_KIND(GTF_ICON_RELOC_ADDR , "relocatable address" , 0) // relocatable handle with an addend

#undef HANDLE_KIND
// clang-format on
34 changes: 27 additions & 7 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8011,16 +8011,36 @@ GenTree* Lowering::LowerAdd(GenTreeOp* node)
// We could do this folding earlier, but that is not trivial as we'll have to introduce a way to restore
// the original object from a byref constant for optimizations.
if (op1->IsCnsIntOrI() && op2->IsCnsIntOrI() && !node->gtOverflow() &&
(op1->IsIconHandle(GTF_ICON_OBJ_HDL) || op2->IsIconHandle(GTF_ICON_OBJ_HDL)) &&
!op1->AsIntCon()->ImmedValNeedsReloc(m_compiler) && !op2->AsIntCon()->ImmedValNeedsReloc(m_compiler))
(op1->IsIconHandle(GTF_ICON_OBJ_HDL) || op2->IsIconHandle(GTF_ICON_OBJ_HDL)))
{
assert(node->TypeIs(TYP_I_IMPL, TYP_BYREF));

// TODO-CQ: we should allow this for AOT too. For that we need to guarantee that the new constant
// will be lowered as the original handle with offset in a reloc.
BlockRange().Remove(op1);
BlockRange().Remove(op2);
node->BashToConst(op1->AsIntCon()->IconValue() + op2->AsIntCon()->IconValue(), node->TypeGet());
GenTreeIntCon* objHandle = op1->IsIconHandle(GTF_ICON_OBJ_HDL) ? op1->AsIntCon() : op2->AsIntCon();
GenTreeIntCon* offset = (objHandle == op1) ? op2->AsIntCon() : op1->AsIntCon();

if (!objHandle->ImmedValNeedsReloc(m_compiler) && !offset->ImmedValNeedsReloc(m_compiler))
{
BlockRange().Remove(op1);
BlockRange().Remove(op2);
node->BashToConst(op1->AsIntCon()->IconValue() + op2->AsIntCon()->IconValue(), node->TypeGet());
}
#ifdef TARGET_AMD64
else if (m_compiler->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && objHandle->ImmedValNeedsReloc(m_compiler) &&
!offset->IsIconHandle() && !offset->ImmedValNeedsReloc(m_compiler) &&
FitsIn<int32_t>(offset->IconValue()))
{
FieldSeq* fieldSeq =
m_compiler->GetFieldSeqStore()->Append(objHandle->GetFieldSeq(), offset->GetFieldSeq());
int32_t relocOffset = static_cast<int32_t>(offset->IconValue());

BlockRange().Remove(op1);
BlockRange().Remove(op2);
node->BashToConst(objHandle->IconValue(), node->TypeGet());
node->gtFlags |= GTF_ICON_RELOC_ADDR;
node->AsIntCon()->SetRelocOffset(relocOffset);
node->AsIntCon()->SetFieldSeq(fieldSeq);
}
#endif // TARGET_AMD64
}
}

Expand Down
Loading