summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-03-15 07:07:50 +0000
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-03-15 07:07:50 +0000
commit3e0da146ac2ad98e7463ce4114b466283ca1345c (patch)
treeb42d7702b65ebf1f950eab6d8ad42e41bd4bd813 /llvm/lib/Target
parent76a7ecb3aeb4ed43ee146dd532f322bbff2adb8f (diff)
downloadbcm5719-llvm-3e0da146ac2ad98e7463ce4114b466283ca1345c.tar.gz
bcm5719-llvm-3e0da146ac2ad98e7463ce4114b466283ca1345c.zip
[MIPS GlobalISel] Improve selection of constants
Certain 32 bit constants can be generated with a single instruction instead of two. Implement materialize32BitImm function for MIPS32. Differential Revision: https://reviews.llvm.org/D59369 llvm-svn: 356238
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/Mips/MipsInstructionSelector.cpp55
1 files changed, 39 insertions, 16 deletions
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 84b520261e7..36aea298359 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -36,6 +36,8 @@ public:
private:
bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
+ bool materialize32BitImm(unsigned DestReg, APInt Imm,
+ MachineIRBuilder &B) const;
const MipsTargetMachine &TM;
const MipsSubtarget &STI;
@@ -90,6 +92,40 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
return true;
}
+bool MipsInstructionSelector::materialize32BitImm(unsigned DestReg, APInt Imm,
+ MachineIRBuilder &B) const {
+ assert(Imm.getBitWidth() == 32 && "Unsupported immediate size.");
+ // Ori zero extends immediate. Used for values with zeros in high 16 bits.
+ if (Imm.getHiBits(16).isNullValue()) {
+ MachineInstr *Inst = B.buildInstr(Mips::ORi, {DestReg}, {Mips::ZERO})
+ .addImm(Imm.getLoBits(16).getLimitedValue());
+ return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
+ }
+ // Lui places immediate in high 16 bits and sets low 16 bits to zero.
+ if (Imm.getLoBits(16).isNullValue()) {
+ MachineInstr *Inst = B.buildInstr(Mips::LUi, {DestReg}, {})
+ .addImm(Imm.getHiBits(16).getLimitedValue());
+ return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
+ }
+ // ADDiu sign extends immediate. Used for values with 1s in high 17 bits.
+ if (Imm.isSignedIntN(16)) {
+ MachineInstr *Inst = B.buildInstr(Mips::ADDiu, {DestReg}, {Mips::ZERO})
+ .addImm(Imm.getLoBits(16).getLimitedValue());
+ return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
+ }
+ // Values that cannot be materialized with single immediate instruction.
+ unsigned LUiReg = B.getMRI()->createVirtualRegister(&Mips::GPR32RegClass);
+ MachineInstr *LUi = B.buildInstr(Mips::LUi, {LUiReg}, {})
+ .addImm(Imm.getHiBits(16).getLimitedValue());
+ MachineInstr *ORi = B.buildInstr(Mips::ORi, {DestReg}, {LUiReg})
+ .addImm(Imm.getLoBits(16).getLimitedValue());
+ if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
+ return false;
+ if (!constrainSelectedInstRegOperands(*ORi, TII, TRI, RBI))
+ return false;
+ return true;
+}
+
/// Returning Opc indicates that we failed to select MIPS instruction opcode.
static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned MemSizeInBytes) {
if (Opc == TargetOpcode::G_STORE)
@@ -266,22 +302,9 @@ bool MipsInstructionSelector::select(MachineInstr &I,
break;
}
case G_CONSTANT: {
- int Imm = I.getOperand(1).getCImm()->getValue().getLimitedValue();
- unsigned LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
- MachineInstr *LUi, *ORi;
-
- LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
- .addDef(LUiReg)
- .addImm(Imm >> 16);
-
- ORi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ORi))
- .addDef(I.getOperand(0).getReg())
- .addUse(LUiReg)
- .addImm(Imm & 0xFFFF);
-
- if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
- return false;
- if (!constrainSelectedInstRegOperands(*ORi, TII, TRI, RBI))
+ MachineIRBuilder B(I);
+ if (!materialize32BitImm(I.getOperand(0).getReg(),
+ I.getOperand(1).getCImm()->getValue(), B))
return false;
I.eraseFromParent();
OpenPOWER on IntegriCloud