bool MachineRegisterInfo::recomputeRegClass(unsigned Reg, const TargetMachine &TM) { const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterClass *OldRC = getRegClass(Reg); const TargetRegisterClass *NewRC = TRI->getLargestLegalSuperClass(OldRC); // Stop early if there is no room to grow. if (NewRC == OldRC) return false; // Accumulate constraints from all uses. for (reg_nodbg_iterator I = reg_nodbg_begin(Reg), E = reg_nodbg_end(); I != E; ++I) { const TargetRegisterClass *OpRC = I->getRegClassConstraint(I.getOperandNo(), TII, TRI); if (unsigned SubIdx = I.getOperand().getSubReg()) { if (OpRC) NewRC = TRI->getMatchingSuperRegClass(NewRC, OpRC, SubIdx); else NewRC = TRI->getSubClassWithSubReg(NewRC, SubIdx); } else if (OpRC) NewRC = TRI->getCommonSubClass(NewRC, OpRC); if (!NewRC || NewRC == OldRC) return false; } setRegClass(Reg, NewRC); return true; }
SITargetLowering::SITargetLowering(TargetMachine &TM) : AMDGPUTargetLowering(TM), TII(static_cast<const SIInstrInfo*>(TM.getInstrInfo())) { addRegisterClass(MVT::v4f32, &AMDIL::VReg_128RegClass); addRegisterClass(MVT::f32, &AMDIL::VReg_32RegClass); setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal); setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal); }
R600TargetLowering::R600TargetLowering(TargetMachine &TM) : AMDGPUTargetLowering(TM), TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo())) { setOperationAction(ISD::MUL, MVT::i64, Expand); // setSchedulingPreference(Sched::VLIW); addRegisterClass(MVT::v4f32, &AMDIL::R600_Reg128RegClass); addRegisterClass(MVT::f32, &AMDIL::R600_Reg32RegClass); setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal); setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal); }
SITargetLowering::SITargetLowering(TargetMachine &TM) : AMDGPUTargetLowering(TM), TII(static_cast<const SIInstrInfo*>(TM.getInstrInfo())) { addRegisterClass(MVT::v4f32, &AMDIL::VReg_128RegClass); addRegisterClass(MVT::f32, &AMDIL::VReg_32RegClass); addRegisterClass(MVT::i32, &AMDIL::VReg_32RegClass); addRegisterClass(MVT::i64, &AMDIL::VReg_64RegClass); addRegisterClass(MVT::v4i32, &AMDIL::SReg_128RegClass); addRegisterClass(MVT::v8i32, &AMDIL::SReg_256RegClass); computeRegisterProperties(); setOperationAction(ISD::ADD, MVT::i64, Legal); setOperationAction(ISD::ADD, MVT::i32, Legal); }
bool MachineRegisterInfo::recomputeRegClass(unsigned Reg, const TargetMachine &TM) { const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterClass *OldRC = getRegClass(Reg); const TargetRegisterClass *NewRC = getTargetRegisterInfo()->getLargestLegalSuperClass(OldRC); // Stop early if there is no room to grow. if (NewRC == OldRC) return false; // Accumulate constraints from all uses. for (reg_nodbg_iterator I = reg_nodbg_begin(Reg), E = reg_nodbg_end(); I != E; ++I) { // Apply the effect of the given operand to NewRC. NewRC = I->getRegClassConstraintEffect(I.getOperandNo(), NewRC, TII, getTargetRegisterInfo()); if (!NewRC || NewRC == OldRC) return false; } setRegClass(Reg, NewRC); return true; }
bool MachineRegisterInfo::recomputeRegClass(unsigned Reg, const TargetMachine &TM) { const TargetInstrInfo *TII = TM.getInstrInfo(); const TargetRegisterClass *OldRC = getRegClass(Reg); const TargetRegisterClass *NewRC = getTargetRegisterInfo()->getLargestLegalSuperClass(OldRC); // Stop early if there is no room to grow. if (NewRC == OldRC) return false; // Accumulate constraints from all uses. for (MachineOperand &MO : reg_nodbg_operands(Reg)) { // Apply the effect of the given operand to NewRC. MachineInstr *MI = MO.getParent(); unsigned OpNo = &MO - &MI->getOperand(0); NewRC = MI->getRegClassConstraintEffect(OpNo, NewRC, TII, getTargetRegisterInfo()); if (!NewRC || NewRC == OldRC) return false; } setRegClass(Reg, NewRC); return true; }
R600TargetLowering::R600TargetLowering(TargetMachine &TM) : AMDGPUTargetLowering(TM), TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo())) { setOperationAction(ISD::MUL, MVT::i64, Expand); addRegisterClass(MVT::v4f32, &AMDGPU::R600_Reg128RegClass); addRegisterClass(MVT::f32, &AMDGPU::R600_Reg32RegClass); addRegisterClass(MVT::v4i32, &AMDGPU::R600_Reg128RegClass); addRegisterClass(MVT::i32, &AMDGPU::R600_Reg32RegClass); computeRegisterProperties(); setOperationAction(ISD::BR_CC, MVT::i32, Custom); setOperationAction(ISD::FSUB, MVT::f32, Expand); setOperationAction(ISD::ROTL, MVT::i32, Custom); setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); setOperationAction(ISD::SETCC, MVT::i32, Custom); setSchedulingPreference(Sched::VLIW); }
/* * Disassemble a function, using the LLVM MC disassembler. * * See also: * - http://blog.llvm.org/2010/01/x86-disassembler.html * - http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html */ extern "C" void lp_disassemble(const void* func) { #if HAVE_LLVM >= 0x0207 using namespace llvm; const uint8_t *bytes = (const uint8_t *)func; /* * Limit disassembly to this extent */ const uint64_t extent = 0x10000; uint64_t max_pc = 0; /* * Initialize all used objects. */ #if HAVE_LLVM >= 0x0301 std::string Triple = sys::getDefaultTargetTriple(); #else std::string Triple = sys::getHostTriple(); #endif std::string Error; const Target *T = TargetRegistry::lookupTarget(Triple, Error); #if HAVE_LLVM >= 0x0208 InitializeNativeTargetAsmPrinter(); #elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) LLVMInitializeX86AsmPrinter(); #elif defined(PIPE_ARCH_ARM) LLVMInitializeARMAsmPrinter(); #elif defined(PIPE_ARCH_PPC) LLVMInitializePowerPCAsmPrinter(); #endif #if HAVE_LLVM >= 0x0301 InitializeNativeTargetDisassembler(); #elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) LLVMInitializeX86Disassembler(); #elif defined(PIPE_ARCH_ARM) LLVMInitializeARMDisassembler(); #endif #if HAVE_LLVM >= 0x0300 OwningPtr<const MCAsmInfo> AsmInfo(T->createMCAsmInfo(Triple)); #else OwningPtr<const MCAsmInfo> AsmInfo(T->createAsmInfo(Triple)); #endif if (!AsmInfo) { debug_printf("error: no assembly info for target %s\n", Triple.c_str()); return; } #if HAVE_LLVM >= 0x0300 const MCSubtargetInfo *STI = T->createMCSubtargetInfo(Triple, sys::getHostCPUName(), ""); OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler(*STI)); #else OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler()); #endif if (!DisAsm) { debug_printf("error: no disassembler for target %s\n", Triple.c_str()); return; } raw_debug_ostream Out; #if HAVE_LLVM >= 0x0300 unsigned int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); #else int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); #endif #if HAVE_LLVM >= 0x0301 OwningPtr<const MCRegisterInfo> MRI(T->createMCRegInfo(Triple)); if (!MRI) { debug_printf("error: no register info for target %s\n", Triple.c_str()); return; } OwningPtr<const MCInstrInfo> MII(T->createMCInstrInfo()); if (!MII) { debug_printf("error: no instruction info for target %s\n", Triple.c_str()); return; } #endif #if HAVE_LLVM >= 0x0301 OwningPtr<MCInstPrinter> Printer( T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI)); #elif HAVE_LLVM == 0x0300 OwningPtr<MCInstPrinter> Printer( T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *STI)); #elif HAVE_LLVM >= 0x0208 OwningPtr<MCInstPrinter> Printer( T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo)); #else OwningPtr<MCInstPrinter> Printer( T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, Out)); #endif if (!Printer) { debug_printf("error: no instruction printer for target %s\n", Triple.c_str()); return; } #if HAVE_LLVM >= 0x0301 TargetOptions options; #if defined(DEBUG) options.JITEmitDebugInfo = true; #endif #if defined(PIPE_ARCH_X86) options.StackAlignmentOverride = 4; #endif #if defined(DEBUG) || defined(PROFILE) options.NoFramePointerElim = true; #endif TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), "", options); #elif HAVE_LLVM == 0x0300 TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), ""); #else TargetMachine *TM = T->createTargetMachine(Triple, ""); #endif const TargetInstrInfo *TII = TM->getInstrInfo(); /* * Wrap the data in a MemoryObject */ BufferMemoryObject memoryObject((const uint8_t *)bytes, extent); uint64_t pc; pc = 0; while (true) { MCInst Inst; uint64_t Size; /* * Print address. We use addresses relative to the start of the function, * so that between runs. */ debug_printf("%6lu:\t", (unsigned long)pc); if (!DisAsm->getInstruction(Inst, Size, memoryObject, pc, #if HAVE_LLVM >= 0x0300 nulls(), nulls())) { #else nulls())) { #endif debug_printf("invalid\n"); pc += 1; } /* * Output the bytes in hexidecimal format. */ if (0) { unsigned i; for (i = 0; i < Size; ++i) { debug_printf("%02x ", ((const uint8_t*)bytes)[pc + i]); } for (; i < 16; ++i) { debug_printf(" "); } } /* * Print the instruction. */ #if HAVE_LLVM >= 0x0300 Printer->printInst(&Inst, Out, ""); #elif HAVE_LLVM >= 0x208 Printer->printInst(&Inst, Out); #else Printer->printInst(&Inst); #endif Out.flush(); /* * Advance. */ pc += Size; #if HAVE_LLVM >= 0x0300 const MCInstrDesc &TID = TII->get(Inst.getOpcode()); #else const TargetInstrDesc &TID = TII->get(Inst.getOpcode()); #endif /* * Keep track of forward jumps to a nearby address. */ if (TID.isBranch()) { for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { const MCOperand &operand = Inst.getOperand(i); if (operand.isImm()) { uint64_t jump; /* * FIXME: Handle both relative and absolute addresses correctly. * EDInstInfo actually has this info, but operandTypes and * operandFlags enums are not exposed in the public interface. */ if (1) { /* * PC relative addr. */ jump = pc + operand.getImm(); } else { /* * Absolute addr. */ jump = (uint64_t)operand.getImm(); } /* * Output the address relative to the function start, given * that MC will print the addresses relative the current pc. */ debug_printf("\t\t; %lu", (unsigned long)jump); /* * Ignore far jumps given it could be actually a tail return to * a random address. */ if (jump > max_pc && jump < extent) { max_pc = jump; } } } } debug_printf("\n"); /* * Stop disassembling on return statements, if there is no record of a * jump to a successive address. */ if (TID.isReturn()) { if (pc > max_pc) { break; } } } /* * Print GDB command, useful to verify output. */ if (0) { debug_printf("disassemble %p %p\n", bytes, bytes + pc); } debug_printf("\n"); #else /* HAVE_LLVM < 0x0207 */ (void)func; #endif /* HAVE_LLVM < 0x0207 */ }