Skip to content

Commit 348d0a6

Browse files
committed
[JITLink] Add target features to LinkGraph
This patch adds SubtargetFeatures to LinkGraph. Similar to Triple, some targets might use this information while linking. One example, and the reason this patch was written, is linker relaxation on RISC-V: different relaxations are possible depending on if the C extension is enabled. Note that the features are stored as `std::vector<std::string>` to prevent a public dependency on MC. There is still a private dependency to be able to convert SubtargetFeatures to a vector. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D149522
1 parent 080ee85 commit 348d0a6

16 files changed

+126
-54
lines changed

llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -984,11 +984,20 @@ class LinkGraph {
984984

985985
using GetEdgeKindNameFunction = const char *(*)(Edge::Kind);
986986

987+
using FeatureVector = std::vector<std::string>;
988+
989+
LinkGraph(std::string Name, const Triple &TT, FeatureVector Features,
990+
unsigned PointerSize, support::endianness Endianness,
991+
GetEdgeKindNameFunction GetEdgeKindName)
992+
: Name(std::move(Name)), TT(TT), Features(std::move(Features)),
993+
PointerSize(PointerSize), Endianness(Endianness),
994+
GetEdgeKindName(std::move(GetEdgeKindName)) {}
995+
987996
LinkGraph(std::string Name, const Triple &TT, unsigned PointerSize,
988997
support::endianness Endianness,
989998
GetEdgeKindNameFunction GetEdgeKindName)
990-
: Name(std::move(Name)), TT(TT), PointerSize(PointerSize),
991-
Endianness(Endianness), GetEdgeKindName(std::move(GetEdgeKindName)) {}
999+
: LinkGraph(std::move(Name), TT, FeatureVector(), PointerSize, Endianness,
1000+
GetEdgeKindName) {}
9921001

9931002
LinkGraph(const LinkGraph &) = delete;
9941003
LinkGraph &operator=(const LinkGraph &) = delete;
@@ -1002,6 +1011,9 @@ class LinkGraph {
10021011
/// Returns the target triple for this Graph.
10031012
const Triple &getTargetTriple() const { return TT; }
10041013

1014+
/// Return the subtarget features for this Graph.
1015+
const FeatureVector &getFeatures() const { return Features; }
1016+
10051017
/// Returns the pointer size for use in this graph.
10061018
unsigned getPointerSize() const { return PointerSize; }
10071019

@@ -1507,6 +1519,7 @@ class LinkGraph {
15071519

15081520
std::string Name;
15091521
Triple TT;
1522+
FeatureVector Features;
15101523
unsigned PointerSize;
15111524
support::endianness Endianness;
15121525
GetEdgeKindNameFunction GetEdgeKindName = nullptr;

llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ add_llvm_component_library(LLVMJITLink
5050

5151
LINK_COMPONENTS
5252
BinaryFormat
53+
MC
5354
Object
5455
Option
5556
OrcTargetProcess

llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ static Triple createTripleWithCOFFFormat(Triple T) {
2525

2626
COFFLinkGraphBuilder::COFFLinkGraphBuilder(
2727
const object::COFFObjectFile &Obj, Triple TT,
28+
LinkGraph::FeatureVector Features,
2829
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
29-
: Obj(Obj),
30-
G(std::make_unique<LinkGraph>(Obj.getFileName().str(),
31-
createTripleWithCOFFFormat(TT),
32-
getPointerSize(Obj), getEndianness(Obj),
33-
std::move(GetEdgeKindName))) {
30+
: Obj(Obj), G(std::make_unique<LinkGraph>(
31+
Obj.getFileName().str(), createTripleWithCOFFFormat(TT),
32+
std::move(Features), getPointerSize(Obj),
33+
getEndianness(Obj), std::move(GetEdgeKindName))) {
3434
LLVM_DEBUG({
3535
dbgs() << "Created COFFLinkGraphBuilder for \"" << Obj.getFileName()
3636
<< "\"\n";

llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class COFFLinkGraphBuilder {
3939
using COFFSymbolIndex = int32_t;
4040

4141
COFFLinkGraphBuilder(const object::COFFObjectFile &Obj, Triple TT,
42+
LinkGraph::FeatureVector Features,
4243
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
4344

4445
LinkGraph &getGraph() const { return *G; }

llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,10 @@ class COFFLinkGraphBuilder_x86_64 : public COFFLinkGraphBuilder {
181181
}
182182

183183
public:
184-
COFFLinkGraphBuilder_x86_64(const object::COFFObjectFile &Obj, const Triple T)
185-
: COFFLinkGraphBuilder(Obj, std::move(T), getCOFFX86RelocationKindName) {}
184+
COFFLinkGraphBuilder_x86_64(const object::COFFObjectFile &Obj, const Triple T,
185+
const LinkGraph::FeatureVector Features)
186+
: COFFLinkGraphBuilder(Obj, std::move(T), std::move(Features),
187+
getCOFFX86RelocationKindName) {}
186188
};
187189

188190
class COFFLinkGraphLowering_x86_64 {
@@ -314,7 +316,12 @@ createLinkGraphFromCOFFObject_x86_64(MemoryBufferRef ObjectBuffer) {
314316
if (!COFFObj)
315317
return COFFObj.takeError();
316318

317-
return COFFLinkGraphBuilder_x86_64(**COFFObj, (*COFFObj)->makeTriple())
319+
auto Features = (*COFFObj)->getFeatures();
320+
if (!Features)
321+
return Features.takeError();
322+
323+
return COFFLinkGraphBuilder_x86_64(**COFFObj, (*COFFObj)->makeTriple(),
324+
Features->getFeatures())
318325
.buildGraph();
319326
}
320327

llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
5959

6060
public:
6161
ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj, Triple TT,
62-
StringRef FileName,
62+
LinkGraph::FeatureVector Features, StringRef FileName,
6363
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
6464

6565
/// Debug sections are included in the graph by default. Use
@@ -195,11 +195,11 @@ class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
195195

196196
template <typename ELFT>
197197
ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder(
198-
const ELFFile &Obj, Triple TT, StringRef FileName,
199-
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
198+
const ELFFile &Obj, Triple TT, LinkGraph::FeatureVector Features,
199+
StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
200200
: ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
201-
FileName.str(), Triple(std::move(TT)), ELFT::Is64Bits ? 8 : 4,
202-
support::endianness(ELFT::TargetEndianness),
201+
FileName.str(), Triple(std::move(TT)), std::move(Features),
202+
ELFT::Is64Bits ? 8 : 4, support::endianness(ELFT::TargetEndianness),
203203
std::move(GetEdgeKindName))),
204204
Obj(Obj) {
205205
LLVM_DEBUG(

llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,10 @@ class ELFLinkGraphBuilder_aarch32
191191
public:
192192
ELFLinkGraphBuilder_aarch32(StringRef FileName,
193193
const llvm::object::ELFFile<ELFT> &Obj, Triple TT,
194+
LinkGraph::FeatureVector Features,
194195
aarch32::ArmConfig ArmCfg)
195-
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), FileName,
196-
getELFAArch32EdgeKindName),
196+
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
197+
FileName, getELFAArch32EdgeKindName),
197198
ArmCfg(std::move(ArmCfg)) {}
198199
};
199200

@@ -217,6 +218,10 @@ createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer) {
217218
if (!ELFObj)
218219
return ELFObj.takeError();
219220

221+
auto Features = (*ELFObj)->getFeatures();
222+
if (!Features)
223+
return Features.takeError();
224+
220225
// Find out what exact AArch32 instruction set and features we target.
221226
auto TT = (*ELFObj)->makeTriple();
222227
ARM::ArchKind AK = ARM::parseArch(TT.getArchName());
@@ -249,14 +254,16 @@ createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer) {
249254
case Triple::thumb: {
250255
auto &ELFFile = cast<ELFObjectFile<ELF32LE>>(**ELFObj).getELFFile();
251256
return ELFLinkGraphBuilder_aarch32<support::little>(
252-
(*ELFObj)->getFileName(), ELFFile, TT, ArmCfg)
257+
(*ELFObj)->getFileName(), ELFFile, TT, Features->getFeatures(),
258+
ArmCfg)
253259
.buildGraph();
254260
}
255261
case Triple::armeb:
256262
case Triple::thumbeb: {
257263
auto &ELFFile = cast<ELFObjectFile<ELF32BE>>(**ELFObj).getELFFile();
258-
return ELFLinkGraphBuilder_aarch32<support::big>((*ELFObj)->getFileName(),
259-
ELFFile, TT, ArmCfg)
264+
return ELFLinkGraphBuilder_aarch32<support::big>(
265+
(*ELFObj)->getFileName(), ELFFile, TT, Features->getFeatures(),
266+
ArmCfg)
260267
.buildGraph();
261268
}
262269
default:

llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,10 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
404404

405405
public:
406406
ELFLinkGraphBuilder_aarch64(StringRef FileName,
407-
const object::ELFFile<ELFT> &Obj, Triple TT)
408-
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), FileName,
409-
aarch64::getEdgeKindName) {}
407+
const object::ELFFile<ELFT> &Obj, Triple TT,
408+
LinkGraph::FeatureVector Features)
409+
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
410+
FileName, aarch64::getEdgeKindName) {}
410411
};
411412

412413
// TLS Info Builder.
@@ -554,13 +555,17 @@ createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer) {
554555
if (!ELFObj)
555556
return ELFObj.takeError();
556557

558+
auto Features = (*ELFObj)->getFeatures();
559+
if (!Features)
560+
return Features.takeError();
561+
557562
assert((*ELFObj)->getArch() == Triple::aarch64 &&
558563
"Only AArch64 (little endian) is supported for now");
559564

560565
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
561-
return ELFLinkGraphBuilder_aarch64<object::ELF64LE>((*ELFObj)->getFileName(),
562-
ELFObjFile.getELFFile(),
563-
(*ELFObj)->makeTriple())
566+
return ELFLinkGraphBuilder_aarch64<object::ELF64LE>(
567+
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
568+
(*ELFObj)->makeTriple(), Features->getFeatures())
564569
.buildGraph();
565570
}
566571

llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,9 @@ class ELFLinkGraphBuilder_i386 : public ELFLinkGraphBuilder<ELFT> {
210210

211211
public:
212212
ELFLinkGraphBuilder_i386(StringRef FileName, const object::ELFFile<ELFT> &Obj,
213-
Triple TT)
214-
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), FileName,
215-
i386::getEdgeKindName) {}
213+
Triple TT, LinkGraph::FeatureVector Features)
214+
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
215+
FileName, i386::getEdgeKindName) {}
216216
};
217217

218218
Expected<std::unique_ptr<LinkGraph>>
@@ -226,13 +226,17 @@ createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer) {
226226
if (!ELFObj)
227227
return ELFObj.takeError();
228228

229+
auto Features = (*ELFObj)->getFeatures();
230+
if (!Features)
231+
return Features.takeError();
232+
229233
assert((*ELFObj)->getArch() == Triple::x86 &&
230234
"Only i386 (little endian) is supported for now");
231235

232236
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
233-
return ELFLinkGraphBuilder_i386<object::ELF32LE>((*ELFObj)->getFileName(),
234-
ELFObjFile.getELFFile(),
235-
(*ELFObj)->makeTriple())
237+
return ELFLinkGraphBuilder_i386<object::ELF32LE>(
238+
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
239+
(*ELFObj)->makeTriple(), Features->getFeatures())
236240
.buildGraph();
237241
}
238242

llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,10 @@ class ELFLinkGraphBuilder_loongarch : public ELFLinkGraphBuilder<ELFT> {
129129

130130
public:
131131
ELFLinkGraphBuilder_loongarch(StringRef FileName,
132-
const object::ELFFile<ELFT> &Obj, Triple TT)
133-
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), FileName,
134-
loongarch::getEdgeKindName) {}
132+
const object::ELFFile<ELFT> &Obj, Triple TT,
133+
LinkGraph::FeatureVector Features)
134+
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
135+
FileName, loongarch::getEdgeKindName) {}
135136
};
136137

137138
Error buildTables_ELF_loongarch(LinkGraph &G) {
@@ -159,11 +160,15 @@ createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer) {
159160
if (!ELFObj)
160161
return ELFObj.takeError();
161162

163+
auto Features = (*ELFObj)->getFeatures();
164+
if (!Features)
165+
return Features.takeError();
166+
162167
if ((*ELFObj)->getArch() == Triple::loongarch64) {
163168
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
164169
return ELFLinkGraphBuilder_loongarch<object::ELF64LE>(
165170
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
166-
(*ELFObj)->makeTriple())
171+
(*ELFObj)->makeTriple(), Features->getFeatures())
167172
.buildGraph();
168173
}
169174

@@ -172,7 +177,7 @@ createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer) {
172177
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
173178
return ELFLinkGraphBuilder_loongarch<object::ELF32LE>(
174179
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
175-
(*ELFObj)->makeTriple())
180+
(*ELFObj)->makeTriple(), Features->getFeatures())
176181
.buildGraph();
177182
}
178183

llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -596,9 +596,10 @@ class ELFLinkGraphBuilder_riscv : public ELFLinkGraphBuilder<ELFT> {
596596

597597
public:
598598
ELFLinkGraphBuilder_riscv(StringRef FileName,
599-
const object::ELFFile<ELFT> &Obj, Triple TT)
600-
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), FileName,
601-
riscv::getEdgeKindName) {}
599+
const object::ELFFile<ELFT> &Obj, Triple TT,
600+
LinkGraph::FeatureVector Features)
601+
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
602+
FileName, riscv::getEdgeKindName) {}
602603
};
603604

604605
Expected<std::unique_ptr<LinkGraph>>
@@ -612,19 +613,23 @@ createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer) {
612613
if (!ELFObj)
613614
return ELFObj.takeError();
614615

616+
auto Features = (*ELFObj)->getFeatures();
617+
if (!Features)
618+
return Features.takeError();
619+
615620
if ((*ELFObj)->getArch() == Triple::riscv64) {
616621
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
617622
return ELFLinkGraphBuilder_riscv<object::ELF64LE>(
618623
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
619-
(*ELFObj)->makeTriple())
624+
(*ELFObj)->makeTriple(), Features->getFeatures())
620625
.buildGraph();
621626
} else {
622627
assert((*ELFObj)->getArch() == Triple::riscv32 &&
623628
"Invalid triple for RISCV ELF object file");
624629
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
625630
return ELFLinkGraphBuilder_riscv<object::ELF32LE>(
626631
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
627-
(*ELFObj)->makeTriple())
632+
(*ELFObj)->makeTriple(), Features->getFeatures())
628633
.buildGraph();
629634
}
630635
}

llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,10 @@ class ELFLinkGraphBuilder_x86_64 : public ELFLinkGraphBuilder<object::ELF64LE> {
227227

228228
public:
229229
ELFLinkGraphBuilder_x86_64(StringRef FileName,
230-
const object::ELFFile<object::ELF64LE> &Obj)
231-
: ELFLinkGraphBuilder(Obj, Triple("x86_64-unknown-linux"), FileName,
230+
const object::ELFFile<object::ELF64LE> &Obj,
231+
LinkGraph::FeatureVector Features)
232+
: ELFLinkGraphBuilder(Obj, Triple("x86_64-unknown-linux"),
233+
std::move(Features), FileName,
232234
x86_64::getEdgeKindName) {}
233235
};
234236

@@ -329,9 +331,14 @@ createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer) {
329331
if (!ELFObj)
330332
return ELFObj.takeError();
331333

334+
auto Features = (*ELFObj)->getFeatures();
335+
if (!Features)
336+
return Features.takeError();
337+
332338
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
333339
return ELFLinkGraphBuilder_x86_64((*ELFObj)->getFileName(),
334-
ELFObjFile.getELFFile())
340+
ELFObjFile.getELFFile(),
341+
Features->getFeatures())
335342
.buildGraph();
336343
}
337344

llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@ Expected<std::unique_ptr<LinkGraph>> MachOLinkGraphBuilder::buildGraph() {
4848

4949
MachOLinkGraphBuilder::MachOLinkGraphBuilder(
5050
const object::MachOObjectFile &Obj, Triple TT,
51+
LinkGraph::FeatureVector Features,
5152
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
5253
: Obj(Obj),
53-
G(std::make_unique<LinkGraph>(
54-
std::string(Obj.getFileName()), std::move(TT), getPointerSize(Obj),
55-
getEndianness(Obj), std::move(GetEdgeKindName))) {
54+
G(std::make_unique<LinkGraph>(std::string(Obj.getFileName()),
55+
std::move(TT), std::move(Features),
56+
getPointerSize(Obj), getEndianness(Obj),
57+
std::move(GetEdgeKindName))) {
5658
auto &MachHeader = Obj.getHeader64();
5759
SubsectionsViaSymbols = MachHeader.flags & MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
5860
}

llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class MachOLinkGraphBuilder {
8484
using SectionParserFunction = std::function<Error(NormalizedSection &S)>;
8585

8686
MachOLinkGraphBuilder(const object::MachOObjectFile &Obj, Triple TT,
87+
LinkGraph::FeatureVector Features,
8788
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
8889

8990
LinkGraph &getGraph() const { return *G; }

0 commit comments

Comments
 (0)