[llvm-commits] CVS: llvm/lib/Target/ARM/ARMConstantIslandPass.cpp

Evan Cheng evan.cheng at apple.com
Wed Jan 31 11:58:01 PST 2007



Changes in directory llvm/lib/Target/ARM:

ARMConstantIslandPass.cpp updated: 1.16 -> 1.17
---
Log message:

When determining whether a pc relative branch / load displacement fits in the
instruction field, adjust it for PC value (4 for thumb, 8 for arm).


---
Diffs of the changes:  (+42 -27)

 ARMConstantIslandPass.cpp |   69 ++++++++++++++++++++++++++++------------------
 1 files changed, 42 insertions(+), 27 deletions(-)


Index: llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
diff -u llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.16 llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.17
--- llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.16	Wed Jan 31 12:29:27 2007
+++ llvm/lib/Target/ARM/ARMConstantIslandPass.cpp	Wed Jan 31 13:57:44 2007
@@ -115,7 +115,8 @@
     MachineBasicBlock *SplitBlockBeforeInstr(MachineInstr *MI);
     void UpdateForInsertedWaterBlock(MachineBasicBlock *NewBB);
     bool HandleConstantPoolUser(MachineFunction &Fn, CPUser &U);
-    bool BBIsInBranchRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned D);
+    bool CPEIsInRange(MachineInstr *MI, MachineInstr *CPEMI, unsigned Disp);
+    bool BBIsInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);
     bool FixUpImmediateBr(MachineFunction &Fn, ImmBranch &Br);
     bool FixUpConditionalBr(MachineFunction &Fn, ImmBranch &Br);
     bool FixUpUnconditionalBr(MachineFunction &Fn, ImmBranch &Br);
@@ -458,33 +459,41 @@
   return NewBB;
 }
 
-/// HandleConstantPoolUser - Analyze the specified user, checking to see if it
-/// is out-of-range.  If so, pick it up the constant pool value and move it some
-/// place in-range.
-bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn, CPUser &U){
-  bool isThumb = AFI->isThumbFunction();
-  MachineInstr *UserMI = U.MI;
-  MachineInstr *CPEMI  = U.CPEMI;
-
-  unsigned UserOffset = GetOffsetOf(UserMI);
+/// CPEIsInRange - Returns true is the distance between specific MI and
+/// specific ConstPool entry instruction can fit in MI's displacement field.
+bool ARMConstantIslands::CPEIsInRange(MachineInstr *MI, MachineInstr *CPEMI,
+                                      unsigned MaxDisp) {
+  unsigned PCAdj      = AFI->isThumbFunction() ? 4 : 8;
+  unsigned UserOffset = GetOffsetOf(MI) + PCAdj;
   unsigned CPEOffset  = GetOffsetOf(CPEMI);
   
   DEBUG(std::cerr << "User of CPE#" << CPEMI->getOperand(0).getImm()
-                  << " max delta=" << U.MaxDisp
+                  << " max delta=" << MaxDisp
                   << " at offset " << int(UserOffset-CPEOffset) << "\t"
-                  << *UserMI);
+                  << *MI);
 
-  // Check to see if the CPE is already in-range.
   if (UserOffset < CPEOffset) {
     // User before the CPE.
-    if (CPEOffset-UserOffset <= U.MaxDisp)
-      return false;
-  } else if (!isThumb) {
+    if (CPEOffset-UserOffset <= MaxDisp)
+      return true;
+  } else if (!AFI->isThumbFunction()) {
     // Thumb LDR cannot encode negative offset.
-    if (UserOffset-CPEOffset <= U.MaxDisp)
-      return false;
+    if (UserOffset-CPEOffset <= MaxDisp)
+      return true;
   }
-  
+  return false;
+}
+
+/// HandleConstantPoolUser - Analyze the specified user, checking to see if it
+/// is out-of-range.  If so, pick it up the constant pool value and move it some
+/// place in-range.
+bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn, CPUser &U){
+  MachineInstr *UserMI = U.MI;
+  MachineInstr *CPEMI  = U.CPEMI;
+
+  // Check to see if the CPE is already in-range.
+  if (CPEIsInRange(UserMI, CPEMI, U.MaxDisp))
+    return false;
 
   // Solution guaranteed to work: split the user's MBB right after the user and
   // insert a clone the CPE into the newly created water.
@@ -500,6 +509,7 @@
     NewMBB = next(MachineFunction::iterator(UserMBB));
     // Add an unconditional branch from UserMBB to fallthrough block.
     // Note the new unconditional branch is not being recorded.
+    bool isThumb = AFI->isThumbFunction();
     BuildMI(UserMBB, TII->get(isThumb ? ARM::tB : ARM::B)).addMBB(NewMBB);
     BBSizes[UserMBB->getNumber()] += isThumb ? 2 : 4;
   } else {
@@ -540,15 +550,19 @@
   return true;
 }
 
-/// BBIsInBranchRange - Returns true is the distance between specific MI and
+/// BBIsInRange - Returns true is the distance between specific MI and
 /// specific BB can fit in MI's displacement field.
-bool ARMConstantIslands::BBIsInBranchRange(MachineInstr *MI,
-                                           MachineBasicBlock *DestBB,
-                                           unsigned MaxDisp) {
-  unsigned BrOffset   = GetOffsetOf(MI);
+bool ARMConstantIslands::BBIsInRange(MachineInstr *MI,MachineBasicBlock *DestBB,
+                                     unsigned MaxDisp) {
+  unsigned PCAdj      = AFI->isThumbFunction() ? 4 : 8;
+  unsigned BrOffset   = GetOffsetOf(MI) + PCAdj;
   unsigned DestOffset = GetOffsetOf(DestBB);
 
-  // Check to see if the destination BB is in range.
+  DEBUG(std::cerr << "Branch of destination BB#" << DestBB->getNumber()
+                  << " max delta=" << MaxDisp
+                  << " at offset " << int(BrOffset-DestOffset) << "\t"
+                  << *MI);
+
   if (BrOffset < DestOffset) {
     if (DestOffset - BrOffset < MaxDisp)
       return true;
@@ -565,7 +579,8 @@
   MachineInstr *MI = Br.MI;
   MachineBasicBlock *DestBB = MI->getOperand(0).getMachineBasicBlock();
 
-  if (BBIsInBranchRange(MI, DestBB, Br.MaxDisp))
+  // Check to see if the DestBB is already in-range.
+  if (BBIsInRange(MI, DestBB, Br.MaxDisp))
     return false;
 
   if (!Br.isCond)
@@ -635,7 +650,7 @@
       // bne L2
       // b   L1
       MachineBasicBlock *NewDest = BackMI->getOperand(0).getMachineBasicBlock();
-      if (BBIsInBranchRange(MI, NewDest, Br.MaxDisp)) {
+      if (BBIsInRange(MI, NewDest, Br.MaxDisp)) {
         BackMI->getOperand(0).setMachineBasicBlock(DestBB);
         MI->getOperand(0).setMachineBasicBlock(NewDest);
         MI->getOperand(1).setImm(CC);






More information about the llvm-commits mailing list