diff options
| author | Anton Korobeynikov <asl@math.spbu.ru> | 2007-04-17 09:20:00 +0000 |
|---|---|---|
| committer | Anton Korobeynikov <asl@math.spbu.ru> | 2007-04-17 09:20:00 +0000 |
| commit | 8b7aab009e564bb38fce5b94b1b506923de29125 (patch) | |
| tree | 9eed91ae85fcc1bb13332f8389fc8a05a551761f /llvm/lib/Target/X86/X86RegisterInfo.cpp | |
| parent | 8e846873502be42321200816575c2ca8159959c8 (diff) | |
| download | bcm5719-llvm-8b7aab009e564bb38fce5b94b1b506923de29125.tar.gz bcm5719-llvm-8b7aab009e564bb38fce5b94b1b506923de29125.zip | |
Implemented correct stack probing on mingw/cygwin for dynamic alloca's.
Also, fixed static case in presence of eax livin. This fixes PR331
PS: Why don't we still have push/pop instructions? :)
llvm-svn: 36195
Diffstat (limited to 'llvm/lib/Target/X86/X86RegisterInfo.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.cpp | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 3737c0e79e7..cd2a0d4a616 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -1039,14 +1039,39 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { if (NumBytes) { // adjust stack pointer: ESP -= numbytes if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) { + // Check, whether EAX is livein for this function + bool isEAXAlive = false; + for (MachineFunction::livein_iterator II = MF.livein_begin(), + EE = MF.livein_end(); (II != EE) && !isEAXAlive; ++II) { + unsigned Reg = II->first; + isEAXAlive = (Reg == X86::EAX || Reg == X86::AX || + Reg == X86::AH || Reg == X86::AL); + } + // Function prologue calls _alloca to probe the stack when allocating // more than 4k bytes in one go. Touching the stack at 4K increments is // necessary to ensure that the guard pages used by the OS virtual memory // manager are allocated in correct sequence. - MI = BuildMI(TII.get(X86::MOV32ri), X86::EAX).addImm(NumBytes); - MBB.insert(MBBI, MI); - MI = BuildMI(TII.get(X86::CALLpcrel32)).addExternalSymbol("_alloca"); - MBB.insert(MBBI, MI); + if (!isEAXAlive) { + MI = BuildMI(TII.get(X86::MOV32ri), X86::EAX).addImm(NumBytes); + MBB.insert(MBBI, MI); + MI = BuildMI(TII.get(X86::CALLpcrel32)).addExternalSymbol("_alloca"); + MBB.insert(MBBI, MI); + } else { + // Save EAX + MI = BuildMI(TII.get(X86::PUSH32r), X86::EAX); + MBB.insert(MBBI, MI); + // Allocate NumBytes-4 bytes on stack. We'll also use 4 already + // allocated bytes for EAX. + MI = BuildMI(TII.get(X86::MOV32ri), X86::EAX).addImm(NumBytes-4); + MBB.insert(MBBI, MI); + MI = BuildMI(TII.get(X86::CALLpcrel32)).addExternalSymbol("_alloca"); + MBB.insert(MBBI, MI); + // Restore EAX + MI = addRegOffset(BuildMI(TII.get(X86::MOV32rm), X86::EAX), + StackPtr, NumBytes-4); + MBB.insert(MBBI, MI); + } } else { unsigned Opc = (NumBytes < 128) ? (Is64Bit ? X86::SUB64ri8 : X86::SUB32ri8) : |

