mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
Move the segmented stack switch to a function attribute
This removes the -segmented-stacks command line flag in favor of a per-function "split-stack" attribute. Patch by Luqman Aden and Alex Crichton! llvm-svn: 205997
This commit is contained in:
parent
c20d02a782
commit
f99741400f
@ -13,9 +13,8 @@ monolithic chunk (of some worst case size) at thread initialization. This is
|
|||||||
done by allocating stack blocks (henceforth called *stacklets*) and linking them
|
done by allocating stack blocks (henceforth called *stacklets*) and linking them
|
||||||
into a doubly linked list. The function prologue is responsible for checking if
|
into a doubly linked list. The function prologue is responsible for checking if
|
||||||
the current stacklet has enough space for the function to execute; and if not,
|
the current stacklet has enough space for the function to execute; and if not,
|
||||||
call into the libgcc runtime to allocate more stack space. When using ``llc``,
|
call into the libgcc runtime to allocate more stack space. Segmented stacks are
|
||||||
segmented stacks can be enabled by adding ``-segmented-stacks`` to the command
|
enabled with the ``"split-stack"`` attribute on LLVM functions.
|
||||||
line.
|
|
||||||
|
|
||||||
The runtime functionality is `already there in libgcc
|
The runtime functionality is `already there in libgcc
|
||||||
<http://gcc.gnu.org/wiki/SplitStacks>`_.
|
<http://gcc.gnu.org/wiki/SplitStacks>`_.
|
||||||
|
@ -189,11 +189,6 @@ EnablePIE("enable-pie",
|
|||||||
cl::desc("Assume the creation of a position independent executable."),
|
cl::desc("Assume the creation of a position independent executable."),
|
||||||
cl::init(false));
|
cl::init(false));
|
||||||
|
|
||||||
cl::opt<bool>
|
|
||||||
SegmentedStacks("segmented-stacks",
|
|
||||||
cl::desc("Use segmented stacks if possible."),
|
|
||||||
cl::init(false));
|
|
||||||
|
|
||||||
cl::opt<bool>
|
cl::opt<bool>
|
||||||
UseInitArray("use-init-array",
|
UseInitArray("use-init-array",
|
||||||
cl::desc("Use .init_array instead of .ctors."),
|
cl::desc("Use .init_array instead of .ctors."),
|
||||||
@ -229,7 +224,6 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
|
|||||||
Options.StackAlignmentOverride = OverrideStackAlignment;
|
Options.StackAlignmentOverride = OverrideStackAlignment;
|
||||||
Options.TrapFuncName = TrapFuncName;
|
Options.TrapFuncName = TrapFuncName;
|
||||||
Options.PositionIndependentExecutable = EnablePIE;
|
Options.PositionIndependentExecutable = EnablePIE;
|
||||||
Options.EnableSegmentedStacks = SegmentedStacks;
|
|
||||||
Options.UseInitArray = UseInitArray;
|
Options.UseInitArray = UseInitArray;
|
||||||
return Options;
|
return Options;
|
||||||
}
|
}
|
||||||
|
@ -259,6 +259,9 @@ public:
|
|||||||
return MBBNumbering[N];
|
return MBBNumbering[N];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Should we be emitting segmented stack stuff for the function
|
||||||
|
bool shouldSplitStack();
|
||||||
|
|
||||||
/// getNumBlockIDs - Return the number of MBB ID's allocated.
|
/// getNumBlockIDs - Return the number of MBB ID's allocated.
|
||||||
///
|
///
|
||||||
unsigned getNumBlockIDs() const { return (unsigned)MBBNumbering.size(); }
|
unsigned getNumBlockIDs() const { return (unsigned)MBBNumbering.size(); }
|
||||||
|
@ -49,7 +49,7 @@ namespace llvm {
|
|||||||
JITEmitDebugInfoToDisk(false), GuaranteedTailCallOpt(false),
|
JITEmitDebugInfoToDisk(false), GuaranteedTailCallOpt(false),
|
||||||
DisableTailCalls(false), StackAlignmentOverride(0),
|
DisableTailCalls(false), StackAlignmentOverride(0),
|
||||||
EnableFastISel(false), PositionIndependentExecutable(false),
|
EnableFastISel(false), PositionIndependentExecutable(false),
|
||||||
EnableSegmentedStacks(false), UseInitArray(false),
|
UseInitArray(false),
|
||||||
DisableIntegratedAS(false), CompressDebugSections(false),
|
DisableIntegratedAS(false), CompressDebugSections(false),
|
||||||
TrapFuncName(""), FloatABIType(FloatABI::Default),
|
TrapFuncName(""), FloatABIType(FloatABI::Default),
|
||||||
AllowFPOpFusion(FPOpFusion::Standard) {}
|
AllowFPOpFusion(FPOpFusion::Standard) {}
|
||||||
@ -152,8 +152,6 @@ namespace llvm {
|
|||||||
/// if the relocation model is anything other than PIC.
|
/// if the relocation model is anything other than PIC.
|
||||||
unsigned PositionIndependentExecutable : 1;
|
unsigned PositionIndependentExecutable : 1;
|
||||||
|
|
||||||
unsigned EnableSegmentedStacks : 1;
|
|
||||||
|
|
||||||
/// UseInitArray - Use .init_array instead of .ctors for static
|
/// UseInitArray - Use .init_array instead of .ctors for static
|
||||||
/// constructors.
|
/// constructors.
|
||||||
unsigned UseInitArray : 1;
|
unsigned UseInitArray : 1;
|
||||||
@ -217,7 +215,6 @@ inline bool operator==(const TargetOptions &LHS,
|
|||||||
ARE_EQUAL(StackAlignmentOverride) &&
|
ARE_EQUAL(StackAlignmentOverride) &&
|
||||||
ARE_EQUAL(EnableFastISel) &&
|
ARE_EQUAL(EnableFastISel) &&
|
||||||
ARE_EQUAL(PositionIndependentExecutable) &&
|
ARE_EQUAL(PositionIndependentExecutable) &&
|
||||||
ARE_EQUAL(EnableSegmentedStacks) &&
|
|
||||||
ARE_EQUAL(UseInitArray) &&
|
ARE_EQUAL(UseInitArray) &&
|
||||||
ARE_EQUAL(TrapFuncName) &&
|
ARE_EQUAL(TrapFuncName) &&
|
||||||
ARE_EQUAL(FloatABIType) &&
|
ARE_EQUAL(FloatABIType) &&
|
||||||
|
@ -123,6 +123,11 @@ getOrCreateJumpTableInfo(unsigned EntryKind) {
|
|||||||
return JumpTableInfo;
|
return JumpTableInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Should we be emitting segmented stack stuff for the function
|
||||||
|
bool MachineFunction::shouldSplitStack() {
|
||||||
|
return getFunction()->hasFnAttribute("split-stack");
|
||||||
|
}
|
||||||
|
|
||||||
/// RenumberBlocks - This discards all of the MachineBasicBlock numbers and
|
/// RenumberBlocks - This discards all of the MachineBasicBlock numbers and
|
||||||
/// recomputes them. This guarantees that the MBB numbers are sequential,
|
/// recomputes them. This guarantees that the MBB numbers are sequential,
|
||||||
/// dense, and match the ordering of the blocks within the function. If a
|
/// dense, and match the ordering of the blocks within the function. If a
|
||||||
|
@ -680,7 +680,7 @@ void PEI::insertPrologEpilogCode(MachineFunction &Fn) {
|
|||||||
// we've been asked for it. This, when linked with a runtime with support
|
// we've been asked for it. This, when linked with a runtime with support
|
||||||
// for segmented stacks (libgcc is one), will result in allocating stack
|
// for segmented stacks (libgcc is one), will result in allocating stack
|
||||||
// space in small chunks instead of one large contiguous block.
|
// space in small chunks instead of one large contiguous block.
|
||||||
if (Fn.getTarget().Options.EnableSegmentedStacks)
|
if (Fn.shouldSplitStack())
|
||||||
TFI.adjustForSegmentedStacks(Fn);
|
TFI.adjustForSegmentedStacks(Fn);
|
||||||
|
|
||||||
// Emit additional code that is required to explicitly handle the stack in
|
// Emit additional code that is required to explicitly handle the stack in
|
||||||
|
@ -140,7 +140,6 @@ void LTOCodeGenerator::setTargetOptions(TargetOptions options) {
|
|||||||
Options.StackAlignmentOverride = options.StackAlignmentOverride;
|
Options.StackAlignmentOverride = options.StackAlignmentOverride;
|
||||||
Options.TrapFuncName = options.TrapFuncName;
|
Options.TrapFuncName = options.TrapFuncName;
|
||||||
Options.PositionIndependentExecutable = options.PositionIndependentExecutable;
|
Options.PositionIndependentExecutable = options.PositionIndependentExecutable;
|
||||||
Options.EnableSegmentedStacks = options.EnableSegmentedStacks;
|
|
||||||
Options.UseInitArray = options.UseInitArray;
|
Options.UseInitArray = options.UseInitArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
!MFI->adjustsStack() && // No calls.
|
!MFI->adjustsStack() && // No calls.
|
||||||
!IsWin64 && // Win64 has no Red Zone
|
!IsWin64 && // Win64 has no Red Zone
|
||||||
!usesTheStack(MF) && // Don't push and pop.
|
!usesTheStack(MF) && // Don't push and pop.
|
||||||
!MF.getTarget().Options.EnableSegmentedStacks) { // Regular stack
|
!MF.shouldSplitStack()) { // Regular stack
|
||||||
uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
|
uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
|
||||||
if (HasFP) MinSize += SlotSize;
|
if (HasFP) MinSize += SlotSize;
|
||||||
StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
|
StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
|
||||||
|
@ -635,15 +635,8 @@ void X86TargetLowering::resetOperationActions() {
|
|||||||
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
|
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
||||||
|
|
||||||
if (Subtarget->isOSWindows() && !Subtarget->isTargetMacho())
|
setOperationAction(ISD::DYNAMIC_STACKALLOC, Subtarget->is64Bit() ?
|
||||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, Subtarget->is64Bit() ?
|
MVT::i64 : MVT::i32, Custom);
|
||||||
MVT::i64 : MVT::i32, Custom);
|
|
||||||
else if (TM.Options.EnableSegmentedStacks)
|
|
||||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, Subtarget->is64Bit() ?
|
|
||||||
MVT::i64 : MVT::i32, Custom);
|
|
||||||
else
|
|
||||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, Subtarget->is64Bit() ?
|
|
||||||
MVT::i64 : MVT::i32, Expand);
|
|
||||||
|
|
||||||
if (!TM.Options.UseSoftFloat && X86ScalarSSEf64) {
|
if (!TM.Options.UseSoftFloat && X86ScalarSSEf64) {
|
||||||
// f32 and f64 use SSE.
|
// f32 and f64 use SSE.
|
||||||
@ -11102,13 +11095,50 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
SDValue
|
SDValue
|
||||||
X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
|
X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
assert((Subtarget->isOSWindows() ||
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
getTargetMachine().Options.EnableSegmentedStacks) &&
|
bool SplitStack = MF.shouldSplitStack();
|
||||||
"This should be used only on Windows targets or when segmented stacks "
|
bool Lower = (Subtarget->isOSWindows() && !Subtarget->isTargetMacho()) ||
|
||||||
"are being used");
|
SplitStack;
|
||||||
assert(!Subtarget->isTargetMacho() && "Not implemented");
|
|
||||||
SDLoc dl(Op);
|
SDLoc dl(Op);
|
||||||
|
|
||||||
|
if (!Lower) {
|
||||||
|
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||||
|
SDNode* Node = Op.getNode();
|
||||||
|
|
||||||
|
unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore();
|
||||||
|
assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"
|
||||||
|
" not tell us which reg is the stack pointer!");
|
||||||
|
EVT VT = Node->getValueType(0);
|
||||||
|
SDValue Tmp1 = SDValue(Node, 0);
|
||||||
|
SDValue Tmp2 = SDValue(Node, 1);
|
||||||
|
SDValue Tmp3 = Node->getOperand(2);
|
||||||
|
SDValue Chain = Tmp1.getOperand(0);
|
||||||
|
|
||||||
|
// Chain the dynamic stack allocation so that it doesn't modify the stack
|
||||||
|
// pointer when other instructions are using the stack.
|
||||||
|
Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, true),
|
||||||
|
SDLoc(Node));
|
||||||
|
|
||||||
|
SDValue Size = Tmp2.getOperand(1);
|
||||||
|
SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
|
||||||
|
Chain = SP.getValue(1);
|
||||||
|
unsigned Align = cast<ConstantSDNode>(Tmp3)->getZExtValue();
|
||||||
|
const TargetFrameLowering &TFI = *getTargetMachine().getFrameLowering();
|
||||||
|
unsigned StackAlign = TFI.getStackAlignment();
|
||||||
|
Tmp1 = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value
|
||||||
|
if (Align > StackAlign)
|
||||||
|
Tmp1 = DAG.getNode(ISD::AND, dl, VT, Tmp1,
|
||||||
|
DAG.getConstant(-(uint64_t)Align, VT));
|
||||||
|
Chain = DAG.getCopyToReg(Chain, dl, SPReg, Tmp1); // Output chain
|
||||||
|
|
||||||
|
Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true),
|
||||||
|
DAG.getIntPtrConstant(0, true), SDValue(),
|
||||||
|
SDLoc(Node));
|
||||||
|
|
||||||
|
SDValue Ops[2] = { Tmp1, Tmp2 };
|
||||||
|
return DAG.getMergeValues(Ops, 2, dl);
|
||||||
|
}
|
||||||
|
|
||||||
// Get the inputs.
|
// Get the inputs.
|
||||||
SDValue Chain = Op.getOperand(0);
|
SDValue Chain = Op.getOperand(0);
|
||||||
SDValue Size = Op.getOperand(1);
|
SDValue Size = Op.getOperand(1);
|
||||||
@ -11118,8 +11148,7 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
|
|||||||
bool Is64Bit = Subtarget->is64Bit();
|
bool Is64Bit = Subtarget->is64Bit();
|
||||||
EVT SPTy = Is64Bit ? MVT::i64 : MVT::i32;
|
EVT SPTy = Is64Bit ? MVT::i64 : MVT::i32;
|
||||||
|
|
||||||
if (getTargetMachine().Options.EnableSegmentedStacks) {
|
if (SplitStack) {
|
||||||
MachineFunction &MF = DAG.getMachineFunction();
|
|
||||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||||
|
|
||||||
if (Is64Bit) {
|
if (Is64Bit) {
|
||||||
@ -15796,7 +15825,7 @@ X86TargetLowering::EmitLoweredSegAlloca(MachineInstr *MI, MachineBasicBlock *BB,
|
|||||||
MachineFunction *MF = BB->getParent();
|
MachineFunction *MF = BB->getParent();
|
||||||
const BasicBlock *LLVM_BB = BB->getBasicBlock();
|
const BasicBlock *LLVM_BB = BB->getBasicBlock();
|
||||||
|
|
||||||
assert(getTargetMachine().Options.EnableSegmentedStacks);
|
assert(MF->shouldSplitStack());
|
||||||
|
|
||||||
unsigned TlsReg = Is64Bit ? X86::FS : X86::GS;
|
unsigned TlsReg = Is64Bit ? X86::FS : X86::GS;
|
||||||
unsigned TlsOffset = Is64Bit ? 0x70 : 0x30;
|
unsigned TlsOffset = Is64Bit ? 0x70 : 0x30;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -segmented-stacks -verify-machineinstrs -filetype=asm | FileCheck %s -check-prefix=ARM-linux
|
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -verify-machineinstrs -filetype=asm | FileCheck %s -check-prefix=ARM-linux
|
||||||
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -filetype=obj
|
||||||
|
|
||||||
!llvm.dbg.cu = !{!0}
|
!llvm.dbg.cu = !{!0}
|
||||||
!llvm.module.flags = !{!9, !10}
|
!llvm.module.flags = !{!9, !10}
|
||||||
!llvm.ident = !{!11}
|
!llvm.ident = !{!11}
|
||||||
|
|
||||||
define void @test_basic() {
|
define void @test_basic() #0 {
|
||||||
%mem = alloca i32, i32 10
|
%mem = alloca i32, i32 10
|
||||||
call void @dummy_use (i32* %mem, i32 10)
|
call void @dummy_use (i32* %mem, i32 10)
|
||||||
ret void
|
ret void
|
||||||
@ -78,3 +78,5 @@ define void @test_basic() {
|
|||||||
|
|
||||||
; Just to prevent the alloca from being optimized away
|
; Just to prevent the alloca from being optimized away
|
||||||
declare void @dummy_use(i32*, i32)
|
declare void @dummy_use(i32*, i32)
|
||||||
|
|
||||||
|
attributes #0 = { "split-stack" }
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
; RUN: llc < %s -mtriple=arm-linux-androideabi -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android
|
; RUN: llc < %s -mtriple=arm-linux-androideabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android
|
||||||
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux
|
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux
|
||||||
; RUN: llc < %s -mtriple=arm-linux-androideabi -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=arm-linux-androideabi -filetype=obj
|
||||||
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -filetype=obj
|
||||||
|
|
||||||
; Just to prevent the alloca from being optimized away
|
; Just to prevent the alloca from being optimized away
|
||||||
declare void @dummy_use(i32*, i32)
|
declare void @dummy_use(i32*, i32)
|
||||||
|
|
||||||
define i32 @test_basic(i32 %l) {
|
define i32 @test_basic(i32 %l) #0 {
|
||||||
%mem = alloca i32, i32 %l
|
%mem = alloca i32, i32 %l
|
||||||
call void @dummy_use (i32* %mem, i32 %l)
|
call void @dummy_use (i32* %mem, i32 %l)
|
||||||
%terminate = icmp eq i32 %l, 0
|
%terminate = icmp eq i32 %l, 0
|
||||||
@ -60,3 +60,5 @@ false:
|
|||||||
; ARM-android: pop {r4, r5}
|
; ARM-android: pop {r4, r5}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "split-stack" }
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
; RUN: llc < %s -mtriple=arm-linux-androideabi -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android
|
; RUN: llc < %s -mtriple=arm-linux-androideabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android
|
||||||
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux
|
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux
|
||||||
|
|
||||||
; We used to crash with filetype=obj
|
; We used to crash with filetype=obj
|
||||||
; RUN: llc < %s -mtriple=arm-linux-androideabi -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=arm-linux-androideabi -filetype=obj
|
||||||
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -filetype=obj
|
||||||
|
|
||||||
|
|
||||||
; Just to prevent the alloca from being optimized away
|
; Just to prevent the alloca from being optimized away
|
||||||
declare void @dummy_use(i32*, i32)
|
declare void @dummy_use(i32*, i32)
|
||||||
|
|
||||||
define void @test_basic() {
|
define void @test_basic() #0 {
|
||||||
%mem = alloca i32, i32 10
|
%mem = alloca i32, i32 10
|
||||||
call void @dummy_use (i32* %mem, i32 10)
|
call void @dummy_use (i32* %mem, i32 10)
|
||||||
ret void
|
ret void
|
||||||
@ -54,7 +54,7 @@ define void @test_basic() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_nested(i32 * nest %closure, i32 %other) {
|
define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
|
||||||
%addend = load i32 * %closure
|
%addend = load i32 * %closure
|
||||||
%result = add i32 %other, %addend
|
%result = add i32 %other, %addend
|
||||||
ret i32 %result
|
ret i32 %result
|
||||||
@ -99,7 +99,7 @@ define i32 @test_nested(i32 * nest %closure, i32 %other) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_large() {
|
define void @test_large() #0 {
|
||||||
%mem = alloca i32, i32 10000
|
%mem = alloca i32, i32 10000
|
||||||
call void @dummy_use (i32* %mem, i32 0)
|
call void @dummy_use (i32* %mem, i32 0)
|
||||||
ret void
|
ret void
|
||||||
@ -144,7 +144,7 @@ define void @test_large() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define fastcc void @test_fastcc() {
|
define fastcc void @test_fastcc() #0 {
|
||||||
%mem = alloca i32, i32 10
|
%mem = alloca i32, i32 10
|
||||||
call void @dummy_use (i32* %mem, i32 10)
|
call void @dummy_use (i32* %mem, i32 10)
|
||||||
ret void
|
ret void
|
||||||
@ -189,7 +189,7 @@ define fastcc void @test_fastcc() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define fastcc void @test_fastcc_large() {
|
define fastcc void @test_fastcc_large() #0 {
|
||||||
%mem = alloca i32, i32 10000
|
%mem = alloca i32, i32 10000
|
||||||
call void @dummy_use (i32* %mem, i32 0)
|
call void @dummy_use (i32* %mem, i32 0)
|
||||||
ret void
|
ret void
|
||||||
@ -233,3 +233,5 @@ define fastcc void @test_fastcc_large() {
|
|||||||
; ARM-android: pop {r4, r5}
|
; ARM-android: pop {r4, r5}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "split-stack" }
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
; RUN: llc < %s -mtriple=thumb-linux-unknown-gnueabi -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-linux
|
; RUN: llc < %s -mtriple=thumb-linux-unknown-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-linux
|
||||||
; RUN: llc < %s -mtriple=thumb-linux-androideabi -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-android
|
; RUN: llc < %s -mtriple=thumb-linux-androideabi -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-android
|
||||||
; RUN: llc < %s -mtriple=thumb-linux-unknown-gnueabi -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=thumb-linux-unknown-gnueabi -filetype=obj
|
||||||
; RUN: llc < %s -mtriple=thumb-linux-androideabi -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=thumb-linux-androideabi -filetype=obj
|
||||||
|
|
||||||
; Just to prevent the alloca from being optimized away
|
; Just to prevent the alloca from being optimized away
|
||||||
declare void @dummy_use(i32*, i32)
|
declare void @dummy_use(i32*, i32)
|
||||||
|
|
||||||
define i32 @test_basic(i32 %l) {
|
define i32 @test_basic(i32 %l) #0 {
|
||||||
%mem = alloca i32, i32 %l
|
%mem = alloca i32, i32 %l
|
||||||
call void @dummy_use (i32* %mem, i32 %l)
|
call void @dummy_use (i32* %mem, i32 %l)
|
||||||
%terminate = icmp eq i32 %l, 0
|
%terminate = icmp eq i32 %l, 0
|
||||||
@ -61,3 +61,5 @@ false:
|
|||||||
; Thumb-android: pop {r4, r5}
|
; Thumb-android: pop {r4, r5}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "split-stack" }
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
; RUN: llc < %s -mtriple=thumb-linux-androideabi -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-android
|
; RUN: llc < %s -mtriple=thumb-linux-androideabi -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-android
|
||||||
; RUN: llc < %s -mtriple=thumb-linux-unknown-gnueabi -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-linux
|
; RUN: llc < %s -mtriple=thumb-linux-unknown-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-linux
|
||||||
; RUN: llc < %s -mtriple=thumb-linux-androideabi -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=thumb-linux-androideabi -filetype=obj
|
||||||
; RUN: llc < %s -mtriple=thumb-linux-unknown-gnueabi -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=thumb-linux-unknown-gnueabi -filetype=obj
|
||||||
|
|
||||||
|
|
||||||
; Just to prevent the alloca from being optimized away
|
; Just to prevent the alloca from being optimized away
|
||||||
declare void @dummy_use(i32*, i32)
|
declare void @dummy_use(i32*, i32)
|
||||||
|
|
||||||
define void @test_basic() {
|
define void @test_basic() #0 {
|
||||||
%mem = alloca i32, i32 10
|
%mem = alloca i32, i32 10
|
||||||
call void @dummy_use (i32* %mem, i32 10)
|
call void @dummy_use (i32* %mem, i32 10)
|
||||||
ret void
|
ret void
|
||||||
@ -54,7 +54,7 @@ define void @test_basic() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_nested(i32 * nest %closure, i32 %other) {
|
define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
|
||||||
%addend = load i32 * %closure
|
%addend = load i32 * %closure
|
||||||
%result = add i32 %other, %addend
|
%result = add i32 %other, %addend
|
||||||
ret i32 %result
|
ret i32 %result
|
||||||
@ -101,7 +101,7 @@ define i32 @test_nested(i32 * nest %closure, i32 %other) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_large() {
|
define void @test_large() #0 {
|
||||||
%mem = alloca i32, i32 10000
|
%mem = alloca i32, i32 10000
|
||||||
call void @dummy_use (i32* %mem, i32 0)
|
call void @dummy_use (i32* %mem, i32 0)
|
||||||
ret void
|
ret void
|
||||||
@ -150,7 +150,7 @@ define void @test_large() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define fastcc void @test_fastcc() {
|
define fastcc void @test_fastcc() #0 {
|
||||||
%mem = alloca i32, i32 10
|
%mem = alloca i32, i32 10
|
||||||
call void @dummy_use (i32* %mem, i32 10)
|
call void @dummy_use (i32* %mem, i32 10)
|
||||||
ret void
|
ret void
|
||||||
@ -197,7 +197,7 @@ define fastcc void @test_fastcc() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define fastcc void @test_fastcc_large() {
|
define fastcc void @test_fastcc_large() #0 {
|
||||||
%mem = alloca i32, i32 10000
|
%mem = alloca i32, i32 10000
|
||||||
call void @dummy_use (i32* %mem, i32 0)
|
call void @dummy_use (i32* %mem, i32 0)
|
||||||
ret void
|
ret void
|
||||||
@ -245,3 +245,5 @@ define fastcc void @test_fastcc_large() {
|
|||||||
; Thumb-linux: pop {r4, r5}
|
; Thumb-linux: pop {r4, r5}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "split-stack" }
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
; RUN: llc < %s -mtriple=thumb-linux-androideabi -march=thumb -mcpu=arm1156t2-s -mattr=+thumb2 -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-android
|
; RUN: llc < %s -mtriple=thumb-linux-androideabi -march=thumb -mcpu=arm1156t2-s -mattr=+thumb2 -verify-machineinstrs | FileCheck %s -check-prefix=Thumb-android
|
||||||
; RUN: llc < %s -mtriple=thumb-linux-androideabi -march=thumb -mcpu=arm1156t2-s -mattr=+thumb2 -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mtriple=thumb-linux-androideabi -march=thumb -mcpu=arm1156t2-s -mattr=+thumb2 -filetype=obj
|
||||||
|
|
||||||
|
|
||||||
; Just to prevent the alloca from being optimized away
|
; Just to prevent the alloca from being optimized away
|
||||||
declare void @dummy_use(i32*, i32)
|
declare void @dummy_use(i32*, i32)
|
||||||
|
|
||||||
define void @test_basic() {
|
define void @test_basic() #0 {
|
||||||
%mem = alloca i32, i32 10
|
%mem = alloca i32, i32 10
|
||||||
call void @dummy_use (i32* %mem, i32 10)
|
call void @dummy_use (i32* %mem, i32 10)
|
||||||
ret void
|
ret void
|
||||||
@ -30,3 +30,5 @@ define void @test_basic() {
|
|||||||
; Thumb-android: pop {r4, r5}
|
; Thumb-android: pop {r4, r5}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "split-stack" }
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X32
|
; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -verify-machineinstrs | FileCheck %s -check-prefix=X32
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -verify-machineinstrs | FileCheck %s -check-prefix=X64
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -filetype=obj
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -filetype=obj
|
||||||
|
|
||||||
; Just to prevent the alloca from being optimized away
|
; Just to prevent the alloca from being optimized away
|
||||||
declare void @dummy_use(i32*, i32)
|
declare void @dummy_use(i32*, i32)
|
||||||
|
|
||||||
define i32 @test_basic(i32 %l) {
|
define i32 @test_basic(i32 %l) #0 {
|
||||||
%mem = alloca i32, i32 %l
|
%mem = alloca i32, i32 %l
|
||||||
call void @dummy_use (i32* %mem, i32 %l)
|
call void @dummy_use (i32* %mem, i32 %l)
|
||||||
%terminate = icmp eq i32 %l, 0
|
%terminate = icmp eq i32 %l, 0
|
||||||
@ -62,3 +62,5 @@ false:
|
|||||||
; X64: movq %rax, %rdi
|
; X64: movq %rax, %rdi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "split-stack" }
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X32-Linux
|
; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -verify-machineinstrs | FileCheck %s -check-prefix=X32-Linux
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-Linux
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -verify-machineinstrs | FileCheck %s -check-prefix=X64-Linux
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X32-Darwin
|
; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X32-Darwin
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-Darwin
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X64-Darwin
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X32-MinGW
|
; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -verify-machineinstrs | FileCheck %s -check-prefix=X32-MinGW
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-FreeBSD
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -verify-machineinstrs | FileCheck %s -check-prefix=X64-FreeBSD
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-MinGW
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -verify-machineinstrs | FileCheck %s -check-prefix=X64-MinGW
|
||||||
|
|
||||||
; We used to crash with filetype=obj
|
; We used to crash with filetype=obj
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -filetype=obj
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -filetype=obj
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -filetype=obj
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -filetype=obj
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -filetype=obj
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -filetype=obj
|
||||||
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -segmented-stacks -filetype=obj
|
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -filetype=obj
|
||||||
|
|
||||||
; RUN: not llc < %s -mcpu=generic -mtriple=x86_64-solaris -segmented-stacks 2> %t.log
|
; RUN: not llc < %s -mcpu=generic -mtriple=x86_64-solaris 2> %t.log
|
||||||
; RUN: FileCheck %s -input-file=%t.log -check-prefix=X64-Solaris
|
; RUN: FileCheck %s -input-file=%t.log -check-prefix=X64-Solaris
|
||||||
; RUN: not llc < %s -mcpu=generic -mtriple=i686-freebsd -segmented-stacks 2> %t.log
|
; RUN: not llc < %s -mcpu=generic -mtriple=i686-freebsd 2> %t.log
|
||||||
; RUN: FileCheck %s -input-file=%t.log -check-prefix=X32-FreeBSD
|
; RUN: FileCheck %s -input-file=%t.log -check-prefix=X32-FreeBSD
|
||||||
|
|
||||||
; X64-Solaris: Segmented stacks not supported on this platform
|
; X64-Solaris: Segmented stacks not supported on this platform
|
||||||
@ -26,7 +26,7 @@
|
|||||||
; Just to prevent the alloca from being optimized away
|
; Just to prevent the alloca from being optimized away
|
||||||
declare void @dummy_use(i32*, i32)
|
declare void @dummy_use(i32*, i32)
|
||||||
|
|
||||||
define void @test_basic() {
|
define void @test_basic() #0 {
|
||||||
%mem = alloca i32, i32 10
|
%mem = alloca i32, i32 10
|
||||||
call void @dummy_use (i32* %mem, i32 10)
|
call void @dummy_use (i32* %mem, i32 10)
|
||||||
ret void
|
ret void
|
||||||
@ -104,7 +104,7 @@ define void @test_basic() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_nested(i32 * nest %closure, i32 %other) {
|
define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
|
||||||
%addend = load i32 * %closure
|
%addend = load i32 * %closure
|
||||||
%result = add i32 %other, %addend
|
%result = add i32 %other, %addend
|
||||||
ret i32 %result
|
ret i32 %result
|
||||||
@ -177,7 +177,7 @@ define i32 @test_nested(i32 * nest %closure, i32 %other) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_large() {
|
define void @test_large() #0 {
|
||||||
%mem = alloca i32, i32 10000
|
%mem = alloca i32, i32 10000
|
||||||
call void @dummy_use (i32* %mem, i32 0)
|
call void @dummy_use (i32* %mem, i32 0)
|
||||||
ret void
|
ret void
|
||||||
@ -249,7 +249,7 @@ define void @test_large() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define fastcc void @test_fastcc() {
|
define fastcc void @test_fastcc() #0 {
|
||||||
%mem = alloca i32, i32 10
|
%mem = alloca i32, i32 10
|
||||||
call void @dummy_use (i32* %mem, i32 10)
|
call void @dummy_use (i32* %mem, i32 10)
|
||||||
ret void
|
ret void
|
||||||
@ -327,7 +327,7 @@ define fastcc void @test_fastcc() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define fastcc void @test_fastcc_large() {
|
define fastcc void @test_fastcc_large() #0 {
|
||||||
%mem = alloca i32, i32 10000
|
%mem = alloca i32, i32 10000
|
||||||
call void @dummy_use (i32* %mem, i32 0)
|
call void @dummy_use (i32* %mem, i32 0)
|
||||||
ret void
|
ret void
|
||||||
@ -412,7 +412,7 @@ define fastcc void @test_fastcc_large() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define fastcc void @test_fastcc_large_with_ecx_arg(i32 %a) {
|
define fastcc void @test_fastcc_large_with_ecx_arg(i32 %a) #0 {
|
||||||
%mem = alloca i32, i32 10000
|
%mem = alloca i32, i32 10000
|
||||||
call void @dummy_use (i32* %mem, i32 %a)
|
call void @dummy_use (i32* %mem, i32 %a)
|
||||||
ret void
|
ret void
|
||||||
@ -434,3 +434,5 @@ define fastcc void @test_fastcc_large_with_ecx_arg(i32 %a) {
|
|||||||
; X32-Darwin-NEXT: ret
|
; X32-Darwin-NEXT: ret
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "split-stack" }
|
||||||
|
Loading…
Reference in New Issue
Block a user