[llvm] [X86] Reimplement bundle alignment mode (PR #175830)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 7 17:31:39 PST 2026


================
@@ -850,7 +912,138 @@ bool X86AsmBackend::padInstructionEncoding(MCFragment &RF,
   return Changed;
 }
 
+// Peephole is a list of Fragments that ends with non-zero-sized
+// BoundaryAlignFragment. Most of the time it will be every instruction within a
+// bundle, but there can be a partial bundle if it has nops in the middle(e.g.,
+// align_to_end).
+bool X86AsmBackend::dividePadInBundle(const MCAssembler &Asm,
+                                      ArrayRef<MCFragment *> Peephole) const {
+  bool Changed = false;
+
+  // Last Fragment is either FT_Align or FT_BoundaryAlign
+  auto *LastF = Peephole.back();
+  unsigned RemainingSize =
+      Asm.computeFragmentSize(*LastF) - LastF->getFixedSize();
+
+  unsigned StartOffset = Asm.getFragmentOffset(*LastF);
+  unsigned EndOffset = StartOffset + RemainingSize;
+  auto BoundaryAlignment = Align(Asm.getBundleAlignSize());
+  bool CrossBoundary = (StartOffset >> Log2(BoundaryAlignment)) !=
+                       ((EndOffset - 1) >> Log2(BoundaryAlignment));
+
+  if (CrossBoundary) {
+    // i.e., this pad is a mix of suffix fragment of one bundle + prefix of the
+    // very next bundle. It prevents overflow of the first bundle when Peephole
+    // contains more than one bundle.
+    //
+    // This design limits the possibly further-optimized code, which might be
+    // achieved by migrating some instructions to the next bundle, but doing
+    // such may cause fixup errors because instructions can shift by more than
+    // a bundle-size and labels may become unreachable. Until we come up with a
+    // better logic, we limits the optimization scope to a single bundle.
+    RemainingSize -= EndOffset % Asm.getBundleAlignSize();
+  }
+  assert(RemainingSize > 0);
+
+  SmallVector<MCFragment *, 4> Relaxable;
+  for (auto *FIB : Peephole) {
+    if (FIB->getKind() == MCFragment::FT_Data) // Skip and ignore
+      continue;
+
+    if (FIB->getKind() == MCFragment::FT_Align) {
+      // p2align within a bundle
+      Relaxable.clear();
+      continue;
+    }
+
+    if (FIB->getKind() == MCFragment::FT_Relaxable) {
+      auto &RF = cast<MCFragment>(*FIB);
+      Relaxable.push_back(&RF);
+      continue;
+    }
+  }
+
+  while (!Relaxable.empty() && RemainingSize != 0) {
+    auto &RF = *Relaxable.pop_back_val();
+    Changed |= padInstructionEncoding(RF, Asm.getEmitter(), RemainingSize);
+
+    if (mayNeedRelaxation(RF.getOpcode(), RF.getOperands(),
+                          *RF.getSubtargetInfo()))
+      break;
+  }
+  Relaxable.clear();
+
+  if (!CrossBoundary && RemainingSize > 0) {
+    if (EndOffset % Asm.getBundleAlignSize() != 0) {
+      // there are following instructions inside the bundle
+      auto *BF = cast<MCBoundaryAlignFragment>(LastF);
+      for (auto *F = BF->getNext();; F = F->getNext()) {
+        if (F->getKind() == MCFragment::FT_Relaxable) {
+          Changed |=
+              padInstructionEncoding(*F, Asm.getEmitter(), RemainingSize);
+        }
+        if (F == BF->getLastFragment() || RemainingSize == 0)
+          break;
+      }
+    }
+  } else if (CrossBoundary && (EndOffset % Asm.getBundleAlignSize()) > 0) {
+    // there are following instructions on the next bundle.
+    unsigned NextRemainingSize = EndOffset % Asm.getBundleAlignSize();
+    auto *BF = cast<MCBoundaryAlignFragment>(LastF);
+    for (auto *F = BF->getNext();; F = F->getNext()) {
+      if (F->getKind() == MCFragment::FT_Relaxable) {
+        Changed |=
+            padInstructionEncoding(*F, Asm.getEmitter(), NextRemainingSize);
+      }
+      if (F == BF->getLastFragment() || NextRemainingSize == 0)
+        break;
+    }
+
+    RemainingSize += NextRemainingSize;
+  }
+
+  // FT_Align sizes will be recalculated by layoutSection(),
+  // FT_BoundaryAlign sizes are adjusted here.
+  if (auto *BF = dyn_cast<MCBoundaryAlignFragment>(LastF)) {
+    BF->setSize(RemainingSize);
----------------
MaskRay wrote:

remove braces for single-line simple body. ditto below

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


More information about the llvm-commits mailing list