blob: 171b2fca175f32d527e115ed726aecfeb58acbcb [file] [log] [blame]
Index: include/llvm/Target/TargetOptions.h
===================================================================
--- include/llvm/Target/TargetOptions.h (revision 48143)
+++ include/llvm/Target/TargetOptions.h (working copy)
@@ -74,10 +74,15 @@
/// be emitted.
extern bool ExceptionHandling;
+ /// SizedMemoryCode - This flags indicates that memory for code is allocated by
+ /// an external allocator which requires the size to allocate
+ extern bool SizedMemoryCode;
+
/// PerformTailCallOpt - This flag is enabled when -tailcallopt is specified
/// on the commandline. When the flag is on, the target will perform tail call
/// optimization (pop the caller's stack) providing it supports it.
extern bool PerformTailCallOpt;
+
} // End llvm namespace
#endif
Index: include/llvm/CodeGen/SizeEmitter.h
===================================================================
--- include/llvm/CodeGen/SizeEmitter.h (revision 0)
+++ include/llvm/CodeGen/SizeEmitter.h (revision 0)
@@ -0,0 +1,116 @@
+//===-- llvm/CodeGen/MachineCodeEmitter.h - Code emission -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an abstract interface that is used by the machine code
+// emission framework to output the code. This allows machine code emission to
+// be separated from concerns such as resolution of call targets, and where the
+// machine code will be written (memory or disk, f.e.).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SIZEEMITTER_H
+#define LLVM_CODEGEN_SIZEEMITTER_H
+
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+ /// SizeEmitter - The JIT implementation of the MachineCodeEmitter, which is
+ /// used to output functions to memory for execution.
+class SizeEmitter : public MachineCodeEmitter {
+ MachineFunction * Fn;
+ void* ConstantPoolBase;
+ void* JumpTableBase;
+ MachineConstantPool *ConstantPool;
+ MachineJumpTableInfo *JumpTable;
+ std::vector<intptr_t> LabelLocations;
+ MachineCodeEmitter* MCE;
+
+public:
+ SizeEmitter(MachineCodeEmitter* mce) {
+ CurBufferPtr = 0;
+ BufferBegin = 0;
+ BufferEnd = (unsigned char*)-1;
+ MCE = mce;
+ }
+
+ SizeEmitter(std::vector<intptr_t> locations) {
+ LabelLocations = locations;
+ CurBufferPtr = 0;
+ BufferBegin = 0;
+ BufferEnd = (unsigned char*)-1;
+ }
+
+ void initConstantPool(MachineConstantPool *MCP);
+
+ void initJumpTableInfo(MachineJumpTableInfo *MJTI);
+
+
+ virtual void startFunction(MachineFunction &F) {
+ CurBufferPtr = 0;
+ Fn = &F;
+
+ // Ensure the constant pool/jump table info is at least 4-byte aligned.
+ emitAlignment(16);
+
+ initConstantPool(F.getConstantPool());
+ initJumpTableInfo(F.getJumpTableInfo());
+
+ ConstantPoolBase = (void*)(((unsigned) ConstantPoolBase) + CurBufferPtr);
+ JumpTableBase = (void*)(((unsigned) JumpTableBase) + CurBufferPtr);
+ }
+
+ virtual bool finishFunction(MachineFunction &F) {
+ MCE->setCurrentPtr(CurBufferPtr);
+ return false;
+ }
+ virtual void startFunctionStub(unsigned StubSize, unsigned Alignment) {}
+ virtual void *finishFunctionStub(const Function *F) { return 0; }
+ virtual void addRelocation(const llvm::MachineRelocation&) { }
+ virtual void emitByte(unsigned char B) {
+ CurBufferPtr++;
+ }
+ virtual void emitWordLE(unsigned W) {
+ CurBufferPtr+=4;
+ }
+ virtual void emitWordBE(unsigned W) {
+ CurBufferPtr+=4;
+ }
+ virtual void emitInt32(int Value) {
+ CurBufferPtr += 4;
+ }
+ virtual void emitInt64(uint64_t Value) {
+ CurBufferPtr += 8;
+ }
+ virtual void emitAt(uintptr_t *Addr, uintptr_t Value) {
+ }
+
+
+
+ virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {}
+ virtual intptr_t getConstantPoolEntryAddress(unsigned ConstantNum) const;
+
+ virtual intptr_t getJumpTableEntryAddress(unsigned Index) const;
+
+ virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
+ assert(0 && "Should not be in getMachineBasicBlockAddress of SizeEmitter");
+ }
+
+ virtual void emitLabel(uint64_t) {}
+ virtual intptr_t getLabelAddress(uint64_t LabelID) const {
+ assert(LabelLocations.size() > (unsigned)LabelID &&
+ LabelLocations[LabelID] && "Label not emitted!");
+ return LabelLocations[LabelID];
+ }
+ virtual void setModuleInfo(llvm::MachineModuleInfo*) {}
+};
+
+} // end llvm namespace
+
+#endif
Index: include/llvm/CodeGen/MachineCodeEmitter.h
===================================================================
--- include/llvm/CodeGen/MachineCodeEmitter.h (revision 48143)
+++ include/llvm/CodeGen/MachineCodeEmitter.h (working copy)
@@ -18,6 +18,7 @@
#define LLVM_CODEGEN_MACHINECODEEMITTER_H
#include "llvm/Support/DataTypes.h"
+#include <string>
#include <vector>
namespace llvm {
@@ -92,7 +93,7 @@
/// emitByte - This callback is invoked when a byte needs to be written to the
/// output stream.
///
- void emitByte(unsigned char B) {
+ virtual void emitByte(unsigned char B) {
if (CurBufferPtr != BufferEnd)
*CurBufferPtr++ = B;
}
@@ -100,7 +101,7 @@
/// emitWordLE - This callback is invoked when a 32-bit word needs to be
/// written to the output stream in little-endian format.
///
- void emitWordLE(unsigned W) {
+ virtual void emitWordLE(unsigned W) {
if (CurBufferPtr+4 <= BufferEnd) {
*CurBufferPtr++ = (unsigned char)(W >> 0);
*CurBufferPtr++ = (unsigned char)(W >> 8);
@@ -114,7 +115,7 @@
/// emitWordBE - This callback is invoked when a 32-bit word needs to be
/// written to the output stream in big-endian format.
///
- void emitWordBE(unsigned W) {
+ virtual void emitWordBE(unsigned W) {
if (CurBufferPtr+4 <= BufferEnd) {
*CurBufferPtr++ = (unsigned char)(W >> 24);
*CurBufferPtr++ = (unsigned char)(W >> 16);
@@ -175,7 +176,7 @@
}
/// emitInt32 - Emit a int32 directive.
- void emitInt32(int Value) {
+ virtual void emitInt32(int Value) {
if (CurBufferPtr+4 <= BufferEnd) {
*((uint32_t*)CurBufferPtr) = Value;
CurBufferPtr += 4;
@@ -185,7 +186,7 @@
}
/// emitInt64 - Emit a int64 directive.
- void emitInt64(uint64_t Value) {
+ virtual void emitInt64(uint64_t Value) {
if (CurBufferPtr+8 <= BufferEnd) {
*((uint64_t*)CurBufferPtr) = Value;
CurBufferPtr += 8;
@@ -195,7 +196,7 @@
}
/// emitAt - Emit Value in Addr
- void emitAt(uintptr_t *Addr, uintptr_t Value) {
+ virtual void emitAt(uintptr_t *Addr, uintptr_t Value) {
if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
(*Addr) = Value;
}
@@ -270,6 +271,11 @@
/// Specifies the MachineModuleInfo object. This is used for exception handling
/// purposes.
virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
+
+ void setCurrentPtr(unsigned char* Ptr) {
+ CurBufferPtr = Ptr;
+ }
+
};
} // End llvm namespace
Index: lib/CodeGen/LLVMTargetMachine.cpp
===================================================================
--- lib/CodeGen/LLVMTargetMachine.cpp (revision 48143)
+++ lib/CodeGen/LLVMTargetMachine.cpp (working copy)
@@ -17,6 +17,7 @@
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/SizeEmitter.h"
#include "llvm/CodeGen/Collector.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
@@ -257,7 +258,13 @@
if (addPreEmitPass(PM, Fast) && PrintMachineCode)
PM.add(createMachineFunctionPrinterPass(cerr));
+
+ if (SizedMemoryCode) {
+ SizeEmitter * SE = new SizeEmitter(&MCE);
+ addSimpleCodeEmitter(PM, Fast, false, *SE);
+ }
+
addCodeEmitter(PM, Fast, PrintEmittedAsm, MCE);
PM.add(createCollectorMetadataDeleter());
Index: lib/CodeGen/SizeEmitter.cpp
===================================================================
--- lib/CodeGen/SizeEmitter.cpp (revision 0)
+++ lib/CodeGen/SizeEmitter.cpp (revision 0)
@@ -0,0 +1,77 @@
+#include "llvm/CodeGen/SizeEmitter.h"
+#include "llvm/Constant.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/Type.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineRelocation.h"
+#include "llvm/ExecutionEngine/GenericValue.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"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/System/Memory.h"
+#include <algorithm>
+using namespace llvm;
+
+
+void SizeEmitter::initConstantPool(MachineConstantPool *MCP) {
+ const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
+ if (Constants.empty()) return;
+
+ MachineConstantPoolEntry CPE = Constants.back();
+ unsigned Size = CPE.Offset;
+ const Type *Ty = CPE.isMachineConstantPoolEntry()
+ ? CPE.Val.MachineCPVal->getType() : CPE.Val.ConstVal->getType();
+ Size += Fn->getTarget().getTargetData()->getABITypeSize(Ty);
+ ConstantPoolBase = allocateSpace(Size, 1 << MCP->getConstantPoolAlignment());
+ ConstantPool = MCP;
+}
+
+void SizeEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) {
+ const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+ if (JT.empty()) return;
+
+ unsigned NumEntries = 0;
+ for (unsigned i = 0, e = JT.size(); i != e; ++i)
+ NumEntries += JT[i].MBBs.size();
+
+ unsigned EntrySize = MJTI->getEntrySize();
+
+ // Just allocate space for all the jump tables now. We will fix up the actual
+ // MBB entries in the tables after we emit the code for each block, since then
+ // we will know the final locations of the MBBs in memory.
+ JumpTable = MJTI;
+ JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment());
+}
+
+intptr_t SizeEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const {
+ assert(ConstantNum < ConstantPool->getConstants().size() &&
+ "Invalid ConstantPoolIndex!");
+ return (intptr_t)ConstantPoolBase +
+ ConstantPool->getConstants()[ConstantNum].Offset;
+}
+
+intptr_t SizeEmitter::getJumpTableEntryAddress(unsigned Index) const {
+ const std::vector<MachineJumpTableEntry> &JT = JumpTable->getJumpTables();
+ assert(Index < JT.size() && "Invalid jump table index!");
+
+ unsigned Offset = 0;
+ unsigned EntrySize = JumpTable->getEntrySize();
+
+ for (unsigned i = 0; i < Index; ++i)
+ Offset += JT[i].MBBs.size();
+
+ Offset *= EntrySize;
+
+ return (intptr_t)((char *)JumpTableBase + Offset);
+}
+
Index: lib/Target/PowerPC/PPCInstrInfo.td
===================================================================
--- lib/Target/PowerPC/PPCInstrInfo.td (revision 48143)
+++ lib/Target/PowerPC/PPCInstrInfo.td (working copy)
@@ -1189,6 +1189,8 @@
(BL_ELF texternalsym:$dst)>;
// Hi and Lo for Darwin Global Addresses.
+def : Pat<(PPChi texternalsym:$in, 0), (LIS texternalsym:$in)>;
+def : Pat<(PPClo texternalsym:$in, 0), (LI texternalsym:$in)>;
def : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>;
def : Pat<(PPClo tglobaladdr:$in, 0), (LI tglobaladdr:$in)>;
def : Pat<(PPChi tconstpool:$in, 0), (LIS tconstpool:$in)>;
Index: lib/Target/PowerPC/PPCJITInfo.cpp
===================================================================
--- lib/Target/PowerPC/PPCJITInfo.cpp (revision 48143)
+++ lib/Target/PowerPC/PPCJITInfo.cpp (working copy)
@@ -13,11 +13,15 @@
#define DEBUG_TYPE "jit"
#include "PPCJITInfo.h"
+#include "PPCRegisterInfo.h"
#include "PPCRelocations.h"
#include "PPCTargetMachine.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/Config/alloca.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Target/TargetOptions.h"
#include <set>
using namespace llvm;
@@ -52,24 +56,27 @@
if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range?
AtI[0] = BUILD_B(Offset, isCall); // b/bl target
} else if (!is64Bit) {
- AtI[0] = BUILD_LIS(12, To >> 16); // lis r12, hi16(address)
+ AtI[0] = BUILD_B(0, false); // thread safety
AtI[1] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address)
AtI[2] = BUILD_MTCTR(12); // mtctr r12
AtI[3] = BUILD_BCTR(isCall); // bctr/bctrl
+ AtI[0] = BUILD_LIS(12, To >> 16); // lis r12, hi16(address)
} else {
- AtI[0] = BUILD_LIS(12, To >> 48); // lis r12, hi16(address)
+ AtI[0] = BUILD_B(0, false); // thread safety
AtI[1] = BUILD_ORI(12, 12, To >> 32); // ori r12, r12, lo16(address)
AtI[2] = BUILD_SLDI(12, 12, 32); // sldi r12, r12, 32
AtI[3] = BUILD_ORIS(12, 12, To >> 16); // oris r12, r12, hi16(address)
AtI[4] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address)
AtI[5] = BUILD_MTCTR(12); // mtctr r12
AtI[6] = BUILD_BCTR(isCall); // bctr/bctrl
+ AtI[0] = BUILD_LIS(12, To >> 48); // lis r12, hi16(address)
}
}
extern "C" void PPC32CompilationCallback();
extern "C" void PPC64CompilationCallback();
+
#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \
!defined(__ppc64__)
// CompilationCallback stub - We can't use a C function with inline assembly in
@@ -143,6 +150,9 @@
// it, because we the prolog/epilog inserted by GCC won't work for us. Instead,
// write our own wrapper, which does things our way, so we have complete control
// over register saving and restoring.
+
+# define CFI(x) x
+
asm(
".text\n"
".align 2\n"
@@ -155,19 +165,29 @@
// FIXME Layout
// 8 double registers - 64 bytes
// 8 int registers - 32 bytes
+ CFI(".cfi_startproc\n")
+ "stwu 1, -104(1)\n"
+ CFI(".cfi_adjust_cfa_offset 104\n")
"mflr 0\n"
- "stw 0, 4(1)\n"
- "stwu 1, -104(1)\n"
+ "stw 0, 108(1)\n"
+ CFI(".cfi_offset lr, 4\n")
// Save all int arg registers
- "stw 10, 100(1)\n" "stw 9, 96(1)\n"
- "stw 8, 92(1)\n" "stw 7, 88(1)\n"
- "stw 6, 84(1)\n" "stw 5, 80(1)\n"
- "stw 4, 76(1)\n" "stw 3, 72(1)\n"
+ "stw 10, 100(1)\n"
+ "stw 9, 96(1)\n"
+ "stw 8, 92(1)\n"
+ "stw 7, 88(1)\n"
+ "stw 6, 84(1)\n"
+ "stw 5, 80(1)\n"
+ "stw 4, 76(1)\n"
+ "stw 3, 72(1)\n"
// Save all call-clobbered FP regs.
"stfd 8, 64(1)\n"
- "stfd 7, 56(1)\n" "stfd 6, 48(1)\n"
- "stfd 5, 40(1)\n" "stfd 4, 32(1)\n"
- "stfd 3, 24(1)\n" "stfd 2, 16(1)\n"
+ "stfd 7, 56(1)\n"
+ "stfd 6, 48(1)\n"
+ "stfd 5, 40(1)\n"
+ "stfd 4, 32(1)\n"
+ "stfd 3, 24(1)\n"
+ "stfd 2, 16(1)\n"
"stfd 1, 8(1)\n"
// Arguments to Compilation Callback:
// r3 - our lr (address of the call instruction in stub plus 4)
@@ -180,21 +200,29 @@
"bl PPCCompilationCallbackC\n"
"mtctr 3\n"
// Restore all int arg registers
- "lwz 10, 100(1)\n" "lwz 9, 96(1)\n"
- "lwz 8, 92(1)\n" "lwz 7, 88(1)\n"
- "lwz 6, 84(1)\n" "lwz 5, 80(1)\n"
- "lwz 4, 76(1)\n" "lwz 3, 72(1)\n"
+ "lwz 10, 100(1)\n"
+ "lwz 9, 96(1)\n"
+ "lwz 8, 92(1)\n"
+ "lwz 7, 88(1)\n"
+ "lwz 6, 84(1)\n"
+ "lwz 5, 80(1)\n"
+ "lwz 4, 76(1)\n"
+ "lwz 3, 72(1)\n"
// Restore all FP arg registers
"lfd 8, 64(1)\n"
- "lfd 7, 56(1)\n" "lfd 6, 48(1)\n"
- "lfd 5, 40(1)\n" "lfd 4, 32(1)\n"
- "lfd 3, 24(1)\n" "lfd 2, 16(1)\n"
+ "lfd 7, 56(1)\n"
+ "lfd 6, 48(1)\n"
+ "lfd 5, 40(1)\n"
+ "lfd 4, 32(1)\n"
+ "lfd 3, 24(1)\n"
+ "lfd 2, 16(1)\n"
"lfd 1, 8(1)\n"
// Pop 3 frames off the stack and branch to target
"lwz 1, 104(1)\n"
"lwz 0, 4(1)\n"
"mtlr 0\n"
"bctr\n"
+ CFI(".cfi_endproc\n")
);
#else
void PPC32CompilationCallback() {
@@ -324,6 +352,31 @@
return is64Bit ? PPC64CompilationCallback : PPC32CompilationCallback;
}
+static const char* GetCommonFrame32() {
+ /*
+ // Size of common frame
+ MCE.emitWordBE(16);
+ // Common frame
+ MCE.emitWordBE(0);
+ MCE.emitByte(1);
+ MCE.emitByte('z');
+ MCE.emitByte('R');
+ MCE.emitByte(0);
+ MCE.emitByte(1);
+ MCE.emitByte(-4 & 0x7f);
+ MCE.emitByte(0x41);
+ MCE.emitByte(1);
+ MCE.emitByte(16);
+ MCE.emitByte(0xc);
+ MCE.emitByte(1);
+ MCE.emitByte(0);*/
+ static const char CF[] = {
+ 0, 0, 0, 16, 0, 0, 0, 0, 1, 'z', 'R', 0, 1, -4 & 0x7f,
+ 0x41, 1, 16, 0xc, 1, 0
+ };
+ return CF;
+}
+
#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \
defined(__APPLE__)
extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
@@ -356,21 +409,26 @@
SyncICache((void*)Addr, 7*4);
return MCE.finishFunctionStub(0);
}
-
- MCE.startFunctionStub(10*4);
+
+ if (ExceptionHandling && !is64Bit) {
+ MCE.startFunctionStub(10*4 + 44);
+ } else {
+ MCE.startFunctionStub(10*4);
+ }
+ intptr_t BeginAddr = (intptr_t)MCE.getCurrentPCValue();
intptr_t Addr = (intptr_t)MCE.getCurrentPCValue();
if (is64Bit) {
+ MCE.emitWordBE(0x7d6802a6); // mflr r11
+ MCE.emitWordBE(0xf9610010); // std r11, 16(r1)
MCE.emitWordBE(0xf821ffb1); // stdu r1,-80(r1)
+ } else if (TM.getSubtargetImpl()->isMachoABI()){
MCE.emitWordBE(0x7d6802a6); // mflr r11
- MCE.emitWordBE(0xf9610060); // std r11, 96(r1)
- } else if (TM.getSubtargetImpl()->isMachoABI()){
+ MCE.emitWordBE(0x91610008); // stw r11, 8(r1)
MCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1)
+ } else {
MCE.emitWordBE(0x7d6802a6); // mflr r11
- MCE.emitWordBE(0x91610028); // stw r11, 40(r1)
- } else {
+ MCE.emitWordBE(0x91610004); // stw r11, 4(r1)
MCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1)
- MCE.emitWordBE(0x7d6802a6); // mflr r11
- MCE.emitWordBE(0x91610024); // stw r11, 36(r1)
}
intptr_t BranchAddr = (intptr_t)MCE.getCurrentPCValue();
MCE.emitWordBE(0);
@@ -382,6 +440,42 @@
MCE.emitWordBE(0);
EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit);
SyncICache((void*)Addr, 10*4);
+ intptr_t EndAddr = (intptr_t)MCE.getCurrentPCValue();
+
+ if (ExceptionHandling && !is64Bit) {
+ // Size of Eh section
+ MCE.emitWordBE(32);
+ // Eh section
+ MCE.emitWordBE(MCE.getCurrentPCValue() - (intptr_t)GetCommonFrame32());
+ MCE.emitWordBE(BeginAddr - MCE.getCurrentPCValue());
+ MCE.emitWordBE(EndAddr - BeginAddr);
+ MCE.emitByte(0);
+ MCE.emitByte(dwarf::DW_CFA_advance_loc4);
+ MCE.emitWordBE(8);
+ MCE.emitByte(dwarf::DW_CFA_def_cfa_offset);
+ MCE.emitByte(32);
+ MCE.emitByte(dwarf::DW_CFA_offset_extended_sf);
+ MCE.emitByte(TM.getRegisterInfo()->getDwarfRegNum(PPC::LR, true));
+ if (TM.getSubtargetImpl()->isMachoABI()){
+ MCE.emitByte(-2 & 0x7f);
+ } else {
+ MCE.emitByte(-1 & 0x7f);
+ }
+ MCE.emitByte(dwarf::DW_CFA_advance_loc4);
+ MCE.emitWordBE(4);
+ MCE.emitByte(dwarf::DW_CFA_def_cfa_register);
+ MCE.emitByte(1);
+ // Alignment
+ MCE.emitByte(0);
+ MCE.emitByte(0);
+
+ // Two zero for the unwind runtime
+ MCE.emitWordBE(0);
+ MCE.emitWordBE(0);
+
+ SyncICache((void*)EndAddr, 44);
+ ExecutionEngine::RegisterTable((void*)EndAddr);
+ }
return MCE.finishFunctionStub(0);
}
Index: lib/Target/TargetMachine.cpp
===================================================================
--- lib/Target/TargetMachine.cpp (revision 48143)
+++ lib/Target/TargetMachine.cpp (working copy)
@@ -31,6 +31,7 @@
bool UseSoftFloat;
bool NoZerosInBSS;
bool ExceptionHandling;
+ bool SizedMemoryCode;
Reloc::Model RelocationModel;
CodeModel::Model CMModel;
bool PerformTailCallOpt;
Index: lib/ExecutionEngine/JIT/JITEmitter.cpp
===================================================================
--- lib/ExecutionEngine/JIT/JITEmitter.cpp (revision 48143)
+++ lib/ExecutionEngine/JIT/JITEmitter.cpp (working copy)
@@ -18,12 +18,14 @@
#include "llvm/Constant.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#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/CodeGen/SizeEmitter.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetJITInfo.h"
@@ -278,8 +280,10 @@
DOUT << "JIT: Lazily resolving function '" << F->getName()
<< "' In stub ptr = " << Stub << " actual ptr = "
<< I->first << "\n";
-
+
+ TheJIT->lock.release();
Result = TheJIT->getPointerToFunction(F);
+ TheJIT->lock.acquire();
}
// We don't need to reuse this stub in the future, as F is now compiled.
@@ -357,9 +361,11 @@
MemMgr->AllocateGOT();
DOUT << "JIT is managing a GOT\n";
}
-
- if (ExceptionHandling) DE = new JITDwarfEmitter(jit);
+
+ if (ExceptionHandling)
+ DE = new JITDwarfEmitter(jit);
}
+
~JITEmitter() {
delete MemMgr;
if (ExceptionHandling) delete DE;
@@ -370,6 +376,7 @@
virtual void startFunction(MachineFunction &F);
virtual bool finishFunction(MachineFunction &F);
+ void initConstantPool(MachineConstantPool *MCP);
void emitConstantPool(MachineConstantPool *MCP);
void initJumpTableInfo(MachineJumpTableInfo *MJTI);
void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
@@ -469,19 +476,47 @@
void JITEmitter::startFunction(MachineFunction &F) {
- uintptr_t ActualSize;
- BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(),
- ActualSize);
- BufferEnd = BufferBegin+ActualSize;
+ MMI->BeginFunction(&F);
- // Ensure the constant pool/jump table info is at least 4-byte aligned.
- emitAlignment(16);
+ if (SizedMemoryCode) {
+ BufferBegin = CurBufferPtr;
+ BufferEnd = (unsigned char*) 0xffffffff;
+
+ // Ensure the constant pool/jump table info is at least 4-byte aligned.
+ emitAlignment(16);
- emitConstantPool(F.getConstantPool());
- initJumpTableInfo(F.getJumpTableInfo());
+ initConstantPool(F.getConstantPool());
+ initJumpTableInfo(F.getJumpTableInfo());
+
+
+ uintptr_t ActualSize = (uintptr_t)CurBufferPtr;
+ CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(),
+ ActualSize);
+
+ ConstantPoolBase = (void*)(((unsigned) ConstantPoolBase) + CurBufferPtr);
+ JumpTableBase = (void*)(((unsigned) JumpTableBase) + CurBufferPtr);
- // About to start emitting the machine code for the function.
- emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
+ emitConstantPool(F.getConstantPool());
+
+ } else {
+ uintptr_t ActualSize;
+ BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(),
+ ActualSize);
+ BufferEnd = BufferBegin+ActualSize;
+
+ // Ensure the constant pool/jump table info is at least 4-byte aligned.
+ emitAlignment(16);
+
+ initConstantPool(F.getConstantPool());
+ emitConstantPool(F.getConstantPool());
+ initJumpTableInfo(F.getJumpTableInfo());
+
+ // About to start emitting the machine code for the function.
+ emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
+
+ }
+
+
TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr);
MBBLocations.clear();
@@ -579,12 +614,18 @@
DOUT << "Disassembled code:\n"
<< sys::disassembleBuffer(FnStart, FnEnd-FnStart, (uintptr_t)FnStart);
#endif
+
if (ExceptionHandling) {
uintptr_t ActualSize;
+ if (SizedMemoryCode) {
+ SizeEmitter sz(LabelLocations);
+ DE->EmitDwarfTable(F, sz, FnStart, FnEnd);
+ ActualSize = sz.getCurrentPCValue();
+ }
SavedBufferBegin = BufferBegin;
SavedBufferEnd = BufferEnd;
SavedCurBufferPtr = CurBufferPtr;
-
+
BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
ActualSize);
BufferEnd = BufferBegin+ActualSize;
@@ -598,11 +639,10 @@
TheJIT->RegisterTable(FrameRegister);
}
MMI->EndFunction();
-
return false;
}
-void JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
+void JITEmitter::initConstantPool(MachineConstantPool *MCP) {
const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
if (Constants.empty()) return;
@@ -611,12 +651,15 @@
const Type *Ty = CPE.isMachineConstantPoolEntry()
? CPE.Val.MachineCPVal->getType() : CPE.Val.ConstVal->getType();
Size += TheJIT->getTargetData()->getABITypeSize(Ty);
-
+
ConstantPoolBase = allocateSpace(Size, 1 << MCP->getConstantPoolAlignment());
ConstantPool = MCP;
+}
+void JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
if (ConstantPoolBase == 0) return; // Buffer overflow.
+ const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
// Initialize the memory for all of the constant pool entries.
for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
void *CAddr = (char*)ConstantPoolBase+Constants[i].Offset;
Index: lib/ExecutionEngine/JIT/JIT.cpp
===================================================================
--- lib/ExecutionEngine/JIT/JIT.cpp (revision 48143)
+++ lib/ExecutionEngine/JIT/JIT.cpp (working copy)
@@ -289,10 +289,10 @@
/// specified function, compiling it if neccesary.
///
void *JIT::getPointerToFunction(Function *F) {
- MutexGuard locked(lock);
- if (void *Addr = getPointerToGlobalIfAvailable(F))
- return Addr; // Check if function already code gen'd
+ if (void *Addr = getPointerToGlobalIfAvailable(F)) {
+ return Addr;
+ }
// Make sure we read in the function if it exists in this Module.
if (F->hasNotBeenReadFromBitcode()) {
@@ -314,13 +314,25 @@
abort();
}
}
+
+ if (void *Addr = getPointerToGlobalIfAvailable(F)) {
+ return Addr;
+ }
if (F->isDeclaration()) {
+ if (void *Addr = getPointerToGlobalIfAvailable(F)) {
+ return Addr;
+ }
void *Addr = getPointerToNamedFunction(F->getName());
addGlobalMapping(F, Addr);
return Addr;
}
+ MutexGuard locked(lock);
+
+ if (void *Addr = getPointerToGlobalIfAvailable(F))
+ return Addr; // Check if function already code gen'd
+
runJITOnFunction(F);
void *Addr = getPointerToGlobalIfAvailable(F);
Index: lib/ExecutionEngine/ExecutionEngine.cpp
===================================================================
--- lib/ExecutionEngine/ExecutionEngine.cpp (revision 48143)
+++ lib/ExecutionEngine/ExecutionEngine.cpp (working copy)
@@ -92,7 +92,7 @@
// If we are using the reverse mapping, add it too
if (!state.getGlobalAddressReverseMap(locked).empty()) {
const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr];
- assert((V == 0 || GV == 0) && "GlobalMapping already established!");
+ // assert((V == 0 || GV == 0) && "GlobalMapping already established!");
V = GV;
}
}
@@ -128,7 +128,7 @@
// If we are using the reverse mapping, add it too
if (!state.getGlobalAddressReverseMap(locked).empty()) {
const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr];
- assert((V == 0 || GV == 0) && "GlobalMapping already established!");
+ // assert((V == 0 || GV == 0) && "GlobalMapping already established!");
V = GV;
}
}
Index: lib/VMCore/AsmWriter.cpp
===================================================================
--- lib/VMCore/AsmWriter.cpp (revision 48143)
+++ lib/VMCore/AsmWriter.cpp (working copy)
@@ -1053,8 +1053,9 @@
case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;
case GlobalValue::ExternalLinkage: break;
case GlobalValue::GhostLinkage:
- cerr << "GhostLinkage not allowed in AsmWriter!\n";
- abort();
+ //cerr << "GhostLinkage not allowed in AsmWriter!\n";
+ //abort();
+ break;
}
switch (F->getVisibility()) {
default: assert(0 && "Invalid visibility style!");
Index: lib/Target/X86/X86JITInfo.cpp
===================================================================
--- lib/Target/X86/X86JITInfo.cpp (revision 48341)
+++ lib/Target/X86/X86JITInfo.cpp (working copy)
@@ -57,7 +57,7 @@
// FIXME: Disable this until we really want to use it. Also, we will
// need to add some workarounds for compilers, which support
// only subset of these directives.
-# define CFI(x)
+# define CFI(x) x
#endif
// Provide a wrapper for X86CompilationCallback2 that saves non-traditional
Index: lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- lib/Target/PowerPC/PPCISelLowering.cpp (revision 48651)
+++ lib/Target/PowerPC/PPCISelLowering.cpp (working copy)
@@ -177,10 +177,12 @@
// We want to legalize GlobalAddress and ConstantPool nodes into the
// appropriate instructions to materialize the address.
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
+ setOperationAction(ISD::ExternalSymbol , MVT::i32 , Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
+ setOperationAction(ISD::ExternalSymbol , MVT::i64 , Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
setOperationAction(ISD::JumpTable, MVT::i64, Custom);
@@ -735,6 +737,36 @@
return isIntS16Immediate(Op.Val, Imm);
}
+ static SDOperand LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG) {
+ MVT::ValueType PtrVT = Op.getValueType();
+ ExternalSymbolSDNode *GSDB = dyn_cast<ExternalSymbolSDNode>(Op);
+ SDOperand GA = DAG.getTargetExternalSymbol(GSDB->getSymbol(), PtrVT);
+ SDOperand Zero = DAG.getConstant(0, PtrVT);
+
+ const TargetMachine &TM = DAG.getTarget();
+
+ SDOperand Hi = DAG.getNode(PPCISD::Hi, PtrVT, GA, Zero);
+ SDOperand Lo = DAG.getNode(PPCISD::Lo, PtrVT, GA, Zero);
+
+ // If this is a non-darwin platform, we don't support non-static relo models
+ // yet.
+ if (TM.getRelocationModel() == Reloc::Static ||
+ !TM.getSubtarget<PPCSubtarget>().isDarwin()) {
+ // Generate non-pic code that has direct accesses to globals.
+ // The address of the global is just (hi(&g)+lo(&g)).
+ return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
+ }
+
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ // With PIC, the first instruction is actually "GR+hi(&G)".
+ Hi = DAG.getNode(ISD::ADD, PtrVT,
+ DAG.getNode(PPCISD::GlobalBaseReg, PtrVT), Hi);
+ }
+
+ Lo = DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
+
+ return Lo;
+ }
/// SelectAddressRegReg - Given the specified addressed, check to see if it
/// can be represented as an indexed [r+r] operation. Returns false if it
@@ -2116,11 +2148,11 @@
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
// node so that legalize doesn't hack it.
- if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
- Callee = DAG.getTargetGlobalAddress(G->getGlobal(), Callee.getValueType());
- else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
- Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType());
- else if (SDNode *Dest = isBLACompatibleAddress(Callee, DAG))
+ //if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
+ // Callee = DAG.getTargetGlobalAddress(G->getGlobal(), Callee.getValueType());
+ //if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
+ // Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType());
+ if (SDNode *Dest = isBLACompatibleAddress(Callee, DAG))
// If this is an absolute destination address, use the munged value.
Callee = SDOperand(Dest, 0);
else {
@@ -3381,6 +3413,7 @@
default: assert(0 && "Wasn't expecting to be able to lower this!");
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
+ case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
case ISD::SETCC: return LowerSETCC(Op, DAG);