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