[llvm] Move SI Lower Control Flow Up (PR #159557)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 29 10:41:29 PDT 2025
================
@@ -0,0 +1,249 @@
+#pragma once
+
+#include "GCNSubtarget.h"
+#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Support/ErrorHandling.h"
+
+#include "SIInstrInfo.h"
+
+#include <cassert>
+#include <unordered_set>
+
+using namespace llvm;
+
+using std::unordered_set;
+using std::vector;
+
+static inline MachineInstr &get_branch_with_dest(MachineBasicBlock &branching_MBB,
+ MachineBasicBlock &dest_MBB) {
+ auto& TII = *branching_MBB.getParent()->getSubtarget<GCNSubtarget>().getInstrInfo();
+ for (MachineInstr &branch_MI : reverse(branching_MBB.instrs()))
+ if (branch_MI.isBranch() && TII.getBranchDestBlock(branch_MI) == &dest_MBB)
+ return branch_MI;
+
+ llvm_unreachable("Don't call this if there's no branch to the destination.");
+}
+
+static inline void move_ins_before_phis(MachineInstr &MI) {
+ MachineBasicBlock& MBB = *MI.getParent();
+ MachineFunction& MF = *MBB.getParent();
+ auto &TII = *MF.getSubtarget<GCNSubtarget>().getInstrInfo();
+ auto& MRI = MF.getRegInfo();
+
+ bool phi_seen = false;
+ MachineBasicBlock::iterator first_phi;
+ for (first_phi = MBB.begin(); first_phi != MBB.end(); first_phi++)
+ if (first_phi->getOpcode() == AMDGPU::PHI) {
+ phi_seen = true;
+ break;
+ }
+
+ if (!phi_seen) {
+ MI.removeFromParent();
+ MBB.insert(MBB.begin(), &MI);
+ } else {
+ auto phi = BuildMI(MBB, first_phi, MI.getDebugLoc(), TII.get(AMDGPU::PHI),
+ MI.getOperand(0).getReg());
+ for (auto *pred_MBB : MBB.predecessors()) {
+ Register cloned_reg = MRI.cloneVirtualRegister(MI.getOperand(0).getReg());
+ MachineInstr& branch_MI = get_branch_with_dest(*pred_MBB,MBB);
+ MachineInstr *cloned_MI = MF.CloneMachineInstr(&MI);
+ cloned_MI->getOperand(0).setReg(cloned_reg);
+ phi.addReg(cloned_reg).addMBB(pred_MBB);
+ pred_MBB->insertAfterBundle(branch_MI.getIterator(), cloned_MI);
+ cloned_MI->bundleWithPred();
+ }
+ MI.eraseFromParent();
+ }
+}
+
+struct Epilog_Iterator {
+ MachineBasicBlock::instr_iterator internal_it;
+ Epilog_Iterator(MachineBasicBlock::instr_iterator i) : internal_it(i) {}
+
+ bool operator==(const Epilog_Iterator &other) {
+ return internal_it == other.internal_it;
+ }
+ bool isEnd() { return internal_it.isEnd(); }
+ MachineInstr &operator*() { return *internal_it; }
+ MachineBasicBlock::instr_iterator operator->() { return internal_it; }
+ Epilog_Iterator &operator++() {
+ ++internal_it;
+ if (!internal_it.isEnd() && internal_it->isBranch())
+ internal_it = internal_it->getParent()->instr_end();
+ return *this;
+ }
+ Epilog_Iterator operator++(int ignored) {
+ Epilog_Iterator to_return = *this;
+ ++*this;
+ return to_return;
+ }
+
+};
+
+static inline Epilog_Iterator
+get_epilog_for_successor(MachineBasicBlock& pred_MBB, MachineBasicBlock& succ_MBB) {
+ MachineFunction& MF = *pred_MBB.getParent();
+ auto& TII = *MF.getSubtarget<GCNSubtarget>().getInstrInfo();
+
+ for (MachineInstr &branch_MI : reverse(pred_MBB.instrs()))
+ if (branch_MI.isBranch() && TII.getBranchDestBlock(branch_MI) == &succ_MBB)
+ return ++Epilog_Iterator(branch_MI.getIterator());
+
+ llvm_unreachable("There should always be a branch to succ_MBB.");
----------------
alex-t wrote:
The fall-throughs are not prohibited and I have seen enough valid MIR in SSA with fall-through CF.
https://github.com/llvm/llvm-project/pull/159557
More information about the llvm-commits
mailing list