assert(0) -> LLVM_UNREACHABLE.
[oota-llvm.git] / lib / ExecutionEngine / JIT / JITDwarfEmitter.cpp
1 //===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a JITDwarfEmitter object that is used by the JIT to
11 // write dwarf tables to memory.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "JIT.h"
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/Target/TargetAsmInfo.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"
31
32 using namespace llvm;
33
34 JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {}
35
36
37 unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F, 
38                                                JITCodeEmitter& jce,
39                                                unsigned char* StartFunction,
40                                                unsigned char* EndFunction) {
41   const TargetMachine& TM = F.getTarget();
42   TD = TM.getTargetData();
43   needsIndirectEncoding = TM.getTargetAsmInfo()->getNeedsIndirectEncoding();
44   stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
45   RI = TM.getRegisterInfo();
46   JCE = &jce;
47   
48   unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
49                                                      EndFunction);
50       
51   unsigned char* Result = 0;
52   unsigned char* EHFramePtr = 0;
53
54   const std::vector<Function *> Personalities = MMI->getPersonalities();
55   EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
56
57   Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
58                        StartFunction, EndFunction, ExceptionTable);
59   
60   return Result;
61 }
62
63
64 void 
65 JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
66                                 const std::vector<MachineMove> &Moves) const {
67   unsigned PointerSize = TD->getPointerSize();
68   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
69           PointerSize : -PointerSize;
70   bool IsLocal = false;
71   unsigned BaseLabelID = 0;
72
73   for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
74     const MachineMove &Move = Moves[i];
75     unsigned LabelID = Move.getLabelID();
76     
77     if (LabelID) {
78       LabelID = MMI->MappedLabel(LabelID);
79     
80       // Throw out move if the label is invalid.
81       if (!LabelID) continue;
82     }
83     
84     intptr_t LabelPtr = 0;
85     if (LabelID) LabelPtr = JCE->getLabelAddress(LabelID);
86
87     const MachineLocation &Dst = Move.getDestination();
88     const MachineLocation &Src = Move.getSource();
89     
90     // Advance row if new location.
91     if (BaseLabelPtr && LabelID && (BaseLabelID != LabelID || !IsLocal)) {
92       JCE->emitByte(dwarf::DW_CFA_advance_loc4);
93       JCE->emitInt32(LabelPtr - BaseLabelPtr);
94       
95       BaseLabelID = LabelID; 
96       BaseLabelPtr = LabelPtr;
97       IsLocal = true;
98     }
99     
100     // If advancing cfa.
101     if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
102       if (!Src.isReg()) {
103         if (Src.getReg() == MachineLocation::VirtualFP) {
104           JCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
105         } else {
106           JCE->emitByte(dwarf::DW_CFA_def_cfa);
107           JCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), true));
108         }
109         
110         int Offset = -Src.getOffset();
111         
112         JCE->emitULEB128Bytes(Offset);
113       } else {
114         LLVM_UNREACHABLE("Machine move no supported yet.");
115       }
116     } else if (Src.isReg() &&
117       Src.getReg() == MachineLocation::VirtualFP) {
118       if (Dst.isReg()) {
119         JCE->emitByte(dwarf::DW_CFA_def_cfa_register);
120         JCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), true));
121       } else {
122         LLVM_UNREACHABLE("Machine move no supported yet.");
123       }
124     } else {
125       unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
126       int Offset = Dst.getOffset() / stackGrowth;
127       
128       if (Offset < 0) {
129         JCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
130         JCE->emitULEB128Bytes(Reg);
131         JCE->emitSLEB128Bytes(Offset);
132       } else if (Reg < 64) {
133         JCE->emitByte(dwarf::DW_CFA_offset + Reg);
134         JCE->emitULEB128Bytes(Offset);
135       } else {
136         JCE->emitByte(dwarf::DW_CFA_offset_extended);
137         JCE->emitULEB128Bytes(Reg);
138         JCE->emitULEB128Bytes(Offset);
139       }
140     }
141   }
142 }
143
144 /// SharedTypeIds - How many leading type ids two landing pads have in common.
145 static unsigned SharedTypeIds(const LandingPadInfo *L,
146                               const LandingPadInfo *R) {
147   const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
148   unsigned LSize = LIds.size(), RSize = RIds.size();
149   unsigned MinSize = LSize < RSize ? LSize : RSize;
150   unsigned Count = 0;
151
152   for (; Count != MinSize; ++Count)
153     if (LIds[Count] != RIds[Count])
154       return Count;
155
156   return Count;
157 }
158
159
160 /// PadLT - Order landing pads lexicographically by type id.
161 static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
162   const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
163   unsigned LSize = LIds.size(), RSize = RIds.size();
164   unsigned MinSize = LSize < RSize ? LSize : RSize;
165
166   for (unsigned i = 0; i != MinSize; ++i)
167     if (LIds[i] != RIds[i])
168       return LIds[i] < RIds[i];
169
170   return LSize < RSize;
171 }
172
173 namespace {
174
175 struct KeyInfo {
176   static inline unsigned getEmptyKey() { return -1U; }
177   static inline unsigned getTombstoneKey() { return -2U; }
178   static unsigned getHashValue(const unsigned &Key) { return Key; }
179   static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
180   static bool isPod() { return true; }
181 };
182
183 /// ActionEntry - Structure describing an entry in the actions table.
184 struct ActionEntry {
185   int ValueForTypeID; // The value to write - may not be equal to the type id.
186   int NextAction;
187   struct ActionEntry *Previous;
188 };
189
190 /// PadRange - Structure holding a try-range and the associated landing pad.
191 struct PadRange {
192   // The index of the landing pad.
193   unsigned PadIndex;
194   // The index of the begin and end labels in the landing pad's label lists.
195   unsigned RangeIndex;
196 };
197
198 typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType;
199
200 /// CallSiteEntry - Structure describing an entry in the call-site table.
201 struct CallSiteEntry {
202   unsigned BeginLabel; // zero indicates the start of the function.
203   unsigned EndLabel;   // zero indicates the end of the function.
204   unsigned PadLabel;   // zero indicates that there is no landing pad.
205   unsigned Action;
206 };
207
208 }
209
210 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
211                                          unsigned char* StartFunction,
212                                          unsigned char* EndFunction) const {
213   // Map all labels and get rid of any dead landing pads.
214   MMI->TidyLandingPads();
215
216   const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
217   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
218   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
219   if (PadInfos.empty()) return 0;
220
221   // Sort the landing pads in order of their type ids.  This is used to fold
222   // duplicate actions.
223   SmallVector<const LandingPadInfo *, 64> LandingPads;
224   LandingPads.reserve(PadInfos.size());
225   for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
226     LandingPads.push_back(&PadInfos[i]);
227   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
228
229   // Negative type ids index into FilterIds, positive type ids index into
230   // TypeInfos.  The value written for a positive type id is just the type
231   // id itself.  For a negative type id, however, the value written is the
232   // (negative) byte offset of the corresponding FilterIds entry.  The byte
233   // offset is usually equal to the type id, because the FilterIds entries
234   // are written using a variable width encoding which outputs one byte per
235   // entry as long as the value written is not too large, but can differ.
236   // This kind of complication does not occur for positive type ids because
237   // type infos are output using a fixed width encoding.
238   // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
239   SmallVector<int, 16> FilterOffsets;
240   FilterOffsets.reserve(FilterIds.size());
241   int Offset = -1;
242   for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
243     E = FilterIds.end(); I != E; ++I) {
244     FilterOffsets.push_back(Offset);
245     Offset -= TargetAsmInfo::getULEB128Size(*I);
246   }
247
248   // Compute the actions table and gather the first action index for each
249   // landing pad site.
250   SmallVector<ActionEntry, 32> Actions;
251   SmallVector<unsigned, 64> FirstActions;
252   FirstActions.reserve(LandingPads.size());
253
254   int FirstAction = 0;
255   unsigned SizeActions = 0;
256   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
257     const LandingPadInfo *LP = LandingPads[i];
258     const std::vector<int> &TypeIds = LP->TypeIds;
259     const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
260     unsigned SizeSiteActions = 0;
261
262     if (NumShared < TypeIds.size()) {
263       unsigned SizeAction = 0;
264       ActionEntry *PrevAction = 0;
265
266       if (NumShared) {
267         const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
268         assert(Actions.size());
269         PrevAction = &Actions.back();
270         SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) +
271           TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
272         for (unsigned j = NumShared; j != SizePrevIds; ++j) {
273           SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
274           SizeAction += -PrevAction->NextAction;
275           PrevAction = PrevAction->Previous;
276         }
277       }
278
279       // Compute the actions.
280       for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
281         int TypeID = TypeIds[I];
282         assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
283         int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
284         unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID);
285
286         int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
287         SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
288         SizeSiteActions += SizeAction;
289
290         ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
291         Actions.push_back(Action);
292
293         PrevAction = &Actions.back();
294       }
295
296       // Record the first action of the landing pad site.
297       FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
298     } // else identical - re-use previous FirstAction
299
300     FirstActions.push_back(FirstAction);
301
302     // Compute this sites contribution to size.
303     SizeActions += SizeSiteActions;
304   }
305
306   // Compute the call-site table.  Entries must be ordered by address.
307   SmallVector<CallSiteEntry, 64> CallSites;
308
309   RangeMapType PadMap;
310   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
311     const LandingPadInfo *LandingPad = LandingPads[i];
312     for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
313       unsigned BeginLabel = LandingPad->BeginLabels[j];
314       assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
315       PadRange P = { i, j };
316       PadMap[BeginLabel] = P;
317     }
318   }
319
320   bool MayThrow = false;
321   unsigned LastLabel = 0;
322   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
323         I != E; ++I) {
324     for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
325           MI != E; ++MI) {
326       if (!MI->isLabel()) {
327         MayThrow |= MI->getDesc().isCall();
328         continue;
329       }
330
331       unsigned BeginLabel = MI->getOperand(0).getImm();
332       assert(BeginLabel && "Invalid label!");
333
334       if (BeginLabel == LastLabel)
335         MayThrow = false;
336
337       RangeMapType::iterator L = PadMap.find(BeginLabel);
338
339       if (L == PadMap.end())
340         continue;
341
342       PadRange P = L->second;
343       const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
344
345       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
346               "Inconsistent landing pad map!");
347
348       // If some instruction between the previous try-range and this one may
349       // throw, create a call-site entry with no landing pad for the region
350       // between the try-ranges.
351       if (MayThrow) {
352         CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
353         CallSites.push_back(Site);
354       }
355
356       LastLabel = LandingPad->EndLabels[P.RangeIndex];
357       CallSiteEntry Site = {BeginLabel, LastLabel,
358         LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
359
360       assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
361               "Invalid landing pad!");
362
363       // Try to merge with the previous call-site.
364       if (CallSites.size()) {
365         CallSiteEntry &Prev = CallSites.back();
366         if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
367           // Extend the range of the previous entry.
368           Prev.EndLabel = Site.EndLabel;
369           continue;
370         }
371       }
372
373       // Otherwise, create a new call-site.
374       CallSites.push_back(Site);
375     }
376   }
377   // If some instruction between the previous try-range and the end of the
378   // function may throw, create a call-site entry with no landing pad for the
379   // region following the try-range.
380   if (MayThrow) {
381     CallSiteEntry Site = {LastLabel, 0, 0, 0};
382     CallSites.push_back(Site);
383   }
384
385   // Final tallies.
386   unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
387                                             sizeof(int32_t) + // Site length.
388                                             sizeof(int32_t)); // Landing pad.
389   for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
390     SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
391
392   unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
393
394   unsigned TypeOffset = sizeof(int8_t) + // Call site format
395                         // Call-site table length
396                         TargetAsmInfo::getULEB128Size(SizeSites) + 
397                         SizeSites + SizeActions + SizeTypes;
398
399   unsigned TotalSize = sizeof(int8_t) + // LPStart format
400                        sizeof(int8_t) + // TType format
401                        TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
402                        TypeOffset;
403
404   unsigned SizeAlign = (4 - TotalSize) & 3;
405
406   // Begin the exception table.
407   JCE->emitAlignment(4);
408   for (unsigned i = 0; i != SizeAlign; ++i) {
409     JCE->emitByte(0);
410     // Asm->EOL("Padding");
411   }
412   
413   unsigned char* DwarfExceptionTable = (unsigned char*)JCE->getCurrentPCValue();
414
415   // Emit the header.
416   JCE->emitByte(dwarf::DW_EH_PE_omit);
417   // Asm->EOL("LPStart format (DW_EH_PE_omit)");
418   JCE->emitByte(dwarf::DW_EH_PE_absptr);
419   // Asm->EOL("TType format (DW_EH_PE_absptr)");
420   JCE->emitULEB128Bytes(TypeOffset);
421   // Asm->EOL("TType base offset");
422   JCE->emitByte(dwarf::DW_EH_PE_udata4);
423   // Asm->EOL("Call site format (DW_EH_PE_udata4)");
424   JCE->emitULEB128Bytes(SizeSites);
425   // Asm->EOL("Call-site table length");
426
427   // Emit the landing pad site information.
428   for (unsigned i = 0; i < CallSites.size(); ++i) {
429     CallSiteEntry &S = CallSites[i];
430     intptr_t BeginLabelPtr = 0;
431     intptr_t EndLabelPtr = 0;
432
433     if (!S.BeginLabel) {
434       BeginLabelPtr = (intptr_t)StartFunction;
435       JCE->emitInt32(0);
436     } else {
437       BeginLabelPtr = JCE->getLabelAddress(S.BeginLabel);
438       JCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
439     }
440
441     // Asm->EOL("Region start");
442
443     if (!S.EndLabel) {
444       EndLabelPtr = (intptr_t)EndFunction;
445       JCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr);
446     } else {
447       EndLabelPtr = JCE->getLabelAddress(S.EndLabel);
448       JCE->emitInt32(EndLabelPtr - BeginLabelPtr);
449     }
450     //Asm->EOL("Region length");
451
452     if (!S.PadLabel) {
453       JCE->emitInt32(0);
454     } else {
455       unsigned PadLabelPtr = JCE->getLabelAddress(S.PadLabel);
456       JCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
457     }
458     // Asm->EOL("Landing pad");
459
460     JCE->emitULEB128Bytes(S.Action);
461     // Asm->EOL("Action");
462   }
463
464   // Emit the actions.
465   for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
466     ActionEntry &Action = Actions[I];
467
468     JCE->emitSLEB128Bytes(Action.ValueForTypeID);
469     //Asm->EOL("TypeInfo index");
470     JCE->emitSLEB128Bytes(Action.NextAction);
471     //Asm->EOL("Next action");
472   }
473
474   // Emit the type ids.
475   for (unsigned M = TypeInfos.size(); M; --M) {
476     GlobalVariable *GV = TypeInfos[M - 1];
477     
478     if (GV) {
479       if (TD->getPointerSize() == sizeof(int32_t)) {
480         JCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
481       } else {
482         JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
483       }
484     } else {
485       if (TD->getPointerSize() == sizeof(int32_t))
486         JCE->emitInt32(0);
487       else
488         JCE->emitInt64(0);
489     }
490     // Asm->EOL("TypeInfo");
491   }
492
493   // Emit the filter typeids.
494   for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
495     unsigned TypeID = FilterIds[j];
496     JCE->emitULEB128Bytes(TypeID);
497     //Asm->EOL("Filter TypeInfo index");
498   }
499   
500   JCE->emitAlignment(4);
501
502   return DwarfExceptionTable;
503 }
504
505 unsigned char*
506 JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
507   unsigned PointerSize = TD->getPointerSize();
508   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
509           PointerSize : -PointerSize;
510   
511   unsigned char* StartCommonPtr = (unsigned char*)JCE->getCurrentPCValue();
512   // EH Common Frame header
513   JCE->allocateSpace(4, 0);
514   unsigned char* FrameCommonBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
515   JCE->emitInt32((int)0);
516   JCE->emitByte(dwarf::DW_CIE_VERSION);
517   JCE->emitString(Personality ? "zPLR" : "zR");
518   JCE->emitULEB128Bytes(1);
519   JCE->emitSLEB128Bytes(stackGrowth);
520   JCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
521   
522   if (Personality) {
523     // Augmentation Size: 3 small ULEBs of one byte each, and the personality
524     // function which size is PointerSize.
525     JCE->emitULEB128Bytes(3 + PointerSize); 
526     
527     // We set the encoding of the personality as direct encoding because we use
528     // the function pointer. The encoding is not relative because the current
529     // PC value may be bigger than the personality function pointer.
530     if (PointerSize == 4) {
531       JCE->emitByte(dwarf::DW_EH_PE_sdata4); 
532       JCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality)));
533     } else {
534       JCE->emitByte(dwarf::DW_EH_PE_sdata8);
535       JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality)));
536     }
537     
538     JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
539     JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
540       
541   } else {
542     JCE->emitULEB128Bytes(1);
543     JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
544   }
545
546   std::vector<MachineMove> Moves;
547   RI->getInitialFrameState(Moves);
548   EmitFrameMoves(0, Moves);
549   JCE->emitAlignment(PointerSize);
550   
551   JCE->emitInt32At((uintptr_t*)StartCommonPtr, 
552               (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() - 
553                           FrameCommonBeginPtr));
554
555   return StartCommonPtr;
556 }
557
558
559 unsigned char*
560 JITDwarfEmitter::EmitEHFrame(const Function* Personality,
561                              unsigned char* StartCommonPtr,
562                              unsigned char* StartFunction, 
563                              unsigned char* EndFunction,
564                              unsigned char* ExceptionTable) const {
565   unsigned PointerSize = TD->getPointerSize();
566   
567   // EH frame header.
568   unsigned char* StartEHPtr = (unsigned char*)JCE->getCurrentPCValue();
569   JCE->allocateSpace(4, 0);
570   unsigned char* FrameBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
571   // FDE CIE Offset
572   JCE->emitInt32(FrameBeginPtr - StartCommonPtr);
573   JCE->emitInt32(StartFunction - (unsigned char*)JCE->getCurrentPCValue());
574   JCE->emitInt32(EndFunction - StartFunction);
575
576   // If there is a personality and landing pads then point to the language
577   // specific data area in the exception table.
578   if (MMI->getPersonalityIndex()) {
579     JCE->emitULEB128Bytes(4);
580         
581     if (!MMI->getLandingPads().empty()) {
582       JCE->emitInt32(ExceptionTable - (unsigned char*)JCE->getCurrentPCValue());
583     } else {
584       JCE->emitInt32((int)0);
585     }
586   } else {
587     JCE->emitULEB128Bytes(0);
588   }
589       
590   // Indicate locations of function specific  callee saved registers in
591   // frame.
592   EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
593       
594   JCE->emitAlignment(PointerSize);
595   
596   // Indicate the size of the table
597   JCE->emitInt32At((uintptr_t*)StartEHPtr, 
598               (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() - 
599                           StartEHPtr));
600   
601   // Double zeroes for the unwind runtime
602   if (PointerSize == 8) {
603     JCE->emitInt64(0);
604     JCE->emitInt64(0);
605   } else {
606     JCE->emitInt32(0);
607     JCE->emitInt32(0);
608   }
609
610   
611   return StartEHPtr;
612 }
613
614 unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction& F,
615                                          JITCodeEmitter& jce,
616                                          unsigned char* StartFunction,
617                                          unsigned char* EndFunction) {
618   const TargetMachine& TM = F.getTarget();
619   TD = TM.getTargetData();
620   needsIndirectEncoding = TM.getTargetAsmInfo()->getNeedsIndirectEncoding();
621   stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection();
622   RI = TM.getRegisterInfo();
623   JCE = &jce;
624   unsigned FinalSize = 0;
625   
626   FinalSize += GetExceptionTableSizeInBytes(&F);
627       
628   const std::vector<Function *> Personalities = MMI->getPersonalities();
629   FinalSize += 
630     GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]);
631
632   FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()],
633                                      StartFunction);
634   
635   return FinalSize;
636 }
637
638 /// RoundUpToAlign - Add the specified alignment to FinalSize and returns
639 /// the new value.
640 static unsigned RoundUpToAlign(unsigned FinalSize, unsigned Alignment) {
641   if (Alignment == 0) Alignment = 1;
642   // Since we do not know where the buffer will be allocated, be pessimistic.
643   return FinalSize + Alignment;
644 }
645   
646 unsigned
647 JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality,
648                                        unsigned char* StartFunction) const { 
649   unsigned PointerSize = TD->getPointerSize();
650   unsigned FinalSize = 0;
651   // EH frame header.
652   FinalSize += PointerSize;
653   // FDE CIE Offset
654   FinalSize += 3 * PointerSize;
655   // If there is a personality and landing pads then point to the language
656   // specific data area in the exception table.
657   if (MMI->getPersonalityIndex()) {
658     FinalSize += TargetAsmInfo::getULEB128Size(4); 
659     FinalSize += PointerSize;
660   } else {
661     FinalSize += TargetAsmInfo::getULEB128Size(0);
662   }
663       
664   // Indicate locations of function specific  callee saved registers in
665   // frame.
666   FinalSize += GetFrameMovesSizeInBytes((intptr_t)StartFunction,
667                                         MMI->getFrameMoves());
668       
669   FinalSize = RoundUpToAlign(FinalSize, 4);
670   
671   // Double zeroes for the unwind runtime
672   FinalSize += 2 * PointerSize;
673
674   return FinalSize;
675 }
676
677 unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function* Personality) 
678   const {
679
680   unsigned PointerSize = TD->getPointerSize();
681   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
682           PointerSize : -PointerSize;
683   unsigned FinalSize = 0; 
684   // EH Common Frame header
685   FinalSize += PointerSize;
686   FinalSize += 4;
687   FinalSize += 1;
688   FinalSize += Personality ? 5 : 3; // "zPLR" or "zR"
689   FinalSize += TargetAsmInfo::getULEB128Size(1);
690   FinalSize += TargetAsmInfo::getSLEB128Size(stackGrowth);
691   FinalSize += 1;
692   
693   if (Personality) {
694     FinalSize += TargetAsmInfo::getULEB128Size(7);
695     
696     // Encoding
697     FinalSize+= 1;
698     //Personality
699     FinalSize += PointerSize;
700     
701     FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
702     FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
703       
704   } else {
705     FinalSize += TargetAsmInfo::getULEB128Size(1);
706     FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel);
707   }
708
709   std::vector<MachineMove> Moves;
710   RI->getInitialFrameState(Moves);
711   FinalSize += GetFrameMovesSizeInBytes(0, Moves);
712   FinalSize = RoundUpToAlign(FinalSize, 4);
713   return FinalSize;
714 }
715
716 unsigned
717 JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr,
718                                   const std::vector<MachineMove> &Moves) const {
719   unsigned PointerSize = TD->getPointerSize();
720   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
721           PointerSize : -PointerSize;
722   bool IsLocal = BaseLabelPtr;
723   unsigned FinalSize = 0; 
724
725   for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
726     const MachineMove &Move = Moves[i];
727     unsigned LabelID = Move.getLabelID();
728     
729     if (LabelID) {
730       LabelID = MMI->MappedLabel(LabelID);
731     
732       // Throw out move if the label is invalid.
733       if (!LabelID) continue;
734     }
735     
736     intptr_t LabelPtr = 0;
737     if (LabelID) LabelPtr = JCE->getLabelAddress(LabelID);
738
739     const MachineLocation &Dst = Move.getDestination();
740     const MachineLocation &Src = Move.getSource();
741     
742     // Advance row if new location.
743     if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
744       FinalSize++;
745       FinalSize += PointerSize;
746       BaseLabelPtr = LabelPtr;
747       IsLocal = true;
748     }
749     
750     // If advancing cfa.
751     if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
752       if (!Src.isReg()) {
753         if (Src.getReg() == MachineLocation::VirtualFP) {
754           ++FinalSize;
755         } else {
756           ++FinalSize;
757           unsigned RegNum = RI->getDwarfRegNum(Src.getReg(), true);
758           FinalSize += TargetAsmInfo::getULEB128Size(RegNum);
759         }
760         
761         int Offset = -Src.getOffset();
762         
763         FinalSize += TargetAsmInfo::getULEB128Size(Offset);
764       } else {
765         LLVM_UNREACHABLE("Machine move no supported yet.");
766       }
767     } else if (Src.isReg() &&
768       Src.getReg() == MachineLocation::VirtualFP) {
769       if (Dst.isReg()) {
770         ++FinalSize;
771         unsigned RegNum = RI->getDwarfRegNum(Dst.getReg(), true);
772         FinalSize += TargetAsmInfo::getULEB128Size(RegNum);
773       } else {
774         LLVM_UNREACHABLE("Machine move no supported yet.");
775       }
776     } else {
777       unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
778       int Offset = Dst.getOffset() / stackGrowth;
779       
780       if (Offset < 0) {
781         ++FinalSize;
782         FinalSize += TargetAsmInfo::getULEB128Size(Reg);
783         FinalSize += TargetAsmInfo::getSLEB128Size(Offset);
784       } else if (Reg < 64) {
785         ++FinalSize;
786         FinalSize += TargetAsmInfo::getULEB128Size(Offset);
787       } else {
788         ++FinalSize;
789         FinalSize += TargetAsmInfo::getULEB128Size(Reg);
790         FinalSize += TargetAsmInfo::getULEB128Size(Offset);
791       }
792     }
793   }
794   return FinalSize;
795 }
796
797 unsigned 
798 JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction* MF) const {
799   unsigned FinalSize = 0;
800
801   // Map all labels and get rid of any dead landing pads.
802   MMI->TidyLandingPads();
803
804   const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
805   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
806   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
807   if (PadInfos.empty()) return 0;
808
809   // Sort the landing pads in order of their type ids.  This is used to fold
810   // duplicate actions.
811   SmallVector<const LandingPadInfo *, 64> LandingPads;
812   LandingPads.reserve(PadInfos.size());
813   for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
814     LandingPads.push_back(&PadInfos[i]);
815   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
816
817   // Negative type ids index into FilterIds, positive type ids index into
818   // TypeInfos.  The value written for a positive type id is just the type
819   // id itself.  For a negative type id, however, the value written is the
820   // (negative) byte offset of the corresponding FilterIds entry.  The byte
821   // offset is usually equal to the type id, because the FilterIds entries
822   // are written using a variable width encoding which outputs one byte per
823   // entry as long as the value written is not too large, but can differ.
824   // This kind of complication does not occur for positive type ids because
825   // type infos are output using a fixed width encoding.
826   // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
827   SmallVector<int, 16> FilterOffsets;
828   FilterOffsets.reserve(FilterIds.size());
829   int Offset = -1;
830   for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
831     E = FilterIds.end(); I != E; ++I) {
832     FilterOffsets.push_back(Offset);
833     Offset -= TargetAsmInfo::getULEB128Size(*I);
834   }
835
836   // Compute the actions table and gather the first action index for each
837   // landing pad site.
838   SmallVector<ActionEntry, 32> Actions;
839   SmallVector<unsigned, 64> FirstActions;
840   FirstActions.reserve(LandingPads.size());
841
842   int FirstAction = 0;
843   unsigned SizeActions = 0;
844   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
845     const LandingPadInfo *LP = LandingPads[i];
846     const std::vector<int> &TypeIds = LP->TypeIds;
847     const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
848     unsigned SizeSiteActions = 0;
849
850     if (NumShared < TypeIds.size()) {
851       unsigned SizeAction = 0;
852       ActionEntry *PrevAction = 0;
853
854       if (NumShared) {
855         const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
856         assert(Actions.size());
857         PrevAction = &Actions.back();
858         SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) +
859           TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
860         for (unsigned j = NumShared; j != SizePrevIds; ++j) {
861           SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
862           SizeAction += -PrevAction->NextAction;
863           PrevAction = PrevAction->Previous;
864         }
865       }
866
867       // Compute the actions.
868       for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
869         int TypeID = TypeIds[I];
870         assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
871         int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
872         unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID);
873
874         int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
875         SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
876         SizeSiteActions += SizeAction;
877
878         ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
879         Actions.push_back(Action);
880
881         PrevAction = &Actions.back();
882       }
883
884       // Record the first action of the landing pad site.
885       FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
886     } // else identical - re-use previous FirstAction
887
888     FirstActions.push_back(FirstAction);
889
890     // Compute this sites contribution to size.
891     SizeActions += SizeSiteActions;
892   }
893
894   // Compute the call-site table.  Entries must be ordered by address.
895   SmallVector<CallSiteEntry, 64> CallSites;
896
897   RangeMapType PadMap;
898   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
899     const LandingPadInfo *LandingPad = LandingPads[i];
900     for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
901       unsigned BeginLabel = LandingPad->BeginLabels[j];
902       assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
903       PadRange P = { i, j };
904       PadMap[BeginLabel] = P;
905     }
906   }
907
908   bool MayThrow = false;
909   unsigned LastLabel = 0;
910   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
911         I != E; ++I) {
912     for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
913           MI != E; ++MI) {
914       if (!MI->isLabel()) {
915         MayThrow |= MI->getDesc().isCall();
916         continue;
917       }
918
919       unsigned BeginLabel = MI->getOperand(0).getImm();
920       assert(BeginLabel && "Invalid label!");
921
922       if (BeginLabel == LastLabel)
923         MayThrow = false;
924
925       RangeMapType::iterator L = PadMap.find(BeginLabel);
926
927       if (L == PadMap.end())
928         continue;
929
930       PadRange P = L->second;
931       const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
932
933       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
934               "Inconsistent landing pad map!");
935
936       // If some instruction between the previous try-range and this one may
937       // throw, create a call-site entry with no landing pad for the region
938       // between the try-ranges.
939       if (MayThrow) {
940         CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
941         CallSites.push_back(Site);
942       }
943
944       LastLabel = LandingPad->EndLabels[P.RangeIndex];
945       CallSiteEntry Site = {BeginLabel, LastLabel,
946         LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
947
948       assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
949               "Invalid landing pad!");
950
951       // Try to merge with the previous call-site.
952       if (CallSites.size()) {
953         CallSiteEntry &Prev = CallSites.back();
954         if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
955           // Extend the range of the previous entry.
956           Prev.EndLabel = Site.EndLabel;
957           continue;
958         }
959       }
960
961       // Otherwise, create a new call-site.
962       CallSites.push_back(Site);
963     }
964   }
965   // If some instruction between the previous try-range and the end of the
966   // function may throw, create a call-site entry with no landing pad for the
967   // region following the try-range.
968   if (MayThrow) {
969     CallSiteEntry Site = {LastLabel, 0, 0, 0};
970     CallSites.push_back(Site);
971   }
972
973   // Final tallies.
974   unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
975                                             sizeof(int32_t) + // Site length.
976                                             sizeof(int32_t)); // Landing pad.
977   for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
978     SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
979
980   unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
981
982   unsigned TypeOffset = sizeof(int8_t) + // Call site format
983                         // Call-site table length
984                         TargetAsmInfo::getULEB128Size(SizeSites) + 
985                         SizeSites + SizeActions + SizeTypes;
986
987   unsigned TotalSize = sizeof(int8_t) + // LPStart format
988                        sizeof(int8_t) + // TType format
989                        TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset
990                        TypeOffset;
991
992   unsigned SizeAlign = (4 - TotalSize) & 3;
993
994   // Begin the exception table.
995   FinalSize = RoundUpToAlign(FinalSize, 4);
996   for (unsigned i = 0; i != SizeAlign; ++i) {
997     ++FinalSize;
998   }
999   
1000   unsigned PointerSize = TD->getPointerSize();
1001
1002   // Emit the header.
1003   ++FinalSize;
1004   // Asm->EOL("LPStart format (DW_EH_PE_omit)");
1005   ++FinalSize;
1006   // Asm->EOL("TType format (DW_EH_PE_absptr)");
1007   ++FinalSize;
1008   // Asm->EOL("TType base offset");
1009   ++FinalSize;
1010   // Asm->EOL("Call site format (DW_EH_PE_udata4)");
1011   ++FinalSize;
1012   // Asm->EOL("Call-site table length");
1013
1014   // Emit the landing pad site information.
1015   for (unsigned i = 0; i < CallSites.size(); ++i) {
1016     CallSiteEntry &S = CallSites[i];
1017
1018     // Asm->EOL("Region start");
1019     FinalSize += PointerSize;
1020     
1021     //Asm->EOL("Region length");
1022     FinalSize += PointerSize;
1023
1024     // Asm->EOL("Landing pad");
1025     FinalSize += PointerSize;
1026
1027     FinalSize += TargetAsmInfo::getULEB128Size(S.Action);
1028     // Asm->EOL("Action");
1029   }
1030
1031   // Emit the actions.
1032   for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
1033     ActionEntry &Action = Actions[I];
1034
1035     //Asm->EOL("TypeInfo index");
1036     FinalSize += TargetAsmInfo::getSLEB128Size(Action.ValueForTypeID);
1037     //Asm->EOL("Next action");
1038     FinalSize += TargetAsmInfo::getSLEB128Size(Action.NextAction);
1039   }
1040
1041   // Emit the type ids.
1042   for (unsigned M = TypeInfos.size(); M; --M) {
1043     // Asm->EOL("TypeInfo");
1044     FinalSize += PointerSize;
1045   }
1046
1047   // Emit the filter typeids.
1048   for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
1049     unsigned TypeID = FilterIds[j];
1050     FinalSize += TargetAsmInfo::getULEB128Size(TypeID);
1051     //Asm->EOL("Filter TypeInfo index");
1052   }
1053   
1054   FinalSize = RoundUpToAlign(FinalSize, 4);
1055
1056   return FinalSize;
1057 }