[llvm-commits] [llvm] r47703 - in /llvm/trunk: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/CellSPU/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Targe
Lauro Ramos Venancio
lauro.venancio at gmail.com
Thu Feb 28 14:29:16 PST 2008
Thanks, Evan.
I think I found the problem.
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080225/058956.html
Lauro
2008/2/28, Evan Cheng <evan.cheng at apple.com>:
> They are not failing on Mac OS X so it's probably target / platform
> specific. Can you tell me how they are failing?
>
>
> Evan
>
>
> On Feb 28, 2008, at 10:45 AM, Lauro Ramos Venancio wrote:
>
> > Hi Evan,
> >
> > This patch caused many regressions. See
> > http://lists.cs.uiuc.edu/pipermail/llvm-testresults/2008-February/008336.html
> >
> > Lauro
> >
> > 2008/2/27, Evan Cheng <evan.cheng at apple.com>:
> >> Author: evancheng
> >> Date: Wed Feb 27 18:43:03 2008
> >> New Revision: 47703
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=47703&view=rev
> >> Log:
> >> Add a quick and dirty "loop aligner pass". x86 uses it to align its
> >> loops to 16-byte boundaries.
> >>
> >> Added:
> >> llvm/trunk/lib/CodeGen/LoopAligner.cpp
> >> Modified:
> >> llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
> >> llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
> >> llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h
> >> llvm/trunk/include/llvm/CodeGen/Passes.h
> >> llvm/trunk/include/llvm/Target/TargetAsmInfo.h
> >> llvm/trunk/include/llvm/Target/TargetLowering.h
> >> llvm/trunk/lib/CodeGen/AsmPrinter.cpp
> >> llvm/trunk/lib/CodeGen/BranchFolding.cpp
> >> llvm/trunk/lib/CodeGen/IfConversion.cpp
> >> llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp
> >> llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
> >> llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
> >> llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp
> >> llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp
> >> llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp
> >> llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
> >> llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
> >> llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp
> >> llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp
> >> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> >> llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp
> >> llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp
> >> llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
> >> llvm/trunk/lib/Target/X86/X86TargetMachine.h
> >>
> >> Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original)
> >> +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Wed Feb 27
> >> 18:43:03 2008
> >> @@ -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;
> >>
> >>
> >> Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original)
> >> +++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Wed Feb 27
> >> 18:43:03 2008
> >> @@ -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; }
> >>
> >> Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h (original)
> >> +++ llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Wed Feb 27
> >> 18:43:03 2008
> >> @@ -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;
> >>
> >> Modified: llvm/trunk/include/llvm/CodeGen/Passes.h
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/include/llvm/CodeGen/Passes.h (original)
> >> +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 27 18:43:03 2008
> >> @@ -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.
> >>
> >> Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original)
> >> +++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Wed Feb 27
> >> 18:43:03 2008
> >> @@ -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;
> >> }
> >>
> >> Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
> >> +++ llvm/trunk/include/llvm/Target/TargetLowering.h Wed Feb 27
> >> 18:43:03 2008
> >> @@ -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.
> >>
> >> Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Wed Feb 27 18:43:03 2008
> >> @@ -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';
> >> }
> >>
> >> Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original)
> >> +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Feb 27 18:43:03 2008
> >> @@ -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) {
> >>
> >> Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/CodeGen/IfConversion.cpp (original)
> >> +++ llvm/trunk/lib/CodeGen/IfConversion.cpp Wed Feb 27 18:43:03 2008
> >> @@ -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.
> >>
> >> Added: llvm/trunk/lib/CodeGen/LoopAligner.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LoopAligner.cpp?rev=47703&view=auto
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/CodeGen/LoopAligner.cpp (added)
> >> +++ llvm/trunk/lib/CodeGen/LoopAligner.cpp Wed Feb 27 18:43:03 2008
> >> @@ -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;
> >> +}
> >>
> >> Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original)
> >> +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -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";
> >>
> >>
> >> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
> >> +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Wed Feb
> >> 27 18:43:03 2008
> >> @@ -206,6 +206,8 @@
> >> JumpBufSize = 0;
> >> JumpBufAlignment = 0;
> >> IfCvtBlockSizeLimit = 2;
> >> + IfCvtDupBlockSizeLimit = 0;
> >> + PrefLoopAlignment = 0;
> >>
> >> InitLibcallNames(LibcallRoutineNames);
> >> InitCmpLibcallCCs(CmpLibcallCCs);
> >>
> >> Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Wed Feb 27 18:43:03
> >> 2008
> >> @@ -248,7 +248,7 @@
> >> I != E; ++I) {
> >> // Print a label for the basic block.
> >> if (I != MF.begin()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >> for (MachineBasicBlock::const_iterator II = I->begin(), E = I-
> >> >end();
> >> @@ -710,13 +710,13 @@
> >> << '_' << JTI << '_' << MO2.getImm()
> >> << "_set_" << MBB->getNumber();
> >> else if (TM.getRelocationModel() == Reloc::PIC_) {
> >> - printBasicBlockLabel(MBB, false, false);
> >> + printBasicBlockLabel(MBB, false, false, false);
> >> // If the arch uses custom Jump Table directives, don't calc
> >> relative to JT
> >> if (!TAI->getJumpTableDirective())
> >> O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
> >> << getFunctionNumber() << '_' << JTI << '_' <<
> >> MO2.getImm();
> >> } else
> >> - printBasicBlockLabel(MBB, false, false);
> >> + printBasicBlockLabel(MBB, false, false, false);
> >> if (i != e-1)
> >> O << '\n';
> >> }
> >>
> >> Modified: llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/Target/Alpha/AlphaAsmPrinter.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -171,7 +171,7 @@
> >> for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
> >> I != E; ++I) {
> >> if (I != MF.begin()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >> for (MachineBasicBlock::const_iterator II = I->begin(), E = I-
> >> >end();
> >>
> >> Modified: llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -460,7 +460,7 @@
> >> I != E; ++I) {
> >> // Print a label for the basic block.
> >> if (I != MF.begin()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >> for (MachineBasicBlock::const_iterator II = I->begin(), E = I-
> >> >end();
> >>
> >> Modified: llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/Target/IA64/IA64AsmPrinter.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -149,7 +149,7 @@
> >> I != E; ++I) {
> >> // Print a label for the basic block if there are any
> >> predecessors.
> >> if (!I->pred_empty()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >> for (MachineBasicBlock::const_iterator II = I->begin(), E = I-
> >> >end();
> >>
> >> Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -297,7 +297,7 @@
> >>
> >> // Print a label for the basic block.
> >> if (I != MF.begin()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >>
> >>
> >> Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -604,7 +604,7 @@
> >> I != E; ++I) {
> >> // Print a label for the basic block.
> >> if (I != MF.begin()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >> for (MachineBasicBlock::const_iterator II = I->begin(), E = I-
> >> >end();
> >> @@ -838,7 +838,7 @@
> >> I != E; ++I) {
> >> // Print a label for the basic block.
> >> if (I != MF.begin()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >> for (MachineBasicBlock::const_iterator II = I->begin(), IE = I-
> >> >end();
> >>
> >> Modified: llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -116,7 +116,7 @@
> >> I != E; ++I) {
> >> // Print a label for the basic block.
> >> if (I != MF.begin()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >> for (MachineBasicBlock::const_iterator II = I->begin(), E = I-
> >> >end();
> >>
> >> Modified: llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -101,36 +101,25 @@
> >> switch (F->getLinkage()) {
> >> default: assert(0 && "Unknown linkage type!");
> >> case Function::InternalLinkage: // Symbols default to internal.
> >> - if (Subtarget->isTargetDarwin())
> >> - // FIXME: This should be parameterized somewhere.
> >> - EmitAlignment(4, F, 0, true, 0x90);
> >> - else
> >> - EmitAlignment(4, F);
> >> + EmitAlignment(4, F);
> >> break;
> >> case Function::DLLExportLinkage:
> >> DLLExportedFns.insert(Mang->makeNameProper(F->getName(), ""));
> >> //FALLS THROUGH
> >> case Function::ExternalLinkage:
> >> - if (Subtarget->isTargetDarwin())
> >> - // FIXME: This should be parameterized somewhere.
> >> - EmitAlignment(4, F, 0, true, 0x90);
> >> - else
> >> - EmitAlignment(4, F);
> >> + EmitAlignment(4, F);
> >> O << "\t.globl\t" << CurrentFnName << "\n";
> >> break;
> >> case Function::LinkOnceLinkage:
> >> case Function::WeakLinkage:
> >> + EmitAlignment(4, F);
> >> if (Subtarget->isTargetDarwin()) {
> >> - // FIXME: This should be parameterized somewhere.
> >> - EmitAlignment(4, F, 0, true, 0x90);
> >> O << "\t.globl\t" << CurrentFnName << "\n";
> >> O << TAI->getWeakDefDirective() << CurrentFnName << "\n";
> >> } else if (Subtarget->isTargetCygMing()) {
> >> - EmitAlignment(4, F);
> >> O << "\t.globl\t" << CurrentFnName << "\n";
> >> O << "\t.linkonce discard\n";
> >> } else {
> >> - EmitAlignment(4, F);
> >> O << "\t.weak\t" << CurrentFnName << "\n";
> >> }
> >> break;
> >> @@ -180,7 +169,7 @@
> >> I != E; ++I) {
> >> // Print a label for the basic block.
> >> if (!I->pred_empty()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >> for (MachineBasicBlock::const_iterator II = I->begin(), IE = I-
> >> >end();
> >> @@ -515,7 +504,7 @@
> >>
> >> O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix()
> >> << getFunctionNumber() << '_' << uid << "_set_" << MBB-
> >> >getNumber() << ',';
> >> - printBasicBlockLabel(MBB, false, false);
> >> + printBasicBlockLabel(MBB, false, false, false);
> >> if (Subtarget->isPICStyleRIPRel())
> >> O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" <<
> >> getFunctionNumber()
> >> << '_' << uid << '\n';
> >> @@ -543,12 +532,12 @@
> >> O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
> >> << '_' << uid << "_set_" << MBB->getNumber();
> >> } else if (Subtarget->isPICStyleGOT()) {
> >> - printBasicBlockLabel(MBB, false, false);
> >> + printBasicBlockLabel(MBB, false, false, false);
> >> O << "@GOTOFF";
> >> } else
> >> assert(0 && "Don't know how to print MBB label for this PIC
> >> mode");
> >> } else
> >> - printBasicBlockLabel(MBB, false, false);
> >> + printBasicBlockLabel(MBB, false, false, false);
> >> }
> >>
> >> bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO,
> >>
> >> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> >> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -714,6 +714,7 @@
> >> maxStoresPerMemcpy = 16; // For %llvm.memcpy -> sequence of stores
> >> maxStoresPerMemmove = 16; // For %llvm.memmove -> sequence of
> >> stores
> >> allowUnalignedMemoryAccesses = true; // x86 supports it!
> >> + setPrefLoopAlignment(16);
> >> }
> >>
> >> /// getMaxByValAlign - Helper for getByValTypeAlignment to determine
> >>
> >> Modified: llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp (original)
> >> +++ llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -78,7 +78,7 @@
> >> I != E; ++I) {
> >> // Print a label for the basic block if there are any
> >> predecessors.
> >> if (!I->pred_empty()) {
> >> - printBasicBlockLabel(I, true);
> >> + printBasicBlockLabel(I, true, true);
> >> O << '\n';
> >> }
> >> for (MachineBasicBlock::const_iterator II = I->begin(), E = I-
> >> >end();
> >> @@ -242,7 +242,7 @@
> >>
> >> O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix()
> >> << getFunctionNumber() << '_' << uid << "_set_" << MBB-
> >> >getNumber() << ',';
> >> - printBasicBlockLabel(MBB, false, false);
> >> + printBasicBlockLabel(MBB, false, false, false);
> >> O << '-' << "\"L" << getFunctionNumber() << "$pb\"'\n";
> >> }
> >>
> >>
> >> Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original)
> >> +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -47,6 +47,7 @@
> >> switch (Subtarget->TargetType) {
> >> case X86Subtarget::isDarwin:
> >> AlignmentIsInBytes = false;
> >> + TextAlignFillValue = 0x90;
> >> GlobalPrefix = "_";
> >> if (!Subtarget->is64Bit())
> >> Data64bitsDirective = 0; // we can't emit a 64-bit unit
> >>
> >> Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp (original)
> >> +++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Wed Feb 27
> >> 18:43:03 2008
> >> @@ -164,6 +164,13 @@
> >> return true; // -print-machineinstr should print after this.
> >> }
> >>
> >> +bool X86TargetMachine::addPreEmitPass(FunctionPassManager &PM,
> >> bool Fast) {
> >> + if (Fast) return false;
> >> +
> >> + PM.add(createLoopAlignerPass());
> >> + return true;
> >> +}
> >> +
> >> bool X86TargetMachine::addAssemblyEmitter(FunctionPassManager &PM,
> >> bool Fast,
> >> std::ostream &Out) {
> >> PM.add(createX86CodePrinterPass(Out, *this));
> >>
> >> Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.h
> >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.h?rev=47703&r1=47702&r2=47703&view=diff
> >>
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =
> >> =====================================================================
> >> --- llvm/trunk/lib/Target/X86/X86TargetMachine.h (original)
> >> +++ llvm/trunk/lib/Target/X86/X86TargetMachine.h Wed Feb 27
> >> 18:43:03 2008
> >> @@ -63,6 +63,7 @@
> >> // Set up the pass pipeline.
> >> virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
> >> virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast);
> >> + virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
> >> virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
> >> std::ostream &Out);
> >> virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
> >>
> >>
> >> _______________________________________________
> >> llvm-commits mailing list
> >> llvm-commits at cs.uiuc.edu
> >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> >>
>
>
More information about the llvm-commits
mailing list