[llvm-branch-commits] [llvm] [AMDGPU] Add machine-level inliner pass (PR #169476)

Diana Picus via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jan 9 04:27:11 PST 2026


================
@@ -121,7 +121,170 @@ bool AMDGPUMachineLevelInliner::runOnMachineFunction(MachineFunction &MF) {
     return false;
   }
 
-  return false;
+  bool Changed = false;
+
+  // Can't inline anything if there aren't any calls.
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  if (!MFI.hasCalls() && !MFI.hasTailCall())
+    return false;
+
+  // Collect calls to inline.
+  SmallVector<MachineInstr *, 4> CallsToInline;
+  const SIInstrInfo *TII = MF.getSubtarget<GCNSubtarget>().getInstrInfo();
+
+  for (auto &MBB : MF) {
+    for (auto &MI : MBB) {
+      if (!MI.isCall())
+        continue;
+
+      const MachineOperand *CalleeOp =
+          TII->getNamedOperand(MI, AMDGPU::OpName::callee);
+      if (CalleeOp && CalleeOp->isGlobal()) {
+        if (auto *CalledFunc = dyn_cast<Function>(CalleeOp->getGlobal())) {
+          // Partial inlining is not supported yet, because the inlining pass
+          // manager does not run the rest of the pass pipeline on functions
+          // that get inlined (including outputting code for them).
+          if (CalledFunc == &F)
+            report_fatal_error("Recursive calls in whole wave functions are "
+                               "not supported yet");
+
+          if (shouldInlineCallsTo(*CalledFunc)) {
+            CallsToInline.push_back(&MI);
+          }
+        }
+      }
+    }
+  }
+
+  // Perform the actual inlining.
+  for (MachineInstr *CallMI : CallsToInline) {
+    const MachineOperand *CalleeOp =
+        TII->getNamedOperand(*CallMI, AMDGPU::OpName::callee);
+    assert(CalleeOp && CalleeOp->isGlobal() &&
+           isa<Function>(CalleeOp->getGlobal()));
+    auto *Callee = cast<Function>(CalleeOp->getGlobal());
+
+    MachineFunction *CalleeMF = MMI.getMachineFunction(*Callee);
+    assert(CalleeMF && "Couldn't get MachineFunction for callee");
+    assert(!CalleeMF->empty() && "Machine function body is empty");
+
+    LLVM_DEBUG(dbgs() << "    Inlining machine call to: " << Callee->getName()
+                      << " (" << CalleeMF->size() << " basic blocks)\n");
+
+    inlineMachineFunction(&MF, CallMI, CalleeMF, TII);
+    cleanupAfterInlining(&MF, CallMI, TII);
+    Changed = true;
+  }
+
+  return Changed;
+}
+
+void AMDGPUMachineLevelInliner::inlineMachineFunction(MachineFunction *CallerMF,
+                                                      MachineInstr *CallMI,
+                                                      MachineFunction *CalleeMF,
+                                                      const SIInstrInfo *TII) {
+
+  MachineBasicBlock *CallMBB = CallMI->getParent();
+  MachineBasicBlock *ContinuationMBB =
+      CallMBB->splitAt(*CallMI, /*UpdateLiveIns=*/true);
+
+  // Splitting marks the ContinuationMBB as a successor, but we want to
+  // fallthrough to the body of the inlined function instead.
+  CallMBB->removeSuccessor(ContinuationMBB);
+
+  // First we clone all the blocks and build a map, so we can patch up the
+  // control flow while cloning their content in a second pass.
+  DenseMap<const MachineBasicBlock *, MachineBasicBlock *> ClonedBlocks;
+  for (const MachineBasicBlock &OrigMBB : *CalleeMF) {
+    MachineBasicBlock *ClonedMBB =
+        CallerMF->CreateMachineBasicBlock(OrigMBB.getBasicBlock());
+    CallerMF->insert(ContinuationMBB->getIterator(), ClonedMBB);
+    ClonedBlocks[&OrigMBB] = ClonedMBB;
+  }
+
+  MachineBasicBlock *ClonedEntry = ClonedBlocks[&CalleeMF->front()];
+  CallMBB->addSuccessor(ClonedEntry);
+
+  for (const MachineBasicBlock &OrigMBB : *CalleeMF) {
+    MachineBasicBlock *ClonedMBB = ClonedBlocks[&OrigMBB];
+
+    for (MachineBasicBlock *OrigSucc : OrigMBB.successors())
+      ClonedMBB->addSuccessor(ClonedBlocks[OrigSucc]);
+
+    for (auto &LiveIn : OrigMBB.liveins())
+      ClonedMBB->addLiveIn(LiveIn);
----------------
rovka wrote:

Fixed, thanks!

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


More information about the llvm-branch-commits mailing list