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

Dale Johannesen dalej at apple.com
Wed Feb 28 15:20:55 PST 2007



Changes in directory llvm/lib/Target/ARM:

ARMConstantIslandPass.cpp updated: 1.31 -> 1.32
---
Log message:

Changes requested in review of last pass.  Also pulled isThumb into a
member, instead of resetting in every function that uses it.


---
Diffs of the changes:  (+142 -113)

 ARMConstantIslandPass.cpp |  255 +++++++++++++++++++++++++---------------------
 1 files changed, 142 insertions(+), 113 deletions(-)


Index: llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
diff -u llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.31 llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.32
--- llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.31	Wed Feb 28 12:41:22 2007
+++ llvm/lib/Target/ARM/ARMConstantIslandPass.cpp	Wed Feb 28 17:20:38 2007
@@ -122,6 +122,7 @@
 
     const TargetInstrInfo *TII;
     const ARMFunctionInfo *AFI;
+    bool isThumb;
   public:
     virtual bool runOnMachineFunction(MachineFunction &Fn);
 
@@ -140,6 +141,10 @@
     void AdjustBBOffsetsAfter(MachineBasicBlock *BB, int delta);
     bool DecrementOldEntry(unsigned CPI, MachineInstr* CPEMI, unsigned Size);
     int LookForExistingCPEntry(CPUser& U, unsigned UserOffset);
+    bool LookForWater(CPUser&U, unsigned UserOffset, bool* PadNewWater,
+                      MachineBasicBlock** NewMBB);
+    void CreateNewWater(unsigned CPUserIndex, unsigned UserOffset,
+                      MachineBasicBlock** NewMBB);
     bool HandleConstantPoolUser(MachineFunction &Fn, unsigned CPUserIndex);
     bool CPEIsInRange(MachineInstr *MI, unsigned UserOffset, 
                       MachineInstr *CPEMI, unsigned Disp,
@@ -169,6 +174,7 @@
   
   TII = Fn.getTarget().getInstrInfo();
   AFI = Fn.getInfo<ARMFunctionInfo>();
+  isThumb = AFI->isThumbFunction();
 
   HasFarJump = false;
 
@@ -207,7 +213,7 @@
   
   // If LR has been forced spilled and no far jumps (i.e. BL) has been issued.
   // Undo the spill / restore of LR if possible.
-  if (!HasFarJump && AFI->isLRForceSpilled() && AFI->isThumbFunction())
+  if (!HasFarJump && AFI->isLRForceSpilled() && isThumb)
     MadeChange |= UndoLRSpillRestore();
 
   BBSizes.clear();
@@ -413,7 +419,7 @@
     // In thumb mode, if this block is a constpool island, pessimistically 
     // assume it needs to be padded by two byte so it's aligned on 4 byte 
     // boundary.
-    if (AFI->isThumbFunction() &&
+    if (isThumb &&
         !MBB.empty() &&
         MBB.begin()->getOpcode() == ARM::CONSTPOOL_ENTRY)
       MBBSize += 2;
@@ -478,7 +484,6 @@
 /// account for this change and returns the newly created block.
 MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) {
   MachineBasicBlock *OrigBB = MI->getParent();
-  bool isThumb = AFI->isThumbFunction();
 
   // Create a new MBB for the code after the OrigBB.
   MachineBasicBlock *NewBB = new MachineBasicBlock(OrigBB->getBasicBlock());
@@ -579,7 +584,6 @@
 bool ARMConstantIslands::WaterIsInRange(unsigned UserOffset,
                          MachineBasicBlock* Water, unsigned MaxDisp)
 {
-  bool isThumb = AFI->isThumbFunction();
   unsigned CPEOffset = BBOffsets[Water->getNumber()] + 
                        BBSizes[Water->getNumber()];
   // If the Water is a constpool island, it has already been aligned.
@@ -599,7 +603,6 @@
                                       unsigned MaxDisp, bool DoDump) {
   // In thumb mode, pessimistically assumes the .align 2 before the first CPE
   // in the island adds two byte padding.
-  bool isThumb = AFI->isThumbFunction();
   unsigned AlignAdj   = isThumb ? 2 : 0;
   unsigned CPEOffset  = GetOffsetOf(CPEMI) + AlignAdj;
 
@@ -728,46 +731,22 @@
   return (Opc == ARM::tB) ? ((1<<10)-1)*2 : ((1<<23)-1)*4;
 }
 
-/// 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.  Return true if we changed any addresses (thus must run
-/// another pass of branch lengthening), false otherwise.
-bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn, 
-                                                unsigned CPUserIndex){
-  CPUser &U = CPUsers[CPUserIndex];
-  MachineInstr *UserMI = U.MI;
-  MachineInstr *CPEMI  = U.CPEMI;
-  unsigned CPI = CPEMI->getOperand(1).getConstantPoolIndex();
-  unsigned Size = CPEMI->getOperand(2).getImm();
-  bool isThumb = AFI->isThumbFunction();
-  MachineBasicBlock *NewMBB;
-  // Compute this only once, it's expensive
-  unsigned UserOffset = GetOffsetOf(UserMI) + (isThumb ? 4 : 8);
- 
-  // See if the current entry is within range, or there is a clone of it
-  // in range.
-  int result = LookForExistingCPEntry(U, UserOffset);
-  if (result==1) return false;
-  else if (result==2) return true;
-
-  // No existing clone of this CPE is within range.
-  // We will be generating a new clone.  Get a UID for it.
-  unsigned ID  = NextUID++;
+/// LookForWater - look for an existing entry in the WaterList in which
+/// we can place the CPE referenced from U so it's within range of U's MI.
+/// Returns true if found, false if not.  If it returns true, *NewMBB
+/// is set to the WaterList entry, and *PadNewWater is set to false if
+/// the WaterList entry is an island.
 
-  // Look for water where we can place this CPE.  We look for the farthest one
-  // away that will work.  Forward references only for now (although later
-  // we might find some that are backwards).
-  bool WaterFound = false;
-  bool PadNewWater = true;
+bool ARMConstantIslands::LookForWater(CPUser &U, unsigned UserOffset,
+                            bool *PadNewWater, MachineBasicBlock** NewMBB) {
   if (!WaterList.empty()) {
     for (std::vector<MachineBasicBlock*>::iterator IP = prior(WaterList.end()),
         B = WaterList.begin();; --IP) {
       MachineBasicBlock* WaterBB = *IP;
       if (WaterIsInRange(UserOffset, WaterBB, U.MaxDisp)) {
-        WaterFound = true;
         DOUT << "found water in range\n";
         // CPE goes before following block (NewMBB).
-        NewMBB = next(MachineFunction::iterator(WaterBB));
+        *NewMBB = next(MachineFunction::iterator(WaterBB));
         // If WaterBB is an island, don't pad the new island.
         // If WaterBB is empty, go backwards until we find something that
         // isn't.  WaterBB may become empty if it's an island whose
@@ -775,97 +754,147 @@
         if (isThumb) {
           MachineBasicBlock* BB = WaterBB;
           while (BB->empty())
-            BB = BB->Prev;
+            BB = prior(MachineFunction::iterator(BB));
           if (BB->begin()->getOpcode() == ARM::CONSTPOOL_ENTRY)
-            PadNewWater = false;
+            *PadNewWater = false;
         }
         // Remove the original WaterList entry; we want subsequent
         // insertions in this vicinity to go after the one we're
         // about to insert.  This considerably reduces the number
         // of times we have to move the same CPE more than once.
         WaterList.erase(IP);
-        break;
+        return true;
       }
       if (IP == B)
         break;
     }
   }
+  return false;
+}
 
-  if (!WaterFound) {
-    // No water found.
+/// CreateNewWater - No existing WaterList entry will work for 
+/// CPUsers[CPUserIndex], so create a place to put the CPE.  The end of the
+/// block is used if in range, and the conditional branch munged so control
+/// flow is correct.  Otherwise the block is split to create a hole with an
+/// unconditional branch around it.  In either case *NewMBB is set to a
+/// block following which the new island can be inserted (the WaterList
+/// is not adjusted).
 
-    DOUT << "No water found\n";
-    MachineBasicBlock *UserMBB = UserMI->getParent();
-    unsigned OffsetOfNextBlock = BBOffsets[UserMBB->getNumber()] + 
-                                 BBSizes[UserMBB->getNumber()];
-    assert(OffsetOfNextBlock = BBOffsets[UserMBB->getNumber()+1]);
-
-    // If the use is at the end of the block, or the end of the block
-    // is within range, make new water there.  (The +2 or 4 below is
-    // for the unconditional branch we will be adding.  If the block ends in
-    // an unconditional branch already, it is water, and is known to
-    // be out of range, so we'll always be adding one.)
-    if (&UserMBB->back() == UserMI ||
-        OffsetIsInRange(UserOffset, OffsetOfNextBlock + (isThumb ? 2 : 4),
-                        U.MaxDisp, !isThumb)) {
-      DOUT << "Split at end of block\n";
-      if (&UserMBB->back() == UserMI)
-        assert(BBHasFallthrough(UserMBB) && "Expected a fallthrough BB!");
-      NewMBB = next(MachineFunction::iterator(UserMBB));
-      // Add an unconditional branch from UserMBB to fallthrough block.
-      // Record it for branch lengthening; this new branch will not get out of
-      // range, but if the preceding conditional branch is out of range, the
-      // targets will be exchanged, and the altered branch may be out of
-      // range, so the machinery has to know about it.
-      int UncondBr = isThumb ? ARM::tB : ARM::B;
-      BuildMI(UserMBB, TII->get(UncondBr)).addMBB(NewMBB);
-      unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
-      ImmBranches.push_back(ImmBranch(&UserMBB->back(), 
-                            MaxDisp, false, UncondBr));
-      int delta = isThumb ? 2 : 4;
-      BBSizes[UserMBB->getNumber()] += delta;
-      AdjustBBOffsetsAfter(UserMBB, delta);
-    } else {
-      // What a big block.  Find a place within the block to split it.
-      // This is a little tricky on Thumb since instructions are 2 bytes
-      // and constant pool entries are 4 bytes: if instruction I references
-      // island CPE, and instruction I+1 references CPE', it will
-      // not work well to put CPE as far forward as possible, since then
-      // CPE' cannot immediately follow it (that location is 2 bytes
-      // farther away from I+1 than CPE was from I) and we'd need to create
-      // a new island.
-      // The 4 in the following is for the unconditional branch we'll be
-      // inserting (allows for long branch on Thumb).  The 2 or 0 is for
-      // alignment of the island.
-      unsigned BaseInsertOffset = UserOffset + U.MaxDisp -4 + (isThumb ? 2 : 0);
-      // This could point off the end of the block if we've already got
-      // constant pool entries following this block; only the last one is
-      // in the water list.  Back past any possible branches.
-      if (BaseInsertOffset >= BBOffsets[UserMBB->getNumber()+1])
-        BaseInsertOffset = BBOffsets[UserMBB->getNumber()+1] - 6;
-      unsigned EndInsertOffset = BaseInsertOffset +
-             CPEMI->getOperand(2).getImm();
-      MachineBasicBlock::iterator MI = UserMI;  ++MI;
-      unsigned CPUIndex = CPUserIndex+1;
-      for (unsigned Offset = UserOffset+ARM::GetInstSize(UserMI);
-           Offset < BaseInsertOffset;
-           Offset += ARM::GetInstSize(MI),
-              MI = next(MI)) {
-        if (CPUIndex < CPUsers.size() && CPUsers[CPUIndex].MI == MI) {
-          if (!OffsetIsInRange(Offset, EndInsertOffset, 
-                CPUsers[CPUIndex].MaxDisp, !isThumb)) {
-            BaseInsertOffset -= (isThumb ? 2 : 4);
-            EndInsertOffset -= (isThumb ? 2 : 4);
-          }
-          // This is overly conservative, as we don't account for CPEMIs
-          // being reused within the block, but it doesn't matter much.
-          EndInsertOffset += CPUsers[CPUIndex].CPEMI->getOperand(2).getImm();
-          CPUIndex++;
+void ARMConstantIslands::CreateNewWater(unsigned CPUserIndex, 
+                        unsigned UserOffset, MachineBasicBlock** NewMBB) {
+  CPUser &U = CPUsers[CPUserIndex];
+  MachineInstr *UserMI = U.MI;
+  MachineInstr *CPEMI  = U.CPEMI;
+  MachineBasicBlock *UserMBB = UserMI->getParent();
+  unsigned OffsetOfNextBlock = BBOffsets[UserMBB->getNumber()] + 
+                               BBSizes[UserMBB->getNumber()];
+  assert(OffsetOfNextBlock = BBOffsets[UserMBB->getNumber()+1]);
+
+  // If the use is at the end of the block, or the end of the block
+  // is within range, make new water there.  (The +2 or 4 below is
+  // for the unconditional branch we will be adding.  If the block ends in
+  // an unconditional branch already, it is water, and is known to
+  // be out of range, so we'll always be adding one.)
+  if (&UserMBB->back() == UserMI ||
+      OffsetIsInRange(UserOffset, OffsetOfNextBlock + (isThumb ? 2 : 4),
+                      U.MaxDisp, !isThumb)) {
+    DOUT << "Split at end of block\n";
+    if (&UserMBB->back() == UserMI)
+      assert(BBHasFallthrough(UserMBB) && "Expected a fallthrough BB!");
+    *NewMBB = next(MachineFunction::iterator(UserMBB));
+    // Add an unconditional branch from UserMBB to fallthrough block.
+    // Record it for branch lengthening; this new branch will not get out of
+    // range, but if the preceding conditional branch is out of range, the
+    // targets will be exchanged, and the altered branch may be out of
+    // range, so the machinery has to know about it.
+    int UncondBr = isThumb ? ARM::tB : ARM::B;
+    BuildMI(UserMBB, TII->get(UncondBr)).addMBB(*NewMBB);
+    unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
+    ImmBranches.push_back(ImmBranch(&UserMBB->back(), 
+                          MaxDisp, false, UncondBr));
+    int delta = isThumb ? 2 : 4;
+    BBSizes[UserMBB->getNumber()] += delta;
+    AdjustBBOffsetsAfter(UserMBB, delta);
+  } else {
+    // What a big block.  Find a place within the block to split it.
+    // This is a little tricky on Thumb since instructions are 2 bytes
+    // and constant pool entries are 4 bytes: if instruction I references
+    // island CPE, and instruction I+1 references CPE', it will
+    // not work well to put CPE as far forward as possible, since then
+    // CPE' cannot immediately follow it (that location is 2 bytes
+    // farther away from I+1 than CPE was from I) and we'd need to create
+    // a new island.
+    // The 4 in the following is for the unconditional branch we'll be
+    // inserting (allows for long branch on Thumb).  The 2 or 0 is for
+    // alignment of the island.
+    unsigned BaseInsertOffset = UserOffset + U.MaxDisp -4 + (isThumb ? 2 : 0);
+    // This could point off the end of the block if we've already got
+    // constant pool entries following this block; only the last one is
+    // in the water list.  Back past any possible branches (allow for a
+    // conditional and a maximally long unconditional).
+    if (BaseInsertOffset >= BBOffsets[UserMBB->getNumber()+1])
+      BaseInsertOffset = BBOffsets[UserMBB->getNumber()+1] - 
+                              (isThumb ? 6 : 8);
+    unsigned EndInsertOffset = BaseInsertOffset +
+           CPEMI->getOperand(2).getImm();
+    MachineBasicBlock::iterator MI = UserMI;
+    ++MI;
+    unsigned CPUIndex = CPUserIndex+1;
+    for (unsigned Offset = UserOffset+ARM::GetInstSize(UserMI);
+         Offset < BaseInsertOffset;
+         Offset += ARM::GetInstSize(MI),
+            MI = next(MI)) {
+      if (CPUIndex < CPUsers.size() && CPUsers[CPUIndex].MI == MI) {
+        if (!OffsetIsInRange(Offset, EndInsertOffset, 
+              CPUsers[CPUIndex].MaxDisp, !isThumb)) {
+          BaseInsertOffset -= (isThumb ? 2 : 4);
+          EndInsertOffset -= (isThumb ? 2 : 4);
         }
+        // This is overly conservative, as we don't account for CPEMIs
+        // being reused within the block, but it doesn't matter much.
+        EndInsertOffset += CPUsers[CPUIndex].CPEMI->getOperand(2).getImm();
+        CPUIndex++;
       }
-      DOUT << "Split in middle of big block\n";
-      NewMBB = SplitBlockBeforeInstr(prior(MI));
     }
+    DOUT << "Split in middle of big block\n";
+    *NewMBB = SplitBlockBeforeInstr(prior(MI));
+  }
+}
+
+/// 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.  Return true if we changed any addresses (thus must run
+/// another pass of branch lengthening), false otherwise.
+bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn, 
+                                                unsigned CPUserIndex){
+  CPUser &U = CPUsers[CPUserIndex];
+  MachineInstr *UserMI = U.MI;
+  MachineInstr *CPEMI  = U.CPEMI;
+  unsigned CPI = CPEMI->getOperand(1).getConstantPoolIndex();
+  unsigned Size = CPEMI->getOperand(2).getImm();
+  MachineBasicBlock *NewMBB;
+  // Compute this only once, it's expensive
+  unsigned UserOffset = GetOffsetOf(UserMI) + (isThumb ? 4 : 8);
+ 
+  // See if the current entry is within range, or there is a clone of it
+  // in range.
+  int result = LookForExistingCPEntry(U, UserOffset);
+  if (result==1) return false;
+  else if (result==2) return true;
+
+  // No existing clone of this CPE is within range.
+  // We will be generating a new clone.  Get a UID for it.
+  unsigned ID  = NextUID++;
+
+  // Look for water where we can place this CPE.  We look for the farthest one
+  // away that will work.  Forward references only for now (although later
+  // we might find some that are backwards).
+  bool PadNewWater = true;
+
+  if (!LookForWater(U, UserOffset, &PadNewWater, &NewMBB)) {
+    // No water found.
+    DOUT << "No water found\n";
+    CreateNewWater(CPUserIndex, UserOffset, &NewMBB);
   }
 
   // Okay, we know we can put an island before NewMBB now, do it!
@@ -908,7 +937,7 @@
 /// specific BB can fit in MI's displacement field.
 bool ARMConstantIslands::BBIsInRange(MachineInstr *MI,MachineBasicBlock *DestBB,
                                      unsigned MaxDisp) {
-  unsigned PCAdj      = AFI->isThumbFunction() ? 4 : 8;
+  unsigned PCAdj      = isThumb ? 4 : 8;
   unsigned BrOffset   = GetOffsetOf(MI) + PCAdj;
   unsigned DestOffset = BBOffsets[DestBB->getNumber()];
 
@@ -943,7 +972,7 @@
 ARMConstantIslands::FixUpUnconditionalBr(MachineFunction &Fn, ImmBranch &Br) {
   MachineInstr *MI = Br.MI;
   MachineBasicBlock *MBB = MI->getParent();
-  assert(AFI->isThumbFunction() && "Expected a Thumb function!");
+  assert(isThumb && "Expected a Thumb function!");
 
   // Use BL to implement far jump.
   Br.MaxDisp = (1 << 21) * 2;






More information about the llvm-commits mailing list