Also set the proper alignment on inner islands and the function itself.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Mon, 12 Dec 2011 18:45:45 +0000 (18:45 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Mon, 12 Dec 2011 18:45:45 +0000 (18:45 +0000)
Downgrade the alignment of the initial constant island when constant
pool entries are moved elsewhere.

This is all gated by -arm-align-constant-islands.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146391 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMConstantIslandPass.cpp

index f81361fa7d6bd053567bb2206881386a41f4464a..6fc46b29a7af651b044843551403fa7fcd29378f 100644 (file)
@@ -270,6 +270,7 @@ namespace {
   private:
     void DoInitialPlacement(std::vector<MachineInstr*> &CPEMIs);
     CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);
+    unsigned getCPELogAlign(const MachineInstr *CPEMI);
     void JumpTableFunctionScan();
     void InitialFunctionScan(const std::vector<MachineInstr*> &CPEMIs);
     MachineBasicBlock *SplitBlockBeforeInstr(MachineInstr *MI);
@@ -402,11 +403,8 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
   // Perform the initial placement of the constant pool entries.  To start with,
   // we put them all at the end of the function.
   std::vector<MachineInstr*> CPEMIs;
-  if (!MCP->isEmpty()) {
+  if (!MCP->isEmpty())
     DoInitialPlacement(CPEMIs);
-    if (isThumb1)
-      MF->EnsureAlignment(2);  // 2 = log2(4)
-  }
 
   /// The next UID to take is the first unused one.
   AFI->initPICLabelUId(CPEMIs.size());
@@ -499,6 +497,10 @@ ARMConstantIslands::DoInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
   // If AlignConstantIslands isn't set, use 4-byte alignment for everything.
   BB->setAlignment(AlignConstantIslands ? MaxAlign : 2);
 
+  // The function needs to be as aligned as the basic blocks. The linker may
+  // move functions around based on their alignment.
+  MF->EnsureAlignment(BB->getAlignment());
+
   // Order the entries in BB by descending alignment.  That ensures correct
   // alignment of all entries as long as BB is sufficiently aligned.  Keep
   // track of the insertion point for each alignment.  We are going to bucket
@@ -577,6 +579,22 @@ ARMConstantIslands::CPEntry
   return NULL;
 }
 
+/// getCPELogAlign - Returns the required alignment of the constant pool entry
+/// represented by CPEMI.  ALignment is measured in log2(bytes) units.
+unsigned ARMConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) {
+  assert(CPEMI && CPEMI->getOpcode() == ARM::CONSTPOOL_ENTRY);
+
+  // Everything is 4-byte aligned unless AlignConstantIslands is set.
+  if (!AlignConstantIslands)
+    return 2;
+
+  unsigned CPI = CPEMI->getOperand(1).getIndex();
+  assert(CPI < MCP->getConstants().size() && "Invalid constant pool index.");
+  unsigned Align = MCP->getConstants()[CPI].getAlignment();
+  assert(isPowerOf2_32(Align) && "Invalid CPE alignment");
+  return Log2_32(Align);
+}
+
 /// JumpTableFunctionScan - Do a scan of the function, building up
 /// information about the sizes of each block and the locations of all
 /// the jump tables.
@@ -1367,8 +1385,8 @@ bool ARMConstantIslands::HandleConstantPoolUser(unsigned CPUserIndex) {
   CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
   ++NumCPEs;
 
-  // Mark the basic block as 4-byte aligned as required by the const-pool entry.
-  NewIsland->setAlignment(2);
+  // Mark the basic block as aligned as required by the const-pool entry.
+  NewIsland->setAlignment(getCPELogAlign(U.CPEMI));
 
   // Increase the size of the island block to account for the new entry.
   BBInfo[NewIsland->getNumber()].Size += Size;
@@ -1396,18 +1414,14 @@ void ARMConstantIslands::RemoveDeadCPEMI(MachineInstr *CPEMI) {
   BBInfo[CPEBB->getNumber()].Size -= Size;
   // All succeeding offsets have the current size value added in, fix this.
   if (CPEBB->empty()) {
-    // In thumb1 mode, the size of island may be padded by two to compensate for
-    // the alignment requirement.  Then it will now be 2 when the block is
-    // empty, so fix this.
-    // All succeeding offsets have the current size value added in, fix this.
-    if (BBInfo[CPEBB->getNumber()].Size != 0) {
-      Size += BBInfo[CPEBB->getNumber()].Size;
-      BBInfo[CPEBB->getNumber()].Size = 0;
-    }
+    BBInfo[CPEBB->getNumber()].Size = 0;
 
     // This block no longer needs to be aligned. <rdar://problem/10534709>.
     CPEBB->setAlignment(0);
-  }
+  } else
+    // Entries are sorted by descending alignment, so realign from the front.
+    CPEBB->setAlignment(getCPELogAlign(CPEBB->begin()));
+
   AdjustBBOffsetsAfter(CPEBB);
   // An island has only one predecessor BB and one successor BB. Check if
   // this BB's predecessor jumps directly to this BB's successor. This