LLVM  14.0.0git
ELF_riscv.cpp
Go to the documentation of this file.
1 //===------- ELF_riscv.cpp -JIT linker implementation for ELF/riscv -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // ELF/riscv jit-link implementation.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "ELFLinkGraphBuilder.h"
15 #include "JITLinkGeneric.h"
17 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/Object/ELF.h"
22 #include "llvm/Support/Endian.h"
23 
24 #define DEBUG_TYPE "jitlink"
25 using namespace llvm;
26 using namespace llvm::jitlink;
27 using namespace llvm::jitlink::riscv;
28 
29 namespace {
30 
31 class PerGraphGOTAndPLTStubsBuilder_ELF_riscv
33  PerGraphGOTAndPLTStubsBuilder_ELF_riscv> {
34 public:
35  static constexpr size_t StubEntrySize = 16;
36  static const uint8_t NullGOTEntryContent[8];
37  static const uint8_t RV64StubContent[StubEntrySize];
38  static const uint8_t RV32StubContent[StubEntrySize];
39 
41  PerGraphGOTAndPLTStubsBuilder_ELF_riscv>::PerGraphGOTAndPLTStubsBuilder;
42 
43  bool isRV64() const { return G.getPointerSize() == 8; }
44 
45  bool isGOTEdgeToFix(Edge &E) const { return E.getKind() == R_RISCV_GOT_HI20; }
46 
47  Symbol &createGOTEntry(Symbol &Target) {
48  Block &GOTBlock =
49  G.createContentBlock(getGOTSection(), getGOTEntryBlockContent(),
50  orc::ExecutorAddr(), G.getPointerSize(), 0);
51  GOTBlock.addEdge(isRV64() ? R_RISCV_64 : R_RISCV_32, 0, Target, 0);
52  return G.addAnonymousSymbol(GOTBlock, 0, G.getPointerSize(), false, false);
53  }
54 
55  Symbol &createPLTStub(Symbol &Target) {
56  Block &StubContentBlock = G.createContentBlock(
57  getStubsSection(), getStubBlockContent(), orc::ExecutorAddr(), 4, 0);
58  auto &GOTEntrySymbol = getGOTEntry(Target);
59  StubContentBlock.addEdge(R_RISCV_CALL, 0, GOTEntrySymbol, 0);
60  return G.addAnonymousSymbol(StubContentBlock, 0, StubEntrySize, true,
61  false);
62  }
63 
64  void fixGOTEdge(Edge &E, Symbol &GOTEntry) {
65  // Replace the relocation pair (R_RISCV_GOT_HI20, R_RISCV_PCREL_LO12)
66  // with (R_RISCV_PCREL_HI20, R_RISCV_PCREL_LO12)
67  // Therefore, here just change the R_RISCV_GOT_HI20 to R_RISCV_PCREL_HI20
68  E.setKind(R_RISCV_PCREL_HI20);
69  E.setTarget(GOTEntry);
70  }
71 
72  void fixPLTEdge(Edge &E, Symbol &PLTStubs) {
73  assert(E.getKind() == R_RISCV_CALL_PLT && "Not a R_RISCV_CALL_PLT edge?");
74  E.setKind(R_RISCV_CALL);
75  E.setTarget(PLTStubs);
76  }
77 
78  bool isExternalBranchEdge(Edge &E) const {
79  return E.getKind() == R_RISCV_CALL_PLT;
80  }
81 
82 private:
83  Section &getGOTSection() const {
84  if (!GOTSection)
85  GOTSection = &G.createSection("$__GOT", MemProt::Read);
86  return *GOTSection;
87  }
88 
89  Section &getStubsSection() const {
90  if (!StubsSection)
91  StubsSection =
92  &G.createSection("$__STUBS", MemProt::Read | MemProt::Exec);
93  return *StubsSection;
94  }
95 
96  ArrayRef<char> getGOTEntryBlockContent() {
97  return {reinterpret_cast<const char *>(NullGOTEntryContent),
98  G.getPointerSize()};
99  }
100 
101  ArrayRef<char> getStubBlockContent() {
102  auto StubContent = isRV64() ? RV64StubContent : RV32StubContent;
103  return {reinterpret_cast<const char *>(StubContent), StubEntrySize};
104  }
105 
106  mutable Section *GOTSection = nullptr;
107  mutable Section *StubsSection = nullptr;
108 };
109 
110 const uint8_t PerGraphGOTAndPLTStubsBuilder_ELF_riscv::NullGOTEntryContent[8] =
111  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
112 
113 const uint8_t
114  PerGraphGOTAndPLTStubsBuilder_ELF_riscv::RV64StubContent[StubEntrySize] = {
115  0x17, 0x0e, 0x00, 0x00, // auipc t3, literal
116  0x03, 0x3e, 0x0e, 0x00, // ld t3, literal(t3)
117  0x67, 0x00, 0x0e, 0x00, // jr t3
118  0x13, 0x00, 0x00, 0x00}; // nop
119 
120 const uint8_t
121  PerGraphGOTAndPLTStubsBuilder_ELF_riscv::RV32StubContent[StubEntrySize] = {
122  0x17, 0x0e, 0x00, 0x00, // auipc t3, literal
123  0x03, 0x2e, 0x0e, 0x00, // lw t3, literal(t3)
124  0x67, 0x00, 0x0e, 0x00, // jr t3
125  0x13, 0x00, 0x00, 0x00}; // nop
126 } // namespace
127 namespace llvm {
128 namespace jitlink {
129 
131  using namespace riscv;
132  assert((E.getKind() == R_RISCV_PCREL_LO12_I ||
133  E.getKind() == R_RISCV_PCREL_LO12_S) &&
134  "Can only have high relocation for R_RISCV_PCREL_LO12_I or "
135  "R_RISCV_PCREL_LO12_S");
136 
137  const Symbol &Sym = E.getTarget();
138  const Block &B = Sym.getBlock();
140 
141  struct Comp {
142  bool operator()(const Edge &Lhs, orc::ExecutorAddrDiff Offset) {
143  return Lhs.getOffset() < Offset;
144  }
145  bool operator()(orc::ExecutorAddrDiff Offset, const Edge &Rhs) {
146  return Offset < Rhs.getOffset();
147  }
148  };
149 
150  auto Bound =
151  std::equal_range(B.edges().begin(), B.edges().end(), Offset, Comp{});
152 
153  for (auto It = Bound.first; It != Bound.second; ++It) {
154  if (It->getKind() == R_RISCV_PCREL_HI20)
155  return *It;
156  }
157 
158  return make_error<JITLinkError>(
159  "No HI20 PCREL relocation type be found for LO12 PCREL relocation type");
160 }
161 
162 static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size) {
163  return (Num & (((1ULL << (Size + 1)) - 1) << Low)) >> Low;
164 }
165 
167  const Edge &E) {
168  if (v & (n - 1))
169  return make_error<JITLinkError>("0x" + llvm::utohexstr(loc.getValue()) +
170  " improper alignment for relocation " +
171  formatv("{0:d}", E.getKind()) + ": 0x" +
172  llvm::utohexstr(v) + " is not aligned to " +
173  Twine(n) + " bytes");
174  return Error::success();
175 }
176 
177 static inline bool isInRangeForImmS32(int64_t Value) {
180 }
181 
182 class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
184 
185 public:
186  ELFJITLinker_riscv(std::unique_ptr<JITLinkContext> Ctx,
187  std::unique_ptr<LinkGraph> G, PassConfiguration PassConfig)
188  : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {}
189 
190 private:
191  Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
192  using namespace riscv;
193  using namespace llvm::support;
194 
195  char *BlockWorkingMem = B.getAlreadyMutableContent().data();
196  char *FixupPtr = BlockWorkingMem + E.getOffset();
197  orc::ExecutorAddr FixupAddress = B.getAddress() + E.getOffset();
198  switch (E.getKind()) {
199  case R_RISCV_32: {
200  int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
201  *(little32_t *)FixupPtr = static_cast<uint32_t>(Value);
202  break;
203  }
204  case R_RISCV_64: {
205  int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
206  *(little64_t *)FixupPtr = static_cast<uint64_t>(Value);
207  break;
208  }
209  case R_RISCV_BRANCH: {
210  int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
211  Error AlignmentIssue = checkAlignment(FixupAddress, Value, 2, E);
212  if (AlignmentIssue) {
213  return AlignmentIssue;
214  }
215  int64_t Lo = Value & 0xFFF;
216  uint32_t Imm31_25 = extractBits(Lo, 5, 6) << 25 | extractBits(Lo, 12, 1)
217  << 31;
218  uint32_t Imm11_7 = extractBits(Lo, 1, 4) << 8 | extractBits(Lo, 11, 1)
219  << 7;
220  uint32_t RawInstr = *(little32_t *)FixupPtr;
221  *(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
222  break;
223  }
224  case R_RISCV_HI20: {
225  int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
226  int64_t Hi = Value + 0x800;
228  return makeTargetOutOfRangeError(G, B, E);
229  uint32_t RawInstr = *(little32_t *)FixupPtr;
230  *(little32_t *)FixupPtr =
231  (RawInstr & 0xFFF) | (static_cast<uint32_t>(Hi & 0xFFFFF000));
232  break;
233  }
234  case R_RISCV_LO12_I: {
235  // FIXME: We assume that R_RISCV_HI20 is present in object code and pairs
236  // with current relocation R_RISCV_LO12_I. So here may need a check.
237  int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
238  int32_t Lo = Value & 0xFFF;
239  uint32_t RawInstr = *(little32_t *)FixupPtr;
240  *(little32_t *)FixupPtr =
241  (RawInstr & 0xFFFFF) | (static_cast<uint32_t>(Lo & 0xFFF) << 20);
242  break;
243  }
244  case R_RISCV_CALL: {
245  int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
246  int64_t Hi = Value + 0x800;
248  return makeTargetOutOfRangeError(G, B, E);
249  int32_t Lo = Value & 0xFFF;
250  uint32_t RawInstrAuipc = *(little32_t *)FixupPtr;
251  uint32_t RawInstrJalr = *(little32_t *)(FixupPtr + 4);
252  *(little32_t *)FixupPtr =
253  RawInstrAuipc | (static_cast<uint32_t>(Hi & 0xFFFFF000));
254  *(little32_t *)(FixupPtr + 4) =
255  RawInstrJalr | (static_cast<uint32_t>(Lo) << 20);
256  break;
257  }
258  case R_RISCV_PCREL_HI20: {
259  int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
260  int64_t Hi = Value + 0x800;
262  return makeTargetOutOfRangeError(G, B, E);
263  uint32_t RawInstr = *(little32_t *)FixupPtr;
264  *(little32_t *)FixupPtr =
265  (RawInstr & 0xFFF) | (static_cast<uint32_t>(Hi & 0xFFFFF000));
266  break;
267  }
268  case R_RISCV_PCREL_LO12_I: {
269  // FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and
270  // pairs with current relocation R_RISCV_PCREL_LO12_I. So here may need a
271  // check.
272  auto RelHI20 = getRISCVPCRelHi20(E);
273  if (!RelHI20)
274  return RelHI20.takeError();
275  int64_t Value = RelHI20->getTarget().getAddress() +
276  RelHI20->getAddend() - E.getTarget().getAddress();
277  int64_t Lo = Value & 0xFFF;
278  uint32_t RawInstr = *(little32_t *)FixupPtr;
279  *(little32_t *)FixupPtr =
280  (RawInstr & 0xFFFFF) | (static_cast<uint32_t>(Lo & 0xFFF) << 20);
281  break;
282  }
283  case R_RISCV_PCREL_LO12_S: {
284  // FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and
285  // pairs with current relocation R_RISCV_PCREL_LO12_S. So here may need a
286  // check.
287  auto RelHI20 = getRISCVPCRelHi20(E);
288  int64_t Value = RelHI20->getTarget().getAddress() +
289  RelHI20->getAddend() - E.getTarget().getAddress();
290  int64_t Lo = Value & 0xFFF;
291  uint32_t Imm31_25 = extractBits(Lo, 5, 7) << 25;
292  uint32_t Imm11_7 = extractBits(Lo, 0, 5) << 7;
293  uint32_t RawInstr = *(little32_t *)FixupPtr;
294 
295  *(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
296  break;
297  }
298  case R_RISCV_ADD64: {
299  int64_t Value = (E.getTarget().getAddress() +
300  support::endian::read64le(reinterpret_cast<const void *>(
301  FixupAddress.getValue())) +
302  E.getAddend())
303  .getValue();
304  *(little64_t *)FixupPtr = static_cast<uint64_t>(Value);
305  break;
306  }
307  case R_RISCV_ADD32: {
308  int64_t Value = (E.getTarget().getAddress() +
309  support::endian::read32le(reinterpret_cast<const void *>(
310  FixupAddress.getValue())) +
311  E.getAddend())
312  .getValue();
313  *(little32_t *)FixupPtr = static_cast<uint32_t>(Value);
314  break;
315  }
316  case R_RISCV_ADD16: {
317  int64_t Value = (E.getTarget().getAddress() +
318  support::endian::read16le(reinterpret_cast<const void *>(
319  FixupAddress.getValue())) +
320  E.getAddend())
321  .getValue();
322  *(little16_t *)FixupPtr = static_cast<uint32_t>(Value);
323  break;
324  }
325  case R_RISCV_ADD8: {
326  int64_t Value =
327  (E.getTarget().getAddress() +
328  *(reinterpret_cast<const uint8_t *>(FixupAddress.getValue())) +
329  E.getAddend())
330  .getValue();
331  *FixupPtr = static_cast<uint8_t>(Value);
332  break;
333  }
334  case R_RISCV_SUB64: {
335  int64_t Value = support::endian::read64le(reinterpret_cast<const void *>(
336  FixupAddress.getValue())) -
337  E.getTarget().getAddress().getValue() - E.getAddend();
338  *(little64_t *)FixupPtr = static_cast<uint64_t>(Value);
339  break;
340  }
341  case R_RISCV_SUB32: {
342  int64_t Value = support::endian::read32le(reinterpret_cast<const void *>(
343  FixupAddress.getValue())) -
344  E.getTarget().getAddress().getValue() - E.getAddend();
345  *(little32_t *)FixupPtr = static_cast<uint32_t>(Value);
346  break;
347  }
348  case R_RISCV_SUB16: {
349  int64_t Value = support::endian::read16le(reinterpret_cast<const void *>(
350  FixupAddress.getValue())) -
351  E.getTarget().getAddress().getValue() - E.getAddend();
352  *(little16_t *)FixupPtr = static_cast<uint32_t>(Value);
353  break;
354  }
355  case R_RISCV_SUB8: {
356  int64_t Value =
357  *(reinterpret_cast<const uint8_t *>(FixupAddress.getValue())) -
358  E.getTarget().getAddress().getValue() - E.getAddend();
359  *FixupPtr = static_cast<uint8_t>(Value);
360  break;
361  }
362  }
363  return Error::success();
364  }
365 };
366 
367 template <typename ELFT>
369 private:
371  getRelocationKind(const uint32_t Type) {
372  using namespace riscv;
373  switch (Type) {
374  case ELF::R_RISCV_32:
376  case ELF::R_RISCV_64:
378  case ELF::R_RISCV_BRANCH:
380  case ELF::R_RISCV_HI20:
382  case ELF::R_RISCV_LO12_I:
384  case ELF::R_RISCV_CALL:
396  case ELF::R_RISCV_ADD64:
398  case ELF::R_RISCV_ADD32:
400  case ELF::R_RISCV_ADD16:
402  case ELF::R_RISCV_ADD8:
404  case ELF::R_RISCV_SUB64:
406  case ELF::R_RISCV_SUB32:
408  case ELF::R_RISCV_SUB16:
410  case ELF::R_RISCV_SUB8:
412  }
413 
414  return make_error<JITLinkError>("Unsupported riscv relocation:" +
415  formatv("{0:d}", Type));
416  }
417 
418  Error addRelocations() override {
419  LLVM_DEBUG(dbgs() << "Processing relocations:\n");
420 
422  using Self = ELFLinkGraphBuilder_riscv<ELFT>;
423  for (const auto &RelSect : Base::Sections)
424  if (Error Err = Base::forEachRelocation(RelSect, this,
425  &Self::addSingleRelocation))
426  return Err;
427 
428  return Error::success();
429  }
430 
431  Error addSingleRelocation(const typename ELFT::Rela &Rel,
432  const typename ELFT::Shdr &FixupSect,
433  Block &BlockToFix) {
435 
436  uint32_t SymbolIndex = Rel.getSymbol(false);
437  auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
438  if (!ObjSymbol)
439  return ObjSymbol.takeError();
440 
441  Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
442  if (!GraphSymbol)
443  return make_error<StringError>(
444  formatv("Could not find symbol at given index, did you add it to "
445  "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
446  SymbolIndex, (*ObjSymbol)->st_shndx,
447  Base::GraphSymbols.size()),
449 
450  uint32_t Type = Rel.getType(false);
451  Expected<riscv::EdgeKind_riscv> Kind = getRelocationKind(Type);
452  if (!Kind)
453  return Kind.takeError();
454 
455  int64_t Addend = Rel.r_addend;
456  auto FixupAddress = orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;
457  Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
458  Edge GE(*Kind, Offset, *GraphSymbol, Addend);
459  LLVM_DEBUG({
460  dbgs() << " ";
461  printEdge(dbgs(), BlockToFix, GE, riscv::getEdgeKindName(*Kind));
462  dbgs() << "\n";
463  });
464 
465  BlockToFix.addEdge(std::move(GE));
466  return Error::success();
467  }
468 
469 public:
471  const object::ELFFile<ELFT> &Obj, const Triple T)
472  : ELFLinkGraphBuilder<ELFT>(Obj, std::move(T), FileName,
473  riscv::getEdgeKindName) {}
474 };
475 
478  LLVM_DEBUG({
479  dbgs() << "Building jitlink graph for new input "
480  << ObjectBuffer.getBufferIdentifier() << "...\n";
481  });
482 
483  auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer);
484  if (!ELFObj)
485  return ELFObj.takeError();
486 
487  if ((*ELFObj)->getArch() == Triple::riscv64) {
488  auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
490  (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
491  (*ELFObj)->makeTriple())
492  .buildGraph();
493  } else {
494  assert((*ELFObj)->getArch() == Triple::riscv32 &&
495  "Invalid triple for RISCV ELF object file");
496  auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
498  (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
499  (*ELFObj)->makeTriple())
500  .buildGraph();
501  }
502 }
503 
504 void link_ELF_riscv(std::unique_ptr<LinkGraph> G,
505  std::unique_ptr<JITLinkContext> Ctx) {
506  PassConfiguration Config;
507  const Triple &TT = G->getTargetTriple();
508  if (Ctx->shouldAddDefaultTargetPasses(TT)) {
509  if (auto MarkLive = Ctx->getMarkLivePass(TT))
510  Config.PrePrunePasses.push_back(std::move(MarkLive));
511  else
512  Config.PrePrunePasses.push_back(markAllSymbolsLive);
513  Config.PostPrunePasses.push_back(
514  PerGraphGOTAndPLTStubsBuilder_ELF_riscv::asPass);
515  }
516  if (auto Err = Ctx->modifyPassConfig(*G, Config))
517  return Ctx->notifyFailed(std::move(Err));
518 
520 }
521 
522 } // namespace jitlink
523 } // namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:30
llvm::Triple::riscv64
@ riscv64
Definition: Triple.h:73
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::support::detail::packed_endian_specific_integral
Definition: Endian.h:206
T
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
llvm::support::endian::read16le
uint16_t read16le(const void *P)
Definition: Endian.h:380
llvm::MipsISD::Lo
@ Lo
Definition: MipsISelLowering.h:79
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::orc::ExecutorAddr::getValue
uint64_t getValue() const
Definition: ExecutorAddress.h:53
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:80
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::MipsISD::Hi
@ Hi
Definition: MipsISelLowering.h:75
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:251
ELF.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::object::ObjectFile::createELFObjectFile
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)
Definition: ELFObjectFile.cpp:72
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
uint64_t
ELF.h
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1707
riscv.h
llvm::AArch64CC::GE
@ GE
Definition: AArch64BaseInfo.h:265
llvm::ArrayRef< char >
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
uint32_t
ELF_riscv.h
ELFObjectFile.h
PerGraphGOTAndPLTStubsBuilder.h
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
std
Definition: BitVector.h:850
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
llvm::Triple::riscv32
@ riscv32
Definition: Triple.h:72
llvm::support
Definition: Endian.h:25
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::support::endian::read64le
uint64_t read64le(const void *P)
Definition: Endian.h:382
llvm::support::endian::read32le
uint32_t read32le(const void *P)
Definition: Endian.h:381
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::MemoryBufferRef::getBufferIdentifier
StringRef getBufferIdentifier() const
Definition: MemoryBufferRef.h:33
ELFLinkGraphBuilder.h
LLVM_UNLIKELY
#define LLVM_UNLIKELY(EXPR)
Definition: Compiler.h:230
n
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
Definition: README.txt:685
Endian.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::object::ELFFile
Definition: ELF.h:94
JITLinkGeneric.h
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
Shdr
Elf_Shdr Shdr
Definition: ELFObjHandler.cpp:78