diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-09-28 09:14:39 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-09-28 09:14:39 +0000 |
commit | 5adb66a646e2ec32265263739f5b01c3f50c176a (patch) | |
tree | 38b5fb6a9d2665466cd3b88031122d9c95de6110 /lib/Target/ARM/Thumb2ITBlockPass.cpp | |
parent | 705428ae4a7fa6d97a95f7811fa2e36630a43c9c (diff) | |
download | llvm-5adb66a646e2ec32265263739f5b01c3f50c176a.tar.gz llvm-5adb66a646e2ec32265263739f5b01c3f50c176a.tar.bz2 llvm-5adb66a646e2ec32265263739f5b01c3f50c176a.tar.xz |
Make ARM and Thumb2 32-bit immediate materialization into a single 32-bit pseudo
instruction. This makes it re-materializable.
Thumb2 will split it back out into two instructions so IT pass will generate the
right mask. Also, this expose opportunies to optimize the movw to a 16-bit move.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82982 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/Thumb2ITBlockPass.cpp')
-rw-r--r-- | lib/Target/ARM/Thumb2ITBlockPass.cpp | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/lib/Target/ARM/Thumb2ITBlockPass.cpp b/lib/Target/ARM/Thumb2ITBlockPass.cpp index e74a526afa..a06ee8eca8 100644 --- a/lib/Target/ARM/Thumb2ITBlockPass.cpp +++ b/lib/Target/ARM/Thumb2ITBlockPass.cpp @@ -40,12 +40,11 @@ namespace { char Thumb2ITBlockPass::ID = 0; } -static ARMCC::CondCodes getPredicate(const MachineInstr *MI, - const Thumb2InstrInfo *TII) { +static ARMCC::CondCodes getPredicate(const MachineInstr *MI, unsigned &PredReg){ unsigned Opc = MI->getOpcode(); if (Opc == ARM::tBcc || Opc == ARM::t2Bcc) return ARMCC::AL; - return TII->getPredicate(MI); + return llvm::getInstrPredicate(MI, PredReg); } bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) { @@ -54,14 +53,39 @@ bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) { MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); while (MBBI != E) { MachineInstr *MI = &*MBBI; - ARMCC::CondCodes CC = getPredicate(MI, TII); + DebugLoc dl = MI->getDebugLoc(); + unsigned PredReg = 0; + ARMCC::CondCodes CC = getPredicate(MI, PredReg); + + // Splitting t2MOVi32imm into a pair of t2MOVi16 + t2MOVTi16 here. + // The only reason it was a single instruction was so it could be + // re-materialized. We want to split it before this and the thumb2 + // size reduction pass to make sure the IT mask is correct and expose + // width reduction opportunities. It doesn't make sense to do this in a + // separate pass so here it is. + if (MI->getOpcode() == ARM::t2MOVi32imm) { + unsigned DstReg = MI->getOperand(0).getReg(); + bool DstDead = MI->getOperand(0).isDead(); // Is this possible? + unsigned Imm = MI->getOperand(1).getImm(); + unsigned Lo16 = Imm & 0xffff; + unsigned Hi16 = (Imm >> 16) & 0xffff; + BuildMI(MBB, MBBI, dl, TII->get(ARM::t2MOVi16), DstReg) + .addImm(Lo16).addImm(CC).addReg(PredReg); + BuildMI(MBB, MBBI, dl, TII->get(ARM::t2MOVTi16)) + .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstDead)) + .addReg(DstReg).addImm(Hi16).addImm(CC).addReg(PredReg); + --MBBI; + --MBBI; + MI->eraseFromParent(); + continue; + } + if (CC == ARMCC::AL) { ++MBBI; continue; } // Insert an IT instruction. - DebugLoc dl = MI->getDebugLoc(); MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT)) .addImm(CC); ++MBBI; @@ -70,7 +94,8 @@ bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) { ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); unsigned Mask = 0, Pos = 3; while (MBBI != E && Pos) { - ARMCC::CondCodes NCC = getPredicate(&*MBBI, TII); + unsigned Dummy = 0; + ARMCC::CondCodes NCC = getPredicate(&*MBBI, Dummy); if (NCC == OCC) { Mask |= (1 << Pos); } else if (NCC != CC) |