Skip to content

Commit

Permalink
Use 8-byte ops when loading/storing a TV type on the stack/frame local
Browse files Browse the repository at this point in the history
Summary: This enables load/store pairs to the stack and locals -- both loads or stores have to have the same width to be combined into a single instruction.

Reviewed By: r1mikey

Differential Revision: D62789014

fbshipit-source-id: 8c619b6b8f63b7097056e1e2e1a6bbe781b2d458
  • Loading branch information
ottoni authored and facebook-github-bot committed Sep 20, 2024
1 parent 2fcbb73 commit 6090314
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
8 changes: 6 additions & 2 deletions hphp/runtime/vm/jit/code-gen-helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,19 @@ void storeTVVal(Vout& v, Type type, Vloc srcLoc, Vptr valPtr) {
}

void storeTVType(Vout& v, Type type, Vloc srcLoc, Vptr typePtr, bool aux) {
if (type.needsReg() || aux) {
if (type.needsReg()) {
assertx(srcLoc.hasReg(1));
if (aux) {
v << store{srcLoc.reg(1), typePtr};
} else {
v << storeb{srcLoc.reg(1), typePtr};
}
} else {
v << storeb{v.cns(type.toDataType()), typePtr};
if (aux) {
v << store{v.cns(type.toDataType()), typePtr};
} else {
v << storeb{v.cns(type.toDataType()), typePtr};
}
}
}

Expand Down
33 changes: 29 additions & 4 deletions hphp/runtime/vm/jit/irlower-load-store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,13 @@ void cgKillLoc(IRLS& env, const IRInstruction* inst) {
void cgLdLoc(IRLS& env, const IRInstruction* inst) {
auto const fp = srcLoc(env, inst, 0).reg();
auto const off = localOffset(inst->extra<LdLoc>()->locId);
loadTV(vmain(env), inst->dst(), dstLoc(env, inst, 0), fp[off]);

// For ARM, if we need to load the type, then request 'aux' too -- even though
// the value is unneeded, it allows for the type and the value to be merged
// into a single loadpair.
const bool loadAux = arch() == Arch::ARM && inst->dst()->type().needsReg();

loadTV(vmain(env), inst->dst(), dstLoc(env, inst, 0), fp[off], loadAux);
}

void cgLdLocForeign(IRLS& env, const IRInstruction* inst) {
Expand Down Expand Up @@ -105,7 +111,14 @@ void cgLdLocAddr(IRLS& env, const IRInstruction* inst) {
void cgStLoc(IRLS& env, const IRInstruction* inst) {
auto const fp = srcLoc(env, inst, 0).reg();
auto const off = localOffset(inst->extra<StLoc>()->locId);
storeTV(vmain(env), fp[off], srcLoc(env, inst, 1), inst->src(1));

// For ARM, we request the `aux' field to be stored too. That's unused, but
// having a wider store for the type allows it to be merged with the store of
// the value into a single storepair instruction.
const bool storeAux = arch() == Arch::ARM;

storeTV(vmain(env), fp[off], srcLoc(env, inst, 1), inst->src(1),
TBottom, storeAux);
}

void cgStLocMeta(IRLS&, const IRInstruction*) {}
Expand Down Expand Up @@ -156,7 +169,13 @@ void cgDbgTrashFrame(IRLS& env, const IRInstruction* inst) {
void cgLdStk(IRLS& env, const IRInstruction* inst) {
auto const sp = srcLoc(env, inst, 0).reg();
auto const off = cellsToBytes(inst->extra<LdStk>()->offset.offset);
loadTV(vmain(env), inst->dst(), dstLoc(env, inst, 0), sp[off]);

// For ARM, if we need to load the type, then request 'aux' too -- even though
// the value is unneeded, it allows for the type and the value to be merged
// into a single loadpair.
const bool loadAux = arch() == Arch::ARM && inst->dst()->type().needsReg();

loadTV(vmain(env), inst->dst(), dstLoc(env, inst, 0), sp[off], loadAux);
}

void cgLdStkAddr(IRLS& env, const IRInstruction* inst) {
Expand All @@ -173,7 +192,13 @@ void cgStStk(IRLS& env, const IRInstruction* inst) {
? inst->typeParam()
: inst->src(1)->type();

storeTV(vmain(env), sp[off], srcLoc(env, inst, 1), inst->src(1), type);
// For ARM, we request the `aux' field to be stored too. That's unused, but
// having a wider store for the type allows it to be merged with the store of
// the value into a single storepair instruction.
const bool storeAux = arch() == Arch::ARM;

storeTV(vmain(env), sp[off], srcLoc(env, inst, 1), inst->src(1), type,
storeAux);
}

void cgStStkMeta(IRLS&, const IRInstruction*) {}
Expand Down

0 comments on commit 6090314

Please sign in to comment.