Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions llvm/include/llvm/CodeGen/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,17 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
return true;
}

/// Return true if it's safe to move a machine instruction.
/// This allows the backend to prevent certain special instruction
/// sequences from being broken by instruction motion in optimization
/// passes.
/// By default, this returns true for every instruction.
virtual bool isSafeToMove(const MachineInstr &MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const {
return true;
}

/// Test if the given instruction should be considered a scheduling boundary.
/// This primarily includes labels and terminators.
virtual bool isSchedulingBoundary(const MachineInstr &MI,
Expand Down
9 changes: 7 additions & 2 deletions llvm/lib/CodeGen/BranchFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1818,7 +1818,7 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
bool BranchFolder::HoistCommonCode(MachineFunction &MF) {
bool MadeChange = false;
for (MachineBasicBlock &MBB : llvm::make_early_inc_range(MF))
MadeChange |= HoistCommonCodeInSuccs(&MBB);
MadeChange |= HoistCommonCodeInSuccs(&MBB, MF);

return MadeChange;
}
Expand Down Expand Up @@ -1948,7 +1948,8 @@ MachineBasicBlock::iterator findHoistingInsertPosAndDeps(MachineBasicBlock *MBB,
return PI;
}

bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {
bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB,
MachineFunction &MF) {
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
SmallVector<MachineOperand, 4> Cond;
if (TII->analyzeBranch(*MBB, TBB, FBB, Cond, true) || !TBB || Cond.empty())
Expand Down Expand Up @@ -1993,6 +1994,10 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {
// Hard to reason about register liveness with predicated instruction.
break;

if (!TII->isSafeToMove(*TIB, MBB, MF))
// Don't hoist the instruction if it isn't safe to move.
break;

bool IsSafe = true;
for (MachineOperand &MO : TIB->operands()) {
// Don't attempt to hoist instructions with register masks.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/BranchFolding.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class TargetRegisterInfo;

/// If the successors of MBB has common instruction sequence at the start of
/// the function, move the instructions before MBB terminator if it's legal.
bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB);
bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB, MachineFunction &MF);
};

} // end namespace llvm
Expand Down
45 changes: 27 additions & 18 deletions llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,12 +378,9 @@ bool LoongArchInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
}
}

bool LoongArchInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const {
if (TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF))
return true;

bool LoongArchInstrInfo::isSafeToMove(const MachineInstr &MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const {
auto MII = MI.getIterator();
auto MIE = MBB->end();

Expand Down Expand Up @@ -429,25 +426,25 @@ bool LoongArchInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
auto MO2 = Lu32I->getOperand(2).getTargetFlags();
if (MO0 == LoongArchII::MO_PCREL_HI && MO1 == LoongArchII::MO_PCREL_LO &&
MO2 == LoongArchII::MO_PCREL64_LO)
return true;
return false;
if ((MO0 == LoongArchII::MO_GOT_PC_HI || MO0 == LoongArchII::MO_LD_PC_HI ||
MO0 == LoongArchII::MO_GD_PC_HI) &&
MO1 == LoongArchII::MO_GOT_PC_LO && MO2 == LoongArchII::MO_GOT_PC64_LO)
return true;
return false;
if (MO0 == LoongArchII::MO_IE_PC_HI && MO1 == LoongArchII::MO_IE_PC_LO &&
MO2 == LoongArchII::MO_IE_PC64_LO)
return true;
return false;
if (MO0 == LoongArchII::MO_DESC_PC_HI &&
MO1 == LoongArchII::MO_DESC_PC_LO &&
MO2 == LoongArchII::MO_DESC64_PC_LO)
return true;
return false;
break;
}
case LoongArch::LU52I_D: {
auto MO = MI.getOperand(2).getTargetFlags();
if (MO == LoongArchII::MO_PCREL64_HI || MO == LoongArchII::MO_GOT_PC64_HI ||
MO == LoongArchII::MO_IE_PC64_HI || MO == LoongArchII::MO_DESC64_PC_HI)
return true;
return false;
break;
}
default:
Expand Down Expand Up @@ -487,7 +484,7 @@ bool LoongArchInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
auto MO1 = LoongArchII::getDirectFlags(SecondOp->getOperand(2));
auto MO2 = LoongArchII::getDirectFlags(Ld->getOperand(2));
if (MO1 == LoongArchII::MO_DESC_PC_LO && MO2 == LoongArchII::MO_DESC_LD)
return true;
return false;
break;
}
if (SecondOp == MIE ||
Expand All @@ -496,41 +493,53 @@ bool LoongArchInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
auto MO1 = LoongArchII::getDirectFlags(SecondOp->getOperand(2));
if (MO0 == LoongArchII::MO_PCREL_HI && SecondOp->getOpcode() == AddiOp &&
MO1 == LoongArchII::MO_PCREL_LO)
return true;
return false;
if (MO0 == LoongArchII::MO_GOT_PC_HI && SecondOp->getOpcode() == LdOp &&
MO1 == LoongArchII::MO_GOT_PC_LO)
return true;
return false;
if ((MO0 == LoongArchII::MO_LD_PC_HI ||
MO0 == LoongArchII::MO_GD_PC_HI) &&
SecondOp->getOpcode() == AddiOp && MO1 == LoongArchII::MO_GOT_PC_LO)
return true;
return false;
break;
}
case LoongArch::ADDI_W:
case LoongArch::ADDI_D: {
auto MO = LoongArchII::getDirectFlags(MI.getOperand(2));
if (MO == LoongArchII::MO_PCREL_LO || MO == LoongArchII::MO_GOT_PC_LO)
return true;
return false;
break;
}
case LoongArch::LD_W:
case LoongArch::LD_D: {
auto MO = LoongArchII::getDirectFlags(MI.getOperand(2));
if (MO == LoongArchII::MO_GOT_PC_LO)
return true;
return false;
break;
}
case LoongArch::PseudoDESC_CALL: {
auto MO = LoongArchII::getDirectFlags(MI.getOperand(2));
if (MO == LoongArchII::MO_DESC_CALL)
return true;
return false;
break;
}
default:
break;
}
}

return true;
}

bool LoongArchInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const {
if (TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF))
return true;

if (!isSafeToMove(MI, MBB, MF))
return true;

return false;
}

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class LoongArchInstrInfo : public LoongArchGenInstrInfo {
bool isBranchOffsetInRange(unsigned BranchOpc,
int64_t BrOffset) const override;

bool isSafeToMove(const MachineInstr &MI, const MachineBasicBlock *MBB,
const MachineFunction &MF) const override;

bool isSchedulingBoundary(const MachineInstr &MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const override;
Expand Down