summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/MachineCodeEmitter.h76
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h18
-rw-r--r--include/llvm/ExecutionEngine/JITMemoryManager.h11
-rw-r--r--lib/CodeGen/ELFWriter.cpp15
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp4
-rw-r--r--lib/CodeGen/MachOWriter.cpp14
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp2
-rw-r--r--lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp636
-rw-r--r--lib/ExecutionEngine/JIT/JITDwarfEmitter.h69
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp55
-rw-r--r--lib/ExecutionEngine/JIT/JITMemoryManager.cpp41
-rw-r--r--lib/Target/PowerPC/PPCCodeEmitter.cpp11
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp17
13 files changed, 961 insertions, 8 deletions
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
index 2c207f22f8..8fe7ecc9e9 100644
--- a/include/llvm/CodeGen/MachineCodeEmitter.h
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -26,6 +26,7 @@ class MachineBasicBlock;
class MachineConstantPool;
class MachineJumpTableInfo;
class MachineFunction;
+class MachineModuleInfo;
class MachineRelocation;
class Value;
class GlobalValue;
@@ -136,6 +137,72 @@ public:
CurBufferPtr = BufferEnd;
}
+
+ /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
+ /// written to the output stream.
+ void emitULEB128Bytes(unsigned Value) {
+ do {
+ unsigned char Byte = Value & 0x7f;
+ Value >>= 7;
+ if (Value) Byte |= 0x80;
+ emitByte(Byte);
+ } while (Value);
+ }
+
+ /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
+ /// written to the output stream.
+ void emitSLEB128Bytes(int Value) {
+ int Sign = Value >> (8 * sizeof(Value) - 1);
+ bool IsMore;
+
+ do {
+ unsigned char Byte = Value & 0x7f;
+ Value >>= 7;
+ IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+ if (IsMore) Byte |= 0x80;
+ emitByte(Byte);
+ } while (IsMore);
+ }
+
+ /// emitString - This callback is invoked when a String needs to be
+ /// written to the output stream.
+ void emitString(const std::string &String) {
+ for (unsigned i = 0, N = String.size(); i < N; ++i) {
+ unsigned char C = String[i];
+ emitByte(C);
+ }
+ emitByte(0);
+ }
+
+ /// emitInt32 - Emit a int32 directive.
+ void emitInt32(int Value) {
+ if (CurBufferPtr+4 <= BufferEnd) {
+ *((uint32_t*)CurBufferPtr) = Value;
+ CurBufferPtr += 4;
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitInt64 - Emit a int64 directive.
+ void emitInt64(uint64_t Value) {
+ if (CurBufferPtr+8 <= BufferEnd) {
+ *((uint64_t*)CurBufferPtr) = Value;
+ CurBufferPtr += 8;
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitAt - Emit Value in Addr
+ void emitAt(uintptr_t *Addr, uintptr_t Value) {
+ if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
+ (*Addr) = Value;
+ }
+
+ /// emitLabel - Emits a label
+ virtual void emitLabel(uint64_t LabelID) = 0;
+
/// allocateSpace - Allocate a block of space in the current output buffer,
/// returning null (and setting conditions to indicate buffer overflow) on
/// failure. Alignment is the alignment in bytes of the buffer desired.
@@ -194,6 +261,15 @@ public:
/// emitted.
///
virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0;
+
+ /// getLabelAddress - Return the address of the specified LabelID, only usable
+ /// after the LabelID has been emitted.
+ ///
+ virtual intptr_t getLabelAddress(uint64_t LabelID) const = 0;
+
+ /// Specifies the MachineModuleInfo object. This is used for exception handling
+ /// purposes.
+ virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
};
} // End llvm namespace
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index f2249ec197..461efe3235 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -85,6 +85,11 @@ protected:
/// pointer is invoked to create it. If this returns null, the JIT will abort.
void* (*LazyFunctionCreator)(const std::string &);
+ /// ExceptionTableRegister - If Exception Handling is set, the JIT will
+ /// register dwarf tables with this function
+ typedef void (*EERegisterFn)(void*);
+ static EERegisterFn ExceptionTableRegister;
+
public:
/// lock - This lock is protects the ExecutionEngine, JIT, JITResolver and
/// JITEmitter classes. It must be held while changing the internal state of
@@ -246,6 +251,19 @@ public:
void InstallLazyFunctionCreator(void* (*P)(const std::string &)) {
LazyFunctionCreator = P;
}
+
+ /// InstallExceptionTableRegister - The JIT will use the given function
+ /// to register the exception tables it generates.
+ static void InstallExceptionTableRegister(void (*F)(void*)) {
+ ExceptionTableRegister = F;
+ }
+
+ /// RegisterTable - Registers the given pointer as an exception table. It uses
+ /// the ExceptionTableRegister function.
+ static void RegisterTable(void* res) {
+ if (ExceptionTableRegister)
+ ExceptionTableRegister(res);
+ }
protected:
explicit ExecutionEngine(ModuleProvider *P);
diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h
index c41be7958a..7226496753 100644
--- a/include/llvm/ExecutionEngine/JITMemoryManager.h
+++ b/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -89,6 +89,17 @@ public:
/// deallocateMemForFunction - Free JIT memory for the specified function.
/// This is never called when the JIT is currently emitting a function.
virtual void deallocateMemForFunction(const Function *F) = 0;
+
+ /// startExceptionTable - When we finished JITing the function, if exception
+ /// handling is set, we emit the exception table.
+ virtual unsigned char* startExceptionTable(const Function* F,
+ uintptr_t &ActualSize) = 0;
+
+ /// endExceptionTable - This method is called when the JIT is done emitting
+ /// the exception table.
+ virtual void endExceptionTable(const Function *F, unsigned char *TableStart,
+ unsigned char *TableEnd,
+ unsigned char* FrameRegister) = 0;
};
} // end namespace llvm.
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index 908abe5f1b..82bf9924d8 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -98,6 +98,21 @@ namespace llvm {
return 0;
}
+ virtual intptr_t getLabelAddress(uint64_t Label) const {
+ assert(0 && "Label address not implementated yet!");
+ abort();
+ return 0;
+ }
+
+ virtual void emitLabel(uint64_t LabelID) {
+ assert(0 && "emit Label not implementated yet!");
+ abort();
+ }
+
+
+ virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+
+
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
assert(0 && "JIT specific function called!");
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 351554bb19..5611b03ba7 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -186,8 +186,8 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
PM.add(createGCLoweringPass());
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass(getTargetLowering()));
+ if (!ExceptionHandling)
+ PM.add(createLowerInvokePass(getTargetLowering()));
// Make sure that no unreachable blocks are instruction selected.
PM.add(createUnreachableBlockEliminationPass());
diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp
index 71e7430635..92b3eb4311 100644
--- a/lib/CodeGen/MachOWriter.cpp
+++ b/lib/CodeGen/MachOWriter.cpp
@@ -125,6 +125,20 @@ namespace llvm {
return MBBLocations[MBB->getNumber()];
}
+ virtual intptr_t getLabelAddress(uint64_t Label) const {
+ assert(0 && "get Label not implemented");
+ abort();
+ return 0;
+ }
+
+ virtual void emitLabel(uint64_t LabelID) {
+ assert(0 && "emit Label not implemented");
+ abort();
+ }
+
+
+ virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
assert(0 && "JIT specific function called!");
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index fe6b811ea6..d1ad03f100 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -34,6 +34,8 @@ STATISTIC(NumGlobals , "Number of global vars initialized");
ExecutionEngine::EECtorFn ExecutionEngine::JITCtor = 0;
ExecutionEngine::EECtorFn ExecutionEngine::InterpCtor = 0;
+ExecutionEngine::EERegisterFn ExecutionEngine::ExceptionTableRegister = 0;
+
ExecutionEngine::ExecutionEngine(ModuleProvider *P) : LazyFunctionCreator(0) {
LazyCompilationDisabled = false;
diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
new file mode 100644
index 0000000000..230ae54224
--- /dev/null
+++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
@@ -0,0 +1,636 @@
+//===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a JITDwarfEmitter object that is used by the JIT to
+// write dwarf tables to memory.
+//
+//===----------------------------------------------------------------------===//
+
+#include "JIT.h"
+#include "JITDwarfEmitter.h"
+#include "llvm/Function.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+using namespace llvm;
+
+JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {}
+
+
+unsigned char* JITDwarfEmitter::EmitDwarfTable(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 char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
+ EndFunction);
+
+ unsigned char* Result = 0;
+ unsigned char* EHFramePtr = 0;
+
+ const std::vector<Function *> Personalities = MMI->getPersonalities();
+ EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
+
+ Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
+ StartFunction, EndFunction, ExceptionTable);
+
+ return Result;
+}
+
+
+void JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
+ const std::vector<MachineMove> &Moves) {
+ unsigned PointerSize = TD->getPointerSize();
+ int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
+ PointerSize : -PointerSize;
+ bool IsLocal = BaseLabelPtr;
+
+ 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)) {
+ MCE->emitByte(dwarf::DW_CFA_advance_loc4);
+ if (PointerSize == 8) {
+ MCE->emitInt64(LabelPtr - BaseLabelPtr);
+ } else {
+ MCE->emitInt32(LabelPtr - BaseLabelPtr);
+ }
+
+ BaseLabelPtr = LabelPtr;
+ IsLocal = true;
+ }
+
+ // If advancing cfa.
+ if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
+ if (!Src.isRegister()) {
+ if (Src.getRegister() == MachineLocation::VirtualFP) {
+ MCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
+ } else {
+ MCE->emitByte(dwarf::DW_CFA_def_cfa);
+ MCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister(), true));
+ }
+
+ int Offset = -Src.getOffset();
+
+ MCE->emitULEB128Bytes(Offset);
+ } else {
+ assert(0 && "Machine move no supported yet.");
+ }
+ } else if (Src.isRegister() &&
+ Src.getRegister() == MachineLocation::VirtualFP) {
+ if (Dst.isRegister()) {
+ MCE->emitByte(dwarf::DW_CFA_def_cfa_register);
+ MCE->emitULEB128Bytes(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) {
+ MCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
+ MCE->emitULEB128Bytes(Reg);
+ MCE->emitSLEB128Bytes(Offset);
+ } else if (Reg < 64) {
+ MCE->emitByte(dwarf::DW_CFA_offset + Reg);
+ MCE->emitULEB128Bytes(Offset);
+ } else {
+ MCE->emitByte(dwarf::DW_CFA_offset_extended);
+ MCE->emitULEB128Bytes(Reg);
+ MCE->emitULEB128Bytes(Offset);
+ }
+ }
+ }
+}
+
+/// SharedTypeIds - How many leading type ids two landing pads have in common.
+static unsigned SharedTypeIds(const LandingPadInfo *L,
+ const LandingPadInfo *R) {
+ const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
+ unsigned LSize = LIds.size(), RSize = RIds.size();
+ unsigned MinSize = LSize < RSize ? LSize : RSize;
+ unsigned Count = 0;
+
+ for (; Count != MinSize; ++Count)
+ if (LIds[Count] != RIds[Count])
+ return Count;
+
+ return Count;
+}
+
+
+/// PadLT - Order landing pads lexicographically by type id.
+static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
+ const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
+ unsigned LSize = LIds.size(), RSize = RIds.size();
+ unsigned MinSize = LSize < RSize ? LSize : RSize;
+
+ for (unsigned i = 0; i != MinSize; ++i)
+ if (LIds[i] != RIds[i])
+ return LIds[i] < RIds[i];
+
+ return LSize < RSize;
+}
+
+struct KeyInfo {
+ static inline unsigned getEmptyKey() { return -1U; }
+ static inline unsigned getTombstoneKey() { return -2U; }
+ static unsigned getHashValue(const unsigned &Key) { return Key; }
+ static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
+ static bool isPod() { return true; }
+};
+
+/// ActionEntry - Structure describing an entry in the actions table.
+struct ActionEntry {
+ int ValueForTypeID; // The value to write - may not be equal to the type id.
+ int NextAction;
+ struct ActionEntry *Previous;
+};
+
+/// PadRange - Structure holding a try-range and the associated landing pad.
+struct PadRange {
+ // The index of the landing pad.
+ unsigned PadIndex;
+ // The index of the begin and end labels in the landing pad's label lists.
+ unsigned RangeIndex;
+};
+
+typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType;
+
+/// CallSiteEntry - Structure describing an entry in the call-site table.
+struct CallSiteEntry {
+ unsigned BeginLabel; // zero indicates the start of the function.
+ unsigned EndLabel; // zero indicates the end of the function.
+ unsigned PadLabel; // zero indicates that there is no landing pad.
+ unsigned Action;
+};
+
+unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
+ unsigned char* StartFunction,
+ unsigned char* EndFunction) {
+ // 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);
+ }
+
+ // 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.
+ MCE->emitAlignment(4);
+ for (unsigned i = 0; i != SizeAlign; ++i) {
+ MCE->emitByte(0);
+ // Asm->EOL("Padding");
+ }
+
+ unsigned char* DwarfExceptionTable = (unsigned char*)MCE->getCurrentPCValue();
+
+ // Emit the header.
+ MCE->emitByte(dwarf::DW_EH_PE_omit);
+ // Asm->EOL("LPStart format (DW_EH_PE_omit)");
+ MCE->emitByte(dwarf::DW_EH_PE_absptr);
+ // Asm->EOL("TType format (DW_EH_PE_absptr)");
+ MCE->emitULEB128Bytes(TypeOffset);
+ // Asm->EOL("TType base offset");
+ MCE->emitByte(dwarf::DW_EH_PE_udata4);
+ // Asm->EOL("Call site format (DW_EH_PE_udata4)");
+ MCE->emitULEB128Bytes(SizeSites);
+ // Asm->EOL("Call-site table length");
+
+ // Emit the landing pad site information.
+ for (unsigned i = 0; i < CallSites.size(); ++i) {
+ CallSiteEntry &S = CallSites[i];
+ intptr_t BeginLabelPtr = 0;
+ intptr_t EndLabelPtr = 0;
+
+ if (!S.BeginLabel) {
+ BeginLabelPtr = (intptr_t)StartFunction;
+ if (TD->getPointerSize() == sizeof(int32_t))
+ MCE->emitInt32(0);
+ else
+ MCE->emitInt64(0);
+ } else {
+ BeginLabelPtr = MCE->getLabelAddress(S.BeginLabel);
+ if (TD->getPointerSize() == sizeof(int32_t))
+ MCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
+ else
+ MCE->emitInt64(BeginLabelPtr - (intptr_t)StartFunction);
+ }
+
+ // Asm->EOL("Region start");
+
+ if (!S.EndLabel) {
+ EndLabelPtr = (intptr_t)EndFunction;
+ if (TD->getPointerSize() == sizeof(int32_t))
+ MCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr);
+ else
+ MCE->emitInt64((intptr_t)EndFunction - BeginLabelPtr);
+ } else {
+ EndLabelPtr = MCE->getLabelAddress(S.EndLabel);
+ if (TD->getPointerSize() == sizeof(int32_t))
+ MCE->emitInt32(EndLabelPtr - BeginLabelPtr);
+ else
+ MCE->emitInt64(EndLabelPtr - BeginLabelPtr);
+ }
+ //Asm->EOL("Region length");
+
+ if (!S.PadLabel) {
+ if (TD->getPointerSize() == sizeof(int32_t))
+ MCE->emitInt32(0);
+ else
+ MCE->emitInt64(0);
+ } else {
+ unsigned PadLabelPtr = MCE->getLabelAddress(S.PadLabel);
+ if (TD->getPointerSize() == sizeof(int32_t))
+ MCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
+ else
+ MCE->emitInt64(PadLabelPtr - (intptr_t)StartFunction);
+ }
+ // Asm->EOL("Landing pad");
+
+ MCE->emitULEB128Bytes(S.Action);
+ // Asm->EOL("Action");
+ }
+
+ // Emit the actions.
+ for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
+ ActionEntry &Action = Actions[I];
+
+ MCE->emitSLEB128Bytes(Action.ValueForTypeID);
+ //Asm->EOL("TypeInfo index");
+ MCE->emitSLEB128Bytes(Action.NextAction);
+ //Asm->EOL("Next action");
+ }
+
+ // Emit the type ids.
+ for (unsigned M = TypeInfos.size(); M; --M) {
+ GlobalVariable *GV = TypeInfos[M - 1];
+
+ if (GV) {
+ if (TD->getPointerSize() == sizeof(int32_t)) {
+ MCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
+ } else {
+ MCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
+ }
+ } else {
+ if (TD->getPointerSize() == sizeof(int32_t))
+ MCE->emitInt32(0);
+ else
+ MCE->emitInt64(0);
+ }
+ // Asm->EOL("TypeInfo");
+ }
+
+ // Emit the filter typeids.
+ for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
+ unsigned TypeID = FilterIds[j];
+ MCE->emitULEB128Bytes(TypeID);
+ //Asm->EOL("Filter TypeInfo index");
+ }
+
+ MCE->emitAlignment(4);
+
+ return DwarfExceptionTable;
+}
+
+unsigned char* JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) {
+ unsigned PointerSize = TD->getPointerSize();
+ int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ?
+ PointerSize : -PointerSize;
+
+ unsigned char* StartCommonPtr = (unsigned char*)MCE->getCurrentPCValue();
+ // EH Common Frame header
+ MCE->allocateSpace(PointerSize, 0);
+ unsigned char* FrameCommonBeginPtr = (unsigned char*)MCE->getCurrentPCValue();
+ MCE->emitInt32((int)0);
+ MCE->emitByte(dwarf::DW_CIE_VERSION);
+ MCE->emitString(Personality ? "zPLR" : "zR");
+ MCE->emitULEB128Bytes(1);
+ MCE->emitSLEB128Bytes(stackGrowth);
+ MCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
+
+ if (Personality) {
+ MCE->emitULEB128Bytes(7);
+
+ if (needsIndirectEncoding)
+ MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 |
+ dwarf::DW_EH_PE_indirect);
+ else
+ MCE->emitByte(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
+
+ if (PointerSize == 8)
+ MCE->emitInt64((intptr_t)Jit.getPointerToGlobal(Personality) -
+ MCE->getCurrentPCValue());
+ else
+ MCE->emitInt32((intptr_t)Jit.getPointerToGlobal(Personality) -
+ MCE->getCurrentPCValue());
+
+ MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
+ MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
+
+ } else {
+ MCE->emitULEB128Bytes(1);
+ MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel);
+ }
+
+ std::vector<MachineMove> Moves;
+ RI->getInitialFrameState(Moves);
+ EmitFrameMoves(0, Moves);
+ MCE->emitAlignment(4);
+
+ MCE->emitAt((uintptr_t*)StartCommonPtr,
+ (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() -
+ FrameCommonBeginPtr));
+
+ return StartCommonPtr;
+}
+
+
+unsigned char* JITDwarfEmitter::EmitEHFrame(const Function* Personality,
+ unsigned char* StartCommonPtr,
+ unsigned char* StartFunction,
+ unsigned char* EndFunction,
+ unsigned char* ExceptionTable) {
+ unsigned PointerSize = TD->getPointerSize();
+
+ // EH frame header.
+ unsigned char* StartEHPtr = (unsigned char*)MCE->getCurrentPCValue();
+ MCE->allocateSpace(PointerSize, 0);
+ unsigned char* FrameBeginPtr = (unsigned char*)MCE->getCurrentPCValue();
+ // FDE CIE Offset
+ if (PointerSize == 8) {
+ MCE->emitInt64(FrameBeginPtr - StartCommonPtr);
+ MCE->emitInt64(StartFunction - (unsigned char*)MCE->getCurrentPCValue());
+ MCE->emitInt64(EndFunction - StartFunction);
+ } else {
+ MCE->emitInt32(FrameBeginPtr - StartCommonPtr);
+ MCE->emitInt32(StartFunction - (unsigned char*)MCE->getCurrentPCValue());
+ MCE->emitInt32(EndFunction - StartFunction);
+ }
+
+ // If there is a personality and landing pads then point to the language
+ // specific data area in the exception table.
+ if (MMI->getPersonalityIndex()) {
+ MCE->emitULEB128Bytes(4);
+
+ if (!MMI->getLandingPads().empty()) {
+ if (PointerSize == 8)
+ MCE->emitInt64(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue());
+ else
+ MCE->emitInt32(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue());
+ } else if (PointerSize == 8) {
+ MCE->emitInt64((int)0);
+ } else {
+ MCE->emitInt32((int)0);
+ }
+ } else {
+ MCE->emitULEB128Bytes(0);
+ }
+
+ // Indicate locations of function specific callee saved registers in
+ // frame.
+ EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
+
+ MCE->emitAlignment(4);
+
+ // Indicate the size of the table
+ MCE->emitAt((uintptr_t*)StartEHPtr,
+ (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() -
+ StartEHPtr));
+
+ // Double zeroes for the unwind runtime
+ if (PointerSize == 8) {
+ MCE->emitInt64(0);
+ MCE->emitInt64(0);
+ } else {
+ MCE->emitInt32(0);
+ MCE->emitInt32(0);
+ }
+
+
+ return StartEHPtr;
+}
diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.h b/lib/ExecutionEngine/JIT/JITDwarfEmitter.h
new file mode 100644
index 0000000000..72c9b45b3b
--- /dev/null
+++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.h
@@ -0,0 +1,69 @@
+//===------ JITDwarfEmitter.h - Write dwarf tables into memory ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a JITDwarfEmitter object that is used by the JIT to
+// write dwarf tables to memory.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
+#define LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
+
+namespace llvm {
+
+class Function;
+class MachineCodeEmitter;
+class MachineFunction;
+class MachineModuleInfo;
+class MachineMove;
+class TargetData;
+class TargetMachine;
+class TargetRegisterInfo;
+
+class JITDwarfEmitter {
+ const TargetData* TD;
+ MachineCodeEmitter* MCE;
+ const TargetRegisterInfo* RI;
+ MachineModuleInfo* MMI;
+ JIT& Jit;
+ bool needsIndirectEncoding;
+ bool stackGrowthDirection;
+
+public:
+ JITDwarfEmitter(JIT& jit);
+
+ unsigned char* EmitExceptionTable(MachineFunction* MF,
+ unsigned char* StartFunction,
+ unsigned char* EndFunction);
+
+ void EmitFrameMoves(intptr_t BaseLabelPtr,
+ const std::vector<MachineMove> &Moves);
+
+ unsigned char* EmitCommonEHFrame(const Function* Personality);
+
+ unsigned char* EmitEHFrame(const Function* Personality,
+ unsigned char* StartBufferPtr,
+ unsigned char* StartFunction,
+ unsigned char* EndFunction,
+ unsigned char* ExceptionTable);
+
+
+ unsigned char* EmitDwarfTable(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
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index d49b64f806..09c60d416b 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -14,6 +14,7 @@
#define DEBUG_TYPE "jit"
#include "JIT.h"
+#include "JITDwarfEmitter.h"
#include "llvm/Constant.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
@@ -21,11 +22,13 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRelocation.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/System/Disassembler.h"
@@ -336,6 +339,17 @@ namespace {
/// Resolver - This contains info about the currently resolved functions.
JITResolver Resolver;
+
+ /// DE - The dwarf emitter for the jit.
+ JITDwarfEmitter *DE;
+
+ /// LabelLocations - This vector is a mapping from Label ID's to their
+ /// address.
+ std::vector<intptr_t> LabelLocations;
+
+ /// MMI - Machine module info for exception informations
+ MachineModuleInfo* MMI;
+
public:
JITEmitter(JIT &jit, JITMemoryManager *JMM) : Resolver(jit) {
MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
@@ -343,9 +357,12 @@ namespace {
MemMgr->AllocateGOT();
DOUT << "JIT is managing a GOT\n";
}
+
+ if (ExceptionHandling) DE = new JITDwarfEmitter(jit);
}
~JITEmitter() {
delete MemMgr;
+ if (ExceptionHandling) delete DE;
}
JITResolver &getJITResolver() { return Resolver; }
@@ -384,6 +401,24 @@ namespace {
void deallocateMemForFunction(Function *F) {
MemMgr->deallocateMemForFunction(F);
}
+
+ virtual void emitLabel(uint64_t LabelID) {
+ if (LabelLocations.size() <= LabelID)
+ LabelLocations.resize((LabelID+1)*2);
+ LabelLocations[LabelID] = getCurrentPCValue();
+ }
+
+ virtual intptr_t getLabelAddress(uint64_t LabelID) const {
+ assert(LabelLocations.size() > (unsigned)LabelID &&
+ LabelLocations[LabelID] && "Label not emitted!");
+ return LabelLocations[LabelID];
+ }
+
+ virtual void setModuleInfo(MachineModuleInfo* Info) {
+ MMI = Info;
+ if (ExceptionHandling) DE->setModuleInfo(Info);
+ }
+
private:
void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
void *getPointerToGVLazyPtr(GlobalValue *V, void *Reference,
@@ -544,7 +579,25 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
DOUT << "Disassembled code:\n"
<< sys::disassembleBuffer(FnStart, FnEnd-FnStart, (uintptr_t)FnStart);
#endif
-
+ if (ExceptionHandling) {
+ uintptr_t ActualSize;
+ SavedBufferBegin = BufferBegin;
+ SavedBufferEnd = BufferEnd;
+ SavedCurBufferPtr = CurBufferPtr;
+
+ BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
+ ActualSize);
+ BufferEnd = BufferBegin+ActualSize;
+ unsigned char* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd);
+ MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, FrameRegister);
+ BufferBegin = SavedBufferBegin;
+ BufferEnd = SavedBufferEnd;
+ CurBufferPtr = SavedCurBufferPtr;
+
+ TheJIT->RegisterTable(FrameRegister);
+ }
+ MMI->EndFunction();
+
return false;
}
diff --git a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
index f70e57f0e9..0bf42b8099 100644
--- a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
+++ b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
@@ -256,6 +256,7 @@ namespace {
sys::MemoryBlock getNewMemoryBlock(unsigned size);
std::map<const Function*, MemoryRangeHeader*> FunctionBlocks;
+ std::map<const Function*, MemoryRangeHeader*> TableBlocks;
public:
DefaultJITMemoryManager();
~DefaultJITMemoryManager();
@@ -290,6 +291,28 @@ namespace {
FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
}
+ /// startExceptionTable - Use startFunctionBody to allocate memory for the
+ /// function's exception table.
+ unsigned char* startExceptionTable(const Function* F, uintptr_t &ActualSize) {
+ return startFunctionBody(F, ActualSize);
+ }
+
+ /// endExceptionTable - The exception table of F is now allocated,
+ /// and takes the memory in the range [TableStart,TableEnd).
+ void endExceptionTable(const Function *F, unsigned char *TableStart,
+ unsigned char *TableEnd,
+ unsigned char* FrameRegister) {
+ assert(TableEnd > TableStart);
+ assert(TableStart == (unsigned char *)(CurBlock+1) &&
+ "Mismatched table start/end!");
+
+ uintptr_t BlockSize = TableEnd - (unsigned char *)CurBlock;
+ TableBlocks[F] = CurBlock;
+
+ // Release the memory at the end of this block that isn't needed.
+ FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
+ }
+
unsigned char *getGOTBase() const {
return GOTBase;
}
@@ -315,6 +338,24 @@ namespace {
// Finally, remove this entry from FunctionBlocks.
FunctionBlocks.erase(I);
+
+ I = TableBlocks.find(F);
+ if (I == TableBlocks.end()) return;
+
+ // Find the block that is allocated for this function.
+ MemRange = I->second;
+ assert(MemRange->ThisAllocated && "Block isn't allocated!");
+
+ // Fill the buffer with garbage!
+#ifndef NDEBUG
+ memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange));
+#endif
+
+ // Free the memory.
+ FreeMemoryList = MemRange->FreeBlock(FreeMemoryList);
+
+ // Finally, remove this entry from TableBlocks.
+ TableBlocks.erase(I);
}
};
}
diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp
index 8f5e6fcbf0..a23f4e41eb 100644
--- a/lib/Target/PowerPC/PPCCodeEmitter.cpp
+++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp
@@ -20,6 +20,7 @@
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
@@ -38,6 +39,11 @@ namespace {
/// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
///
int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
+
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineModuleInfo>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
public:
static char ID;
@@ -82,6 +88,8 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
MF.getTarget().getRelocationModel() != Reloc::Static) &&
"JIT relocation model must be set to static or default!");
+
+ MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
do {
MovePCtoLROffset = 0;
MCE.startFunction(MF);
@@ -101,6 +109,9 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
default:
MCE.emitWordBE(getBinaryCodeForInstr(*I));
break;
+ case TargetInstrInfo::LABEL:
+ MCE.emitLabel(MI.getOperand(0).getImm());
+ break;
case PPC::IMPLICIT_DEF_GPRC:
case PPC::IMPLICIT_DEF_G8RC:
case PPC::IMPLICIT_DEF_F8:
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index 144473320a..fe459f9fda 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -23,6 +23,7 @@
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Function.h"
#include "llvm/ADT/Statistic.h"
@@ -61,6 +62,11 @@ namespace {
void emitInstruction(const MachineInstr &MI,
const TargetInstrDesc *Desc);
+
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineModuleInfo>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
private:
void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
@@ -104,10 +110,13 @@ bool Emitter::runOnMachineFunction(MachineFunction &MF) {
assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
MF.getTarget().getRelocationModel() != Reloc::Static) &&
"JIT relocation model must be set to static or default!");
+
+ MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
+
II = ((X86TargetMachine&)TM).getInstrInfo();
TD = ((X86TargetMachine&)TM).getTargetData();
Is64BitMode = TM.getSubtarget<X86Subtarget>().is64Bit();
-
+
do {
MCE.startFunction(MF);
for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
@@ -596,13 +605,13 @@ void Emitter::emitInstruction(const MachineInstr &MI,
// Remember the current PC offset, this is the PIC relocation
// base address.
switch (Opcode) {
-#ifndef NDEBUG
default:
assert(0 && "psuedo instructions should be removed before code emission");
case TargetInstrInfo::INLINEASM:
assert(0 && "JIT does not support inline asm!\n");
case TargetInstrInfo::LABEL:
- assert(0 && "JIT does not support meta labels!\n");
+ MCE.emitLabel(MI.getOperand(0).getImm());
+ break;
case X86::IMPLICIT_DEF_GR8:
case X86::IMPLICIT_DEF_GR16:
case X86::IMPLICIT_DEF_GR32:
@@ -613,7 +622,6 @@ void Emitter::emitInstruction(const MachineInstr &MI,
case X86::IMPLICIT_DEF_VR128:
case X86::FP_REG_KILL:
break;
-#endif
case X86::MOVPC32r: {
// This emits the "call" portion of this pseudo instruction.
MCE.emitByte(BaseOpcode);
@@ -627,7 +635,6 @@ void Emitter::emitInstruction(const MachineInstr &MI,
}
CurOp = NumOps;
break;
-
case X86II::RawFrm:
MCE.emitByte(BaseOpcode);