Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit e228078

Browse files
Artyom SkrobovArtyom Skrobov
authored andcommitted
Generate the DWARF stack frame decode operations in the function prologue for ARM/Thumb functions.
Patch by Keith Walker! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201423 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 54136ca commit e228078

13 files changed

+1195
-47
lines changed

lib/CodeGen/AsmPrinter/ARMException.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
using namespace llvm;
3838

3939
ARMException::ARMException(AsmPrinter *A)
40-
: DwarfException(A) {}
40+
: DwarfException(A),
41+
shouldEmitCFI(false) {}
4142

4243
ARMException::~ARMException() {}
4344

@@ -46,7 +47,11 @@ ARMTargetStreamer &ARMException::getTargetStreamer() {
4647
return static_cast<ARMTargetStreamer &>(TS);
4748
}
4849

50+
/// endModule - Emit all exception information that should come after the
51+
/// content.
4952
void ARMException::endModule() {
53+
if (shouldEmitCFI)
54+
Asm->OutStreamer.EmitCFISections(false, true);
5055
}
5156

5257
/// beginFunction - Gather pre-function exception information. Assumes it's
@@ -56,11 +61,22 @@ void ARMException::beginFunction(const MachineFunction *MF) {
5661
if (Asm->MF->getFunction()->needsUnwindTableEntry())
5762
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
5863
Asm->getFunctionNumber()));
64+
// See if we need call frame info.
65+
AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
66+
assert(MoveType != AsmPrinter::CFI_M_EH &&
67+
"non-EH CFI not yet supported in prologue with EHABI lowering");
68+
if (MoveType == AsmPrinter::CFI_M_Debug) {
69+
shouldEmitCFI = true;
70+
Asm->OutStreamer.EmitCFIStartProc(false);
71+
}
5972
}
6073

6174
/// endFunction - Gather and emit post-function exception information.
6275
///
6376
void ARMException::endFunction(const MachineFunction *) {
77+
if (shouldEmitCFI)
78+
Asm->OutStreamer.EmitCFIEndProc();
79+
6480
ARMTargetStreamer &ATS = getTargetStreamer();
6581
if (!Asm->MF->getFunction()->needsUnwindTableEntry())
6682
ATS.emitCantUnwind();

lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,10 @@ bool AsmPrinter::needsSEHMoves() {
697697
void AsmPrinter::emitPrologLabel(const MachineInstr &MI) {
698698
const MCSymbol *Label = MI.getOperand(0).getMCSymbol();
699699

700-
if (MAI->getExceptionHandlingType() != ExceptionHandling::DwarfCFI)
700+
ExceptionHandling::ExceptionsType ExceptionHandlingType =
701+
MAI->getExceptionHandlingType();
702+
if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
703+
ExceptionHandlingType != ExceptionHandling::ARM)
701704
return;
702705

703706
if (needsCFIMoves() == CFI_M_None)

lib/CodeGen/AsmPrinter/DwarfException.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ class ARMException : public DwarfException {
186186
void EmitTypeInfos(unsigned TTypeEncoding);
187187
ARMTargetStreamer &getTargetStreamer();
188188

189+
/// shouldEmitCFI - Per-function flag to indicate if frame CFI info
190+
/// should be emitted.
191+
bool shouldEmitCFI;
192+
189193
public:
190194
//===--------------------------------------------------------------------===//
191195
// Main entry points.

lib/Target/ARM/ARMFrameLowering.cpp

Lines changed: 181 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
#include "llvm/CodeGen/MachineFrameInfo.h"
2020
#include "llvm/CodeGen/MachineFunction.h"
2121
#include "llvm/CodeGen/MachineInstrBuilder.h"
22+
#include "llvm/CodeGen/MachineModuleInfo.h"
2223
#include "llvm/CodeGen/MachineRegisterInfo.h"
2324
#include "llvm/CodeGen/RegisterScavenging.h"
2425
#include "llvm/IR/CallingConv.h"
2526
#include "llvm/IR/Function.h"
27+
#include "llvm/MC/MCContext.h"
2628
#include "llvm/Support/CommandLine.h"
2729
#include "llvm/Target/TargetOptions.h"
2830

@@ -129,11 +131,24 @@ static void emitSPUpdate(bool isARM, MachineBasicBlock &MBB,
129131
MIFlags, Pred, PredReg);
130132
}
131133

134+
static int sizeOfSPAdjustment(const MachineInstr *MI) {
135+
assert(MI->getOpcode() == ARM::VSTMDDB_UPD);
136+
int count = 0;
137+
// ARM and Thumb2 push/pop insts have explicit "sp, sp" operands (+
138+
// pred) so the list starts at 4.
139+
for (int i = MI->getNumOperands() - 1; i >= 4; --i)
140+
count += 8;
141+
return count;
142+
}
143+
132144
void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
133145
MachineBasicBlock &MBB = MF.front();
134146
MachineBasicBlock::iterator MBBI = MBB.begin();
135147
MachineFrameInfo *MFI = MF.getFrameInfo();
136148
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
149+
MachineModuleInfo &MMI = MF.getMMI();
150+
MCContext &Context = MMI.getContext();
151+
const MCRegisterInfo *MRI = Context.getRegisterInfo();
137152
const ARMBaseRegisterInfo *RegInfo =
138153
static_cast<const ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo());
139154
const ARMBaseInstrInfo &TII =
@@ -147,6 +162,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
147162
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
148163
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
149164
unsigned FramePtr = RegInfo->getFrameRegister(MF);
165+
int CFAOffset = 0;
150166

151167
// Determine the sizes of each callee-save spill areas and record which frame
152168
// belongs to which callee-save spill areas.
@@ -160,21 +176,46 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
160176
return;
161177

162178
// Allocate the vararg register save area. This is not counted in NumBytes.
163-
if (ArgRegsSaveSize)
179+
if (ArgRegsSaveSize) {
164180
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
165181
MachineInstr::FrameSetup);
182+
MCSymbol *SPLabel = Context.CreateTempSymbol();
183+
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
184+
.addSym(SPLabel);
185+
CFAOffset -= ArgRegsSaveSize;
186+
MMI.addFrameInst(
187+
MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
188+
}
166189

167190
if (!AFI->hasStackFrame()) {
168-
if (NumBytes != 0)
191+
if (NumBytes != 0) {
169192
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
170193
MachineInstr::FrameSetup);
194+
MCSymbol *SPLabel = Context.CreateTempSymbol();
195+
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
196+
.addSym(SPLabel);
197+
CFAOffset -= NumBytes;
198+
MMI.addFrameInst(MCCFIInstruction::createDefCfaOffset(SPLabel,
199+
CFAOffset));
200+
}
171201
return;
172202
}
173203

204+
// Determine spill area sizes.
174205
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
175206
unsigned Reg = CSI[i].getReg();
176207
int FI = CSI[i].getFrameIdx();
177208
switch (Reg) {
209+
case ARM::R8:
210+
case ARM::R9:
211+
case ARM::R10:
212+
case ARM::R11:
213+
case ARM::R12:
214+
if (STI.isTargetMachO()) {
215+
GPRCS2Size += 4;
216+
break;
217+
}
218+
// fallthrough
178219
case ARM::R0:
179220
case ARM::R1:
180221
case ARM::R2:
@@ -188,18 +229,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
188229
FramePtrSpillFI = FI;
189230
GPRCS1Size += 4;
190231
break;
191-
case ARM::R8:
192-
case ARM::R9:
193-
case ARM::R10:
194-
case ARM::R11:
195-
case ARM::R12:
196-
if (Reg == FramePtr)
197-
FramePtrSpillFI = FI;
198-
if (STI.isTargetMachO())
199-
GPRCS2Size += 4;
200-
else
201-
GPRCS1Size += 4;
202-
break;
203232
default:
204233
// This is a DPR. Exclude the aligned DPRCS2 spills.
205234
if (Reg == ARM::D8)
@@ -210,9 +239,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
210239
}
211240

212241
// Move past area 1.
213-
MachineBasicBlock::iterator LastPush = MBB.end(), FramePtrPush;
242+
MachineBasicBlock::iterator LastPush = MBB.end(), GPRCS1Push, GPRCS2Push,
243+
DPRCSPush;
214244
if (GPRCS1Size > 0)
215-
FramePtrPush = LastPush = MBBI++;
245+
GPRCS1Push = LastPush = MBBI++;
216246

217247
// Determine starting offsets of spill areas.
218248
bool HasFP = hasFP(MF);
@@ -230,13 +260,12 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
230260
AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
231261

232262
// Move past area 2.
233-
if (GPRCS2Size > 0) {
234-
LastPush = MBBI++;
235-
}
263+
if (GPRCS2Size > 0)
264+
GPRCS2Push = LastPush = MBBI++;
236265

237266
// Move past area 3.
238267
if (DPRCSSize > 0) {
239-
LastPush = MBBI++;
268+
DPRCSPush = MBBI;
240269
// Since vpush register list cannot have gaps, there may be multiple vpush
241270
// instructions in the prologue.
242271
while (MBBI->getOpcode() == ARM::VSTMDDB_UPD)
@@ -254,11 +283,15 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
254283
} else
255284
NumBytes = DPRCSOffset;
256285

286+
unsigned adjustedGPRCS1Size = GPRCS1Size;
257287
if (NumBytes) {
258288
// Adjust SP after all the callee-save spills.
259289
if (tryFoldSPUpdateIntoPushPop(STI, MF, LastPush, NumBytes)) {
260-
if (LastPush == FramePtrPush)
290+
if (LastPush == GPRCS1Push) {
261291
FramePtrOffsetInPush += NumBytes;
292+
adjustedGPRCS1Size += NumBytes;
293+
NumBytes = 0;
294+
}
262295
} else
263296
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
264297
MachineInstr::FrameSetup);
@@ -275,17 +308,142 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
275308
AFI->setShouldRestoreSPFromFP(true);
276309
}
277310

311+
if (adjustedGPRCS1Size > 0) {
312+
MCSymbol *SPLabel = Context.CreateTempSymbol();
313+
BuildMI(MBB, ++GPRCS1Push, dl, TII.get(TargetOpcode::PROLOG_LABEL))
314+
.addSym(SPLabel);
315+
CFAOffset -= adjustedGPRCS1Size;
316+
MMI.addFrameInst(
317+
MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
318+
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
319+
E = CSI.end(); I != E; ++I) {
320+
unsigned Reg = I->getReg();
321+
int FI = I->getFrameIdx();
322+
switch (Reg) {
323+
case ARM::R8:
324+
case ARM::R9:
325+
case ARM::R10:
326+
case ARM::R11:
327+
case ARM::R12:
328+
if (STI.isTargetMachO())
329+
break;
330+
// fallthrough
331+
case ARM::R0:
332+
case ARM::R1:
333+
case ARM::R2:
334+
case ARM::R3:
335+
case ARM::R4:
336+
case ARM::R5:
337+
case ARM::R6:
338+
case ARM::R7:
339+
case ARM::LR:
340+
MMI.addFrameInst(MCCFIInstruction::createOffset(SPLabel,
341+
MRI->getDwarfRegNum(Reg, true),
342+
MFI->getObjectOffset(FI) - ArgRegsSaveSize));
343+
break;
344+
}
345+
}
346+
}
347+
278348
// Set FP to point to the stack slot that contains the previous FP.
279349
// For iOS, FP is R7, which has now been stored in spill area 1.
280350
// Otherwise, if this is not iOS, all the callee-saved registers go
281351
// into spill area 1, including the FP in R11. In either case, it
282352
// is in area one and the adjustment needs to take place just after
283353
// that push.
284-
if (HasFP)
285-
emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, ++FramePtrPush, dl, TII,
354+
if (HasFP) {
355+
emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, GPRCS1Push, dl, TII,
286356
FramePtr, ARM::SP, FramePtrOffsetInPush,
287357
MachineInstr::FrameSetup);
358+
MCSymbol *SPLabel = Context.CreateTempSymbol();
359+
BuildMI(MBB, GPRCS1Push, dl, TII.get(TargetOpcode::PROLOG_LABEL))
360+
.addSym(SPLabel);
361+
if (FramePtrOffsetInPush) {
362+
CFAOffset += FramePtrOffsetInPush;
363+
MMI.addFrameInst(
364+
MCCFIInstruction::createDefCfa(SPLabel,
365+
MRI->getDwarfRegNum(FramePtr, true), CFAOffset));
366+
} else
367+
MMI.addFrameInst(
368+
MCCFIInstruction::createDefCfaRegister(SPLabel,
369+
MRI->getDwarfRegNum(FramePtr, true)));
370+
}
288371

372+
if (GPRCS2Size > 0) {
373+
MCSymbol *SPLabel = Context.CreateTempSymbol();
374+
BuildMI(MBB, ++GPRCS2Push, dl, TII.get(TargetOpcode::PROLOG_LABEL))
375+
.addSym(SPLabel);
376+
if (!HasFP) {
377+
CFAOffset -= GPRCS2Size;
378+
MMI.addFrameInst(
379+
MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
380+
}
381+
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
382+
E = CSI.end(); I != E; ++I) {
383+
unsigned Reg = I->getReg();
384+
int FI = I->getFrameIdx();
385+
switch (Reg) {
386+
case ARM::R8:
387+
case ARM::R9:
388+
case ARM::R10:
389+
case ARM::R11:
390+
case ARM::R12:
391+
if (STI.isTargetMachO()) {
392+
unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
393+
unsigned Offset = MFI->getObjectOffset(FI) - ArgRegsSaveSize;
394+
MMI.addFrameInst(
395+
MCCFIInstruction::createOffset(SPLabel, DwarfReg, Offset));
396+
}
397+
break;
398+
}
399+
}
400+
}
401+
402+
if (DPRCSSize > 0) {
403+
// Since vpush register list cannot have gaps, there may be multiple vpush
404+
// instructions in the prologue.
405+
MCSymbol *SPLabel = NULL;
406+
do {
407+
MachineBasicBlock::iterator Push = DPRCSPush++;
408+
if (!HasFP) {
409+
SPLabel = Context.CreateTempSymbol();
410+
BuildMI(MBB, DPRCSPush, dl, TII.get(TargetOpcode::PROLOG_LABEL))
411+
.addSym(SPLabel);
412+
CFAOffset -= sizeOfSPAdjustment(Push);;
413+
MMI.addFrameInst(
414+
MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
415+
}
416+
} while (DPRCSPush->getOpcode() == ARM::VSTMDDB_UPD);
417+
418+
if (!SPLabel) {
419+
SPLabel = Context.CreateTempSymbol();
420+
BuildMI(MBB, DPRCSPush, dl, TII.get(TargetOpcode::PROLOG_LABEL))
421+
.addSym(SPLabel);
422+
}
423+
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
424+
E = CSI.end(); I != E; ++I) {
425+
unsigned Reg = I->getReg();
426+
int FI = I->getFrameIdx();
427+
if ((Reg >= ARM::D0 && Reg <= ARM::D31) &&
428+
(Reg < ARM::D8 || Reg >= ARM::D8 + AFI->getNumAlignedDPRCS2Regs())) {
429+
unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
430+
unsigned Offset = MFI->getObjectOffset(FI);
431+
MMI.addFrameInst(MCCFIInstruction::createOffset(SPLabel, DwarfReg,
432+
Offset));
433+
}
434+
}
435+
}
436+
437+
if (NumBytes) {
438+
if (!HasFP) {
439+
MCSymbol *SPLabel = Context.CreateTempSymbol();
440+
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
441+
.addSym(SPLabel);
442+
CFAOffset -= NumBytes;
443+
MMI.addFrameInst(
444+
MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
445+
}
446+
}
289447

290448
if (STI.isTargetELF() && hasFP(MF))
291449
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -

0 commit comments

Comments
 (0)