Lower dynamic stack allocation on mingw32 to separate instruction.

We cannot use a normal call here since it has extra unmodelled side
effects (it changes stack pointer). This should fix PR5292.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97884 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anton Korobeynikov 2010-03-06 19:32:29 +00:00
parent 0ddda3b8c6
commit 043f3c2a0e
4 changed files with 56 additions and 20 deletions

View File

@ -6418,24 +6418,13 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
EVT IntPtr = getPointerTy(); EVT IntPtr = getPointerTy();
EVT SPTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32; EVT SPTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, true));
Chain = DAG.getCopyToReg(Chain, dl, X86::EAX, Size, Flag); Chain = DAG.getCopyToReg(Chain, dl, X86::EAX, Size, Flag);
Flag = Chain.getValue(1); Flag = Chain.getValue(1);
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain,
DAG.getTargetExternalSymbol("_alloca", IntPtr),
DAG.getRegister(X86::EAX, IntPtr),
DAG.getRegister(X86StackPtr, SPTy),
Flag };
Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops, 5);
Flag = Chain.getValue(1);
Chain = DAG.getCALLSEQ_END(Chain, Chain = DAG.getNode(X86ISD::MINGW_ALLOCA, dl, NodeTys, Chain, Flag);
DAG.getIntPtrConstant(0, true), Flag = Chain.getValue(1);
DAG.getIntPtrConstant(0, true),
Flag);
Chain = DAG.getCopyFromReg(Chain, dl, X86StackPtr, SPTy).getValue(1); Chain = DAG.getCopyFromReg(Chain, dl, X86StackPtr, SPTy).getValue(1);
@ -7741,6 +7730,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
case X86ISD::MUL_IMM: return "X86ISD::MUL_IMM"; case X86ISD::MUL_IMM: return "X86ISD::MUL_IMM";
case X86ISD::PTEST: return "X86ISD::PTEST"; case X86ISD::PTEST: return "X86ISD::PTEST";
case X86ISD::VASTART_SAVE_XMM_REGS: return "X86ISD::VASTART_SAVE_XMM_REGS"; case X86ISD::VASTART_SAVE_XMM_REGS: return "X86ISD::VASTART_SAVE_XMM_REGS";
case X86ISD::MINGW_ALLOCA: return "X86ISD::MINGW_ALLOCA";
} }
} }
@ -8410,6 +8400,29 @@ X86TargetLowering::EmitLoweredSelect(MachineInstr *MI,
return BB; return BB;
} }
MachineBasicBlock *
X86TargetLowering::EmitLoweredMingwAlloca(MachineInstr *MI,
MachineBasicBlock *BB,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
DebugLoc DL = MI->getDebugLoc();
MachineFunction *F = BB->getParent();
// The lowering is pretty easy: we're just emitting the call to _alloca. The
// non-trivial part is impdef of ESP.
// FIXME: The code should be tweaked as soon as we'll try to do codegen for
// mingw-w64.
BuildMI(BB, DL, TII->get(X86::CALLpcrel32))
.addExternalSymbol("_alloca")
.addReg(X86::EAX, RegState::Implicit)
.addReg(X86::ESP, RegState::Implicit)
.addReg(X86::EAX, RegState::Define | RegState::Implicit)
.addReg(X86::ESP, RegState::Define | RegState::Implicit);
F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
return BB;
}
MachineBasicBlock * MachineBasicBlock *
X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
@ -8417,6 +8430,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
switch (MI->getOpcode()) { switch (MI->getOpcode()) {
default: assert(false && "Unexpected instr type to insert"); default: assert(false && "Unexpected instr type to insert");
case X86::MINGW_ALLOCA:
return EmitLoweredMingwAlloca(MI, BB, EM);
case X86::CMOV_GR8: case X86::CMOV_GR8:
case X86::CMOV_V1I64: case X86::CMOV_V1I64:
case X86::CMOV_FR32: case X86::CMOV_FR32:

View File

@ -249,6 +249,9 @@ namespace llvm {
// with control flow. // with control flow.
VASTART_SAVE_XMM_REGS, VASTART_SAVE_XMM_REGS,
// MINGW_ALLOCA - MingW's __alloca call to do stack probing.
MINGW_ALLOCA,
// ATOMADD64_DAG, ATOMSUB64_DAG, ATOMOR64_DAG, ATOMAND64_DAG, // ATOMADD64_DAG, ATOMSUB64_DAG, ATOMOR64_DAG, ATOMAND64_DAG,
// ATOMXOR64_DAG, ATOMNAND64_DAG, ATOMSWAP64_DAG - // ATOMXOR64_DAG, ATOMNAND64_DAG, ATOMSWAP64_DAG -
// Atomic 64-bit binary operations. // Atomic 64-bit binary operations.
@ -259,6 +262,10 @@ namespace llvm {
ATOMAND64_DAG, ATOMAND64_DAG,
ATOMNAND64_DAG, ATOMNAND64_DAG,
ATOMSWAP64_DAG ATOMSWAP64_DAG
// WARNING: Do not add anything in the end unless you want the node to
// have memop! In fact, starting from ATOMADD64_DAG all opcodes will be
// thought as target memory ops!
}; };
} }
@ -789,7 +796,11 @@ namespace llvm {
MachineBasicBlock *EmitLoweredSelect(MachineInstr *I, MachineBasicBlock *EmitLoweredSelect(MachineInstr *I,
MachineBasicBlock *BB, MachineBasicBlock *BB,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const; DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
MachineBasicBlock *EmitLoweredMingwAlloca(MachineInstr *MI,
MachineBasicBlock *BB,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
/// Emit nodes that will be selected as "test Op0,Op0", or something /// Emit nodes that will be selected as "test Op0,Op0", or something
/// equivalent, for use with the given x86 condition code. /// equivalent, for use with the given x86 condition code.
SDValue EmitTest(SDValue Op0, unsigned X86CC, SelectionDAG &DAG); SDValue EmitTest(SDValue Op0, unsigned X86CC, SelectionDAG &DAG);

View File

@ -65,7 +65,7 @@ def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>; def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
def SDTX86RdTsc : SDTypeProfile<0, 0, []>; def SDTX86Void : SDTypeProfile<0, 0, []>;
def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
@ -143,7 +143,7 @@ def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
[SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore, [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore,
SDNPMayLoad]>; SDNPMayLoad]>;
def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc, def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
[SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>; [SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>;
def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>; def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
@ -178,6 +178,9 @@ def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>; def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
def X86MingwAlloca : SDNode<"X86ISD::MINGW_ALLOCA", SDTX86Void,
[SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// X86 Operand Definitions. // X86 Operand Definitions.
// //
@ -519,7 +522,7 @@ def ADJCALLSTACKUP32 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
} }
// x86-64 va_start lowering magic. // x86-64 va_start lowering magic.
let usesCustomInserter = 1 in let usesCustomInserter = 1 in {
def VASTART_SAVE_XMM_REGS : I<0, Pseudo, def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
(outs), (outs),
(ins GR8:$al, (ins GR8:$al,
@ -530,6 +533,11 @@ def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
imm:$regsavefi, imm:$regsavefi,
imm:$offset)]>; imm:$offset)]>;
def MINGW_ALLOCA : I<0, Pseudo, (outs), (ins),
"call __alloca",
[(X86MingwAlloca)]>;
}
// Nop // Nop
let neverHasSideEffects = 1 in { let neverHasSideEffects = 1 in {
def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>; def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;

View File

@ -1057,7 +1057,8 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
.addImm(NumBytes); .addImm(NumBytes);
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32)) BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
.addExternalSymbol("_alloca"); .addExternalSymbol("_alloca")
.addReg(StackPtr, RegState::Define | RegState::Implicit);
} else { } else {
// Save EAX // Save EAX
BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r)) BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
@ -1068,7 +1069,8 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
.addImm(NumBytes - 4); .addImm(NumBytes - 4);
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32)) BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
.addExternalSymbol("_alloca"); .addExternalSymbol("_alloca")
.addReg(StackPtr, RegState::Define | RegState::Implicit);
// Restore EAX // Restore EAX
MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm), MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm),