diff options
-rw-r--r-- | lib/Support/Memory.cpp | 35 | ||||
-rw-r--r-- | lib/Target/Mips/MipsCodeEmitter.cpp | 198 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.h | 27 | ||||
-rw-r--r-- | lib/Target/Mips/MipsJITInfo.cpp | 137 | ||||
-rw-r--r-- | lib/Target/Mips/MipsRelocations.h | 19 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetMachine.h | 1 |
6 files changed, 287 insertions, 130 deletions
diff --git a/lib/Support/Memory.cpp b/lib/Support/Memory.cpp index a9689b2c39..1294744649 100644 --- a/lib/Support/Memory.cpp +++ b/lib/Support/Memory.cpp @@ -30,6 +30,39 @@ using namespace sys; extern "C" void sys_icache_invalidate(const void *Addr, size_t len); +/// ClearMipsCache - Invalidates instruction cache for Mips. This assembly code +/// is copied from the MIPS32 Instruction Set Reference. Since the code ends +/// with the return instruction "jr.hb ra" (Jump Register with Hazard Barrier), +/// it must be implemented as a function (which is called from the +/// InvalidateInstructionCache function). It cannot be directly inlined into +/// InvalidateInstructionCache function, because in that case the epilog of +/// InvalidateInstructionCache will not be executed. +#if defined(__mips__) +extern "C" void ClearMipsCache(const void* Addr, size_t Size); + asm volatile( + ".text\n" + ".align 2\n" + ".globl ClearMipsCache\n" + "ClearMipsCache:\n" + ".set noreorder\n" + "beq $a1, $zero, 20f\n" /* If size==0, branch around */ + "nop\n" + "addu $a1, $a0, $a1\n" /* Calculate end address + 1 */ + "rdhwr $v0, $1\n" /* Get step size for SYNCI */ + /* $1 is $HW_SYNCI_Step */ + "beq $v0, $zero, 20f\n" /* If no caches require synchronization, */ + /* branch around */ + "nop\n" + "10: synci 0($a0)\n" /* Synchronize all caches around address */ + "sltu $v1, $a0, $a1\n" /* Compare current with end address */ + "bne $v1, $zero, 10b\n" /* Branch if more to do */ + "addu $a0, $a0, $v0\n" /* Add step size in delay slot */ + "sync\n" /* Clear memory hazards */ + "20: jr.hb $ra\n" /* Return, clearing instruction hazards */ + "nop\n" + ); +#endif + /// InvalidateInstructionCache - Before the JIT can run a block of code /// that has been emitted it must invalidate the instruction cache on some /// platforms. @@ -66,6 +99,8 @@ void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr, char *Start = (char*) Addr; char *End = Start + Len; __clear_cache(Start, End); +# elif defined(__mips__) + ClearMipsCache(Addr, Len); # endif #endif // end apple diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp index eb8f7e0870..9220d9c7ab 100644 --- a/lib/Target/Mips/MipsCodeEmitter.cpp +++ b/lib/Target/Mips/MipsCodeEmitter.cpp @@ -41,6 +41,8 @@ using namespace llvm; +STATISTIC(NumEmitted, "Number of machine instructions emitted"); + namespace { class MipsCodeEmitter : public MachineFunctionPass { @@ -75,65 +77,38 @@ class MipsCodeEmitter : public MachineFunctionPass { return "Mips Machine Code Emitter"; } - void emitInstruction(const MachineInstr &MI); + /// getBinaryCodeForInstr - This function, generated by the + /// CodeEmitterGenerator using TableGen, produces the binary encoding for + /// machine instructions. + unsigned getBinaryCodeForInstr(const MachineInstr &MI) const; - unsigned getOperandValue(const MachineOperand &MO, - unsigned relocType = -1); + void emitInstruction(const MachineInstr &MI); - void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, - bool MayNeedFarStub = true); + private: - void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc, - intptr_t JTBase = 0); + void emitWordLE(unsigned Word); - void emitExternalSymbolAddress(const char *ES, unsigned Reloc); + /// Routines that handle operands which add machine relocations which are + /// fixed up by the relocation stage. + void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, + bool MayNeedFarStub) const; + void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const; + void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const; void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const; - void emitConstPoolAddress(unsigned CPI, unsigned Reloc); -}; -} - -void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, - bool mayNeedFarStub) { - MachineRelocation MR = MachineRelocation::getGV(MCE.getCurrentPCOffset(), - Reloc, const_cast<GlobalValue *> (GV), 0, mayNeedFarStub); - MCE.addRelocation(MR); -} - -/// emitMachineBasicBlock - Emit the specified address basic block. -void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, - unsigned Reloc, intptr_t JTBase) { - MCE.addRelocation( - MachineRelocation::getBB(MCE.getCurrentPCOffset(), Reloc, BB, JTBase)); -} - -void MipsCodeEmitter::emitExternalSymbolAddress(const char *ES, - unsigned Reloc) { - MCE.addRelocation( - MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, ES, 0, 0, - false)); -} + void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const; -void MipsCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) - const { - MCE.addRelocation( - MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), Reloc, JTIndex, - 0, false)); -} + /// getMachineOpValue - Return binary encoding of operand. If the machine + /// operand requires relocation, record the relocation and return zero. + unsigned getMachineOpValue(const MachineInstr &MI, + const MachineOperand &MO) const; -void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) { - MCE.addRelocation( - MachineRelocation::getConstPool - (MCE.getCurrentPCOffset(), Reloc, CPI, 0)); -} + unsigned getRelocation(const MachineInstr &MI, + const MachineOperand &MO) const; -/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips -/// code to the specified MCE object. -FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM, - JITCodeEmitter &JCE) { - return new MipsCodeEmitter(TM, JCE); + }; } -char MipsCodeEmitter::ID = 10; +char MipsCodeEmitter::ID = 0; bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) { JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo(); @@ -163,31 +138,108 @@ bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) { return false; } -void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {} - -unsigned MipsCodeEmitter::getOperandValue(const MachineOperand &MO, - unsigned relocType) { - switch (MO.getType()) { - case MachineOperand::MO_Immediate: - return MO.getImm(); - case MachineOperand::MO_GlobalAddress: - emitGlobalAddress(MO.getGlobal(), relocType, false); - return 0; - case MachineOperand::MO_ExternalSymbol: - emitExternalSymbolAddress(MO.getSymbolName(), relocType); - return 0; - case MachineOperand::MO_MachineBasicBlock: - emitMachineBasicBlock(MO.getMBB(), relocType, MCE.getCurrentPCValue()); - return 0; - case MachineOperand::MO_Register: +unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI, + const MachineOperand &MO) const { + // NOTE: This relocations are for static. + uint64_t TSFlags = MI.getDesc().TSFlags; + uint64_t Form = TSFlags & MipsII::FormMask; + if (Form == MipsII::FrmJ) + return Mips::reloc_mips_26; + if ((Form == MipsII::FrmI || Form == MipsII::FrmFI) + && MI.getDesc().isBranch()) + return Mips::reloc_mips_branch; + if (Form == MipsII::FrmI && MI.getOpcode() == Mips::LUi) + return Mips::reloc_mips_hi; + return Mips::reloc_mips_lo; +} + +/// getMachineOpValue - Return binary encoding of operand. If the machine +/// operand requires relocation, record the relocation and return zero. +unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI, + const MachineOperand &MO) const { + if (MO.isReg()) return MipsRegisterInfo::getRegisterNumbering(MO.getReg()); - case MachineOperand::MO_JumpTableIndex: - emitJumpTableAddress(MO.getIndex(), relocType); - return 0; - case MachineOperand::MO_ConstantPoolIndex: - emitConstPoolAddress(MO.getIndex(), relocType); - return 0; - default: return 0; + else if (MO.isImm()) + return static_cast<unsigned>(MO.getImm()); + else if (MO.isGlobal()) + emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true); + else if (MO.isSymbol()) + emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); + else if (MO.isCPI()) + emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO)); + else if (MO.isJTI()) + emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO)); + else if (MO.isMBB()) + emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); + else + llvm_unreachable("Unable to encode MachineOperand!"); + return 0; +} + +void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, + bool MayNeedFarStub) const { + MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, + const_cast<GlobalValue *>(GV), 0, MayNeedFarStub)); +} + +void MipsCodeEmitter:: +emitExternalSymbolAddress(const char *ES, unsigned Reloc) const { + MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), + Reloc, ES, 0, 0, false)); +} + +void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const { + MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), + Reloc, CPI, 0, false)); +} + +void MipsCodeEmitter:: +emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const { + MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), + Reloc, JTIndex, 0, false)); +} + +void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, + unsigned Reloc) const { + MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), + Reloc, BB)); +} + +void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) { + DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI); + + MCE.processDebugLoc(MI.getDebugLoc(), true); + + // Skip pseudo instructions. + if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo) + return; + + ++NumEmitted; // Keep track of the # of mi's emitted + + switch (MI.getOpcode()) { + default: + emitWordLE(getBinaryCodeForInstr(MI)); + break; } + + MCE.processDebugLoc(MI.getDebugLoc(), false); } +void MipsCodeEmitter::emitWordLE(unsigned Word) { + DEBUG(errs() << " 0x"; + errs().write_hex(Word) << "\n"); + MCE.emitWordLE(Word); +} + +/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips +/// code to the specified MCE object. +FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM, + JITCodeEmitter &JCE) { + return new MipsCodeEmitter(TM, JCE); +} + +unsigned MipsCodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const { + // this function will be automatically generated by the CodeEmitterGenerator + // using TableGen + return 0; +} diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index 4421c4862f..274f30761a 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -74,6 +74,33 @@ namespace MipsII { MO_TPREL_HI, MO_TPREL_LO }; + + enum { + //===------------------------------------------------------------------===// + // Instruction encodings. These are the standard/most common forms for + // Mips instructions. + // + + // Pseudo - This represents an instruction that is a pseudo instruction + // or one that has not been implemented yet. It is illegal to code generate + // it, but tolerated for intermediate implementation stages. + Pseudo = 0, + + /// FrmR - This form is for instructions of the format R. + FrmR = 1, + /// FrmI - This form is for instructions of the format I. + FrmI = 2, + /// FrmJ - This form is for instructions of the format J. + FrmJ = 3, + /// FrmFR - This form is for instructions of the format FR. + FrmFR = 4, + /// FrmFI - This form is for instructions of the format FI. + FrmFI = 5, + /// FrmOther - This form is for instructions that have no specific format. + FrmOther = 6, + + FormMask = 15 + }; } class MipsInstrInfo : public MipsGenInstrInfo { diff --git a/lib/Target/Mips/MipsJITInfo.cpp b/lib/Target/Mips/MipsJITInfo.cpp index 88f5f2d8d8..28c2b48b2e 100644 --- a/lib/Target/Mips/MipsJITInfo.cpp +++ b/lib/Target/Mips/MipsJITInfo.cpp @@ -42,7 +42,11 @@ static TargetJITInfo::JITCompilerFn JITCompilerFunction; #define GETASMPREFIX(X) GETASMPREFIX2(X) #define ASMPREFIX GETASMPREFIX(__USER_LABEL_PREFIX__) -// save registers, call MipsCompilationCallbackC, restore registers +// CompilationCallback stub - We can't use a C function with inline assembly in +// it, because 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. This code saves registers, calls +// MipsCompilationCallbackC and restores registers. extern "C" { #if defined (__mips__) void MipsCompilationCallback(); @@ -53,35 +57,46 @@ void MipsCompilationCallback(); ".globl " ASMPREFIX "MipsCompilationCallback\n" ASMPREFIX "MipsCompilationCallback:\n" ".ent " ASMPREFIX "MipsCompilationCallback\n" + ".frame $29, 32, $31\n" ".set noreorder\n" ".cpload $t9\n" - ".frame $29, 32, $31\n" - "addiu $sp, $sp, -40\n" - "sw $a0, 4($sp)\n" - "sw $a1, 8($sp)\n" - "sw $a2, 12($sp)\n" - "sw $a3, 20($sp)\n" - "sw $ra, 24($sp)\n" - "sw $v0, 28($sp)\n" - "sw $v1, 32($sp)\n" - "sw $t8, 36($sp)\n" + "addiu $sp, $sp, -60\n" ".cprestore 16\n" + // Save argument registers a0, a1, a2, a3, f12, f14 since they may contain + // stuff for the real target function right now. We have to act as if this + // whole compilation callback doesn't exist as far as the caller is + // concerned. We also need to save the ra register since it contains the + // original return address, and t8 register since it contains the address + // of the end of function stub. + "sw $a0, 20($sp)\n" + "sw $a1, 24($sp)\n" + "sw $a2, 28($sp)\n" + "sw $a3, 32($sp)\n" + "sw $ra, 36($sp)\n" + "sw $t8, 40($sp)\n" + "sdc1 $f12, 44($sp)\n" + "sdc1 $f14, 52($sp)\n" + + // t8 points at the end of function stub. Pass the beginning of the stub + // to the MipsCompilationCallbackC. "addiu $a0, $t8, -16\n" - "jal " ASMPREFIX "MipsCompilationCallbackC\n" + "jal " ASMPREFIX "MipsCompilationCallbackC\n" "nop\n" - "lw $a0, 4($sp)\n" - "lw $a1, 8($sp)\n" - "lw $a2, 12($sp)\n" - "lw $a3, 20($sp)\n" - "lw $ra, 24($sp)\n" - "lw $v0, 28($sp)\n" - "lw $v1, 32($sp)\n" - "lw $t8, 36($sp)\n" - "addiu $sp, $sp, 40\n" - + // Restore registers. + "lw $a0, 20($sp)\n" + "lw $a1, 24($sp)\n" + "lw $a2, 28($sp)\n" + "lw $a3, 32($sp)\n" + "lw $ra, 36($sp)\n" + "lw $t8, 40($sp)\n" + "ldc1 $f12, 44($sp)\n" + "ldc1 $f14, 52($sp)\n" + "addiu $sp, $sp, 60\n" + + // Jump to the (newly modified) stub to invoke the real function. "addiu $t8, $t8, -16\n" "jr $t8\n" "nop\n" @@ -102,14 +117,26 @@ void MipsCompilationCallback(); /// This function must locate the start of the stub or call site and pass /// it into the JIT compiler function. extern "C" void MipsCompilationCallbackC(intptr_t StubAddr) { - // Get the address of the compiled code for this function. intptr_t NewVal = (intptr_t) JITCompilerFunction((void*) StubAddr); - *(intptr_t *) (StubAddr) = 2 << 26 | ((NewVal & 0x0fffffff) >> 2); // J NewVal - *(intptr_t *) (StubAddr + 4) = 0; // NOP - *(intptr_t *) (StubAddr + 8) = 0; // NOP - *(intptr_t *) (StubAddr + 12) = 0; // NOP + // Rewrite the function stub so that we don't end up here every time we + // execute the call. We're replacing the first four instructions of the + // stub with code that jumps to the compiled function: + // lui $t9, %hi(NewVal) + // addiu $t9, $t9, %lo(NewVal) + // jr $t9 + // nop + + int Hi = ((unsigned)NewVal & 0xffff0000) >> 16; + if ((NewVal & 0x8000) != 0) + Hi++; + int Lo = (int)(NewVal & 0xffff); + + *(intptr_t *)(StubAddr) = 0xf << 26 | 25 << 16 | Hi; + *(intptr_t *)(StubAddr + 4) = 9 << 26 | 25 << 21 | 25 << 16 | Lo; + *(intptr_t *)(StubAddr + 8) = 25 << 21 | 8; + *(intptr_t *)(StubAddr + 12) = 0; sys::Memory::InvalidateInstructionCache((void*) StubAddr, 16); } @@ -121,7 +148,9 @@ TargetJITInfo::LazyResolverFn MipsJITInfo::getLazyResolverFunction( } TargetJITInfo::StubLayout MipsJITInfo::getStubLayout() { - StubLayout Result = { 24, 4 }; // {Size. Alignment} (of FunctionStub) + // The stub contains 4 4-byte instructions, aligned at 4 bytes. See + // emitFunctionStub for details. + StubLayout Result = { 4*4, 4 }; return Result; } @@ -129,22 +158,33 @@ void *MipsJITInfo::emitFunctionStub(const Function* F, void *Fn, JITCodeEmitter &JCE) { JCE.emitAlignment(4); void *Addr = (void*) (JCE.getCurrentPCValue()); - - unsigned arg0 = ((intptr_t) MipsCompilationCallback >> 16); - if ((((intptr_t) MipsCompilationCallback & 0xffff) >> 15) == 1) { - arg0 += 1; // same hack as in relocate() - } - - // LUI t9, %hi(MipsCompilationCallback) - JCE.emitWordLE(0xf << 26 | 25 << 16 | arg0); - // ADDiu t9, t9, %lo(MipsCompilationCallback) - JCE.emitWordLE(9 << 26 | 25 << 21 | 25 << 16 - | ((intptr_t) MipsCompilationCallback & 0xffff)); - // JALR t8, t9 + if (!sys::Memory::setRangeWritable(Addr, 16)) + llvm_unreachable("ERROR: Unable to mark stub writable."); + + intptr_t EmittedAddr; + if (Fn != (void*)(intptr_t)MipsCompilationCallback) + EmittedAddr = (intptr_t)Fn; + else + EmittedAddr = (intptr_t)MipsCompilationCallback; + + + int Hi = ((unsigned)EmittedAddr & 0xffff0000) >> 16; + if ((EmittedAddr & 0x8000) != 0) + Hi++; + int Lo = (int)(EmittedAddr & 0xffff); + + // lui t9, %hi(EmittedAddr) + // addiu t9, t9, %lo(EmittedAddr) + // jalr t8, t9 + // nop + JCE.emitWordLE(0xf << 26 | 25 << 16 | Hi); + JCE.emitWordLE(9 << 26 | 25 << 21 | 25 << 16 | Lo); JCE.emitWordLE(25 << 21 | 24 << 11 | 9); - JCE.emitWordLE(0); // NOP + JCE.emitWordLE(0); - sys::Memory::InvalidateInstructionCache((void*) Addr, 16); + sys::Memory::InvalidateInstructionCache(Addr, 16); + if (!sys::Memory::setRangeExecutable(Addr, 16)) + llvm_unreachable("ERROR: Unable to mark stub executable."); return Addr; } @@ -160,27 +200,22 @@ void MipsJITInfo::relocate(void *Function, MachineRelocation *MR, intptr_t ResultPtr = (intptr_t) MR->getResultPointer(); switch ((Mips::RelocationType) MR->getRelocationType()) { - case Mips::reloc_mips_pcrel: + case Mips::reloc_mips_branch: ResultPtr = (((ResultPtr - (intptr_t) RelocPos) - 4) >> 2) & 0xffff; *((unsigned*) RelocPos) |= (unsigned) ResultPtr; break; - case Mips::reloc_mips_j_jal: { + case Mips::reloc_mips_26: ResultPtr = (ResultPtr & 0x0fffffff) >> 2; *((unsigned*) RelocPos) |= (unsigned) ResultPtr; - } break; - case Mips::reloc_mips_hi: { + case Mips::reloc_mips_hi: ResultPtr = ResultPtr >> 16; - - // see See MIPS Run Linux, chapter 9.4 if ((((intptr_t) (MR->getResultPointer()) & 0xffff) >> 15) == 1) { ResultPtr += 1; } - *((unsigned*) RelocPos) |= (unsigned) ResultPtr; - } break; case Mips::reloc_mips_lo: @@ -189,7 +224,7 @@ void MipsJITInfo::relocate(void *Function, MachineRelocation *MR, break; default: - assert(0 && "MipsJITInfo.unknown relocation;"); + llvm_unreachable("ERROR: Unknown Mips relocation."); } } } diff --git a/lib/Target/Mips/MipsRelocations.h b/lib/Target/Mips/MipsRelocations.h index 0df21be3f1..66d1bfd993 100644 --- a/lib/Target/Mips/MipsRelocations.h +++ b/lib/Target/Mips/MipsRelocations.h @@ -20,13 +20,22 @@ namespace llvm { namespace Mips{ enum RelocationType { - reloc_mips_pcrel = 1, - reloc_mips_hi = 3, - reloc_mips_lo = 4, - reloc_mips_j_jal = 5 + // reloc_mips_branch - pc relative relocation for branches. The lower 18 + // bits of the difference between the branch target and the branch + // instruction, shifted right by 2. + reloc_mips_branch = 1, + + // reloc_mips_hi - upper 16 bits of the address (modified by +1 if the + // lower 16 bits of the address is negative). + reloc_mips_hi = 2, + + // reloc_mips_lo - lower 16 bits of the address. + reloc_mips_lo = 3, + + // reloc_mips_26 - lower 28 bits of the address, shifted right by 2. + reloc_mips_26 = 4 }; } } #endif /* MIPSRELOCATIONS_H_ */ - diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h index 36211fa446..bba9111a06 100644 --- a/lib/Target/Mips/MipsTargetMachine.h +++ b/lib/Target/Mips/MipsTargetMachine.h @@ -35,7 +35,6 @@ namespace llvm { MipsTargetLowering TLInfo; MipsSelectionDAGInfo TSInfo; MipsJITInfo JITInfo; - Reloc::Model DefRelocModel; // Reloc model before it's overridden. public: MipsTargetMachine(const Target &T, StringRef TT, |