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
diff --git a/lib/Target/ARM/Thumb2ITBlockPass.cpp b/lib/Target/ARM/Thumb2ITBlockPass.cpp
index e74a526..a06ee8e 100644
--- a/lib/Target/ARM/Thumb2ITBlockPass.cpp
+++ b/lib/Target/ARM/Thumb2ITBlockPass.cpp
@@ -40,12 +40,11 @@
   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 @@
   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 @@
     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)