1cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines//===-- EHStreamer.h - Exception Handling Directive Streamer ---*- C++ -*--===// 2cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// 3cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// The LLVM Compiler Infrastructure 4cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// 5cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// This file is distributed under the University of Illinois Open Source 6cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// License. See LICENSE.TXT for details. 7cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// 8cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines//===----------------------------------------------------------------------===// 9cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// 10cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// This file contains support for writing exception info into assembly files. 11cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// 12cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines//===----------------------------------------------------------------------===// 13cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 14cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#ifndef LLVM_CODEGEN_ASMPRINTER_EHSTREAMER_H 15cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#define LLVM_CODEGEN_ASMPRINTER_EHSTREAMER_H 16cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 17cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "AsmPrinterHandler.h" 18cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/ADT/DenseMap.h" 19cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 20cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesnamespace llvm { 21cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstruct LandingPadInfo; 22cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass MachineModuleInfo; 23cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass MachineInstr; 24cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass MachineFunction; 25cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass AsmPrinter; 26cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 27cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <typename T> 28cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass SmallVectorImpl; 29cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 30cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// Emits exception handling directives. 31cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass EHStreamer : public AsmPrinterHandler { 32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprotected: 33cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Target of directive emission. 34cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AsmPrinter *Asm; 35cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 36cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Collected machine module information. 37cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachineModuleInfo *MMI; 38cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 39cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// How many leading type ids two landing pads have in common. 40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static unsigned sharedTypeIDs(const LandingPadInfo *L, 41cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const LandingPadInfo *R); 42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Structure holding a try-range and the associated landing pad. 44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines struct PadRange { 45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // The index of the landing pad. 46cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned PadIndex; 47cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // The index of the begin and end labels in the landing pad's label lists. 48cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned RangeIndex; 49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines }; 50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines typedef DenseMap<MCSymbol *, PadRange> RangeMapType; 52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 53cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Structure describing an entry in the actions table. 54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines struct ActionEntry { 55cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int ValueForTypeID; // The value to write - may not be equal to the type id. 56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int NextAction; 57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Previous; 58cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines }; 59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Structure describing an entry in the call-site table. 61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines struct CallSiteEntry { 62cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // The 'try-range' is BeginLabel .. EndLabel. 63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *BeginLabel; // zero indicates the start of the function. 64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *EndLabel; // zero indicates the end of the function. 65cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 66cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // The landing pad starts at PadLabel. 67cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *PadLabel; // zero indicates that there is no landing pad. 68cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Action; 69cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines }; 70cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 71cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Compute the actions table and gather the first action index for each 72cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// landing pad site. 73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned computeActionsTable(const SmallVectorImpl<const LandingPadInfo*>&LPs, 74cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SmallVectorImpl<ActionEntry> &Actions, 75cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SmallVectorImpl<unsigned> &FirstActions); 76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 77cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Return `true' if this is a call to a function marked `nounwind'. Return 78cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// `false' otherwise. 79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool callToNoUnwindFunction(const MachineInstr *MI); 80cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 81cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Compute the call-site table. The entry for an invoke has a try-range 82cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// containing the call, a non-zero landing pad and an appropriate action. 83cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// The entry for an ordinary call has a try-range containing the call and 84cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// zero for the landing pad and the action. Calls marked 'nounwind' have 85cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// no entry and must not be contained in the try-range of any entry - they 86cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// form gaps in the table. Entries must be ordered by try-range address. 87cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 88cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, 89cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const RangeMapType &PadMap, 90cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const SmallVectorImpl<const LandingPadInfo *> &LPs, 91cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const SmallVectorImpl<unsigned> &FirstActions); 92cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 93cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Emit landing pads and actions. 94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// 95cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// The general organization of the table is complex, but the basic concepts 96cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// are easy. First there is a header which describes the location and 97cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// organization of the three components that follow. 98cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// 1. The landing pad site information describes the range of code covered 99cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// by the try. In our case it's an accumulation of the ranges covered 100cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// by the invokes in the try. There is also a reference to the landing 101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// pad that handles the exception once processed. Finally an index into 102cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// the actions table. 103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// 2. The action table, in our case, is composed of pairs of type ids 104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// and next action offset. Starting with the action index from the 105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// landing pad site, each type Id is checked for a match to the current 106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// exception. If it matches then the exception and type id are passed 107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// on to the landing pad. Otherwise the next action is looked up. This 108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// chain is terminated with a next action of zero. If no type id is 109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// found the frame is unwound and handling continues. 110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// 3. Type id table contains references to all the C++ typeinfo for all 111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// catches in the function. This tables is reversed indexed base 1. 112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void emitExceptionTable(); 113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines virtual void emitTypeInfos(unsigned TTypeEncoding); 115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinespublic: 117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EHStreamer(AsmPrinter *A); 118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines virtual ~EHStreamer(); 119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Emit all exception information that should come after the content. 121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void endModule() override; 122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Gather pre-function exception information. Assumes being emitted 124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// immediately after the function entry point. 125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void beginFunction(const MachineFunction *MF) override; 126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Gather and emit post-function exception information. 128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void endFunction(const MachineFunction *) override; 129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Unused. 131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {} 132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void beginInstruction(const MachineInstr *MI) override {} 133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void endInstruction() override {} 134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}; 135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#endif 138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 139