[llvm] [SFrames] Emit and relax FREs (PR #158154)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 12 11:56:08 PDT 2025


================
@@ -33,10 +34,86 @@ struct SFrameFRE {
   size_t CFAOffset = 0;
   size_t FPOffset = 0;
   size_t RAOffset = 0;
-  bool FromFP = false;
+  FREInfo<endianness::native> Info;
   bool CFARegSet = false;
 
   SFrameFRE(const MCSymbol *Start) : Label(Start) {}
+
+  void emit(MCObjectStreamer &S, const MCSymbol *FuncBegin,
+            MCFragment *FDEFrag) {
+    S.emitSFrameCalculateFuncOffset(FuncBegin, Label, FDEFrag, SMLoc());
+
+    // fre_cfa_base_reg_id already set during parsing
+
+    // fre_offset_count
+    unsigned RegsTracked = 1; // always track the cfa.
+    if (FPOffset != 0)
+      RegsTracked++;
+    if (RAOffset != 0)
+      RegsTracked++;
+    Info.setOffsetCount(RegsTracked);
+
+    // fre_offset_size
+    if (isInt<8>(CFAOffset) && isInt<8>(FPOffset) && isInt<8>(RAOffset))
+      Info.setOffsetSize(FREOffset::B1);
+    else if (isInt<16>(CFAOffset) && isInt<16>(FPOffset) && isInt<16>(RAOffset))
+      Info.setOffsetSize(FREOffset::B2);
+    else {
+      assert(isInt<32>(CFAOffset) && isInt<32>(FPOffset) &&
+             isInt<32>(RAOffset) && "Offset too big for sframe");
+      Info.setOffsetSize(FREOffset::B4);
+    }
+
+    // No support for fre_mangled_ra_p yet.
+    Info.setReturnAddressSigned(false);
+
+    // sframe_fre_info_word
+    S.emitInt8(Info.getFREInfo());
+
+    // FRE Offsets
+    [[maybe_unused]] unsigned OffsetsEmitted = 1;
+    switch (Info.getOffsetSize()) {
+    case (FREOffset::B1):
+      S.emitInt8(CFAOffset);
+      break;
+    case (FREOffset::B2):
+      S.emitInt16(CFAOffset);
+      break;
+    case (FREOffset::B4):
+      S.emitInt32(CFAOffset);
+      break;
+    }
+    if (FPOffset) {
+      OffsetsEmitted++;
+      switch (Info.getOffsetSize()) {
+      case (FREOffset::B1):
+        S.emitInt8(FPOffset);
+        break;
+      case (FREOffset::B2):
+        S.emitInt16(FPOffset);
+        break;
+      case (FREOffset::B4):
+        S.emitInt32(FPOffset);
+        break;
+      }
+    }
+    if (RAOffset) {
+      OffsetsEmitted++;
+      switch (Info.getOffsetSize()) {
+      case (FREOffset::B1):
+        S.emitInt8(RAOffset);
+        break;
+      case (FREOffset::B2):
+        S.emitInt16(RAOffset);
+        break;
+      case (FREOffset::B4):
+        S.emitInt32(RAOffset);
+        break;
+      }
+    }
----------------
weiguozhi wrote:

Could you outline them into an inline function?

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


More information about the llvm-commits mailing list