diff options
| author | Petar Avramovic <Petar.Avramovic@rt-rk.com> | 2019-03-15 07:07:50 +0000 |
|---|---|---|
| committer | Petar Avramovic <Petar.Avramovic@rt-rk.com> | 2019-03-15 07:07:50 +0000 |
| commit | 3e0da146ac2ad98e7463ce4114b466283ca1345c (patch) | |
| tree | b42d7702b65ebf1f950eab6d8ad42e41bd4bd813 /llvm/lib/Target | |
| parent | 76a7ecb3aeb4ed43ee146dd532f322bbff2adb8f (diff) | |
| download | bcm5719-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.cpp | 55 |
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(); |

