Skip to content

Commit 36c3ab5

Browse files
committed
[wip] Use captable importing of frequently used globals
1 parent f4f1dfb commit 36c3ab5

File tree

4 files changed

+34
-11
lines changed

4 files changed

+34
-11
lines changed

lld/ELF/Arch/RISCV.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,19 @@ static uint32_t setLO12_S(uint32_t insn, uint32_t imm) {
124124
(extractBits(imm, 4, 0) << 7);
125125
}
126126

127+
static bool isCheriotHighPartReloc(RelType ty) {
128+
switch (ty) {
129+
case R_RISCV_CHERIOT_COMPARTMENT_HI:
130+
case R_RISCV_CHERI_CAPTAB_PCREL_HI20:
131+
// FIXME: This can be enabled once they handle cheriot 11-bit AUIPC shifts.
132+
// case R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20:
133+
// case R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20:
134+
return true;
135+
default:
136+
return false;
137+
}
138+
}
139+
127140
RISCV::RISCV(Ctx &ctx) : TargetInfo(ctx) {
128141
copyRel = R_RISCV_COPY;
129142
pltRel = R_RISCV_JUMP_SLOT;
@@ -540,6 +553,13 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
540553
case R_RISCV_TLS_GOT_HI20:
541554
case R_RISCV_TPREL_HI20:
542555
case R_RISCV_HI20: {
556+
if (ctx.arg.isCheriot && isCheriotHighPartReloc(rel.type)) {
557+
relocate(loc,
558+
Relocation{rel.expr, R_RISCV_CHERIOT_COMPARTMENT_HI, rel.offset,
559+
rel.addend, rel.sym},
560+
val);
561+
return;
562+
}
543563
uint64_t hi = val + 0x800;
544564
checkInt(ctx, loc, SignExtend64(hi, bits) >> 12, 20, rel);
545565
write32le(loc, (read32le(loc) & 0xFFF) | (hi & 0xFFFFF000));
@@ -1079,8 +1099,7 @@ static bool rewriteCheriotLowRelocs(Ctx &ctx, InputSection &sec) {
10791099
if (isPCCRelative(ctx, nullptr, r.sym)) {
10801100
const Defined *d = cast<Defined>(r.sym);
10811101
if (!d->section)
1082-
error("R_RISCV_CHERIOT_COMPARTMENT_LO_I relocation points to an "
1083-
"absolute symbol: " +
1102+
error("high-part relocation points to an absolute symbol: " +
10841103
r.sym->getName());
10851104
InputSection *isec = cast<InputSection>(d->section);
10861105

@@ -1096,14 +1115,14 @@ static bool rewriteCheriotLowRelocs(Ctx &ctx, InputSection &sec) {
10961115

10971116
const Relocation *target = nullptr;
10981117
for (auto it = range.first; it != range.second; ++it)
1099-
if (it->type == R_RISCV_CHERIOT_COMPARTMENT_HI) {
1118+
if (isCheriotHighPartReloc(it->type)) {
11001119
target = &*it;
11011120
break;
11021121
}
11031122
if (!target) {
1104-
error(
1105-
"Could not find R_RISCV_CHERIOT_COMPARTMENT_HI relocation for " +
1106-
toStr(ctx, *r.sym));
1123+
error("Could not find high-part relocation for " +
1124+
toStr(ctx, *r.sym) + " at 0x" +
1125+
llvm::utohexstr(r.offset, false, 8) + "@" + toStr(ctx, &sec));
11071126
}
11081127
// If the target is PCC-relative then the auipcc can't be erased and so
11091128
// skip the rewriting.

llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,8 @@ bool RISCVExpandPseudo::expandAuipccInstPair(
707707
MF->getSubtarget<RISCVSubtarget>().isRV32E() && Symbol.isGlobal() &&
708708
isa<GlobalVariable>(Symbol.getGlobal()) &&
709709
(cast<GlobalVariable>(Symbol.getGlobal())->getSection() !=
710-
".compartment_imports"))
710+
".compartment_imports") &&
711+
FlagsHi != RISCVII::MO_CAPTAB_PCREL_HI)
711712
BuildMI(NewMBB, DL, TII->get(RISCV::CSetBoundsImm), DestReg)
712713
.addReg(DestReg)
713714
.addDisp(Symbol, 0, RISCVII::MO_CHERIOT_COMPARTMENT_SIZE);

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8977,14 +8977,16 @@ static SDValue getLargeExternalSymbol(ExternalSymbolSDNode *N, const SDLoc &DL,
89778977
template <class NodeTy>
89788978
SDValue RISCVTargetLowering::getAddr(NodeTy *N, EVT Ty, SelectionDAG &DAG,
89798979
bool IsLocal, bool CanDeriveFromPcc,
8980-
bool IsExternWeak) const {
8980+
bool IsExternWeak,
8981+
const GlobalValue *GV) const {
89818982
SDLoc DL(N);
89828983

89838984
if (RISCVABI::isCheriPureCapABI(Subtarget.getTargetABI())) {
89848985
bool IsCheriot = Subtarget.getTargetABI() == RISCVABI::ABI_CHERIOT ||
89858986
Subtarget.getTargetABI() == RISCVABI::ABI_CHERIOT_BAREMETAL;
89868987
SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
8987-
if ((IsLocal && CanDeriveFromPcc) || IsCheriot) {
8988+
bool NotHighUseGV = !GV || GV->getNumUses() < 4;
8989+
if ((IsLocal && CanDeriveFromPcc) || (IsCheriot && NotHighUseGV)) {
89888990
// Use PC-relative addressing to access the symbol. This generates the
89898991
// pattern (PseudoCLLC sym), which expands to
89908992
// (cincoffsetimm (auipcc %pcrel_hi(sym)) %pcrel_lo(auipc)).
@@ -9121,7 +9123,7 @@ SDValue RISCVTargetLowering::lowerGlobalAddress(SDValue Op,
91219123
}
91229124

91239125
return getAddr(N, Ty, DAG, GV->isDSOLocal(), /*CanDeriveFromPcc=*/false,
9124-
GV->hasExternalWeakLinkage());
9126+
GV->hasExternalWeakLinkage(), GV);
91259127
}
91269128

91279129
SDValue RISCVTargetLowering::lowerBlockAddress(SDValue Op,

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,8 @@ class RISCVTargetLowering : public TargetLowering {
500500

501501
template <class NodeTy>
502502
SDValue getAddr(NodeTy *N, EVT Ty, SelectionDAG &DAG, bool IsLocal,
503-
bool CanDeriveFromPcc, bool IsExternWeak = false) const;
503+
bool CanDeriveFromPcc, bool IsExternWeak = false,
504+
const GlobalValue *GV = nullptr) const;
504505
SDValue getStaticTLSAddr(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
505506
bool NotLocal) const;
506507
SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, EVT Ty,

0 commit comments

Comments
 (0)