[llvm-commits] [llvm] r68096 - in /llvm/branches/Apple/Dib: lib/CodeGen/TwoAddressInstructionPass.cpp test/CodeGen/X86/inline-asm-2addr.ll

Bill Wendling isanbard at gmail.com
Tue Mar 31 01:33:19 PDT 2009


Author: void
Date: Tue Mar 31 03:33:19 2009
New Revision: 68096

URL: http://llvm.org/viewvc/llvm-project?rev=68096&view=rev
Log:
--- Merging (from foreign repository) r68065 into '.':
U    test/CodeGen/X86/inline-asm-2addr.ll
U    lib/CodeGen/TwoAddressInstructionPass.cpp

Turn a 2-address instruction into a 3-address one when it's profitable even if
the two-address operand is killed. e.g.

%reg1024<def> = MOV r1
%reg1025<def> = ADD %reg1024, %reg1026
r0            = MOV %reg1025

If it's not possible / profitable to commute ADD, then turning ADD into a LEA
saves a copy.

Modified:
    llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp
    llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll

Modified: llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=68096&r1=68095&r2=68096&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp Tue Mar 31 03:33:19 2009
@@ -96,6 +96,13 @@
                             MachineFunction::iterator &mbbi,
                             unsigned RegB, unsigned RegC, unsigned Dist);
 
+    bool isProfitableToConv3Addr(unsigned RegA);
+
+    bool ConvertInstTo3Addr(MachineBasicBlock::iterator &mi,
+                            MachineBasicBlock::iterator &nmi,
+                            MachineFunction::iterator &mbbi,
+                            unsigned RegB, unsigned Dist);
+
     void ProcessCopy(MachineInstr *MI, MachineBasicBlock *MBB,
                      SmallPtrSet<MachineInstr*, 8> &Processed);
   public:
@@ -334,7 +341,9 @@
 /// as a two-address use. If so, return the destination register by reference.
 static bool isTwoAddrUse(MachineInstr &MI, unsigned Reg, unsigned &DstReg) {
   const TargetInstrDesc &TID = MI.getDesc();
-  for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) {
+  unsigned NumOps = (MI.getOpcode() == TargetInstrInfo::INLINEASM)
+    ? MI.getNumOperands() : TID.getNumOperands();
+  for (unsigned i = 0; i != NumOps; ++i) {
     const MachineOperand &MO = MI.getOperand(i);
     if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg)
       continue;
@@ -503,6 +512,53 @@
   return true;
 }
 
+/// isProfitableToConv3Addr - Return true if it is profitable to convert the
+/// given 2-address instruction to a 3-address one.
+bool
+TwoAddressInstructionPass::isProfitableToConv3Addr(unsigned RegA) {
+  // Look for situations like this:
+  // %reg1024<def> = MOV r1
+  // %reg1025<def> = MOV r0
+  // %reg1026<def> = ADD %reg1024, %reg1025
+  // r2            = MOV %reg1026
+  // Turn ADD into a 3-address instruction to avoid a copy.
+  unsigned FromRegA = getMappedReg(RegA, SrcRegMap);
+  unsigned ToRegA = getMappedReg(RegA, DstRegMap);
+  return (FromRegA && ToRegA && !regsAreCompatible(FromRegA, ToRegA, TRI));
+}
+
+/// ConvertInstTo3Addr - Convert the specified two-address instruction into a
+/// three address one. Return true if this transformation was successful.
+bool
+TwoAddressInstructionPass::ConvertInstTo3Addr(MachineBasicBlock::iterator &mi,
+                                              MachineBasicBlock::iterator &nmi,
+                                              MachineFunction::iterator &mbbi,
+                                              unsigned RegB, unsigned Dist) {
+  MachineInstr *NewMI = TII->convertToThreeAddress(mbbi, mi, LV);
+  if (NewMI) {
+    DOUT << "2addr: CONVERTING 2-ADDR: " << *mi;
+    DOUT << "2addr:         TO 3-ADDR: " << *NewMI;
+    bool Sunk = false;
+
+    if (NewMI->findRegisterUseOperand(RegB, false, TRI))
+      // FIXME: Temporary workaround. If the new instruction doesn't
+      // uses RegB, convertToThreeAddress must have created more
+      // then one instruction.
+      Sunk = Sink3AddrInstruction(mbbi, NewMI, RegB, mi);
+
+    mbbi->erase(mi); // Nuke the old inst.
+
+    if (!Sunk) {
+      DistanceMap.insert(std::make_pair(NewMI, Dist));
+      mi = NewMI;
+      nmi = next(mi);
+    }
+    return true;
+  }
+
+  return false;
+}
+
 /// ProcessCopy - If the specified instruction is not yet processed, process it
 /// if it's a copy. For a copy instruction, we find the physical registers the
 /// source and destination registers might be mapped to. These are kept in
@@ -716,26 +772,7 @@
                 assert(TID.getOperandConstraint(i, TOI::TIED_TO) == -1);
 #endif
 
-              MachineInstr *NewMI = TII->convertToThreeAddress(mbbi, mi, LV);
-              if (NewMI) {
-                DOUT << "2addr: CONVERTING 2-ADDR: " << *mi;
-                DOUT << "2addr:         TO 3-ADDR: " << *NewMI;
-                bool Sunk = false;
-
-                if (NewMI->findRegisterUseOperand(regB, false, TRI))
-                  // FIXME: Temporary workaround. If the new instruction doesn't
-                  // uses regB, convertToThreeAddress must have created more
-                  // then one instruction.
-                  Sunk = Sink3AddrInstruction(mbbi, NewMI, regB, mi);
-
-                mbbi->erase(mi); // Nuke the old inst.
-
-                if (!Sunk) {
-                  DistanceMap.insert(std::make_pair(NewMI, Dist));
-                  mi = NewMI;
-                  nmi = next(mi);
-                }
-
+              if (ConvertInstTo3Addr(mi, nmi, mbbi, regB, Dist)) {
                 ++NumConvertedTo3Addr;
                 break; // Done with this instruction.
               }
@@ -750,9 +787,19 @@
                 ++NumAggrCommuted;
                 ++NumCommuted;
                 regB = regC;
+                goto InstructionRearranged;
               }
           }
 
+          // If it's profitable to convert the 2-address instruction to a
+          // 3-address one, do so.
+          if (TID.isConvertibleTo3Addr() && isProfitableToConv3Addr(regA)) {
+            if (ConvertInstTo3Addr(mi, nmi, mbbi, regB, Dist)) {
+              ++NumConvertedTo3Addr;
+              break; // Done with this instruction.
+            }
+          }
+
         InstructionRearranged:
           const TargetRegisterClass* rc = MRI->getRegClass(regB);
           MachineInstr *DefMI = MRI->getVRegDef(regB);

Modified: llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll?rev=68096&r1=68095&r2=68096&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll (original)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll Tue Mar 31 03:33:19 2009
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=x86-64 | grep movq | count 1
+; RUN: llvm-as < %s | llc -march=x86-64 | not grep movq
 
 define i64 @t(i64 %a, i64 %b) nounwind ssp {
 entry:





More information about the llvm-commits mailing list