mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
fix to outline cfi instruction when can be grouped in a tail call
[MachineOutliner] fix test for excluding CFI and add test to include CFI in outlining New test to check that we only outline CFI instruction if all CFI Instructions in the function would be captured by the outlining adding x86 tests analagous to AARCH64 cfi tests Revision: https://reviews.llvm.org/D77852
This commit is contained in:
parent
a4ccc4b743
commit
c5eb58bb14
@ -1160,9 +1160,17 @@ MachineFunction *MachineOutliner::createOutlinedFunction(
|
|||||||
// Insert the new function into the module.
|
// Insert the new function into the module.
|
||||||
MF.insert(MF.begin(), &MBB);
|
MF.insert(MF.begin(), &MBB);
|
||||||
|
|
||||||
|
MachineFunction *OriginalMF = FirstCand.front()->getMF();
|
||||||
|
const std::vector<MCCFIInstruction> &Instrs =
|
||||||
|
OriginalMF->getFrameInstructions();
|
||||||
for (auto I = FirstCand.front(), E = std::next(FirstCand.back()); I != E;
|
for (auto I = FirstCand.front(), E = std::next(FirstCand.back()); I != E;
|
||||||
++I) {
|
++I) {
|
||||||
MachineInstr *NewMI = MF.CloneMachineInstr(&*I);
|
MachineInstr *NewMI = MF.CloneMachineInstr(&*I);
|
||||||
|
if (I->isCFIInstruction()) {
|
||||||
|
unsigned CFIIndex = NewMI->getOperand(0).getCFIIndex();
|
||||||
|
MCCFIInstruction CFI = Instrs[CFIIndex];
|
||||||
|
(void)MF.addFrameInst(CFI);
|
||||||
|
}
|
||||||
NewMI->dropMemRefs(MF);
|
NewMI->dropMemRefs(MF);
|
||||||
|
|
||||||
// Don't keep debug information for outlined instructions.
|
// Don't keep debug information for outlined instructions.
|
||||||
@ -1331,7 +1339,6 @@ bool MachineOutliner::outline(Module &M,
|
|||||||
}
|
}
|
||||||
|
|
||||||
LLVM_DEBUG(dbgs() << "OutlinedSomething = " << OutlinedSomething << "\n";);
|
LLVM_DEBUG(dbgs() << "OutlinedSomething = " << OutlinedSomething << "\n";);
|
||||||
|
|
||||||
return OutlinedSomething;
|
return OutlinedSomething;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@
|
|||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||||
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||||
#include "llvm/CodeGen/MachineOperand.h"
|
#include "llvm/CodeGen/MachineOperand.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
|
||||||
#include "llvm/CodeGen/StackMaps.h"
|
#include "llvm/CodeGen/StackMaps.h"
|
||||||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||||
@ -5862,6 +5862,35 @@ outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo(
|
|||||||
return C.getMF()->getFunction().hasFnAttribute("branch-target-enforcement");
|
return C.getMF()->getFunction().hasFnAttribute("branch-target-enforcement");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// We check to see if CFI Instructions are present, and if they are
|
||||||
|
// we find the number of CFI Instructions in the candidates.
|
||||||
|
unsigned CFICount = 0;
|
||||||
|
MachineBasicBlock::iterator MBBI = RepeatedSequenceLocs[0].front();
|
||||||
|
for (unsigned Loc = RepeatedSequenceLocs[0].getStartIdx();
|
||||||
|
Loc < RepeatedSequenceLocs[0].getEndIdx() + 1; Loc++) {
|
||||||
|
const std::vector<MCCFIInstruction> &CFIInstructions =
|
||||||
|
RepeatedSequenceLocs[0].getMF()->getFrameInstructions();
|
||||||
|
if (MBBI->isCFIInstruction()) {
|
||||||
|
unsigned CFIIndex = MBBI->getOperand(0).getCFIIndex();
|
||||||
|
MCCFIInstruction CFI = CFIInstructions[CFIIndex];
|
||||||
|
CFICount++;
|
||||||
|
}
|
||||||
|
MBBI++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We compare the number of found CFI Instructions to the number of CFI
|
||||||
|
// instructions in the parent function for each candidate. We must check this
|
||||||
|
// since if we outline one of the CFI instructions in a function, we have to
|
||||||
|
// outline them all for correctness. If we do not, the address offsets will be
|
||||||
|
// incorrect between the two sections of the program.
|
||||||
|
for (outliner::Candidate &C : RepeatedSequenceLocs) {
|
||||||
|
std::vector<MCCFIInstruction> CFIInstructions =
|
||||||
|
C.getMF()->getFrameInstructions();
|
||||||
|
|
||||||
|
if (CFICount > 0 && CFICount != CFIInstructions.size())
|
||||||
|
return outliner::OutlinedFunction();
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if an instructions is safe to fix up, false otherwise.
|
// Returns true if an instructions is safe to fix up, false otherwise.
|
||||||
auto IsSafeToFixup = [this, &TRI](MachineInstr &MI) {
|
auto IsSafeToFixup = [this, &TRI](MachineInstr &MI) {
|
||||||
if (MI.isCall())
|
if (MI.isCall())
|
||||||
@ -6037,6 +6066,11 @@ outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have CFI instructions, we can only outline if the outlined section
|
||||||
|
// can be a tail call
|
||||||
|
if (FrameID != MachineOutlinerTailCall && CFICount > 0)
|
||||||
|
return outliner::OutlinedFunction();
|
||||||
|
|
||||||
return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize,
|
return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize,
|
||||||
NumBytesToCreateFrame, FrameID);
|
NumBytesToCreateFrame, FrameID);
|
||||||
}
|
}
|
||||||
@ -6159,12 +6193,13 @@ AArch64InstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
|
|||||||
return outliner::InstrType::Illegal;
|
return outliner::InstrType::Illegal;
|
||||||
|
|
||||||
// We can only outline these if we will tail call the outlined function, or
|
// We can only outline these if we will tail call the outlined function, or
|
||||||
// fix up the CFI offsets. For the sake of safety, don't outline CFI
|
// fix up the CFI offsets. Currently, CFI instructions are outlined only if
|
||||||
// instructions.
|
// in a tail call.
|
||||||
//
|
//
|
||||||
// FIXME: If the proper fixups are implemented, this should be possible.
|
// FIXME: If the proper fixups for the offset are implemented, this should be
|
||||||
|
// possible.
|
||||||
if (MI.isCFIInstruction())
|
if (MI.isCFIInstruction())
|
||||||
return outliner::InstrType::Illegal;
|
return outliner::InstrType::Legal;
|
||||||
|
|
||||||
// Don't allow debug values to impact outlining type.
|
// Don't allow debug values to impact outlining type.
|
||||||
if (MI.isDebugInstr() || MI.isIndirectDebugValue())
|
if (MI.isDebugInstr() || MI.isIndirectDebugValue())
|
||||||
|
@ -8682,6 +8682,35 @@ outliner::OutlinedFunction X86InstrInfo::getOutliningCandidateInfo(
|
|||||||
return Sum + 1;
|
return Sum + 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// We check to see if CFI Instructions are present, and if they are
|
||||||
|
// we find the number of CFI Instructions in the candidates.
|
||||||
|
unsigned CFICount = 0;
|
||||||
|
MachineBasicBlock::iterator MBBI = RepeatedSequenceLocs[0].front();
|
||||||
|
for (unsigned Loc = RepeatedSequenceLocs[0].getStartIdx();
|
||||||
|
Loc < RepeatedSequenceLocs[0].getEndIdx() + 1; Loc++) {
|
||||||
|
const std::vector<MCCFIInstruction> &CFIInstructions =
|
||||||
|
RepeatedSequenceLocs[0].getMF()->getFrameInstructions();
|
||||||
|
if (MBBI->isCFIInstruction()) {
|
||||||
|
unsigned CFIIndex = MBBI->getOperand(0).getCFIIndex();
|
||||||
|
MCCFIInstruction CFI = CFIInstructions[CFIIndex];
|
||||||
|
CFICount++;
|
||||||
|
}
|
||||||
|
MBBI++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We compare the number of found CFI Instructions to the number of CFI
|
||||||
|
// instructions in the parent function for each candidate. We must check this
|
||||||
|
// since if we outline one of the CFI instructions in a function, we have to
|
||||||
|
// outline them all for correctness. If we do not, the address offsets will be
|
||||||
|
// incorrect between the two sections of the program.
|
||||||
|
for (outliner::Candidate &C : RepeatedSequenceLocs) {
|
||||||
|
std::vector<MCCFIInstruction> CFIInstructions =
|
||||||
|
C.getMF()->getFrameInstructions();
|
||||||
|
|
||||||
|
if (CFICount > 0 && CFICount != CFIInstructions.size())
|
||||||
|
return outliner::OutlinedFunction();
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Use real size in bytes for call and ret instructions.
|
// FIXME: Use real size in bytes for call and ret instructions.
|
||||||
if (RepeatedSequenceLocs[0].back()->isTerminator()) {
|
if (RepeatedSequenceLocs[0].back()->isTerminator()) {
|
||||||
for (outliner::Candidate &C : RepeatedSequenceLocs)
|
for (outliner::Candidate &C : RepeatedSequenceLocs)
|
||||||
@ -8693,6 +8722,9 @@ outliner::OutlinedFunction X86InstrInfo::getOutliningCandidateInfo(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CFICount > 0)
|
||||||
|
return outliner::OutlinedFunction();
|
||||||
|
|
||||||
for (outliner::Candidate &C : RepeatedSequenceLocs)
|
for (outliner::Candidate &C : RepeatedSequenceLocs)
|
||||||
C.setCallInfo(MachineOutlinerDefault, 1);
|
C.setCallInfo(MachineOutlinerDefault, 1);
|
||||||
|
|
||||||
|
84
test/CodeGen/AArch64/machine-outliner-cfi-tail-some.mir
Normal file
84
test/CodeGen/AArch64/machine-outliner-cfi-tail-some.mir
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||||
|
# RUN: llc -mtriple=aarch64-apple-unknown -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s
|
||||||
|
|
||||||
|
# Outlining CFI instructions is unsafe if we cannot outline all of the CFI
|
||||||
|
# instructions from a function. This shows that we choose not to outline the
|
||||||
|
# CFI instructions since function foo has a CFI Instruction that would not
|
||||||
|
# be caught.
|
||||||
|
|
||||||
|
--- |
|
||||||
|
define void @foo() #0 { ret void }
|
||||||
|
define void @bar() #0 { ret void }
|
||||||
|
define void @baz() #0 { ret void }
|
||||||
|
attributes #0 = { noredzone }
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: foo
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
liveins: $lr
|
||||||
|
; CHECK-LABEL: name: foo
|
||||||
|
; CHECK: liveins: $lr
|
||||||
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w28, 16
|
||||||
|
; CHECK: $w9 = ORRWri $wzr, 1
|
||||||
|
; CHECK: $w10 = ORRWri $wzr, 2
|
||||||
|
; CHECK: $w11 = ORRWri $wzr, 3
|
||||||
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15, implicit $wzr, implicit $sp
|
||||||
|
frame-setup CFI_INSTRUCTION def_cfa $w28, 16
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w10 = ORRWri $wzr, 2
|
||||||
|
$w11 = ORRWri $wzr, 3
|
||||||
|
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
$w12 = ORRWri $wzr, 1
|
||||||
|
$w13 = ORRWri $wzr, 2
|
||||||
|
$w14 = ORRWri $wzr, 3
|
||||||
|
$w15 = ORRWri $wzr, 4
|
||||||
|
RET undef $lr
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: bar
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
liveins: $lr
|
||||||
|
; CHECK-LABEL: name: bar
|
||||||
|
; CHECK: liveins: $lr
|
||||||
|
; CHECK: $w9 = ORRWri $wzr, 1
|
||||||
|
; CHECK: $w10 = ORRWri $wzr, 2
|
||||||
|
; CHECK: $w11 = ORRWri $wzr, 3
|
||||||
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15, implicit $wzr, implicit $sp
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w10 = ORRWri $wzr, 2
|
||||||
|
$w11 = ORRWri $wzr, 3
|
||||||
|
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
$w12 = ORRWri $wzr, 1
|
||||||
|
$w13 = ORRWri $wzr, 2
|
||||||
|
$w14 = ORRWri $wzr, 3
|
||||||
|
$w15 = ORRWri $wzr, 4
|
||||||
|
RET undef $lr
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: baz
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
liveins: $lr
|
||||||
|
; CHECK-LABEL: name: baz
|
||||||
|
; CHECK: liveins: $lr
|
||||||
|
; CHECK: $w9 = ORRWri $wzr, 1
|
||||||
|
; CHECK: $w10 = ORRWri $wzr, 2
|
||||||
|
; CHECK: $w11 = ORRWri $wzr, 3
|
||||||
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15, implicit $wzr, implicit $sp
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w10 = ORRWri $wzr, 2
|
||||||
|
$w11 = ORRWri $wzr, 3
|
||||||
|
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
$w12 = ORRWri $wzr, 1
|
||||||
|
$w13 = ORRWri $wzr, 2
|
||||||
|
$w14 = ORRWri $wzr, 3
|
||||||
|
$w15 = ORRWri $wzr, 4
|
||||||
|
RET undef $lr
|
69
test/CodeGen/AArch64/machine-outliner-cfi-tail.mir
Normal file
69
test/CodeGen/AArch64/machine-outliner-cfi-tail.mir
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||||
|
# RUN: llc -mtriple=aarch64-apple-unknown -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s
|
||||||
|
|
||||||
|
# Outlining CFI instructions is unsafe if it is not tail called, but otherwise,
|
||||||
|
# it requires fixups. Show that we include CFI instructions in tail call
|
||||||
|
# outlined sequences right now.
|
||||||
|
|
||||||
|
--- |
|
||||||
|
define void @foo() #0 { ret void }
|
||||||
|
define void @bar() #0 { ret void }
|
||||||
|
define void @baz() #0 { ret void }
|
||||||
|
attributes #0 = { noredzone }
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: foo
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
liveins: $lr
|
||||||
|
; CHECK-LABEL: name: foo
|
||||||
|
; CHECK: liveins: $lr
|
||||||
|
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w9, implicit-def $w10, implicit-def $w11, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15, implicit $wzr, implicit $sp
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w10 = ORRWri $wzr, 2
|
||||||
|
$w11 = ORRWri $wzr, 3
|
||||||
|
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
$w12 = ORRWri $wzr, 1
|
||||||
|
$w13 = ORRWri $wzr, 2
|
||||||
|
$w14 = ORRWri $wzr, 3
|
||||||
|
$w15 = ORRWri $wzr, 4
|
||||||
|
RET undef $lr
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: bar
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
liveins: $lr
|
||||||
|
; CHECK-LABEL: name: bar
|
||||||
|
; CHECK: liveins: $lr
|
||||||
|
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w9, implicit-def $w10, implicit-def $w11, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15, implicit $wzr, implicit $sp
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w10 = ORRWri $wzr, 2
|
||||||
|
$w11 = ORRWri $wzr, 3
|
||||||
|
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
$w12 = ORRWri $wzr, 1
|
||||||
|
$w13 = ORRWri $wzr, 2
|
||||||
|
$w14 = ORRWri $wzr, 3
|
||||||
|
$w15 = ORRWri $wzr, 4
|
||||||
|
RET undef $lr
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: baz
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
liveins: $lr
|
||||||
|
; CHECK-LABEL: name: baz
|
||||||
|
; CHECK: liveins: $lr
|
||||||
|
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w9, implicit-def $w10, implicit-def $w11, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15, implicit $wzr, implicit $sp
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w10 = ORRWri $wzr, 2
|
||||||
|
$w11 = ORRWri $wzr, 3
|
||||||
|
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
$w12 = ORRWri $wzr, 1
|
||||||
|
$w13 = ORRWri $wzr, 2
|
||||||
|
$w14 = ORRWri $wzr, 3
|
||||||
|
$w15 = ORRWri $wzr, 4
|
||||||
|
RET undef $lr
|
@ -1,9 +1,9 @@
|
|||||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||||
# RUN: llc -mtriple=aarch64-apple-unknown -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s
|
# RUN: llc -mtriple=aarch64-apple-unknown -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s
|
||||||
|
|
||||||
# Outlining CFI instructions is unsafe. It is possible if the call is tail
|
# Outlining CFI instructions is unsafe if it is not tail called, but otherwise,
|
||||||
# called, but otherwise, it requires fixups. Show that we don't include CFI
|
# it requires fixups. Show that we don't include CFI instructions in non
|
||||||
# instructions in outlined sequences right now.
|
# tail call outlined sequences right now.
|
||||||
|
|
||||||
--- |
|
--- |
|
||||||
define void @foo() #0 { ret void }
|
define void @foo() #0 { ret void }
|
||||||
@ -19,9 +19,17 @@ body: |
|
|||||||
liveins: $lr
|
liveins: $lr
|
||||||
; CHECK-LABEL: name: foo
|
; CHECK-LABEL: name: foo
|
||||||
; CHECK: liveins: $lr
|
; CHECK: liveins: $lr
|
||||||
|
; CHECK: $w9 = ORRWri $wzr, 1
|
||||||
|
; CHECK: $w10 = ORRWri $wzr, 2
|
||||||
|
; CHECK: $w11 = ORRWri $wzr, 3
|
||||||
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15
|
; CHECK: $w20 = ORRWri $wzr, 1
|
||||||
|
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15, implicit $wzr, implicit $sp
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w10 = ORRWri $wzr, 2
|
||||||
|
$w11 = ORRWri $wzr, 3
|
||||||
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
$w20 = ORRWri $wzr, 1
|
||||||
$w12 = ORRWri $wzr, 1
|
$w12 = ORRWri $wzr, 1
|
||||||
$w13 = ORRWri $wzr, 2
|
$w13 = ORRWri $wzr, 2
|
||||||
$w14 = ORRWri $wzr, 3
|
$w14 = ORRWri $wzr, 3
|
||||||
@ -36,9 +44,17 @@ body: |
|
|||||||
liveins: $lr
|
liveins: $lr
|
||||||
; CHECK-LABEL: name: bar
|
; CHECK-LABEL: name: bar
|
||||||
; CHECK: liveins: $lr
|
; CHECK: liveins: $lr
|
||||||
|
; CHECK: $w9 = ORRWri $wzr, 1
|
||||||
|
; CHECK: $w10 = ORRWri $wzr, 2
|
||||||
|
; CHECK: $w11 = ORRWri $wzr, 3
|
||||||
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15
|
; CHECK: $w21 = ORRWri $wzr, 1
|
||||||
|
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15, implicit $wzr, implicit $sp
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w10 = ORRWri $wzr, 2
|
||||||
|
$w11 = ORRWri $wzr, 3
|
||||||
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
$w21 = ORRWri $wzr, 1
|
||||||
$w12 = ORRWri $wzr, 1
|
$w12 = ORRWri $wzr, 1
|
||||||
$w13 = ORRWri $wzr, 2
|
$w13 = ORRWri $wzr, 2
|
||||||
$w14 = ORRWri $wzr, 3
|
$w14 = ORRWri $wzr, 3
|
||||||
@ -53,9 +69,17 @@ body: |
|
|||||||
liveins: $lr
|
liveins: $lr
|
||||||
; CHECK-LABEL: name: baz
|
; CHECK-LABEL: name: baz
|
||||||
; CHECK: liveins: $lr
|
; CHECK: liveins: $lr
|
||||||
|
; CHECK: $w9 = ORRWri $wzr, 1
|
||||||
|
; CHECK: $w10 = ORRWri $wzr, 2
|
||||||
|
; CHECK: $w11 = ORRWri $wzr, 3
|
||||||
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15
|
; CHECK: $w22 = ORRWri $wzr, 1
|
||||||
|
; CHECK: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp, implicit-def $w12, implicit-def $w13, implicit-def $w14, implicit-def $w15, implicit $wzr, implicit $sp
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w10 = ORRWri $wzr, 2
|
||||||
|
$w11 = ORRWri $wzr, 3
|
||||||
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
frame-setup CFI_INSTRUCTION def_cfa $w29, 16
|
||||||
|
$w22 = ORRWri $wzr, 1
|
||||||
$w12 = ORRWri $wzr, 1
|
$w12 = ORRWri $wzr, 1
|
||||||
$w13 = ORRWri $wzr, 2
|
$w13 = ORRWri $wzr, 2
|
||||||
$w14 = ORRWri $wzr, 3
|
$w14 = ORRWri $wzr, 3
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
; CHECK-SAME: Bytes from outlining all occurrences (16) >=
|
; CHECK-SAME: Bytes from outlining all occurrences (16) >=
|
||||||
; CHECK-SAME: Unoutlined instruction bytes (16)
|
; CHECK-SAME: Unoutlined instruction bytes (16)
|
||||||
; CHECK-SAME: (Also found at: <UNKNOWN LOCATION>)
|
; CHECK-SAME: (Also found at: <UNKNOWN LOCATION>)
|
||||||
; CHECK: remark: <unknown>:0:0: Saved 36 bytes by outlining 11 instructions
|
; CHECK: remark: <unknown>:0:0: Saved 40 bytes by outlining 13 instructions
|
||||||
; CHECK-SAME: from 2 locations. (Found at: <UNKNOWN LOCATION>,
|
; CHECK-SAME: from 2 locations. (Found at: <UNKNOWN LOCATION>,
|
||||||
; CHECK-SAME: <UNKNOWN LOCATION>)
|
; CHECK-SAME: <UNKNOWN LOCATION>)
|
||||||
; RUN: llc %s -enable-machine-outliner -mtriple=aarch64-unknown-unknown -o /dev/null -pass-remarks-missed=machine-outliner -pass-remarks-output=%t.yaml
|
; RUN: llc %s -enable-machine-outliner -mtriple=aarch64-unknown-unknown -o /dev/null -pass-remarks-missed=machine-outliner -pass-remarks-output=%t.yaml
|
||||||
@ -38,10 +38,10 @@
|
|||||||
; YAML-NEXT: Function: OUTLINED_FUNCTION_0
|
; YAML-NEXT: Function: OUTLINED_FUNCTION_0
|
||||||
; YAML-NEXT: Args:
|
; YAML-NEXT: Args:
|
||||||
; YAML-NEXT: - String: 'Saved '
|
; YAML-NEXT: - String: 'Saved '
|
||||||
; YAML-NEXT: - OutliningBenefit: '36'
|
; YAML-NEXT: - OutliningBenefit: '40'
|
||||||
; YAML-NEXT: - String: ' bytes by '
|
; YAML-NEXT: - String: ' bytes by '
|
||||||
; YAML-NEXT: - String: 'outlining '
|
; YAML-NEXT: - String: 'outlining '
|
||||||
; YAML-NEXT: - Length: '11'
|
; YAML-NEXT: - Length: '13'
|
||||||
; YAML-NEXT: - String: ' instructions '
|
; YAML-NEXT: - String: ' instructions '
|
||||||
; YAML-NEXT: - String: 'from '
|
; YAML-NEXT: - String: 'from '
|
||||||
; YAML-NEXT: - NumOccurrences: '2'
|
; YAML-NEXT: - NumOccurrences: '2'
|
||||||
|
90
test/CodeGen/X86/machine-outliner-cfi-tail-some.mir
Normal file
90
test/CodeGen/X86/machine-outliner-cfi-tail-some.mir
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||||
|
# RUN: llc -mtriple=x86_64-apple-unknown -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s
|
||||||
|
|
||||||
|
# Outlining CFI instructions is unsafe if we cannot outline all of the CFI
|
||||||
|
# instructions from a function. This shows that we choose not to outline the
|
||||||
|
# CFI instructions since function foo has a CFI Instruction that would not
|
||||||
|
# be caught.
|
||||||
|
|
||||||
|
--- |
|
||||||
|
define void @foo() #0 { ret void }
|
||||||
|
define void @bar() #0 { ret void }
|
||||||
|
define void @baz() #0 { ret void }
|
||||||
|
attributes #0 = { noredzone }
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: foo
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
; CHECK-LABEL: name: foo
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
; CHECK: CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_register $rbp
|
||||||
|
; CHECK: CALL64pcrel32 @OUTLINED_FUNCTION_1, implicit $rsp, implicit $ssp, implicit-def $eax, implicit-def $ebx, implicit-def $ecx, implicit $rsp, implicit $ssp
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
; CHECK: CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
; CHECK: TAILJMPd64 @OUTLINED_FUNCTION_0, implicit $rsp, implicit $ssp, implicit-def $eax, implicit-def $edi, implicit-def $edx, implicit-def $esi, implicit $rsp, implicit $ssp
|
||||||
|
CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
CFI_INSTRUCTION def_cfa_register $rbp
|
||||||
|
$eax = MOV32ri 1
|
||||||
|
$ebx = MOV32ri 2
|
||||||
|
$ecx = MOV32ri 3
|
||||||
|
CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
$esi = MOV32ri 1
|
||||||
|
$edx = MOV32ri 2
|
||||||
|
$edi = MOV32ri 3
|
||||||
|
$eax = MOV32ri 4
|
||||||
|
RETQ
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: bar
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
;liveins: $lr
|
||||||
|
; CHECK-LABEL: name: bar
|
||||||
|
; CHECK: CALL64pcrel32 @OUTLINED_FUNCTION_1, implicit $rsp, implicit $ssp, implicit-def $eax, implicit-def $ebx, implicit-def $ecx, implicit $rsp, implicit $ssp
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
; CHECK: CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
; CHECK: TAILJMPd64 @OUTLINED_FUNCTION_0, implicit $rsp, implicit $ssp, implicit-def $eax, implicit-def $edi, implicit-def $edx, implicit-def $esi, implicit $rsp, implicit $ssp
|
||||||
|
$eax = MOV32ri 1
|
||||||
|
$ebx = MOV32ri 2
|
||||||
|
$ecx = MOV32ri 3
|
||||||
|
CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
$esi = MOV32ri 1
|
||||||
|
$edx = MOV32ri 2
|
||||||
|
$edi = MOV32ri 3
|
||||||
|
$eax = MOV32ri 4
|
||||||
|
RETQ
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: baz
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
;liveins: $lr
|
||||||
|
; CHECK-LABEL: name: baz
|
||||||
|
; CHECK: CALL64pcrel32 @OUTLINED_FUNCTION_1, implicit $rsp, implicit $ssp, implicit-def $eax, implicit-def $ebx, implicit-def $ecx, implicit $rsp, implicit $ssp
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
; CHECK: CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
; CHECK: TAILJMPd64 @OUTLINED_FUNCTION_0, implicit $rsp, implicit $ssp, implicit-def $eax, implicit-def $edi, implicit-def $edx, implicit-def $esi, implicit $rsp, implicit $ssp
|
||||||
|
$eax = MOV32ri 1
|
||||||
|
$ebx = MOV32ri 2
|
||||||
|
$ecx = MOV32ri 3
|
||||||
|
CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
$esi = MOV32ri 1
|
||||||
|
$edx = MOV32ri 2
|
||||||
|
$edi = MOV32ri 3
|
||||||
|
$eax = MOV32ri 4
|
||||||
|
RETQ
|
77
test/CodeGen/X86/machine-outliner-cfi-tail.mir
Normal file
77
test/CodeGen/X86/machine-outliner-cfi-tail.mir
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||||
|
# RUN: llc -mtriple=x86_64-apple-unknown -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s
|
||||||
|
|
||||||
|
# Outlining CFI instructions is unsafe if we cannot outline all of the CFI
|
||||||
|
# instructions from a function. This shows that we choose to outline the
|
||||||
|
# CFI instructions if they can be included in a tail call.
|
||||||
|
|
||||||
|
--- |
|
||||||
|
define void @foo() #0 { ret void }
|
||||||
|
define void @bar() #0 { ret void }
|
||||||
|
define void @baz() #0 { ret void }
|
||||||
|
attributes #0 = { noredzone }
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: foo
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
; CHECK-LABEL: name: foo
|
||||||
|
; CHECK: $ecx = MOV32ri 3
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
; CHECK: CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
; CHECK: TAILJMPd64 @OUTLINED_FUNCTION_0, implicit $rsp, implicit $ssp, implicit-def $eax, implicit-def $edi, implicit-def $edx, implicit-def $esi, implicit $rsp, implicit $ssp
|
||||||
|
$ecx = MOV32ri 3
|
||||||
|
CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
$esi = MOV32ri 1
|
||||||
|
$edx = MOV32ri 2
|
||||||
|
$edi = MOV32ri 3
|
||||||
|
$eax = MOV32ri 4
|
||||||
|
RETQ
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: bar
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
;liveins: $lr
|
||||||
|
; CHECK-LABEL: name: bar
|
||||||
|
; CHECK: $ecx = MOV32ri 3
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
; CHECK: CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
; CHECK: TAILJMPd64 @OUTLINED_FUNCTION_0, implicit $rsp, implicit $ssp, implicit-def $eax, implicit-def $edi, implicit-def $edx, implicit-def $esi, implicit $rsp, implicit $ssp
|
||||||
|
$ecx = MOV32ri 3
|
||||||
|
CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
$esi = MOV32ri 1
|
||||||
|
$edx = MOV32ri 2
|
||||||
|
$edi = MOV32ri 3
|
||||||
|
$eax = MOV32ri 4
|
||||||
|
RETQ
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: baz
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
;liveins: $lr
|
||||||
|
; CHECK-LABEL: name: baz
|
||||||
|
; CHECK: $ecx = MOV32ri 3
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
; CHECK: CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
; CHECK: CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
; CHECK: TAILJMPd64 @OUTLINED_FUNCTION_0, implicit $rsp, implicit $ssp, implicit-def $eax, implicit-def $edi, implicit-def $edx, implicit-def $esi, implicit $rsp, implicit $ssp
|
||||||
|
$ecx = MOV32ri 3
|
||||||
|
CFI_INSTRUCTION def_cfa_offset 16
|
||||||
|
CFI_INSTRUCTION offset $rbp, -16
|
||||||
|
CFI_INSTRUCTION def_cfa_register $rsp
|
||||||
|
$esi = MOV32ri 1
|
||||||
|
$edx = MOV32ri 2
|
||||||
|
$edi = MOV32ri 3
|
||||||
|
$eax = MOV32ri 4
|
||||||
|
RETQ
|
Loading…
x
Reference in New Issue
Block a user