Add a quick and dirty "loop aligner pass". x86 uses it to align its loops to 16-byte boundaries.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47703 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp
index 7a01a87..9cdae34 100644
--- a/lib/CodeGen/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter.cpp
@@ -39,7 +39,8 @@
 char AsmPrinter::ID = 0;
 AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm,
                        const TargetAsmInfo *T)
-  : MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o), TM(tm), TAI(T)
+  : MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o), TM(tm), TAI(T),
+    IsInTextSection(false)
 {}
 
 std::string AsmPrinter::getSectionForFunction(const Function &F) const {
@@ -69,6 +70,8 @@
 
   if (!CurrentSection.empty())
     O << CurrentSection << TAI->getTextSectionStartSuffix() << '\n';
+
+  IsInTextSection = true;
 }
 
 /// SwitchToDataSection - Switch to the specified data section of the executable
@@ -93,6 +96,8 @@
   
   if (!CurrentSection.empty())
     O << CurrentSection << TAI->getDataSectionStartSuffix() << '\n';
+
+  IsInTextSection = false;
 }
 
 
@@ -344,7 +349,7 @@
       O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
         << '_' << uid << "_set_" << MBB->getNumber();
     } else {
-      printBasicBlockLabel(MBB, false, false);
+      printBasicBlockLabel(MBB, false, false, false);
       // If the arch uses custom Jump Table directives, don't calc relative to
       // JT
       if (!HadJTEntryDirective) 
@@ -352,7 +357,7 @@
           << getFunctionNumber() << '_' << uid;
     }
   } else {
-    printBasicBlockLabel(MBB, false, false);
+    printBasicBlockLabel(MBB, false, false, false);
   }
 }
 
@@ -679,8 +684,7 @@
 //     Align = std::max(Align, ForcedAlignBits);
 //
 void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV,
-                               unsigned ForcedAlignBits, bool UseFillExpr,
-                               unsigned FillValue) const {
+                               unsigned ForcedAlignBits) const {
   if (GV && GV->getAlignment())
     NumBits = Log2_32(GV->getAlignment());
   NumBits = std::max(NumBits, ForcedAlignBits);
@@ -688,6 +692,9 @@
   if (NumBits == 0) return;   // No need to emit alignment.
   if (TAI->getAlignmentIsInBytes()) NumBits = 1 << NumBits;
   O << TAI->getAlignDirective() << NumBits;
+
+  unsigned FillValue = TAI->getTextAlignFillValue();
+  bool UseFillExpr = IsInTextSection && FillValue;
   if (UseFillExpr) O << ",0x" << std::hex << FillValue << std::dec;
   O << "\n";
 }
@@ -1252,7 +1259,7 @@
 
           if (Modifier[0]=='l')  // labels are target independent
             printBasicBlockLabel(MI->getOperand(OpNo).getMBB(), 
-                                 false, false);
+                                 false, false, false);
           else {
             AsmPrinter *AP = const_cast<AsmPrinter*>(this);
             if ((OpFlags & 7) == 4 /*ADDR MODE*/) {
@@ -1318,8 +1325,15 @@
 /// printBasicBlockLabel - This method prints the label for the specified
 /// MachineBasicBlock
 void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB,
+                                      bool printAlign, 
                                       bool printColon,
                                       bool printComment) const {
+  if (printAlign) {
+    unsigned Align = MBB->getAlignment();
+    if (Align)
+      EmitAlignment(Log2_32(Align));
+  }
+
   O << TAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber() << "_"
     << MBB->getNumber();
   if (printColon)
@@ -1338,7 +1352,7 @@
   
   O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix()
     << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ',';
-  printBasicBlockLabel(MBB, false, false);
+  printBasicBlockLabel(MBB, false, false, false);
   O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 
     << '_' << uid << '\n';
 }
@@ -1351,7 +1365,7 @@
   O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix()
     << getFunctionNumber() << '_' << uid << '_' << uid2
     << "_set_" << MBB->getNumber() << ',';
-  printBasicBlockLabel(MBB, false, false);
+  printBasicBlockLabel(MBB, false, false, false);
   O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 
     << '_' << uid << '_' << uid2 << '\n';
 }
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 2d7836f..d9874b5 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -44,7 +44,7 @@
             cl::desc("Max number of predecessors to consider tail merging"),
             cl::init(100), cl::Hidden);
 
-  struct BranchFolder : public MachineFunctionPass {
+  struct VISIBILITY_HIDDEN BranchFolder : public MachineFunctionPass {
     static char ID;
     explicit BranchFolder(bool defaultEnableTailMerge) : 
         MachineFunctionPass((intptr_t)&ID) {
diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp
index 7d7f33e..a77ccb7 100644
--- a/lib/CodeGen/IfConversion.cpp
+++ b/lib/CodeGen/IfConversion.cpp
@@ -56,7 +56,7 @@
 STATISTIC(NumDupBBs,       "Number of duplicated blocks");
 
 namespace {
-  class IfConverter : public MachineFunctionPass {
+  class VISIBILITY_HIDDEN IfConverter : public MachineFunctionPass {
     enum IfcvtKind {
       ICNotClassfied,  // BB data valid, but not classified.
       ICSimpleFalse,   // Same as ICSimple, but on the false path.
diff --git a/lib/CodeGen/LoopAligner.cpp b/lib/CodeGen/LoopAligner.cpp
new file mode 100644
index 0000000..a40bb50
--- /dev/null
+++ b/lib/CodeGen/LoopAligner.cpp
@@ -0,0 +1,65 @@
+//===-- LoopAligner.cpp - Loop aligner pass. ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the pass that align loop headers to target specific
+// alignment boundary.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "loopalign"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+using namespace llvm;
+
+namespace {
+  class LoopAligner : public MachineFunctionPass {
+    const TargetLowering *TLI;
+
+  public:
+    static char ID;
+    LoopAligner() : MachineFunctionPass((intptr_t)&ID) {}
+
+    virtual bool runOnMachineFunction(MachineFunction &MF);
+    virtual const char *getPassName() const { return "Loop aligner"; }
+
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.addRequired<MachineLoopInfo>();
+      AU.addPreserved<MachineLoopInfo>();
+      MachineFunctionPass::getAnalysisUsage(AU);
+    }
+  };
+
+  char LoopAligner::ID = 0;
+} // end anonymous namespace
+
+FunctionPass *llvm::createLoopAlignerPass() { return new LoopAligner(); }
+
+bool LoopAligner::runOnMachineFunction(MachineFunction &MF) {
+  const MachineLoopInfo *MLI = &getAnalysis<MachineLoopInfo>();
+
+  if (MLI->begin() == MLI->end())
+    return false;  // No loops.
+
+  unsigned Align = MF.getTarget().getTargetLowering()->getPrefLoopAlignment();
+  if (!Align)
+    return false;  // Don't care about loop alignment.
+
+  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
+    MachineBasicBlock *MBB = I;
+    if (MLI->isLoopHeader(MBB))
+      MBB->setAlignment(Align);
+  }
+
+  return true;
+}
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index dc6a618..af91a2f 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -166,6 +166,7 @@
   if (LBB) OS << LBB->getName() << ": ";
   OS << (const void*)this
      << ", LLVM BB @" << (const void*) LBB << ", ID#" << getNumber();
+  if (Alignment) OS << ", Alignment " << Alignment;
   if (isLandingPad()) OS << ", EH LANDING PAD";
   OS << ":\n";
 
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index ba5a34b..ff5289e 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -206,6 +206,8 @@
   JumpBufSize = 0;
   JumpBufAlignment = 0;
   IfCvtBlockSizeLimit = 2;
+  IfCvtDupBlockSizeLimit = 0;
+  PrefLoopAlignment = 0;
 
   InitLibcallNames(LibcallRoutineNames);
   InitCmpLibcallCCs(CmpLibcallCCs);