[llvm] [RuntimeDyld] Add LoongArch support (PR #114741)

David Spickett via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 7 02:11:37 PST 2024


================
@@ -645,6 +645,203 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
   }
 }
 
+bool RuntimeDyldELF::resolveLoongArch64ShortBranch(
+    unsigned SectionID, relocation_iterator RelI,
+    const RelocationValueRef &Value) {
+  uint64_t Address;
+  if (Value.SymbolName) {
+    auto Loc = GlobalSymbolTable.find(Value.SymbolName);
+    // Don't create direct branch for external symbols.
+    if (Loc == GlobalSymbolTable.end())
+      return false;
+    const auto &SymInfo = Loc->second;
+    Address =
+        uint64_t(Sections[SymInfo.getSectionID()].getLoadAddressWithOffset(
+            SymInfo.getOffset()));
+  } else {
+    Address = uint64_t(Sections[Value.SectionID].getLoadAddress());
+  }
+  uint64_t Offset = RelI->getOffset();
+  uint64_t SourceAddress = Sections[SectionID].getLoadAddressWithOffset(Offset);
+  if (!isInt<28>(Address + Value.Addend - SourceAddress))
+    return false;
+  resolveRelocation(Sections[SectionID], Offset, Address, RelI->getType(),
+                    Value.Addend);
+  return true;
+}
+
+void RuntimeDyldELF::resolveLoongArch64Branch(unsigned SectionID,
+                                              const RelocationValueRef &Value,
+                                              relocation_iterator RelI,
+                                              StubMap &Stubs) {
+  LLVM_DEBUG(dbgs() << "\t\tThis is an LoongArch64 branch relocation.\n");
+  SectionEntry &Section = Sections[SectionID];
+  uint64_t Offset = RelI->getOffset();
+  unsigned RelType = RelI->getType();
+  // Look for an existing stub.
+  StubMap::const_iterator i = Stubs.find(Value);
+  if (i != Stubs.end()) {
----------------
DavidSpickett wrote:

This logic might be easier to parse if it was organised like this:
```
if (i != Stubs.end()) {
  // resolve using the stub
  return;
}

if (resolveLoongArch64ShortBranch(SectionID, RelI, Value))
  return;

// Create a new stub function.
LLVM_DEBUG(dbgs() << " Create a new stub function\n");
```
Same logic, but it's easier to see that all paths will resolve the relocation in some way.

Also do you want to prefer stubs over a short branch if you could use one? That seems to be what this does, but I don't know enough about JIT to say if that makes sense.

My assumption is that anything that could be resolved by a short branch would never have needed a stub, so looking for a stub for it will always fail. Perhaps sometimes the same location must be reached via a stub if you are too far away, but if you are close enough for a short branch wouldn't that be the most efficient option?

https://github.com/llvm/llvm-project/pull/114741


More information about the llvm-commits mailing list