1 //===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines a JITDwarfEmitter object that is used by the JIT to
11 // write dwarf tables to memory.
13 //===----------------------------------------------------------------------===//
16 #include "JITDwarfEmitter.h"
17 #include "llvm/Function.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/CodeGen/JITCodeEmitter.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineLocation.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/ExecutionEngine/JITMemoryManager.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/Target/TargetData.h"
27 #include "llvm/Target/TargetInstrInfo.h"
28 #include "llvm/Target/TargetFrameInfo.h"
29 #include "llvm/Target/TargetMachine.h"
30 #include "llvm/Target/TargetRegisterInfo.h"
33 JITDwarfEmitter::JITDwarfEmitter(JIT
& theJit
) : Jit(theJit
) {}
36 unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction
& F
,
38 unsigned char* StartFunction
,
39 unsigned char* EndFunction
) {
40 const TargetMachine
& TM
= F
.getTarget();
41 TD
= TM
.getTargetData();
42 needsIndirectEncoding
= TM
.getMCAsmInfo()->getNeedsIndirectEncoding();
43 stackGrowthDirection
= TM
.getFrameInfo()->getStackGrowthDirection();
44 RI
= TM
.getRegisterInfo();
47 unsigned char* ExceptionTable
= EmitExceptionTable(&F
, StartFunction
,
50 unsigned char* Result
= 0;
51 unsigned char* EHFramePtr
= 0;
53 const std::vector
<Function
*> Personalities
= MMI
->getPersonalities();
54 EHFramePtr
= EmitCommonEHFrame(Personalities
[MMI
->getPersonalityIndex()]);
56 Result
= EmitEHFrame(Personalities
[MMI
->getPersonalityIndex()], EHFramePtr
,
57 StartFunction
, EndFunction
, ExceptionTable
);
64 JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr
,
65 const std::vector
<MachineMove
> &Moves
) const {
66 unsigned PointerSize
= TD
->getPointerSize();
67 int stackGrowth
= stackGrowthDirection
== TargetFrameInfo::StackGrowsUp
?
68 PointerSize
: -PointerSize
;
70 unsigned BaseLabelID
= 0;
72 for (unsigned i
= 0, N
= Moves
.size(); i
< N
; ++i
) {
73 const MachineMove
&Move
= Moves
[i
];
74 unsigned LabelID
= Move
.getLabelID();
77 LabelID
= MMI
->MappedLabel(LabelID
);
79 // Throw out move if the label is invalid.
80 if (!LabelID
) continue;
83 intptr_t LabelPtr
= 0;
84 if (LabelID
) LabelPtr
= JCE
->getLabelAddress(LabelID
);
86 const MachineLocation
&Dst
= Move
.getDestination();
87 const MachineLocation
&Src
= Move
.getSource();
89 // Advance row if new location.
90 if (BaseLabelPtr
&& LabelID
&& (BaseLabelID
!= LabelID
|| !IsLocal
)) {
91 JCE
->emitByte(dwarf::DW_CFA_advance_loc4
);
92 JCE
->emitInt32(LabelPtr
- BaseLabelPtr
);
94 BaseLabelID
= LabelID
;
95 BaseLabelPtr
= LabelPtr
;
100 if (Dst
.isReg() && Dst
.getReg() == MachineLocation::VirtualFP
) {
102 if (Src
.getReg() == MachineLocation::VirtualFP
) {
103 JCE
->emitByte(dwarf::DW_CFA_def_cfa_offset
);
105 JCE
->emitByte(dwarf::DW_CFA_def_cfa
);
106 JCE
->emitULEB128Bytes(RI
->getDwarfRegNum(Src
.getReg(), true));
109 JCE
->emitULEB128Bytes(-Src
.getOffset());
111 llvm_unreachable("Machine move not supported yet.");
113 } else if (Src
.isReg() &&
114 Src
.getReg() == MachineLocation::VirtualFP
) {
116 JCE
->emitByte(dwarf::DW_CFA_def_cfa_register
);
117 JCE
->emitULEB128Bytes(RI
->getDwarfRegNum(Dst
.getReg(), true));
119 llvm_unreachable("Machine move not supported yet.");
122 unsigned Reg
= RI
->getDwarfRegNum(Src
.getReg(), true);
123 int Offset
= Dst
.getOffset() / stackGrowth
;
126 JCE
->emitByte(dwarf::DW_CFA_offset_extended_sf
);
127 JCE
->emitULEB128Bytes(Reg
);
128 JCE
->emitSLEB128Bytes(Offset
);
129 } else if (Reg
< 64) {
130 JCE
->emitByte(dwarf::DW_CFA_offset
+ Reg
);
131 JCE
->emitULEB128Bytes(Offset
);
133 JCE
->emitByte(dwarf::DW_CFA_offset_extended
);
134 JCE
->emitULEB128Bytes(Reg
);
135 JCE
->emitULEB128Bytes(Offset
);
141 /// SharedTypeIds - How many leading type ids two landing pads have in common.
142 static unsigned SharedTypeIds(const LandingPadInfo
*L
,
143 const LandingPadInfo
*R
) {
144 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
145 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
146 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
149 for (; Count
!= MinSize
; ++Count
)
150 if (LIds
[Count
] != RIds
[Count
])
157 /// PadLT - Order landing pads lexicographically by type id.
158 static bool PadLT(const LandingPadInfo
*L
, const LandingPadInfo
*R
) {
159 const std::vector
<int> &LIds
= L
->TypeIds
, &RIds
= R
->TypeIds
;
160 unsigned LSize
= LIds
.size(), RSize
= RIds
.size();
161 unsigned MinSize
= LSize
< RSize
? LSize
: RSize
;
163 for (unsigned i
= 0; i
!= MinSize
; ++i
)
164 if (LIds
[i
] != RIds
[i
])
165 return LIds
[i
] < RIds
[i
];
167 return LSize
< RSize
;
173 static inline unsigned getEmptyKey() { return -1U; }
174 static inline unsigned getTombstoneKey() { return -2U; }
175 static unsigned getHashValue(const unsigned &Key
) { return Key
; }
176 static bool isEqual(unsigned LHS
, unsigned RHS
) { return LHS
== RHS
; }
177 static bool isPod() { return true; }
180 /// ActionEntry - Structure describing an entry in the actions table.
182 int ValueForTypeID
; // The value to write - may not be equal to the type id.
184 struct ActionEntry
*Previous
;
187 /// PadRange - Structure holding a try-range and the associated landing pad.
189 // The index of the landing pad.
191 // The index of the begin and end labels in the landing pad's label lists.
195 typedef DenseMap
<unsigned, PadRange
, KeyInfo
> RangeMapType
;
197 /// CallSiteEntry - Structure describing an entry in the call-site table.
198 struct CallSiteEntry
{
199 unsigned BeginLabel
; // zero indicates the start of the function.
200 unsigned EndLabel
; // zero indicates the end of the function.
201 unsigned PadLabel
; // zero indicates that there is no landing pad.
207 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction
* MF
,
208 unsigned char* StartFunction
,
209 unsigned char* EndFunction
) const {
210 // Map all labels and get rid of any dead landing pads.
211 MMI
->TidyLandingPads();
213 const std::vector
<GlobalVariable
*> &TypeInfos
= MMI
->getTypeInfos();
214 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
215 const std::vector
<LandingPadInfo
> &PadInfos
= MMI
->getLandingPads();
216 if (PadInfos
.empty()) return 0;
218 // Sort the landing pads in order of their type ids. This is used to fold
219 // duplicate actions.
220 SmallVector
<const LandingPadInfo
*, 64> LandingPads
;
221 LandingPads
.reserve(PadInfos
.size());
222 for (unsigned i
= 0, N
= PadInfos
.size(); i
!= N
; ++i
)
223 LandingPads
.push_back(&PadInfos
[i
]);
224 std::sort(LandingPads
.begin(), LandingPads
.end(), PadLT
);
226 // Negative type ids index into FilterIds, positive type ids index into
227 // TypeInfos. The value written for a positive type id is just the type
228 // id itself. For a negative type id, however, the value written is the
229 // (negative) byte offset of the corresponding FilterIds entry. The byte
230 // offset is usually equal to the type id, because the FilterIds entries
231 // are written using a variable width encoding which outputs one byte per
232 // entry as long as the value written is not too large, but can differ.
233 // This kind of complication does not occur for positive type ids because
234 // type infos are output using a fixed width encoding.
235 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
236 SmallVector
<int, 16> FilterOffsets
;
237 FilterOffsets
.reserve(FilterIds
.size());
239 for(std::vector
<unsigned>::const_iterator I
= FilterIds
.begin(),
240 E
= FilterIds
.end(); I
!= E
; ++I
) {
241 FilterOffsets
.push_back(Offset
);
242 Offset
-= MCAsmInfo::getULEB128Size(*I
);
245 // Compute the actions table and gather the first action index for each
247 SmallVector
<ActionEntry
, 32> Actions
;
248 SmallVector
<unsigned, 64> FirstActions
;
249 FirstActions
.reserve(LandingPads
.size());
252 unsigned SizeActions
= 0;
253 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
254 const LandingPadInfo
*LP
= LandingPads
[i
];
255 const std::vector
<int> &TypeIds
= LP
->TypeIds
;
256 const unsigned NumShared
= i
? SharedTypeIds(LP
, LandingPads
[i
-1]) : 0;
257 unsigned SizeSiteActions
= 0;
259 if (NumShared
< TypeIds
.size()) {
260 unsigned SizeAction
= 0;
261 ActionEntry
*PrevAction
= 0;
264 const unsigned SizePrevIds
= LandingPads
[i
-1]->TypeIds
.size();
265 assert(Actions
.size());
266 PrevAction
= &Actions
.back();
267 SizeAction
= MCAsmInfo::getSLEB128Size(PrevAction
->NextAction
) +
268 MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
269 for (unsigned j
= NumShared
; j
!= SizePrevIds
; ++j
) {
270 SizeAction
-= MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
271 SizeAction
+= -PrevAction
->NextAction
;
272 PrevAction
= PrevAction
->Previous
;
276 // Compute the actions.
277 for (unsigned I
= NumShared
, M
= TypeIds
.size(); I
!= M
; ++I
) {
278 int TypeID
= TypeIds
[I
];
279 assert(-1-TypeID
< (int)FilterOffsets
.size() && "Unknown filter id!");
280 int ValueForTypeID
= TypeID
< 0 ? FilterOffsets
[-1 - TypeID
] : TypeID
;
281 unsigned SizeTypeID
= MCAsmInfo::getSLEB128Size(ValueForTypeID
);
283 int NextAction
= SizeAction
? -(SizeAction
+ SizeTypeID
) : 0;
284 SizeAction
= SizeTypeID
+ MCAsmInfo::getSLEB128Size(NextAction
);
285 SizeSiteActions
+= SizeAction
;
287 ActionEntry Action
= {ValueForTypeID
, NextAction
, PrevAction
};
288 Actions
.push_back(Action
);
290 PrevAction
= &Actions
.back();
293 // Record the first action of the landing pad site.
294 FirstAction
= SizeActions
+ SizeSiteActions
- SizeAction
+ 1;
295 } // else identical - re-use previous FirstAction
297 FirstActions
.push_back(FirstAction
);
299 // Compute this sites contribution to size.
300 SizeActions
+= SizeSiteActions
;
303 // Compute the call-site table. Entries must be ordered by address.
304 SmallVector
<CallSiteEntry
, 64> CallSites
;
307 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
308 const LandingPadInfo
*LandingPad
= LandingPads
[i
];
309 for (unsigned j
=0, E
= LandingPad
->BeginLabels
.size(); j
!= E
; ++j
) {
310 unsigned BeginLabel
= LandingPad
->BeginLabels
[j
];
311 assert(!PadMap
.count(BeginLabel
) && "Duplicate landing pad labels!");
312 PadRange P
= { i
, j
};
313 PadMap
[BeginLabel
] = P
;
317 bool MayThrow
= false;
318 unsigned LastLabel
= 0;
319 for (MachineFunction::const_iterator I
= MF
->begin(), E
= MF
->end();
321 for (MachineBasicBlock::const_iterator MI
= I
->begin(), E
= I
->end();
323 if (!MI
->isLabel()) {
324 MayThrow
|= MI
->getDesc().isCall();
328 unsigned BeginLabel
= MI
->getOperand(0).getImm();
329 assert(BeginLabel
&& "Invalid label!");
331 if (BeginLabel
== LastLabel
)
334 RangeMapType::iterator L
= PadMap
.find(BeginLabel
);
336 if (L
== PadMap
.end())
339 PadRange P
= L
->second
;
340 const LandingPadInfo
*LandingPad
= LandingPads
[P
.PadIndex
];
342 assert(BeginLabel
== LandingPad
->BeginLabels
[P
.RangeIndex
] &&
343 "Inconsistent landing pad map!");
345 // If some instruction between the previous try-range and this one may
346 // throw, create a call-site entry with no landing pad for the region
347 // between the try-ranges.
349 CallSiteEntry Site
= {LastLabel
, BeginLabel
, 0, 0};
350 CallSites
.push_back(Site
);
353 LastLabel
= LandingPad
->EndLabels
[P
.RangeIndex
];
354 CallSiteEntry Site
= {BeginLabel
, LastLabel
,
355 LandingPad
->LandingPadLabel
, FirstActions
[P
.PadIndex
]};
357 assert(Site
.BeginLabel
&& Site
.EndLabel
&& Site
.PadLabel
&&
358 "Invalid landing pad!");
360 // Try to merge with the previous call-site.
361 if (CallSites
.size()) {
362 CallSiteEntry
&Prev
= CallSites
.back();
363 if (Site
.PadLabel
== Prev
.PadLabel
&& Site
.Action
== Prev
.Action
) {
364 // Extend the range of the previous entry.
365 Prev
.EndLabel
= Site
.EndLabel
;
370 // Otherwise, create a new call-site.
371 CallSites
.push_back(Site
);
374 // If some instruction between the previous try-range and the end of the
375 // function may throw, create a call-site entry with no landing pad for the
376 // region following the try-range.
378 CallSiteEntry Site
= {LastLabel
, 0, 0, 0};
379 CallSites
.push_back(Site
);
383 unsigned SizeSites
= CallSites
.size() * (sizeof(int32_t) + // Site start.
384 sizeof(int32_t) + // Site length.
385 sizeof(int32_t)); // Landing pad.
386 for (unsigned i
= 0, e
= CallSites
.size(); i
< e
; ++i
)
387 SizeSites
+= MCAsmInfo::getULEB128Size(CallSites
[i
].Action
);
389 unsigned SizeTypes
= TypeInfos
.size() * TD
->getPointerSize();
391 unsigned TypeOffset
= sizeof(int8_t) + // Call site format
392 // Call-site table length
393 MCAsmInfo::getULEB128Size(SizeSites
) +
394 SizeSites
+ SizeActions
+ SizeTypes
;
396 // Begin the exception table.
397 JCE
->emitAlignmentWithFill(4, 0);
398 // Asm->EOL("Padding");
400 unsigned char* DwarfExceptionTable
= (unsigned char*)JCE
->getCurrentPCValue();
403 JCE
->emitByte(dwarf::DW_EH_PE_omit
);
404 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
405 JCE
->emitByte(dwarf::DW_EH_PE_absptr
);
406 // Asm->EOL("TType format (DW_EH_PE_absptr)");
407 JCE
->emitULEB128Bytes(TypeOffset
);
408 // Asm->EOL("TType base offset");
409 JCE
->emitByte(dwarf::DW_EH_PE_udata4
);
410 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
411 JCE
->emitULEB128Bytes(SizeSites
);
412 // Asm->EOL("Call-site table length");
414 // Emit the landing pad site information.
415 for (unsigned i
= 0; i
< CallSites
.size(); ++i
) {
416 CallSiteEntry
&S
= CallSites
[i
];
417 intptr_t BeginLabelPtr
= 0;
418 intptr_t EndLabelPtr
= 0;
421 BeginLabelPtr
= (intptr_t)StartFunction
;
424 BeginLabelPtr
= JCE
->getLabelAddress(S
.BeginLabel
);
425 JCE
->emitInt32(BeginLabelPtr
- (intptr_t)StartFunction
);
428 // Asm->EOL("Region start");
431 EndLabelPtr
= (intptr_t)EndFunction
;
432 JCE
->emitInt32((intptr_t)EndFunction
- BeginLabelPtr
);
434 EndLabelPtr
= JCE
->getLabelAddress(S
.EndLabel
);
435 JCE
->emitInt32(EndLabelPtr
- BeginLabelPtr
);
437 //Asm->EOL("Region length");
442 unsigned PadLabelPtr
= JCE
->getLabelAddress(S
.PadLabel
);
443 JCE
->emitInt32(PadLabelPtr
- (intptr_t)StartFunction
);
445 // Asm->EOL("Landing pad");
447 JCE
->emitULEB128Bytes(S
.Action
);
448 // Asm->EOL("Action");
452 for (unsigned I
= 0, N
= Actions
.size(); I
!= N
; ++I
) {
453 ActionEntry
&Action
= Actions
[I
];
455 JCE
->emitSLEB128Bytes(Action
.ValueForTypeID
);
456 //Asm->EOL("TypeInfo index");
457 JCE
->emitSLEB128Bytes(Action
.NextAction
);
458 //Asm->EOL("Next action");
461 // Emit the type ids.
462 for (unsigned M
= TypeInfos
.size(); M
; --M
) {
463 GlobalVariable
*GV
= TypeInfos
[M
- 1];
466 if (TD
->getPointerSize() == sizeof(int32_t))
467 JCE
->emitInt32((intptr_t)Jit
.getOrEmitGlobalVariable(GV
));
469 JCE
->emitInt64((intptr_t)Jit
.getOrEmitGlobalVariable(GV
));
471 if (TD
->getPointerSize() == sizeof(int32_t))
476 // Asm->EOL("TypeInfo");
479 // Emit the filter typeids.
480 for (unsigned j
= 0, M
= FilterIds
.size(); j
< M
; ++j
) {
481 unsigned TypeID
= FilterIds
[j
];
482 JCE
->emitULEB128Bytes(TypeID
);
483 //Asm->EOL("Filter TypeInfo index");
486 JCE
->emitAlignmentWithFill(4, 0);
488 return DwarfExceptionTable
;
492 JITDwarfEmitter::EmitCommonEHFrame(const Function
* Personality
) const {
493 unsigned PointerSize
= TD
->getPointerSize();
494 int stackGrowth
= stackGrowthDirection
== TargetFrameInfo::StackGrowsUp
?
495 PointerSize
: -PointerSize
;
497 unsigned char* StartCommonPtr
= (unsigned char*)JCE
->getCurrentPCValue();
498 // EH Common Frame header
499 JCE
->allocateSpace(4, 0);
500 unsigned char* FrameCommonBeginPtr
= (unsigned char*)JCE
->getCurrentPCValue();
501 JCE
->emitInt32((int)0);
502 JCE
->emitByte(dwarf::DW_CIE_VERSION
);
503 JCE
->emitString(Personality
? "zPLR" : "zR");
504 JCE
->emitULEB128Bytes(1);
505 JCE
->emitSLEB128Bytes(stackGrowth
);
506 JCE
->emitByte(RI
->getDwarfRegNum(RI
->getRARegister(), true));
509 // Augmentation Size: 3 small ULEBs of one byte each, and the personality
510 // function which size is PointerSize.
511 JCE
->emitULEB128Bytes(3 + PointerSize
);
513 // We set the encoding of the personality as direct encoding because we use
514 // the function pointer. The encoding is not relative because the current
515 // PC value may be bigger than the personality function pointer.
516 if (PointerSize
== 4) {
517 JCE
->emitByte(dwarf::DW_EH_PE_sdata4
);
518 JCE
->emitInt32(((intptr_t)Jit
.getPointerToGlobal(Personality
)));
520 JCE
->emitByte(dwarf::DW_EH_PE_sdata8
);
521 JCE
->emitInt64(((intptr_t)Jit
.getPointerToGlobal(Personality
)));
524 JCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
525 JCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
527 JCE
->emitULEB128Bytes(1);
528 JCE
->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4
);
531 std::vector
<MachineMove
> Moves
;
532 RI
->getInitialFrameState(Moves
);
533 EmitFrameMoves(0, Moves
);
535 JCE
->emitAlignmentWithFill(PointerSize
, dwarf::DW_CFA_nop
);
537 JCE
->emitInt32At((uintptr_t*)StartCommonPtr
,
538 (uintptr_t)((unsigned char*)JCE
->getCurrentPCValue() -
539 FrameCommonBeginPtr
));
541 return StartCommonPtr
;
546 JITDwarfEmitter::EmitEHFrame(const Function
* Personality
,
547 unsigned char* StartCommonPtr
,
548 unsigned char* StartFunction
,
549 unsigned char* EndFunction
,
550 unsigned char* ExceptionTable
) const {
551 unsigned PointerSize
= TD
->getPointerSize();
554 unsigned char* StartEHPtr
= (unsigned char*)JCE
->getCurrentPCValue();
555 JCE
->allocateSpace(4, 0);
556 unsigned char* FrameBeginPtr
= (unsigned char*)JCE
->getCurrentPCValue();
558 JCE
->emitInt32(FrameBeginPtr
- StartCommonPtr
);
559 JCE
->emitInt32(StartFunction
- (unsigned char*)JCE
->getCurrentPCValue());
560 JCE
->emitInt32(EndFunction
- StartFunction
);
562 // If there is a personality and landing pads then point to the language
563 // specific data area in the exception table.
565 JCE
->emitULEB128Bytes(PointerSize
== 4 ? 4 : 8);
567 if (PointerSize
== 4) {
568 if (!MMI
->getLandingPads().empty())
569 JCE
->emitInt32(ExceptionTable
-(unsigned char*)JCE
->getCurrentPCValue());
571 JCE
->emitInt32((int)0);
573 if (!MMI
->getLandingPads().empty())
574 JCE
->emitInt64(ExceptionTable
-(unsigned char*)JCE
->getCurrentPCValue());
576 JCE
->emitInt64((int)0);
579 JCE
->emitULEB128Bytes(0);
582 // Indicate locations of function specific callee saved registers in
584 EmitFrameMoves((intptr_t)StartFunction
, MMI
->getFrameMoves());
586 JCE
->emitAlignmentWithFill(PointerSize
, dwarf::DW_CFA_nop
);
588 // Indicate the size of the table
589 JCE
->emitInt32At((uintptr_t*)StartEHPtr
,
590 (uintptr_t)((unsigned char*)JCE
->getCurrentPCValue() -
593 // Double zeroes for the unwind runtime
594 if (PointerSize
== 8) {
605 unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction
& F
,
607 unsigned char* StartFunction
,
608 unsigned char* EndFunction
) {
609 const TargetMachine
& TM
= F
.getTarget();
610 TD
= TM
.getTargetData();
611 needsIndirectEncoding
= TM
.getMCAsmInfo()->getNeedsIndirectEncoding();
612 stackGrowthDirection
= TM
.getFrameInfo()->getStackGrowthDirection();
613 RI
= TM
.getRegisterInfo();
615 unsigned FinalSize
= 0;
617 FinalSize
+= GetExceptionTableSizeInBytes(&F
);
619 const std::vector
<Function
*> Personalities
= MMI
->getPersonalities();
621 GetCommonEHFrameSizeInBytes(Personalities
[MMI
->getPersonalityIndex()]);
623 FinalSize
+= GetEHFrameSizeInBytes(Personalities
[MMI
->getPersonalityIndex()],
629 /// RoundUpToAlign - Add the specified alignment to FinalSize and returns
631 static unsigned RoundUpToAlign(unsigned FinalSize
, unsigned Alignment
) {
632 if (Alignment
== 0) Alignment
= 1;
633 // Since we do not know where the buffer will be allocated, be pessimistic.
634 return FinalSize
+ Alignment
;
638 JITDwarfEmitter::GetEHFrameSizeInBytes(const Function
* Personality
,
639 unsigned char* StartFunction
) const {
640 unsigned PointerSize
= TD
->getPointerSize();
641 unsigned FinalSize
= 0;
643 FinalSize
+= PointerSize
;
645 FinalSize
+= 3 * PointerSize
;
646 // If there is a personality and landing pads then point to the language
647 // specific data area in the exception table.
649 FinalSize
+= MCAsmInfo::getULEB128Size(4);
650 FinalSize
+= PointerSize
;
652 FinalSize
+= MCAsmInfo::getULEB128Size(0);
655 // Indicate locations of function specific callee saved registers in
657 FinalSize
+= GetFrameMovesSizeInBytes((intptr_t)StartFunction
,
658 MMI
->getFrameMoves());
660 FinalSize
= RoundUpToAlign(FinalSize
, 4);
662 // Double zeroes for the unwind runtime
663 FinalSize
+= 2 * PointerSize
;
668 unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function
* Personality
)
671 unsigned PointerSize
= TD
->getPointerSize();
672 int stackGrowth
= stackGrowthDirection
== TargetFrameInfo::StackGrowsUp
?
673 PointerSize
: -PointerSize
;
674 unsigned FinalSize
= 0;
675 // EH Common Frame header
676 FinalSize
+= PointerSize
;
679 FinalSize
+= Personality
? 5 : 3; // "zPLR" or "zR"
680 FinalSize
+= MCAsmInfo::getULEB128Size(1);
681 FinalSize
+= MCAsmInfo::getSLEB128Size(stackGrowth
);
685 FinalSize
+= MCAsmInfo::getULEB128Size(7);
690 FinalSize
+= PointerSize
;
692 FinalSize
+= MCAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel
);
693 FinalSize
+= MCAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel
);
696 FinalSize
+= MCAsmInfo::getULEB128Size(1);
697 FinalSize
+= MCAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel
);
700 std::vector
<MachineMove
> Moves
;
701 RI
->getInitialFrameState(Moves
);
702 FinalSize
+= GetFrameMovesSizeInBytes(0, Moves
);
703 FinalSize
= RoundUpToAlign(FinalSize
, 4);
708 JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr
,
709 const std::vector
<MachineMove
> &Moves
) const {
710 unsigned PointerSize
= TD
->getPointerSize();
711 int stackGrowth
= stackGrowthDirection
== TargetFrameInfo::StackGrowsUp
?
712 PointerSize
: -PointerSize
;
713 bool IsLocal
= BaseLabelPtr
;
714 unsigned FinalSize
= 0;
716 for (unsigned i
= 0, N
= Moves
.size(); i
< N
; ++i
) {
717 const MachineMove
&Move
= Moves
[i
];
718 unsigned LabelID
= Move
.getLabelID();
721 LabelID
= MMI
->MappedLabel(LabelID
);
723 // Throw out move if the label is invalid.
724 if (!LabelID
) continue;
727 intptr_t LabelPtr
= 0;
728 if (LabelID
) LabelPtr
= JCE
->getLabelAddress(LabelID
);
730 const MachineLocation
&Dst
= Move
.getDestination();
731 const MachineLocation
&Src
= Move
.getSource();
733 // Advance row if new location.
734 if (BaseLabelPtr
&& LabelID
&& (BaseLabelPtr
!= LabelPtr
|| !IsLocal
)) {
736 FinalSize
+= PointerSize
;
737 BaseLabelPtr
= LabelPtr
;
742 if (Dst
.isReg() && Dst
.getReg() == MachineLocation::VirtualFP
) {
744 if (Src
.getReg() == MachineLocation::VirtualFP
) {
748 unsigned RegNum
= RI
->getDwarfRegNum(Src
.getReg(), true);
749 FinalSize
+= MCAsmInfo::getULEB128Size(RegNum
);
752 int Offset
= -Src
.getOffset();
754 FinalSize
+= MCAsmInfo::getULEB128Size(Offset
);
756 llvm_unreachable("Machine move no supported yet.");
758 } else if (Src
.isReg() &&
759 Src
.getReg() == MachineLocation::VirtualFP
) {
762 unsigned RegNum
= RI
->getDwarfRegNum(Dst
.getReg(), true);
763 FinalSize
+= MCAsmInfo::getULEB128Size(RegNum
);
765 llvm_unreachable("Machine move no supported yet.");
768 unsigned Reg
= RI
->getDwarfRegNum(Src
.getReg(), true);
769 int Offset
= Dst
.getOffset() / stackGrowth
;
773 FinalSize
+= MCAsmInfo::getULEB128Size(Reg
);
774 FinalSize
+= MCAsmInfo::getSLEB128Size(Offset
);
775 } else if (Reg
< 64) {
777 FinalSize
+= MCAsmInfo::getULEB128Size(Offset
);
780 FinalSize
+= MCAsmInfo::getULEB128Size(Reg
);
781 FinalSize
+= MCAsmInfo::getULEB128Size(Offset
);
789 JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction
* MF
) const {
790 unsigned FinalSize
= 0;
792 // Map all labels and get rid of any dead landing pads.
793 MMI
->TidyLandingPads();
795 const std::vector
<GlobalVariable
*> &TypeInfos
= MMI
->getTypeInfos();
796 const std::vector
<unsigned> &FilterIds
= MMI
->getFilterIds();
797 const std::vector
<LandingPadInfo
> &PadInfos
= MMI
->getLandingPads();
798 if (PadInfos
.empty()) return 0;
800 // Sort the landing pads in order of their type ids. This is used to fold
801 // duplicate actions.
802 SmallVector
<const LandingPadInfo
*, 64> LandingPads
;
803 LandingPads
.reserve(PadInfos
.size());
804 for (unsigned i
= 0, N
= PadInfos
.size(); i
!= N
; ++i
)
805 LandingPads
.push_back(&PadInfos
[i
]);
806 std::sort(LandingPads
.begin(), LandingPads
.end(), PadLT
);
808 // Negative type ids index into FilterIds, positive type ids index into
809 // TypeInfos. The value written for a positive type id is just the type
810 // id itself. For a negative type id, however, the value written is the
811 // (negative) byte offset of the corresponding FilterIds entry. The byte
812 // offset is usually equal to the type id, because the FilterIds entries
813 // are written using a variable width encoding which outputs one byte per
814 // entry as long as the value written is not too large, but can differ.
815 // This kind of complication does not occur for positive type ids because
816 // type infos are output using a fixed width encoding.
817 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
818 SmallVector
<int, 16> FilterOffsets
;
819 FilterOffsets
.reserve(FilterIds
.size());
821 for(std::vector
<unsigned>::const_iterator I
= FilterIds
.begin(),
822 E
= FilterIds
.end(); I
!= E
; ++I
) {
823 FilterOffsets
.push_back(Offset
);
824 Offset
-= MCAsmInfo::getULEB128Size(*I
);
827 // Compute the actions table and gather the first action index for each
829 SmallVector
<ActionEntry
, 32> Actions
;
830 SmallVector
<unsigned, 64> FirstActions
;
831 FirstActions
.reserve(LandingPads
.size());
834 unsigned SizeActions
= 0;
835 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
836 const LandingPadInfo
*LP
= LandingPads
[i
];
837 const std::vector
<int> &TypeIds
= LP
->TypeIds
;
838 const unsigned NumShared
= i
? SharedTypeIds(LP
, LandingPads
[i
-1]) : 0;
839 unsigned SizeSiteActions
= 0;
841 if (NumShared
< TypeIds
.size()) {
842 unsigned SizeAction
= 0;
843 ActionEntry
*PrevAction
= 0;
846 const unsigned SizePrevIds
= LandingPads
[i
-1]->TypeIds
.size();
847 assert(Actions
.size());
848 PrevAction
= &Actions
.back();
849 SizeAction
= MCAsmInfo::getSLEB128Size(PrevAction
->NextAction
) +
850 MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
851 for (unsigned j
= NumShared
; j
!= SizePrevIds
; ++j
) {
852 SizeAction
-= MCAsmInfo::getSLEB128Size(PrevAction
->ValueForTypeID
);
853 SizeAction
+= -PrevAction
->NextAction
;
854 PrevAction
= PrevAction
->Previous
;
858 // Compute the actions.
859 for (unsigned I
= NumShared
, M
= TypeIds
.size(); I
!= M
; ++I
) {
860 int TypeID
= TypeIds
[I
];
861 assert(-1-TypeID
< (int)FilterOffsets
.size() && "Unknown filter id!");
862 int ValueForTypeID
= TypeID
< 0 ? FilterOffsets
[-1 - TypeID
] : TypeID
;
863 unsigned SizeTypeID
= MCAsmInfo::getSLEB128Size(ValueForTypeID
);
865 int NextAction
= SizeAction
? -(SizeAction
+ SizeTypeID
) : 0;
866 SizeAction
= SizeTypeID
+ MCAsmInfo::getSLEB128Size(NextAction
);
867 SizeSiteActions
+= SizeAction
;
869 ActionEntry Action
= {ValueForTypeID
, NextAction
, PrevAction
};
870 Actions
.push_back(Action
);
872 PrevAction
= &Actions
.back();
875 // Record the first action of the landing pad site.
876 FirstAction
= SizeActions
+ SizeSiteActions
- SizeAction
+ 1;
877 } // else identical - re-use previous FirstAction
879 FirstActions
.push_back(FirstAction
);
881 // Compute this sites contribution to size.
882 SizeActions
+= SizeSiteActions
;
885 // Compute the call-site table. Entries must be ordered by address.
886 SmallVector
<CallSiteEntry
, 64> CallSites
;
889 for (unsigned i
= 0, N
= LandingPads
.size(); i
!= N
; ++i
) {
890 const LandingPadInfo
*LandingPad
= LandingPads
[i
];
891 for (unsigned j
=0, E
= LandingPad
->BeginLabels
.size(); j
!= E
; ++j
) {
892 unsigned BeginLabel
= LandingPad
->BeginLabels
[j
];
893 assert(!PadMap
.count(BeginLabel
) && "Duplicate landing pad labels!");
894 PadRange P
= { i
, j
};
895 PadMap
[BeginLabel
] = P
;
899 bool MayThrow
= false;
900 unsigned LastLabel
= 0;
901 for (MachineFunction::const_iterator I
= MF
->begin(), E
= MF
->end();
903 for (MachineBasicBlock::const_iterator MI
= I
->begin(), E
= I
->end();
905 if (!MI
->isLabel()) {
906 MayThrow
|= MI
->getDesc().isCall();
910 unsigned BeginLabel
= MI
->getOperand(0).getImm();
911 assert(BeginLabel
&& "Invalid label!");
913 if (BeginLabel
== LastLabel
)
916 RangeMapType::iterator L
= PadMap
.find(BeginLabel
);
918 if (L
== PadMap
.end())
921 PadRange P
= L
->second
;
922 const LandingPadInfo
*LandingPad
= LandingPads
[P
.PadIndex
];
924 assert(BeginLabel
== LandingPad
->BeginLabels
[P
.RangeIndex
] &&
925 "Inconsistent landing pad map!");
927 // If some instruction between the previous try-range and this one may
928 // throw, create a call-site entry with no landing pad for the region
929 // between the try-ranges.
931 CallSiteEntry Site
= {LastLabel
, BeginLabel
, 0, 0};
932 CallSites
.push_back(Site
);
935 LastLabel
= LandingPad
->EndLabels
[P
.RangeIndex
];
936 CallSiteEntry Site
= {BeginLabel
, LastLabel
,
937 LandingPad
->LandingPadLabel
, FirstActions
[P
.PadIndex
]};
939 assert(Site
.BeginLabel
&& Site
.EndLabel
&& Site
.PadLabel
&&
940 "Invalid landing pad!");
942 // Try to merge with the previous call-site.
943 if (CallSites
.size()) {
944 CallSiteEntry
&Prev
= CallSites
.back();
945 if (Site
.PadLabel
== Prev
.PadLabel
&& Site
.Action
== Prev
.Action
) {
946 // Extend the range of the previous entry.
947 Prev
.EndLabel
= Site
.EndLabel
;
952 // Otherwise, create a new call-site.
953 CallSites
.push_back(Site
);
956 // If some instruction between the previous try-range and the end of the
957 // function may throw, create a call-site entry with no landing pad for the
958 // region following the try-range.
960 CallSiteEntry Site
= {LastLabel
, 0, 0, 0};
961 CallSites
.push_back(Site
);
965 unsigned SizeSites
= CallSites
.size() * (sizeof(int32_t) + // Site start.
966 sizeof(int32_t) + // Site length.
967 sizeof(int32_t)); // Landing pad.
968 for (unsigned i
= 0, e
= CallSites
.size(); i
< e
; ++i
)
969 SizeSites
+= MCAsmInfo::getULEB128Size(CallSites
[i
].Action
);
971 unsigned SizeTypes
= TypeInfos
.size() * TD
->getPointerSize();
973 unsigned TypeOffset
= sizeof(int8_t) + // Call site format
974 // Call-site table length
975 MCAsmInfo::getULEB128Size(SizeSites
) +
976 SizeSites
+ SizeActions
+ SizeTypes
;
978 unsigned TotalSize
= sizeof(int8_t) + // LPStart format
979 sizeof(int8_t) + // TType format
980 MCAsmInfo::getULEB128Size(TypeOffset
) + // TType base offset
983 unsigned SizeAlign
= (4 - TotalSize
) & 3;
985 // Begin the exception table.
986 FinalSize
= RoundUpToAlign(FinalSize
, 4);
987 for (unsigned i
= 0; i
!= SizeAlign
; ++i
) {
991 unsigned PointerSize
= TD
->getPointerSize();
995 // Asm->EOL("LPStart format (DW_EH_PE_omit)");
997 // Asm->EOL("TType format (DW_EH_PE_absptr)");
999 // Asm->EOL("TType base offset");
1001 // Asm->EOL("Call site format (DW_EH_PE_udata4)");
1003 // Asm->EOL("Call-site table length");
1005 // Emit the landing pad site information.
1006 for (unsigned i
= 0; i
< CallSites
.size(); ++i
) {
1007 CallSiteEntry
&S
= CallSites
[i
];
1009 // Asm->EOL("Region start");
1010 FinalSize
+= PointerSize
;
1012 //Asm->EOL("Region length");
1013 FinalSize
+= PointerSize
;
1015 // Asm->EOL("Landing pad");
1016 FinalSize
+= PointerSize
;
1018 FinalSize
+= MCAsmInfo::getULEB128Size(S
.Action
);
1019 // Asm->EOL("Action");
1022 // Emit the actions.
1023 for (unsigned I
= 0, N
= Actions
.size(); I
!= N
; ++I
) {
1024 ActionEntry
&Action
= Actions
[I
];
1026 //Asm->EOL("TypeInfo index");
1027 FinalSize
+= MCAsmInfo::getSLEB128Size(Action
.ValueForTypeID
);
1028 //Asm->EOL("Next action");
1029 FinalSize
+= MCAsmInfo::getSLEB128Size(Action
.NextAction
);
1032 // Emit the type ids.
1033 for (unsigned M
= TypeInfos
.size(); M
; --M
) {
1034 // Asm->EOL("TypeInfo");
1035 FinalSize
+= PointerSize
;
1038 // Emit the filter typeids.
1039 for (unsigned j
= 0, M
= FilterIds
.size(); j
< M
; ++j
) {
1040 unsigned TypeID
= FilterIds
[j
];
1041 FinalSize
+= MCAsmInfo::getULEB128Size(TypeID
);
1042 //Asm->EOL("Filter TypeInfo index");
1045 FinalSize
= RoundUpToAlign(FinalSize
, 4);