[llvm] [JITLink][AArch32] Add dynamic lookup for relocation fixup infos (PR #71649)

Stefan Gränitz via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 8 02:51:34 PST 2023


================
@@ -248,15 +247,49 @@ Error makeUnexpectedOpcodeError(const LinkGraph &G, const ArmRelocation &R,
               static_cast<uint32_t>(R.Wd), G.getEdgeKindName(Kind)));
 }
 
-template <EdgeKind_aarch32 Kind> bool checkOpcode(const ThumbRelocation &R) {
-  uint16_t Hi = R.Hi & FixupInfo<Kind>::OpcodeMask.Hi;
-  uint16_t Lo = R.Lo & FixupInfo<Kind>::OpcodeMask.Lo;
-  return Hi == FixupInfo<Kind>::Opcode.Hi && Lo == FixupInfo<Kind>::Opcode.Lo;
+static auto &getFixupInfoTableArm() {
+  static constexpr size_t Items = LastArmRelocation - FirstArmRelocation + 1;
+  static std::array<std::unique_ptr<FixupInfoBaseArm>, Items> FixupInfoTableArm;
+  return FixupInfoTableArm;
+}
+
+static auto &getFixupInfoTableThumb() {
+  static constexpr size_t Items = LastThumbRelocation - FirstThumbRelocation + 1;
+  static std::array<std::unique_ptr<FixupInfoBaseThumb>, Items> FixupInfoTableThumb;
+  return FixupInfoTableThumb;
 }
 
-template <EdgeKind_aarch32 Kind> bool checkOpcode(const ArmRelocation &R) {
-  uint32_t Wd = R.Wd & FixupInfo<Kind>::OpcodeMask;
-  return Wd == FixupInfo<Kind>::Opcode;
+template <EdgeKind_aarch32 It, EdgeKind_aarch32 Last, typename TableT>
+void populateFixupInfos(TableT &Table, size_t Idx = 0) {
+  Table[Idx] = std::make_unique<FixupInfo<It>>();
+  if constexpr (It < Last) {
+    constexpr auto Next = EdgeKind_aarch32((Edge::Kind)It + 1);
+    populateFixupInfos<Next, Last>(Table, Idx + 1);
+  }
+}
+
+void populateFixupInfos() {
+  static std::once_flag Flag;
+  std::call_once(Flag, []() {
+    populateFixupInfos<FirstArmRelocation, LastArmRelocation>(getFixupInfoTableArm());
+    populateFixupInfos<FirstThumbRelocation, LastThumbRelocation>(getFixupInfoTableThumb());
+  });
+}
+
+static bool checkOpcode(const ArmRelocation &R, Edge::Kind Kind) {
+  assert(Kind >= FirstArmRelocation && Kind <= LastArmRelocation &&
+         "Edge kind is no Arm relocation");
+  assert(getFixupInfoTableArm().at(Kind - FirstArmRelocation) != nullptr &&
+         "Call populateFixupInfos() before dynamic access");
+  return getFixupInfoTableArm()[Kind - FirstArmRelocation]->checkOpcode(R.Wd);
+}
----------------
weliveindetail wrote:

The opcode checks are on the hot-path of relocation processing. Doing them dynamically involves a virtual function call. This will add a little overhead. I haven't benchmarked it yet, but my gut feeling is: measurable but acceptable (the amount of code going through this backend won't be gigabytes).

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


More information about the llvm-commits mailing list