[LLVMdev] Being able to know the jitted code-size before emitting
Evan Cheng
evan.cheng at apple.com
Fri Apr 18 14:21:02 PDT 2008
Comments below:
On Apr 17, 2008, at 2:38 AM, Nicolas Geoffray wrote:
> Thx again Evan for the review. Here's a new patch for the JIT in
> itself. The major changes are:
> 1) A JITMemoryManager now has a flag saying "I require to know the
> size of what you want to emit"
> 2) DwarfJITEmitter is augmented with GetSize* functions
> 3) JITEmitter::startFunction checks if the JITMemoryManager requires
> to know the size. If so, it computes it and gives it through the
> ActualPtr argument.
>
> I suppose it's OK to commit, but if anyone wants to complain, I'm
> listening :)
>
> Thanks,
> Nicolas
>
>
>
> +
> +static void AddAlignment(uintptr_t& Size, unsigned Alignment) {
> + if (Alignment == 0) Alignment = 1;
> + Size = (Size + Alignment - 1) & (Alignment - 1);
> +}
> +
> void JITEmitter::startFunction(MachineFunction &F) {
> - uintptr_t ActualSize;
> + uintptr_t ActualSize = 0;
> + if (MemMgr->RequiresSize()) {
> + const TargetInstrInfo* TII = F.getTarget().getInstrInfo();
> + MachineJumpTableInfo *MJTI = F.getJumpTableInfo();
> + MachineConstantPool *MCP = F.getConstantPool();
> +
> + // Ensure the constant pool/jump table info is at least 4-byte
> aligned.
> + AddAlignment(ActualSize, 16);
> +
> + // Add the alignment of the constant pool
> + AddAlignment(ActualSize, 1 << MCP->getConstantPoolAlignment());
Nitpick. I would call this to something like roundUpToAlign(). It
should return a value rather then taking a reference argument.
> +
> + // Add the constant pool size
> + ActualSize += GetConstantPoolSizeInBytes(MCP);
> +
> + // Add the aligment of the jump table info
> + AddAlignment(ActualSize, MJTI->getAlignment());
> +
> + // Add the jump table size
> + ActualSize += GetJumpTableSizeInBytes(MJTI);
> +
> + // Add the alignment for the function
> + AddAlignment(ActualSize, std::max(F.getFunction()-
> >getAlignment(), 8U));
> +
> + // Add the function size
> + ActualSize += TII->GetFunctionSizeInBytes(F);
> + }
> +
> BufferBegin = CurBufferPtr = MemMgr-
> >startFunctionBody(F.getFunction(),
> ActualSize);
> BufferEnd = BufferBegin+ActualSize;
> @@ -714,10 +771,14 @@
> << sys::disassembleBuffer(FnStart, FnEnd-FnStart,
> (uintptr_t)FnStart);
> #endif
> if (ExceptionHandling) {
> - uintptr_t ActualSize;
> + uintptr_t ActualSize = 0;
> SavedBufferBegin = BufferBegin;
> SavedBufferEnd = BufferEnd;
> SavedCurBufferPtr = CurBufferPtr;
> +
> + if (MemMgr->RequiresSize()) {
RequiresSize -> NeedExactSize?
>
> + ActualSize = DE->GetDwarfTableSize(F, *this, FnStart, FnEnd);
> + }
>
> BufferBegin = CurBufferPtr = MemMgr-
> >startExceptionTable(F.getFunction(),
>
> ActualSize);
> Index: lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
> ===================================================================
> --- lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp (revision 49843)
> +++ lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp (working copy)
> @@ -634,3 +634,472 @@
>
> return StartEHPtr;
> }
> +
> +unsigned JITDwarfEmitter::GetDwarfTableSize(MachineFunction& F,
> + MachineCodeEmitter& mce,
> + unsigned char*
> StartFunction,
> + unsigned char*
> EndFunction) {
> + const TargetMachine& TM = F.getTarget();
> + TD = TM.getTargetData();
> + needsIndirectEncoding = TM.getTargetAsmInfo()-
> >getNeedsIndirectEncoding();
> + stackGrowthDirection = TM.getFrameInfo()-
> >getStackGrowthDirection();
> + RI = TM.getRegisterInfo();
> + MCE = &mce;
> + unsigned FinalSize = 0;
> +
> + FinalSize += GetExceptionTableSize(&F);
> +
> + const std::vector<Function *> Personalities = MMI-
> >getPersonalities();
> + FinalSize += GetCommonEHFrameSize(Personalities[MMI-
> >getPersonalityIndex()]);
> +
> + FinalSize += GetEHFrameSize(Personalities[MMI-
> >getPersonalityIndex()], StartFunction);
> +
> + return FinalSize;
> +}
> +
> +/// AddAlignment - Add the specified alignment.
> +static void AddAlignment(unsigned& FinalSize, unsigned Alignment) {
> + if (Alignment == 0) Alignment = 1;
> + FinalSize = (FinalSize + Alignment - 1) & ~(Alignment - 1);
> +}
> +
> +
> +/// SizeULEB128Bytes - Gives the size of the ULEB128.
> +static unsigned SizeULEB128Bytes(unsigned Value) {
More consistent naming please. How about getULEB128SizeInBytes?
>
> + unsigned FinalSize = 0;
> + do {
> + Value >>= 7;
> + ++FinalSize;
> + } while (Value);
> + return FinalSize;
> +}
> +
> +/// SizeSLEB128Bytes - Gives the size of the SLEB128.
> +static unsigned SizeSLEB128Bytes(int Value) {
> + int Sign = Value >> (8 * sizeof(Value) - 1);
> + bool IsMore;
> + unsigned FinalSize = 0;
> +
> + do {
> + unsigned char Byte = Value & 0x7f;
> + Value >>= 7;
> + IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
> + ++FinalSize;
> + } while (IsMore);
> +
> + return FinalSize;
> +}
> +
> +/// SizeString - Gives the size of the string.
> +static unsigned SizeString(const std::string &String) {
> + return String.size() + 1;
> +}
Seems silly to separate this out to a function.
>
> +
> +unsigned JITDwarfEmitter::GetEHFrameSize(const Function* Personality,
> + unsigned char*
> StartFunction) {
Should be "const"?
>
> + unsigned PointerSize = TD->getPointerSize();
> + unsigned FinalSize = 0;
> + // EH frame header.
> + FinalSize += PointerSize;
> + // FDE CIE Offset
> + FinalSize += 3 * PointerSize;
> + // If there is a personality and landing pads then point to the
> language
> + // specific data area in the exception table.
> + if (MMI->getPersonalityIndex()) {
> + FinalSize += SizeULEB128Bytes(4);
> + FinalSize += PointerSize;
> + } else {
> + FinalSize += SizeULEB128Bytes(0);
> + }
> +
> + // Indicate locations of function specific callee saved
> registers in
> + // frame.
> + FinalSize += GetFrameMovesSize((intptr_t)StartFunction, MMI-
> >getFrameMoves());
> +
> + AddAlignment(FinalSize, 4);
> +
> + // Double zeroes for the unwind runtime
> + FinalSize += 2 * PointerSize;
> +
> + return FinalSize;
> +}
> +
> +unsigned JITDwarfEmitter::GetCommonEHFrameSize(const Function*
> Personality) {
Should be "const"?
>
> +
> + unsigned PointerSize = TD->getPointerSize();
> + int stackGrowth = stackGrowthDirection ==
> TargetFrameInfo::StackGrowsUp ?
> + PointerSize : -PointerSize;
> + unsigned FinalSize = 0;
> + // EH Common Frame header
> + FinalSize += PointerSize;
> + FinalSize += 4;
> + FinalSize += 1;
> + FinalSize += SizeString(Personality ? "zPLR" : "zR");
> + FinalSize += SizeULEB128Bytes(1);
> + FinalSize += SizeSLEB128Bytes(stackGrowth);
> + FinalSize += 1;
> +
> + if (Personality) {
> + FinalSize += SizeULEB128Bytes(7);
> +
> + // Encoding
> + FinalSize+= 1;
> + //Personality
> + FinalSize += PointerSize;
> +
> + FinalSize += SizeULEB128Bytes(dwarf::DW_EH_PE_pcrel);
> + FinalSize += SizeULEB128Bytes(dwarf::DW_EH_PE_pcrel);
> +
> + } else {
> + FinalSize += SizeULEB128Bytes(1);
> + FinalSize += SizeULEB128Bytes(dwarf::DW_EH_PE_pcrel);
> + }
> +
> + std::vector<MachineMove> Moves;
> + RI->getInitialFrameState(Moves);
> + FinalSize += GetFrameMovesSize(0, Moves);
> + AddAlignment(FinalSize, 4);
> + return FinalSize;
> +}
> +
> +unsigned
> +JITDwarfEmitter::GetFrameMovesSize(intptr_t BaseLabelPtr,
> + const std::vector<MachineMove>
> &Moves) {
> + unsigned PointerSize = TD->getPointerSize();
> + int stackGrowth = stackGrowthDirection ==
> TargetFrameInfo::StackGrowsUp ?
> + PointerSize : -PointerSize;
> + bool IsLocal = BaseLabelPtr;
> + unsigned FinalSize = 0;
> +
> + for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
> + const MachineMove &Move = Moves[i];
> + unsigned LabelID = Move.getLabelID();
> +
> + if (LabelID) {
> + LabelID = MMI->MappedLabel(LabelID);
> +
> + // Throw out move if the label is invalid.
> + if (!LabelID) continue;
> + }
> +
> + intptr_t LabelPtr = 0;
> + if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID);
> +
> + const MachineLocation &Dst = Move.getDestination();
> + const MachineLocation &Src = Move.getSource();
> +
> + // Advance row if new location.
> + if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !
> IsLocal)) {
> + FinalSize++;
> + FinalSize += PointerSize;
> + BaseLabelPtr = LabelPtr;
> + IsLocal = true;
> + }
> +
> + // If advancing cfa.
> + if (Dst.isRegister() && Dst.getRegister() ==
> MachineLocation::VirtualFP) {
> + if (!Src.isRegister()) {
> + if (Src.getRegister() == MachineLocation::VirtualFP) {
> + ++FinalSize;
> + } else {
> + ++FinalSize;
> + FinalSize +=
> + SizeULEB128Bytes(RI->getDwarfRegNum(Src.getRegister(),
> true));
> + }
> +
> + int Offset = -Src.getOffset();
> +
> + FinalSize += SizeULEB128Bytes(Offset);
> + } else {
> + assert(0 && "Machine move no supported yet.");
> + }
> + } else if (Src.isRegister() &&
> + Src.getRegister() == MachineLocation::VirtualFP) {
> + if (Dst.isRegister()) {
> + ++FinalSize;
> + FinalSize +=
> + SizeULEB128Bytes(RI->getDwarfRegNum(Dst.getRegister(),
> true));
> + } else {
> + assert(0 && "Machine move no supported yet.");
> + }
> + } else {
> + unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), true);
> + int Offset = Dst.getOffset() / stackGrowth;
> +
> + if (Offset < 0) {
> + ++FinalSize;
> + FinalSize += SizeULEB128Bytes(Reg);
> + FinalSize += SizeSLEB128Bytes(Offset);
> + } else if (Reg < 64) {
> + ++FinalSize;
> + FinalSize += SizeULEB128Bytes(Offset);
> + } else {
> + ++FinalSize;
> + FinalSize += SizeULEB128Bytes(Reg);
> + FinalSize += SizeULEB128Bytes(Offset);
> + }
> + }
> + }
> + return FinalSize;
> +}
> +
> +unsigned JITDwarfEmitter::GetExceptionTableSize(MachineFunction*
> MF) {
Also "const"?
>
> + unsigned FinalSize = 0;
> +
> + // Map all labels and get rid of any dead landing pads.
> + MMI->TidyLandingPads();
> +
> + const std::vector<GlobalVariable *> &TypeInfos = MMI-
> >getTypeInfos();
> + const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
> + const std::vector<LandingPadInfo> &PadInfos = MMI-
> >getLandingPads();
> + if (PadInfos.empty()) return 0;
> +
> + // Sort the landing pads in order of their type ids. This is
> used to fold
> + // duplicate actions.
> + SmallVector<const LandingPadInfo *, 64> LandingPads;
> + LandingPads.reserve(PadInfos.size());
> + for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
> + LandingPads.push_back(&PadInfos[i]);
> + std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
> +
> + // Negative type ids index into FilterIds, positive type ids
> index into
> + // TypeInfos. The value written for a positive type id is just
> the type
> + // id itself. For a negative type id, however, the value written
> is the
> + // (negative) byte offset of the corresponding FilterIds entry.
> The byte
> + // offset is usually equal to the type id, because the FilterIds
> entries
> + // are written using a variable width encoding which outputs one
> byte per
> + // entry as long as the value written is not too large, but can
> differ.
> + // This kind of complication does not occur for positive type ids
> because
> + // type infos are output using a fixed width encoding.
> + // FilterOffsets[i] holds the byte offset corresponding to
> FilterIds[i].
> + SmallVector<int, 16> FilterOffsets;
> + FilterOffsets.reserve(FilterIds.size());
> + int Offset = -1;
> + for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
> + E = FilterIds.end(); I != E; ++I) {
> + FilterOffsets.push_back(Offset);
> + Offset -= AsmPrinter::SizeULEB128(*I);
Can you change the name to getULEB128SizeInBytes while you're at
it? :-) Actually, why not move them to Support/Dwarf.h and avoid
duplication?
Looks good otherwise. Thanks!
Evan
>
> + }
> +
> + // Compute the actions table and gather the first action index
> for each
> + // landing pad site.
> + SmallVector<ActionEntry, 32> Actions;
> + SmallVector<unsigned, 64> FirstActions;
> + FirstActions.reserve(LandingPads.size());
> +
> + int FirstAction = 0;
> + unsigned SizeActions = 0;
> + for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
> + const LandingPadInfo *LP = LandingPads[i];
> + const std::vector<int> &TypeIds = LP->TypeIds;
> + const unsigned NumShared = i ? SharedTypeIds(LP,
> LandingPads[i-1]) : 0;
> + unsigned SizeSiteActions = 0;
> +
> + if (NumShared < TypeIds.size()) {
> + unsigned SizeAction = 0;
> + ActionEntry *PrevAction = 0;
> +
> + if (NumShared) {
> + const unsigned SizePrevIds = LandingPads[i-1]-
> >TypeIds.size();
> + assert(Actions.size());
> + PrevAction = &Actions.back();
> + SizeAction = AsmPrinter::SizeSLEB128(PrevAction-
> >NextAction) +
> + AsmPrinter::SizeSLEB128(PrevAction->ValueForTypeID);
> + for (unsigned j = NumShared; j != SizePrevIds; ++j) {
> + SizeAction -= AsmPrinter::SizeSLEB128(PrevAction-
> >ValueForTypeID);
> + SizeAction += -PrevAction->NextAction;
> + PrevAction = PrevAction->Previous;
> + }
> + }
> +
> + // Compute the actions.
> + for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
> + int TypeID = TypeIds[I];
> + assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown
> filter id!");
> + int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 -
> TypeID] : TypeID;
> + unsigned SizeTypeID =
> AsmPrinter::SizeSLEB128(ValueForTypeID);
> +
> + int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
> + SizeAction = SizeTypeID +
> AsmPrinter::SizeSLEB128(NextAction);
> + SizeSiteActions += SizeAction;
> +
> + ActionEntry Action = {ValueForTypeID, NextAction,
> PrevAction};
> + Actions.push_back(Action);
> +
> + PrevAction = &Actions.back();
> + }
> +
> + // Record the first action of the landing pad site.
> + FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
> + } // else identical - re-use previous FirstAction
> +
> + FirstActions.push_back(FirstAction);
> +
> + // Compute this sites contribution to size.
> + SizeActions += SizeSiteActions;
> + }
> +
> + // Compute the call-site table. Entries must be ordered by
> address.
> + SmallVector<CallSiteEntry, 64> CallSites;
> +
> + RangeMapType PadMap;
> + for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
> + const LandingPadInfo *LandingPad = LandingPads[i];
> + for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; +
> +j) {
> + unsigned BeginLabel = LandingPad->BeginLabels[j];
> + assert(!PadMap.count(BeginLabel) && "Duplicate landing pad
> labels!");
> + PadRange P = { i, j };
> + PadMap[BeginLabel] = P;
> + }
> + }
> +
> + bool MayThrow = false;
> + unsigned LastLabel = 0;
> + for (MachineFunction::const_iterator I = MF->begin(), E = MF-
> >end();
> + I != E; ++I) {
> + for (MachineBasicBlock::const_iterator MI = I->begin(), E = I-
> >end();
> + MI != E; ++MI) {
> + if (MI->getOpcode() != TargetInstrInfo::LABEL) {
> + MayThrow |= MI->getDesc().isCall();
> + continue;
> + }
> +
> + unsigned BeginLabel = MI->getOperand(0).getImm();
> + assert(BeginLabel && "Invalid label!");
> +
> + if (BeginLabel == LastLabel)
> + MayThrow = false;
> +
> + RangeMapType::iterator L = PadMap.find(BeginLabel);
> +
> + if (L == PadMap.end())
> + continue;
> +
> + PadRange P = L->second;
> + const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
> +
> + assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
> + "Inconsistent landing pad map!");
> +
> + // If some instruction between the previous try-range and
> this one may
> + // throw, create a call-site entry with no landing pad for
> the region
> + // between the try-ranges.
> + if (MayThrow) {
> + CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
> + CallSites.push_back(Site);
> + }
> +
> + LastLabel = LandingPad->EndLabels[P.RangeIndex];
> + CallSiteEntry Site = {BeginLabel, LastLabel,
> + LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
> +
> + assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
> + "Invalid landing pad!");
> +
> + // Try to merge with the previous call-site.
> + if (CallSites.size()) {
> + CallSiteEntry &Prev = CallSites[CallSites.size()-1];
> + if (Site.PadLabel == Prev.PadLabel && Site.Action ==
> Prev.Action) {
> + // Extend the range of the previous entry.
> + Prev.EndLabel = Site.EndLabel;
> + continue;
> + }
> + }
> +
> + // Otherwise, create a new call-site.
> + CallSites.push_back(Site);
> + }
> + }
> + // If some instruction between the previous try-range and the end
> of the
> + // function may throw, create a call-site entry with no landing
> pad for the
> + // region following the try-range.
> + if (MayThrow) {
> + CallSiteEntry Site = {LastLabel, 0, 0, 0};
> + CallSites.push_back(Site);
> + }
> +
> + // Final tallies.
> + unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + //
> Site start.
> + sizeof(int32_t) + //
> Site length.
> + sizeof(int32_t)); //
> Landing pad.
> + for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
> + SizeSites += AsmPrinter::SizeULEB128(CallSites[i].Action);
> +
> + unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
> +
> + unsigned TypeOffset = sizeof(int8_t) + // Call site format
> + // Call-site table length
> + AsmPrinter::SizeULEB128(SizeSites) +
> + SizeSites + SizeActions + SizeTypes;
> +
> + unsigned TotalSize = sizeof(int8_t) + // LPStart format
> + sizeof(int8_t) + // TType format
> + AsmPrinter::SizeULEB128(TypeOffset) + //
> TType base offset
> + TypeOffset;
> +
> + unsigned SizeAlign = (4 - TotalSize) & 3;
> +
> + // Begin the exception table.
> + AddAlignment(FinalSize, 4);
> + for (unsigned i = 0; i != SizeAlign; ++i) {
> + ++FinalSize;
> + }
> +
> + unsigned PointerSize = TD->getPointerSize();
> +
> + // Emit the header.
> + ++FinalSize;
> + // Asm->EOL("LPStart format (DW_EH_PE_omit)");
> + ++FinalSize;
> + // Asm->EOL("TType format (DW_EH_PE_absptr)");
> + ++FinalSize;
> + // Asm->EOL("TType base offset");
> + ++FinalSize;
> + // Asm->EOL("Call site format (DW_EH_PE_udata4)");
> + ++FinalSize;
> + // Asm->EOL("Call-site table length");
> +
> + // Emit the landing pad site information.
> + for (unsigned i = 0; i < CallSites.size(); ++i) {
> + CallSiteEntry &S = CallSites[i];
> +
> + // Asm->EOL("Region start");
> + FinalSize += PointerSize;
> +
> + //Asm->EOL("Region length");
> + FinalSize += PointerSize;
> +
> + // Asm->EOL("Landing pad");
> + FinalSize += PointerSize;
> +
> + FinalSize += SizeULEB128Bytes(S.Action);
> + // Asm->EOL("Action");
> + }
> +
> + // Emit the actions.
> + for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
> + ActionEntry &Action = Actions[I];
> +
> + //Asm->EOL("TypeInfo index");
> + FinalSize += SizeSLEB128Bytes(Action.ValueForTypeID);
> + //Asm->EOL("Next action");
> + FinalSize += SizeSLEB128Bytes(Action.NextAction);
> + }
> +
> + // Emit the type ids.
> + for (unsigned M = TypeInfos.size(); M; --M) {
> + // Asm->EOL("TypeInfo");
> + FinalSize += PointerSize;
> + }
> +
> + // Emit the filter typeids.
> + for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
> + unsigned TypeID = FilterIds[j];
> + FinalSize += SizeULEB128Bytes(TypeID);
> + //Asm->EOL("Filter TypeInfo index");
> + }
> +
> + AddAlignment(FinalSize, 4);
> +
> + return FinalSize;
> +}
> Index: lib/ExecutionEngine/JIT/JITDwarfEmitter.h
> ===================================================================
> --- lib/ExecutionEngine/JIT/JITDwarfEmitter.h (revision 49843)
> +++ lib/ExecutionEngine/JIT/JITDwarfEmitter.h (working copy)
> @@ -35,9 +35,6 @@
> bool needsIndirectEncoding;
> bool stackGrowthDirection;
>
> -public:
> - JITDwarfEmitter(JIT& jit);
> -
> unsigned char* EmitExceptionTable(MachineFunction* MF,
> unsigned char* StartFunction,
> unsigned char* EndFunction);
> @@ -53,17 +50,37 @@
> unsigned char* EndFunction,
> unsigned char* ExceptionTable);
>
> + unsigned GetExceptionTableSize(MachineFunction* MF);
> +
> + unsigned GetFrameMovesSize(intptr_t BaseLabelPtr,
> + const std::vector<MachineMove> &Moves);
> +
> + unsigned GetCommonEHFrameSize(const Function* Personality);
>
> + unsigned GetEHFrameSize(const Function* Personality,
> + unsigned char* StartFunction);
> +
> +public:
> +
> + JITDwarfEmitter(JIT& jit);
> +
> unsigned char* EmitDwarfTable(MachineFunction& F,
> MachineCodeEmitter& MCE,
> unsigned char* StartFunction,
> unsigned char* EndFunction);
>
> +
> + unsigned GetDwarfTableSize(MachineFunction& F,
> + MachineCodeEmitter& MCE,
> + unsigned char* StartFunction,
> + unsigned char* EndFunction);
> +
> void setModuleInfo(MachineModuleInfo* Info) {
> MMI = Info;
> }
> };
>
> +
> } // end namespace llvm
>
> #endif // LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
More information about the llvm-dev
mailing list