llvm.org GIT mirror llvm / 420f72a
X86: Make @llvm.frameaddress work correctly with Windows unwind codes Simply loading or storing the frame pointer is not sufficient for Windows targets. Instead, create a synthetic frame object that we will lower later. References to this synthetic object will be replaced with the correct reference to the frame address. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228748 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 5 years ago
4 changed file(s) with 39 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
12411241 NumBytes = FrameSize - CSSize;
12421242 }
12431243 uint64_t SEHFrameOffset = calculateSetFPREG(NumBytes);
1244 if (FI && FI == X86FI->getFAIndex())
1245 return -SEHFrameOffset;
1246
12441247 // FPDelta is the offset from the "traditional" FP location of the old base
12451248 // pointer followed by return address and the location required by the
12461249 // restricted Win64 prologue.
1795217952 }
1795317953
1795417954 SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
17955 MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
17955 MachineFunction &MF = DAG.getMachineFunction();
17956 MachineFrameInfo *MFI = MF.getFrameInfo();
17957 X86MachineFunctionInfo *FuncInfo = MF.getInfo();
17958 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
17959 EVT VT = Op.getValueType();
17960
1795617961 MFI->setFrameAddressIsTaken(true);
1795717962
17958 EVT VT = Op.getValueType();
17963 if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI()) {
17964 // Depth > 0 makes no sense on targets which use Windows unwind codes. It
17965 // is not possible to crawl up the stack without looking at the unwind codes
17966 // simultaneously.
17967 int FrameAddrIndex = FuncInfo->getFAIndex();
17968 if (!FrameAddrIndex) {
17969 // Set up a frame object for the return address.
17970 unsigned SlotSize = RegInfo->getSlotSize();
17971 FrameAddrIndex = MF.getFrameInfo()->CreateFixedObject(
17972 SlotSize, /*Offset=*/INT64_MIN, /*IsImmutable=*/false);
17973 FuncInfo->setFAIndex(FrameAddrIndex);
17974 }
17975 return DAG.getFrameIndex(FrameAddrIndex, VT);
17976 }
17977
17978 unsigned FrameReg =
17979 RegInfo->getPtrSizedFrameRegister(DAG.getMachineFunction());
1795917980 SDLoc dl(Op); // FIXME probably not meaningful
1796017981 unsigned Depth = cast(Op.getOperand(0))->getZExtValue();
17961 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
17962 unsigned FrameReg = RegInfo->getPtrSizedFrameRegister(
17963 DAG.getMachineFunction());
1796417982 assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
1796517983 (FrameReg == X86::EBP && VT == MVT::i32)) &&
1796617984 "Invalid Frame Register!");
4949 /// ReturnAddrIndex - FrameIndex for return slot.
5050 int ReturnAddrIndex;
5151
52 /// \brief FrameIndex for return slot.
53 int FrameAddrIndex;
54
5255 /// TailCallReturnAddrDelta - The number of bytes by which return address
5356 /// stack slot is moved as the result of tail call optimization.
5457 int TailCallReturnAddrDelta;
9194 CalleeSavedFrameSize(0),
9295 BytesToPopOnReturn(0),
9396 ReturnAddrIndex(0),
97 FrameAddrIndex(0),
9498 TailCallReturnAddrDelta(0),
9599 SRetReturnReg(0),
96100 GlobalBaseReg(0),
108112 CalleeSavedFrameSize(0),
109113 BytesToPopOnReturn(0),
110114 ReturnAddrIndex(0),
115 FrameAddrIndex(0),
111116 TailCallReturnAddrDelta(0),
112117 SRetReturnReg(0),
113118 GlobalBaseReg(0),
137142
138143 int getRAIndex() const { return ReturnAddrIndex; }
139144 void setRAIndex(int Index) { ReturnAddrIndex = Index; }
145
146 int getFAIndex() const { return FrameAddrIndex; }
147 void setFAIndex(int Index) { FrameAddrIndex = Index; }
140148
141149 int getTCReturnAddrDelta() const { return TailCallReturnAddrDelta; }
142150 void setTCReturnAddrDelta(int delta) {TailCallReturnAddrDelta = delta;}
3131 }
3232
3333 ; CHECK-LABEL: alloc_func:
34 ; CHECK: subq $48, %rsp
35 ; CHECK: .seh_stackalloc 48
36 ; CHECK: leaq 48(%rsp), %rbp
37 ; CHECK: .seh_setframe 5, 48
3438 ; CHECK: .Lframeallocation_alloc_func = -[[offs:[0-9]+]]
3539 ; CHECK: movl $42, -[[offs]](%rbp)
36 ; CHECK: movq %rbp, %rcx
40 ; CHECK: leaq -48(%rbp), %rcx
3741 ; CHECK: callq print_framealloc_from_fp
3842 ; CHECK: retq