aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/MipsLegalizerInfo.cpp3
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp96
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.h11
3 files changed, 100 insertions, 10 deletions
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index f86e829..9be5071 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -43,6 +43,9 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
{p0, p0, 32, 8}})
.minScalar(0, s32);
+ getActionDefinitionsBuilder(G_UNMERGE_VALUES)
+ .legalFor({{s32, s64}});
+
getActionDefinitionsBuilder(G_MERGE_VALUES)
.legalFor({{s64, s32}});
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index cd8937d..eebd7fe 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -112,6 +112,22 @@ static bool isFloatingPointOpcode(unsigned Opc) {
}
}
+// Instructions where use operands are floating point registers.
+// Def operands are general purpose.
+static bool isFloatingPointOpcodeUse(unsigned Opc) {
+ switch (Opc) {
+ case TargetOpcode::G_FPTOSI:
+ case TargetOpcode::G_FPTOUI:
+ case TargetOpcode::G_FCMP:
+ case Mips::MFC1:
+ case Mips::ExtractElementF64:
+ case Mips::ExtractElementF64_64:
+ return true;
+ default:
+ return isFloatingPointOpcode(Opc);
+ }
+}
+
// Instructions where def operands are floating point registers.
// Use operands are general purpose.
static bool isFloatingPointOpcodeDef(unsigned Opc) {
@@ -139,6 +155,20 @@ static bool isAmbiguous(unsigned Opc) {
}
}
+void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
+ Register Reg, const MachineRegisterInfo &MRI) {
+ assert(!MRI.getType(Reg).isPointer() &&
+ "Pointers are gprb, they should not be considered as ambiguous.\n");
+ for (MachineInstr &UseMI : MRI.use_instructions(Reg)) {
+ if (UseMI.getOpcode() == TargetOpcode::COPY &&
+ !TargetRegisterInfo::isPhysicalRegister(UseMI.getOperand(0).getReg()))
+ // Copies of non-physical registers are not supported
+ return;
+
+ DefUses.push_back(&UseMI);
+ }
+}
+
void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
Register Reg, const MachineRegisterInfo &MRI) {
assert(!MRI.getType(Reg).isPointer() &&
@@ -159,6 +189,9 @@ MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
+ if (MI->getOpcode() == TargetOpcode::G_LOAD)
+ addDefUses(MI->getOperand(0).getReg(), MRI);
+
if (MI->getOpcode() == TargetOpcode::G_STORE)
addUseDef(MI->getOperand(0).getReg(), MRI);
}
@@ -169,27 +202,33 @@ bool MipsRegisterBankInfo::TypeInfoForMF::visit(const MachineInstr *MI) {
startVisit(MI);
AmbiguousRegDefUseContainer DefUseContainer(MI);
+ // Visit instructions where MI's DEF operands are USED.
+ if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true))
+ return true;
+
// Visit instructions that DEFINE MI's USE operands.
- if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs()))
+ if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false))
return true;
return false;
}
bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
- const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs) {
+ const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
+ bool isDefUse) {
while (!AdjacentInstrs.empty()) {
MachineInstr *AdjMI = AdjacentInstrs.pop_back_val();
- if (isFloatingPointOpcodeDef(AdjMI->getOpcode())) {
+ if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode())
+ : isFloatingPointOpcodeDef(AdjMI->getOpcode())) {
setTypes(MI, InstType::FloatingPoint);
return true;
}
// Determine InstType from register bank of phys register that is
- // use of this copy.
+ // 'isDefUse ? def : use' of this copy.
if (AdjMI->getOpcode() == TargetOpcode::COPY) {
- setTypesAccordingToPhysicalRegister(MI, AdjMI, 1);
+ setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1);
return true;
}
@@ -276,7 +315,6 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_SUB:
case G_MUL:
case G_UMULH:
- case G_LOAD:
case G_ZEXTLOAD:
case G_SEXTLOAD:
case G_GEP:
@@ -292,6 +330,30 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_UREM:
OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
break;
+ case G_LOAD: {
+ unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
+ InstType InstTy = InstType::Integer;
+ if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
+ InstTy = TI.determineInstType(&MI);
+ }
+
+ if (InstTy == InstType::FloatingPoint) { // fprb
+ OperandsMapping =
+ getOperandsMapping({Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
+ : &Mips::ValueMappings[Mips::DPRIdx],
+ &Mips::ValueMappings[Mips::GPRIdx]});
+ break;
+ } else { // gprb
+ OperandsMapping =
+ getOperandsMapping({Size <= 32 ? &Mips::ValueMappings[Mips::GPRIdx]
+ : &Mips::ValueMappings[Mips::DPRIdx],
+ &Mips::ValueMappings[Mips::GPRIdx]});
+ if (Size == 64)
+ MappingID = CustomMappingID;
+ }
+
+ break;
+ }
case G_STORE: {
unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
InstType InstTy = InstType::Integer;
@@ -315,6 +377,13 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
}
break;
}
+ case G_UNMERGE_VALUES: {
+ OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
+ &Mips::ValueMappings[Mips::GPRIdx],
+ &Mips::ValueMappings[Mips::DPRIdx]});
+ MappingID = CustomMappingID;
+ break;
+ }
case G_MERGE_VALUES: {
OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx],
&Mips::ValueMappings[Mips::GPRIdx],
@@ -449,6 +518,7 @@ void MipsRegisterBankInfo::applyMappingImpl(
B, MF->getRegInfo(), *MF->getSubtarget().getLegalizerInfo());
switch (MI.getOpcode()) {
+ case TargetOpcode::G_LOAD:
case TargetOpcode::G_STORE: {
Helper.narrowScalar(MI, 0, LLT::scalar(32));
// Handle new instructions.
@@ -462,7 +532,12 @@ void MipsRegisterBankInfo::applyMappingImpl(
ArtCombiner.tryCombineMerges(*NewMI, DeadInstrs);
for (MachineInstr *DeadMI : DeadInstrs)
DeadMI->eraseFromParent();
- } else
+ }
+ // This G_MERGE will be combined away when its corresponding G_UNMERGE
+ // gets regBankSelected.
+ else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
+ continue;
+ else
// Manually set register banks for all register operands to 32 bit gprb.
for (auto Op : NewMI->operands()) {
if (Op.isReg()) {
@@ -474,6 +549,13 @@ void MipsRegisterBankInfo::applyMappingImpl(
}
return;
}
+ case TargetOpcode::G_UNMERGE_VALUES: {
+ SmallVector<MachineInstr *, 2> DeadInstrs;
+ ArtCombiner.tryCombineMerges(MI, DeadInstrs);
+ for (MachineInstr *DeadMI : DeadInstrs)
+ DeadMI->eraseFromParent();
+ return;
+ }
default:
break;
}
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
index e5a5bdd..456797e 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
@@ -57,15 +57,19 @@ private:
/// Some generic instructions have operands that can be mapped to either fprb
/// or gprb e.g. for G_LOAD we consider only operand 0 as ambiguous, operand 1
/// is always gprb since it is a pointer.
- /// This class provides container for MI's ambiguous:
+ /// This class provides containers for MI's ambiguous:
+ /// DefUses : MachineInstrs that use one of MI's ambiguous def operands.
/// UseDefs : MachineInstrs that define MI's ambiguous use operands.
class AmbiguousRegDefUseContainer {
+ SmallVector<MachineInstr *, 2> DefUses;
SmallVector<MachineInstr *, 2> UseDefs;
+ void addDefUses(Register Reg, const MachineRegisterInfo &MRI);
void addUseDef(Register Reg, const MachineRegisterInfo &MRI);
public:
AmbiguousRegDefUseContainer(const MachineInstr *MI);
+ SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; }
SmallVectorImpl<MachineInstr *> &getUseDefs() { return UseDefs; }
};
@@ -77,9 +81,10 @@ private:
bool visit(const MachineInstr *MI);
- /// Visit MI's adjacent UseDefs.
+ /// Visit MI's adjacent UseDefs or DefUses.
bool visitAdjacentInstrs(const MachineInstr *MI,
- SmallVectorImpl<MachineInstr *> &AdjacentInstrs);
+ SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
+ bool isDefUse);
void setTypes(const MachineInstr *MI, InstType ITy);