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/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 6607afe..462c401 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -78,6 +78,10 @@
     /// CurrentSection - The current section we are emitting to.  This is
     /// controlled and used by the SwitchSection method.
     std::string CurrentSection;
+
+    /// IsInTextSection - True if the current section we are emitting to is a
+    /// text section.
+    bool IsInTextSection;
   
   protected:
     AsmPrinter(std::ostream &o, TargetMachine &TM, const TargetAsmInfo *T);
@@ -269,9 +273,7 @@
     /// an explicit alignment requested, it will unconditionally override the
     /// alignment request.  However, if ForcedAlignBits is specified, this value
     /// has final say: the ultimate alignment will be the max of ForcedAlignBits
-    /// and the alignment computed with NumBits and the global. If UseFillExpr
-    /// is true, it also emits an optional second value FillValue which the
-    /// assembler uses to fill gaps to match alignment.
+    /// and the alignment computed with NumBits and the global
     ///
     /// The algorithm is:
     ///     Align = NumBits;
@@ -279,8 +281,7 @@
     ///     Align = std::max(Align, ForcedAlignBits);
     ///
     void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0,
-                       unsigned ForcedAlignBits = 0, bool UseFillExpr = false,
-                       unsigned FillValue = 0) const;
+                       unsigned ForcedAlignBits = 0) const;
 
     /// printLabel - This method prints a local label used by debug and
     /// exception handling tables.
@@ -317,6 +318,7 @@
     /// printBasicBlockLabel - This method prints the label for the specified
     /// MachineBasicBlock
     virtual void printBasicBlockLabel(const MachineBasicBlock *MBB,
+                                      bool printAlign = false,
                                       bool printColon = false,
                                       bool printComment = true) const;
                                       
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index d2b1d5f..66de06d 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -75,6 +75,10 @@
   /// LiveIns - Keep track of the physical registers that are livein of
   /// the basicblock.
   std::vector<unsigned> LiveIns;
+
+  /// Alignment - Alignment of the basic block. Zero if the basic block does
+  /// not need to be aligned.
+  unsigned Alignment;
   
   /// IsLandingPad - Indicate that this basic block is entered via an
   /// exception handler.
@@ -82,7 +86,8 @@
 
 public:
   explicit MachineBasicBlock(const BasicBlock *bb = 0)
-    : Prev(0), Next(0), BB(bb), Number(-1), xParent(0), IsLandingPad(false) {
+    : Prev(0), Next(0), BB(bb), Number(-1), xParent(0),
+      Alignment(0), IsLandingPad(false) {
     Insts.parent = this;
   }
 
@@ -181,6 +186,14 @@
   const_livein_iterator livein_end()   const { return LiveIns.end(); }
   bool            livein_empty() const { return LiveIns.empty(); }
 
+  /// getAlignment - Return alignment of the basic block.
+  ///
+  unsigned getAlignment() const { return Alignment; }
+
+  /// setAlignment - Set alignment of the basic block.
+  ///
+  void setAlignment(unsigned Align) { Alignment = Align; }
+
   /// isLandingPad - Returns true if the block is a landing pad. That is
   /// this basic block is entered via an exception handler.
   bool isLandingPad() const { return IsLandingPad; }
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 3a04325..4cc9073 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -204,7 +204,7 @@
   }
 
   /// getObjectAlignment - Return the alignment of the specified stack object...
-  int getObjectAlignment(int ObjectIdx) const {
+  unsigned getObjectAlignment(int ObjectIdx) const {
     assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
            "Invalid Object Idx!");
     return Objects[ObjectIdx+NumFixedObjects].Alignment;
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index be7857c..5218f7a 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -129,6 +129,10 @@
   /// IfConverter Pass - This pass performs machine code if conversion.
   FunctionPass *createIfConverterPass();
 
+  /// LoopAligner Pass - This pass aligns loop headers to target specific
+  /// alignment boundary.
+  FunctionPass *createLoopAlignerPass();
+
   /// DebugLabelFoldingPass - This pass prunes out redundant debug labels.  This
   /// allows a debug emitter to determine if the range of two labels is empty,
   /// by seeing if the labels map to the same reduced label.
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index 8597e40..f1d29ac 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -164,6 +164,10 @@
     /// boundary.
     bool AlignmentIsInBytes;              // Defaults to true
 
+    /// TextAlignFillValue - If non-zero, this is used to fill the executable
+    /// space created as the result of a alignment directive.
+    unsigned TextAlignFillValue;
+
     //===--- Section Switching Directives ---------------------------------===//
     
     /// SwitchToSectionDirective - This is the directive used when we want to
@@ -503,6 +507,9 @@
     bool getAlignmentIsInBytes() const {
       return AlignmentIsInBytes;
     }
+    unsigned getTextAlignFillValue() const {
+      return TextAlignFillValue;
+    }
     const char *getSwitchToSectionDirective() const {
       return SwitchToSectionDirective;
     }
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index b010a69..4f04ce3 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -548,17 +548,23 @@
 
   /// getIfCvtBlockLimit - returns the target specific if-conversion block size
   /// limit. Any block whose size is greater should not be predicated.
-  virtual unsigned getIfCvtBlockSizeLimit() const {
+  unsigned getIfCvtBlockSizeLimit() const {
     return IfCvtBlockSizeLimit;
   }
 
   /// getIfCvtDupBlockLimit - returns the target specific size limit for a
   /// block to be considered for duplication. Any block whose size is greater
   /// should not be duplicated to facilitate its predication.
-  virtual unsigned getIfCvtDupBlockSizeLimit() const {
+  unsigned getIfCvtDupBlockSizeLimit() const {
     return IfCvtDupBlockSizeLimit;
   }
 
+  /// getPrefLoopAlignment - return the preferred loop alignment.
+  ///
+  unsigned getPrefLoopAlignment() const {
+    return PrefLoopAlignment;
+  }
+  
   /// getPreIndexedAddressParts - returns true by value, base pointer and
   /// offset pointer and addressing mode by reference if the node's address
   /// can be legally represented as pre-indexed load / store address.
@@ -583,7 +589,7 @@
   /// jumptable.
   virtual SDOperand getPICJumpTableRelocBase(SDOperand Table,
                                              SelectionDAG &DAG) const;
-  
+
   //===--------------------------------------------------------------------===//
   // TargetLowering Optimization Methods
   //
@@ -890,6 +896,12 @@
   void setIfCvtDupBlockSizeLimit(unsigned Limit) {
     IfCvtDupBlockSizeLimit = Limit;
   }
+
+  /// setPrefLoopAlignment - Set the target's preferred loop alignment. Default
+  /// alignment is zero, it means the target does not care about loop alignment.
+  void setPrefLoopAlignment(unsigned Align) {
+    PrefLoopAlignment = Align;
+  }
   
 public:
 
@@ -1276,6 +1288,10 @@
   /// duplicated during if-conversion.
   unsigned IfCvtDupBlockSizeLimit;
 
+  /// PrefLoopAlignment - The perferred loop alignment.
+  ///
+  unsigned PrefLoopAlignment;
+
   /// StackPointerRegisterToSaveRestore - If set to a physical register, this
   /// specifies the register that llvm.savestack/llvm.restorestack should save
   /// and restore.