mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Add NoMerge MIFlag to avoid MIR branch folding
Let the codegen recognized the nomerge attribute and disable branch folding when the attribute is given Differential Revision: https://reviews.llvm.org/D79537
This commit is contained in:
parent
bbfe17114c
commit
25d7f2f024
@ -105,6 +105,9 @@ public:
|
||||
// known to be exact.
|
||||
NoFPExcept = 1 << 14, // Instruction does not raise
|
||||
// floatint-point exceptions.
|
||||
NoMerge = 1 << 15, // Passes that drop source location info
|
||||
// (e.g. branch folding) should skip
|
||||
// this instruction.
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -278,6 +278,7 @@ class SelectionDAG {
|
||||
struct CallSiteDbgInfo {
|
||||
CallSiteInfo CSInfo;
|
||||
MDNode *HeapAllocSite = nullptr;
|
||||
bool NoMerge = false;
|
||||
};
|
||||
|
||||
DenseMap<const SDNode *, CallSiteDbgInfo> SDCallSiteDbgInfo;
|
||||
@ -1916,6 +1917,18 @@ public:
|
||||
return It->second.HeapAllocSite;
|
||||
}
|
||||
|
||||
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge) {
|
||||
if (NoMerge)
|
||||
SDCallSiteDbgInfo[Node].NoMerge = NoMerge;
|
||||
}
|
||||
|
||||
bool getNoMergeSiteInfo(const SDNode *Node) {
|
||||
auto I = SDCallSiteDbgInfo.find(Node);
|
||||
if (I == SDCallSiteDbgInfo.end())
|
||||
return false;
|
||||
return I->second.NoMerge;
|
||||
}
|
||||
|
||||
/// Return the current function's default denormal handling kind for the given
|
||||
/// floating point type.
|
||||
DenormalMode getDenormalMode(EVT VT) const {
|
||||
|
@ -3613,6 +3613,7 @@ public:
|
||||
bool IsConvergent : 1;
|
||||
bool IsPatchPoint : 1;
|
||||
bool IsPreallocated : 1;
|
||||
bool NoMerge : 1;
|
||||
|
||||
// IsTailCall should be modified by implementations of
|
||||
// TargetLowering::LowerCall that perform tail call conversions.
|
||||
@ -3636,7 +3637,8 @@ public:
|
||||
CallLoweringInfo(SelectionDAG &DAG)
|
||||
: RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false),
|
||||
DoesNotReturn(false), IsReturnValueUsed(true), IsConvergent(false),
|
||||
IsPatchPoint(false), IsPreallocated(false), DAG(DAG) {}
|
||||
IsPatchPoint(false), IsPreallocated(false), NoMerge(false),
|
||||
DAG(DAG) {}
|
||||
|
||||
CallLoweringInfo &setDebugLoc(const SDLoc &dl) {
|
||||
DL = dl;
|
||||
@ -3685,7 +3687,8 @@ public:
|
||||
IsReturnValueUsed = !Call.use_empty();
|
||||
RetSExt = Call.hasRetAttr(Attribute::SExt);
|
||||
RetZExt = Call.hasRetAttr(Attribute::ZExt);
|
||||
|
||||
NoMerge = Call.hasFnAttr(Attribute::NoMerge);
|
||||
|
||||
Callee = Target;
|
||||
|
||||
CallConv = Call.getCallingConv();
|
||||
|
@ -348,6 +348,9 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
|
||||
MBBI1->isInlineAsm()) {
|
||||
break;
|
||||
}
|
||||
if (MBBI1->getFlag(MachineInstr::NoMerge) ||
|
||||
MBBI2->getFlag(MachineInstr::NoMerge))
|
||||
break;
|
||||
++TailLen;
|
||||
I1 = MBBI1;
|
||||
I2 = MBBI2;
|
||||
|
@ -778,6 +778,8 @@ void MIPrinter::print(const MachineInstr &MI) {
|
||||
OS << "exact ";
|
||||
if (MI.getFlag(MachineInstr::NoFPExcept))
|
||||
OS << "nofpexcept ";
|
||||
if (MI.getFlag(MachineInstr::NoMerge))
|
||||
OS << "nomerge ";
|
||||
|
||||
OS << TII->getName(MI.getOpcode());
|
||||
if (I < E)
|
||||
|
@ -1595,6 +1595,8 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
|
||||
OS << "exact ";
|
||||
if (getFlag(MachineInstr::NoFPExcept))
|
||||
OS << "nofpexcept ";
|
||||
if (getFlag(MachineInstr::NoMerge))
|
||||
OS << "nomerge ";
|
||||
|
||||
// Print the opcode name.
|
||||
if (TII)
|
||||
|
@ -872,6 +872,10 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
|
||||
DAG->getTarget().Options.EmitCallSiteInfo)
|
||||
MF.addCallArgsForwardingRegs(MI, DAG->getSDCallSiteInfo(Node));
|
||||
|
||||
if (DAG->getNoMergeSiteInfo(Node)) {
|
||||
MI->setFlag(MachineInstr::MIFlag::NoMerge);
|
||||
}
|
||||
|
||||
return MI;
|
||||
};
|
||||
|
||||
|
@ -4541,6 +4541,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
|
||||
|
||||
// Returns a chain and a flag for retval copy to use.
|
||||
Chain = DAG.getNode(AArch64ISD::CALL, DL, NodeTys, Ops);
|
||||
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
|
||||
InFlag = Chain.getValue(1);
|
||||
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
|
||||
|
||||
|
@ -2542,6 +2542,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
|
||||
// Returns a chain and a flag for retval copy to use.
|
||||
Chain = DAG.getNode(CallOpc, dl, NodeTys, Ops);
|
||||
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
|
||||
InFlag = Chain.getValue(1);
|
||||
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
|
||||
|
||||
|
@ -5586,6 +5586,7 @@ SDValue PPCTargetLowering::FinishCall(
|
||||
|
||||
std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
|
||||
Chain = DAG.getNode(CallOpc, dl, ReturnTypes, Ops);
|
||||
DAG.addNoMergeSiteInfo(Chain.getNode(), CFlags.NoMerge);
|
||||
Glue = Chain.getValue(1);
|
||||
|
||||
// When performing tail call optimization the callee pops its arguments off
|
||||
@ -5667,7 +5668,8 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
isIndirectCall(Callee, DAG, Subtarget, isPatchPoint),
|
||||
// hasNest
|
||||
Subtarget.is64BitELFABI() &&
|
||||
any_of(Outs, [](ISD::OutputArg Arg) { return Arg.Flags.isNest(); }));
|
||||
any_of(Outs, [](ISD::OutputArg Arg) { return Arg.Flags.isNest(); }),
|
||||
CLI.NoMerge);
|
||||
|
||||
if (Subtarget.isSVR4ABI() && Subtarget.isPPC64())
|
||||
return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
|
||||
|
@ -979,12 +979,13 @@ namespace llvm {
|
||||
const bool IsPatchPoint : 1;
|
||||
const bool IsIndirect : 1;
|
||||
const bool HasNest : 1;
|
||||
const bool NoMerge : 1;
|
||||
|
||||
CallFlags(CallingConv::ID CC, bool IsTailCall, bool IsVarArg,
|
||||
bool IsPatchPoint, bool IsIndirect, bool HasNest)
|
||||
bool IsPatchPoint, bool IsIndirect, bool HasNest, bool NoMerge)
|
||||
: CallConv(CC), IsTailCall(IsTailCall), IsVarArg(IsVarArg),
|
||||
IsPatchPoint(IsPatchPoint), IsIndirect(IsIndirect),
|
||||
HasNest(HasNest) {}
|
||||
HasNest(HasNest), NoMerge(NoMerge) {}
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -2353,6 +2353,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
|
||||
}
|
||||
|
||||
Chain = DAG.getNode(RISCVISD::CALL, DL, NodeTys, Ops);
|
||||
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
|
||||
Glue = Chain.getValue(1);
|
||||
|
||||
// Mark the end of the call, which is glued to the call itself.
|
||||
|
@ -4336,6 +4336,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops);
|
||||
}
|
||||
InFlag = Chain.getValue(1);
|
||||
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
|
||||
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
|
||||
|
||||
// Save heapallocsite metadata.
|
||||
|
36
test/CodeGen/AArch64/nomerge.ll
Normal file
36
test/CodeGen/AArch64/nomerge.ll
Normal file
@ -0,0 +1,36 @@
|
||||
; RUN: llc < %s -mtriple=aarch64 -o - | FileCheck %s
|
||||
|
||||
define void @foo(i32 %i) {
|
||||
entry:
|
||||
switch i32 %i, label %if.end3 [
|
||||
i32 5, label %if.then
|
||||
i32 7, label %if.then2
|
||||
]
|
||||
|
||||
if.then:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.then2:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.end3:
|
||||
tail call void @bar() #0
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
attributes #0 = { nomerge }
|
||||
|
||||
; CHECK-LABEL: foo:
|
||||
; CHECK: // %bb.0: // %entry
|
||||
; CHECK: // %bb.1: // %entry
|
||||
; CHECK: // %bb.2: // %if.then
|
||||
; CHECK-NEXT: bl bar
|
||||
; CHECK: b bar
|
||||
; CHECK: .LBB0_3: // %if.then2
|
||||
; CHECK-NEXT: bl bar
|
||||
; CHECK: .LBB0_4: // %if.end3
|
||||
; CHECK: b bar
|
36
test/CodeGen/ARM/nomerge.ll
Normal file
36
test/CodeGen/ARM/nomerge.ll
Normal file
@ -0,0 +1,36 @@
|
||||
; RUN: llc < %s -mtriple=arm -o - | FileCheck %s
|
||||
|
||||
define void @foo(i32 %i) {
|
||||
entry:
|
||||
switch i32 %i, label %if.end3 [
|
||||
i32 5, label %if.then
|
||||
i32 7, label %if.then2
|
||||
]
|
||||
|
||||
if.then:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.then2:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.end3:
|
||||
tail call void @bar() #0
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
attributes #0 = { nomerge }
|
||||
|
||||
; CHECK-LABEL: foo:
|
||||
; CHECK: @ %bb.0: @ %entry
|
||||
; CHECK: @ %bb.1: @ %entry
|
||||
; CHECK: @ %bb.2: @ %if.then
|
||||
; CHECK-NEXT: bl bar
|
||||
; CHECK: b bar
|
||||
; CHECK: .LBB0_3: @ %if.then2
|
||||
; CHECK-NEXT: bl bar
|
||||
; CHECK: .LBB0_4: @ %if.end3
|
||||
; CHECK: b bar
|
35
test/CodeGen/PowerPC/nomerge.ll
Normal file
35
test/CodeGen/PowerPC/nomerge.ll
Normal file
@ -0,0 +1,35 @@
|
||||
; RUN: llc < %s -mtriple=powerpc -o - | FileCheck %s
|
||||
|
||||
define void @foo(i32 %i) {
|
||||
entry:
|
||||
switch i32 %i, label %if.end3 [
|
||||
i32 5, label %if.then
|
||||
i32 7, label %if.then2
|
||||
]
|
||||
|
||||
if.then:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.then2:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.end3:
|
||||
tail call void @bar() #0
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
attributes #0 = { nomerge }
|
||||
|
||||
; CHECK-LABEL: foo:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK: # %bb.1: # %entry
|
||||
; CHECK: # %bb.2: # %if.then
|
||||
; CHECK-NEXT: bl bar
|
||||
; CHECK: .LBB0_3: # %if.then2
|
||||
; CHECK-NEXT: bl bar
|
||||
; CHECK: .LBB0_4: # %if.end3
|
||||
; CHECK-NEXT: bl bar
|
35
test/CodeGen/RISCV/nomerge.ll
Normal file
35
test/CodeGen/RISCV/nomerge.ll
Normal file
@ -0,0 +1,35 @@
|
||||
; RUN: llc < %s -mtriple=riscv64 -o - | FileCheck %s
|
||||
|
||||
define void @foo(i32 %i) {
|
||||
entry:
|
||||
switch i32 %i, label %if.end3 [
|
||||
i32 5, label %if.then
|
||||
i32 7, label %if.then2
|
||||
]
|
||||
|
||||
if.then:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.then2:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.end3:
|
||||
tail call void @bar() #0
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
attributes #0 = { nomerge }
|
||||
|
||||
; CHECK-LABEL: foo:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK: # %bb.1: # %entry
|
||||
; CHECK: # %bb.2: # %if.then
|
||||
; CHECK-NEXT: call bar
|
||||
; CHECK: .LBB0_3: # %if.then2
|
||||
; CHECK-NEXT: call bar
|
||||
; CHECK: .LBB0_4: # %if.end3
|
||||
; CHECK: tail bar
|
36
test/CodeGen/X86/nomerge.ll
Normal file
36
test/CodeGen/X86/nomerge.ll
Normal file
@ -0,0 +1,36 @@
|
||||
; RUN: llc < %s -mtriple=x86_64 -o - | FileCheck %s
|
||||
|
||||
define void @foo(i32 %i) {
|
||||
entry:
|
||||
switch i32 %i, label %if.end3 [
|
||||
i32 5, label %if.then
|
||||
i32 7, label %if.then2
|
||||
]
|
||||
|
||||
if.then:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.then2:
|
||||
tail call void @bar() #0
|
||||
br label %if.end3
|
||||
|
||||
if.end3:
|
||||
tail call void @bar() #0
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
attributes #0 = { nomerge }
|
||||
|
||||
; CHECK-LABEL: foo:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK: # %bb.1: # %entry
|
||||
; CHECK: # %bb.2: # %if.then
|
||||
; CHECK-NEXT: callq bar
|
||||
; CHECK: jmp bar # TAILCALL
|
||||
; CHECK: .LBB0_3: # %if.then2
|
||||
; CHECK: callq bar
|
||||
; CHECK: .LBB0_4: # %if.end3
|
||||
; CHECK: jmp bar # TAILCALL
|
Loading…
x
Reference in New Issue
Block a user