void AArch64RegisterBankInfo::applyMappingImpl( const OperandsMapper &OpdMapper) const { switch (OpdMapper.getMI().getOpcode()) { case TargetOpcode::G_OR: { // Those ID must match getInstrAlternativeMappings. assert((OpdMapper.getInstrMapping().getID() == 1 || OpdMapper.getInstrMapping().getID() == 2) && "Don't know how to handle that ID"); return applyDefaultMapping(OpdMapper); } default: llvm_unreachable("Don't know how to handle that operation"); } }
void RegisterBankInfo::applyDefaultMapping(const OperandsMapper &OpdMapper) { MachineInstr &MI = OpdMapper.getMI(); MachineRegisterInfo &MRI = OpdMapper.getMRI(); LLVM_DEBUG(dbgs() << "Applying default-like mapping\n"); for (unsigned OpIdx = 0, EndIdx = OpdMapper.getInstrMapping().getNumOperands(); OpIdx != EndIdx; ++OpIdx) { LLVM_DEBUG(dbgs() << "OpIdx " << OpIdx); MachineOperand &MO = MI.getOperand(OpIdx); if (!MO.isReg()) { LLVM_DEBUG(dbgs() << " is not a register, nothing to be done\n"); continue; } if (!MO.getReg()) { LLVM_DEBUG(dbgs() << " is %%noreg, nothing to be done\n"); continue; } assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns != 0 && "Invalid mapping"); assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns == 1 && "This mapping is too complex for this function"); iterator_range<SmallVectorImpl<unsigned>::const_iterator> NewRegs = OpdMapper.getVRegs(OpIdx); if (empty(NewRegs)) { LLVM_DEBUG(dbgs() << " has not been repaired, nothing to be done\n"); continue; } unsigned OrigReg = MO.getReg(); unsigned NewReg = *NewRegs.begin(); LLVM_DEBUG(dbgs() << " changed, replace " << printReg(OrigReg, nullptr)); MO.setReg(NewReg); LLVM_DEBUG(dbgs() << " with " << printReg(NewReg, nullptr)); // The OperandsMapper creates plain scalar, we may have to fix that. // Check if the types match and if not, fix that. LLT OrigTy = MRI.getType(OrigReg); LLT NewTy = MRI.getType(NewReg); if (OrigTy != NewTy) { // The default mapping is not supposed to change the size of // the storage. However, right now we don't necessarily bump all // the types to storage size. For instance, we can consider // s16 G_AND legal whereas the storage size is going to be 32. assert(OrigTy.getSizeInBits() <= NewTy.getSizeInBits() && "Types with difference size cannot be handled by the default " "mapping"); LLVM_DEBUG(dbgs() << "\nChange type of new opd from " << NewTy << " to " << OrigTy); MRI.setType(NewReg, OrigTy); } LLVM_DEBUG(dbgs() << '\n'); } }