Cosmetic changes, as suggested by Evan. No functionality changes.
[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   return (FinalSize + Alignment - 1) & ~(Alignment - 1);
668 }
669   
670 unsigned
671 JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality,
672                                        unsigned char* StartFunction) const { 
673   unsigned PointerSize = TD->getPointerSize();
674   unsigned FinalSize = 0;
675   // EH frame header.
676   FinalSize += PointerSize;
677   // FDE CIE Offset
678   FinalSize += 3 * PointerSize;
679   // If there is a personality and landing pads then point to the language
680   // specific data area in the exception table.
681   if (MMI->getPersonalityIndex()) {
682     FinalSize += AsmPrinter::SizeULEB128(4); 
683     FinalSize += PointerSize;
684   } else {
685     FinalSize += AsmPrinter::SizeULEB128(0);
686   }
687       
688   // Indicate locations of function specific  callee saved registers in
689   // frame.
690   FinalSize += GetFrameMovesSizeInBytes((intptr_t)StartFunction,
691                                         MMI->getFrameMoves());
692       
693   FinalSize = RoundUpToAlign(FinalSize, 4);
694   
695   // Double zeroes for the unwind runtime
696   FinalSize += 2 * PointerSize;
697
698   return FinalSize;
699 }
700
701 unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function* Personality) 
702   const {
703
704   unsigned PointerSize = TD->getPointerSize();
705   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
706           PointerSize : -PointerSize;
707   unsigned FinalSize = 0; 
708   // EH Common Frame header
709   FinalSize += PointerSize;
710   FinalSize += 4;
711   FinalSize += 1;
712   FinalSize += Personality ? 5 : 3; // "zPLR" or "zR"
713   FinalSize += AsmPrinter::SizeULEB128(1);
714   FinalSize += AsmPrinter::SizeSLEB128(stackGrowth);
715   FinalSize += 1;
716   
717   if (Personality) {
718     FinalSize += AsmPrinter::SizeULEB128(7);
719     
720     // Encoding
721     FinalSize+= 1;
722     //Personality
723     FinalSize += PointerSize;
724     
725     FinalSize += AsmPrinter::SizeULEB128(dwarf::DW_EH_PE_pcrel);
726     FinalSize += AsmPrinter::SizeULEB128(dwarf::DW_EH_PE_pcrel);
727       
728   } else {
729     FinalSize += AsmPrinter::SizeULEB128(1);
730     FinalSize += AsmPrinter::SizeULEB128(dwarf::DW_EH_PE_pcrel);
731   }
732
733   std::vector<MachineMove> Moves;
734   RI->getInitialFrameState(Moves);
735   FinalSize += GetFrameMovesSizeInBytes(0, Moves);
736   FinalSize = RoundUpToAlign(FinalSize, 4);
737   return FinalSize;
738 }
739
740 unsigned
741 JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr,
742                                   const std::vector<MachineMove> &Moves) const {
743   unsigned PointerSize = TD->getPointerSize();
744   int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
745           PointerSize : -PointerSize;
746   bool IsLocal = BaseLabelPtr;
747   unsigned FinalSize = 0; 
748
749   for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
750     const MachineMove &Move = Moves[i];
751     unsigned LabelID = Move.getLabelID();
752     
753     if (LabelID) {
754       LabelID = MMI->MappedLabel(LabelID);
755     
756       // Throw out move if the label is invalid.
757       if (!LabelID) continue;
758     }
759     
760     intptr_t LabelPtr = 0;
761     if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
762
763     const MachineLocation &Dst = Move.getDestination();
764     const MachineLocation &Src = Move.getSource();
765     
766     // Advance row if new location.
767     if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) {
768       FinalSize++;
769       FinalSize += PointerSize;
770       BaseLabelPtr = LabelPtr;
771       IsLocal = true;
772     }
773     
774     // If advancing cfa.
775     if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
776       if (!Src.isRegister()) {
777         if (Src.getRegister() == MachineLocation::VirtualFP) {
778           ++FinalSize;
779         } else {
780           ++FinalSize;
781           unsigned RegNum = RI->getDwarfRegNum(Src.getRegister(), true);
782           FinalSize += AsmPrinter::SizeULEB128(RegNum);
783         }
784         
785         int Offset = -Src.getOffset();
786         
787         FinalSize += AsmPrinter::SizeULEB128(Offset);
788       } else {
789         assert(0 && "Machine move no supported yet.");
790       }
791     } else if (Src.isRegister() &&
792       Src.getRegister() == MachineLocation::VirtualFP) {
793       if (Dst.isRegister()) {
794         ++FinalSize;
795         unsigned RegNum = RI->getDwarfRegNum(Dst.getRegister(), true);
796         FinalSize += AsmPrinter::SizeULEB128(RegNum);
797       } else {
798         assert(0 && "Machine move no supported yet.");
799       }
800     } else {
801       unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), true);
802       int Offset = Dst.getOffset() / stackGrowth;
803       
804       if (Offset < 0) {
805         ++FinalSize;
806         FinalSize += AsmPrinter::SizeULEB128(Reg);
807         FinalSize += AsmPrinter::SizeSLEB128(Offset);
808       } else if (Reg < 64) {
809         ++FinalSize;
810         FinalSize += AsmPrinter::SizeULEB128(Offset);
811       } else {
812         ++FinalSize;
813         FinalSize += AsmPrinter::SizeULEB128(Reg);
814         FinalSize += AsmPrinter::SizeULEB128(Offset);
815       }
816     }
817   }
818   return FinalSize;
819 }
820
821 unsigned 
822 JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction* MF) const {
823   unsigned FinalSize = 0;
824
825   // Map all labels and get rid of any dead landing pads.
826   MMI->TidyLandingPads();
827
828   const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
829   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
830   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
831   if (PadInfos.empty()) return 0;
832
833   // Sort the landing pads in order of their type ids.  This is used to fold
834   // duplicate actions.
835   SmallVector<const LandingPadInfo *, 64> LandingPads;
836   LandingPads.reserve(PadInfos.size());
837   for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
838     LandingPads.push_back(&PadInfos[i]);
839   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
840
841   // Negative type ids index into FilterIds, positive type ids index into
842   // TypeInfos.  The value written for a positive type id is just the type
843   // id itself.  For a negative type id, however, the value written is the
844   // (negative) byte offset of the corresponding FilterIds entry.  The byte
845   // offset is usually equal to the type id, because the FilterIds entries
846   // are written using a variable width encoding which outputs one byte per
847   // entry as long as the value written is not too large, but can differ.
848   // This kind of complication does not occur for positive type ids because
849   // type infos are output using a fixed width encoding.
850   // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
851   SmallVector<int, 16> FilterOffsets;
852   FilterOffsets.reserve(FilterIds.size());
853   int Offset = -1;
854   for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
855     E = FilterIds.end(); I != E; ++I) {
856     FilterOffsets.push_back(Offset);
857     Offset -= AsmPrinter::SizeULEB128(*I);
858   }
859
860   // Compute the actions table and gather the first action index for each
861   // landing pad site.
862   SmallVector<ActionEntry, 32> Actions;
863   SmallVector<unsigned, 64> FirstActions;
864   FirstActions.reserve(LandingPads.size());
865
866   int FirstAction = 0;
867   unsigned SizeActions = 0;
868   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
869     const LandingPadInfo *LP = LandingPads[i];
870     const std::vector<int> &TypeIds = LP->TypeIds;
871     const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
872     unsigned SizeSiteActions = 0;
873
874     if (NumShared < TypeIds.size()) {
875       unsigned SizeAction = 0;
876       ActionEntry *PrevAction = 0;
877
878       if (NumShared) {
879         const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
880         assert(Actions.size());
881         PrevAction = &Actions.back();
882         SizeAction = AsmPrinter::SizeSLEB128(PrevAction->NextAction) +
883           AsmPrinter::SizeSLEB128(PrevAction->ValueForTypeID);
884         for (unsigned j = NumShared; j != SizePrevIds; ++j) {
885           SizeAction -= AsmPrinter::SizeSLEB128(PrevAction->ValueForTypeID);
886           SizeAction += -PrevAction->NextAction;
887           PrevAction = PrevAction->Previous;
888         }
889       }
890
891       // Compute the actions.
892       for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
893         int TypeID = TypeIds[I];
894         assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
895         int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
896         unsigned SizeTypeID = AsmPrinter::SizeSLEB128(ValueForTypeID);
897
898         int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
899         SizeAction = SizeTypeID + AsmPrinter::SizeSLEB128(NextAction);
900         SizeSiteActions += SizeAction;
901
902         ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
903         Actions.push_back(Action);
904
905         PrevAction = &Actions.back();
906       }
907
908       // Record the first action of the landing pad site.
909       FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
910     } // else identical - re-use previous FirstAction
911
912     FirstActions.push_back(FirstAction);
913
914     // Compute this sites contribution to size.
915     SizeActions += SizeSiteActions;
916   }
917
918   // Compute the call-site table.  Entries must be ordered by address.
919   SmallVector<CallSiteEntry, 64> CallSites;
920
921   RangeMapType PadMap;
922   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
923     const LandingPadInfo *LandingPad = LandingPads[i];
924     for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
925       unsigned BeginLabel = LandingPad->BeginLabels[j];
926       assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
927       PadRange P = { i, j };
928       PadMap[BeginLabel] = P;
929     }
930   }
931
932   bool MayThrow = false;
933   unsigned LastLabel = 0;
934   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
935         I != E; ++I) {
936     for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
937           MI != E; ++MI) {
938       if (MI->getOpcode() != TargetInstrInfo::LABEL) {
939         MayThrow |= MI->getDesc().isCall();
940         continue;
941       }
942
943       unsigned BeginLabel = MI->getOperand(0).getImm();
944       assert(BeginLabel && "Invalid label!");
945
946       if (BeginLabel == LastLabel)
947         MayThrow = false;
948
949       RangeMapType::iterator L = PadMap.find(BeginLabel);
950
951       if (L == PadMap.end())
952         continue;
953
954       PadRange P = L->second;
955       const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
956
957       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
958               "Inconsistent landing pad map!");
959
960       // If some instruction between the previous try-range and this one may
961       // throw, create a call-site entry with no landing pad for the region
962       // between the try-ranges.
963       if (MayThrow) {
964         CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
965         CallSites.push_back(Site);
966       }
967
968       LastLabel = LandingPad->EndLabels[P.RangeIndex];
969       CallSiteEntry Site = {BeginLabel, LastLabel,
970         LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
971
972       assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
973               "Invalid landing pad!");
974
975       // Try to merge with the previous call-site.
976       if (CallSites.size()) {
977         CallSiteEntry &Prev = CallSites[CallSites.size()-1];
978         if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
979           // Extend the range of the previous entry.
980           Prev.EndLabel = Site.EndLabel;
981           continue;
982         }
983       }
984
985       // Otherwise, create a new call-site.
986       CallSites.push_back(Site);
987     }
988   }
989   // If some instruction between the previous try-range and the end of the
990   // function may throw, create a call-site entry with no landing pad for the
991   // region following the try-range.
992   if (MayThrow) {
993     CallSiteEntry Site = {LastLabel, 0, 0, 0};
994     CallSites.push_back(Site);
995   }
996
997   // Final tallies.
998   unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
999                                             sizeof(int32_t) + // Site length.
1000                                             sizeof(int32_t)); // Landing pad.
1001   for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
1002     SizeSites += AsmPrinter::SizeULEB128(CallSites[i].Action);
1003
1004   unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
1005
1006   unsigned TypeOffset = sizeof(int8_t) + // Call site format
1007                         // Call-site table length
1008                         AsmPrinter::SizeULEB128(SizeSites) + 
1009                         SizeSites + SizeActions + SizeTypes;
1010
1011   unsigned TotalSize = sizeof(int8_t) + // LPStart format
1012                        sizeof(int8_t) + // TType format
1013                        AsmPrinter::SizeULEB128(TypeOffset) + // TType base offset
1014                        TypeOffset;
1015
1016   unsigned SizeAlign = (4 - TotalSize) & 3;
1017
1018   // Begin the exception table.
1019   FinalSize = RoundUpToAlign(FinalSize, 4);
1020   for (unsigned i = 0; i != SizeAlign; ++i) {
1021     ++FinalSize;
1022   }
1023   
1024   unsigned PointerSize = TD->getPointerSize();
1025
1026   // Emit the header.
1027   ++FinalSize;
1028   // Asm->EOL("LPStart format (DW_EH_PE_omit)");
1029   ++FinalSize;
1030   // Asm->EOL("TType format (DW_EH_PE_absptr)");
1031   ++FinalSize;
1032   // Asm->EOL("TType base offset");
1033   ++FinalSize;
1034   // Asm->EOL("Call site format (DW_EH_PE_udata4)");
1035   ++FinalSize;
1036   // Asm->EOL("Call-site table length");
1037
1038   // Emit the landing pad site information.
1039   for (unsigned i = 0; i < CallSites.size(); ++i) {
1040     CallSiteEntry &S = CallSites[i];
1041
1042     // Asm->EOL("Region start");
1043     FinalSize += PointerSize;
1044     
1045     //Asm->EOL("Region length");
1046     FinalSize += PointerSize;
1047
1048     // Asm->EOL("Landing pad");
1049     FinalSize += PointerSize;
1050
1051     FinalSize += AsmPrinter::SizeULEB128(S.Action);
1052     // Asm->EOL("Action");
1053   }
1054
1055   // Emit the actions.
1056   for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
1057     ActionEntry &Action = Actions[I];
1058
1059     //Asm->EOL("TypeInfo index");
1060     FinalSize += AsmPrinter::SizeSLEB128(Action.ValueForTypeID);
1061     //Asm->EOL("Next action");
1062     FinalSize += AsmPrinter::SizeSLEB128(Action.NextAction);
1063   }
1064
1065   // Emit the type ids.
1066   for (unsigned M = TypeInfos.size(); M; --M) {
1067     // Asm->EOL("TypeInfo");
1068     FinalSize += PointerSize;
1069   }
1070
1071   // Emit the filter typeids.
1072   for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
1073     unsigned TypeID = FilterIds[j];
1074     FinalSize += AsmPrinter::SizeULEB128(TypeID);
1075     //Asm->EOL("Filter TypeInfo index");
1076   }
1077   
1078   FinalSize = RoundUpToAlign(FinalSize, 4);
1079
1080   return FinalSize;
1081 }