Refactor TargetMachine, pushing handling of TargetData into the target-specific subclasses.  This has one caller-visible change: getTargetData() now returns a pointer instead of a reference.

This fixes PR 759.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28074 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Alpha/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AlphaAsmPrinter.cpp
index b078b68..74af78e 100644
--- a/lib/Target/Alpha/AlphaAsmPrinter.cpp
+++ b/lib/Target/Alpha/AlphaAsmPrinter.cpp
@@ -221,7 +221,7 @@
 }
 
 bool AlphaAsmPrinter::doFinalization(Module &M) {
-  const TargetData &TD = TM.getTargetData();
+  const TargetData *TD = TM.getTargetData();
 
   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
     if (I->hasInitializer()) {   // External global require no code
@@ -232,8 +232,8 @@
       O << "\n\n";
       std::string name = Mang->getValueName(I);
       Constant *C = I->getInitializer();
-      unsigned Size = TD.getTypeSize(C->getType());
-      //      unsigned Align = TD.getTypeAlignmentShift(C->getType());
+      unsigned Size = TD->getTypeSize(C->getType());
+      //      unsigned Align = TD->getTypeAlignmentShift(C->getType());
       unsigned Align = getPreferredAlignmentLog(I);
 
       if (C->isNullValue() &&
@@ -243,7 +243,7 @@
         if (I->hasInternalLinkage())
           O << "\t.local " << name << "\n";
 
-        O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
+        O << "\t.comm " << name << "," << TD->getTypeSize(C->getType())
           << "," << (1 << Align)
           <<  "\n";
       } else {
diff --git a/lib/Target/Alpha/AlphaTargetMachine.cpp b/lib/Target/Alpha/AlphaTargetMachine.cpp
index 709669f..2970f82 100644
--- a/lib/Target/Alpha/AlphaTargetMachine.cpp
+++ b/lib/Target/Alpha/AlphaTargetMachine.cpp
@@ -54,7 +54,8 @@
 }
 
 AlphaTargetMachine::AlphaTargetMachine(const Module &M, const std::string &FS)
-  : TargetMachine("alpha", true),
+  : TargetMachine("alpha"),
+    DataLayout("alpha", true),
     FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
     JITInfo(*this),
     Subtarget(M, FS)
diff --git a/lib/Target/Alpha/AlphaTargetMachine.h b/lib/Target/Alpha/AlphaTargetMachine.h
index 8f6caeb..6e23868 100644
--- a/lib/Target/Alpha/AlphaTargetMachine.h
+++ b/lib/Target/Alpha/AlphaTargetMachine.h
@@ -26,11 +26,12 @@
 class GlobalValue;
 
 class AlphaTargetMachine : public TargetMachine {
+  const TargetData DataLayout;       // Calculates type size & alignment
   AlphaInstrInfo InstrInfo;
   TargetFrameInfo FrameInfo;
   AlphaJITInfo JITInfo;
   AlphaSubtarget Subtarget;
-
+  
 public:
   AlphaTargetMachine(const Module &M, const std::string &FS);
 
@@ -40,6 +41,7 @@
   virtual const MRegisterInfo *getRegisterInfo() const {
     return &InstrInfo.getRegisterInfo();
   }
+  virtual const TargetData       *getTargetData() const { return &DataLayout; }
   virtual TargetJITInfo* getJITInfo() {
     return &JITInfo;
   }
diff --git a/lib/Target/CBackend/CTargetMachine.h b/lib/Target/CBackend/CTargetMachine.h
index f947f65..271a2bf 100644
--- a/lib/Target/CBackend/CTargetMachine.h
+++ b/lib/Target/CBackend/CTargetMachine.h
@@ -19,8 +19,11 @@
 namespace llvm {
 
 struct CTargetMachine : public TargetMachine {
+  const TargetData DataLayout;       // Calculates type size & alignment
+
   CTargetMachine(const Module &M, const std::string &FS)
-    : TargetMachine("CBackend", M) {}
+    : TargetMachine("CBackend", M),
+      DataLayout("CBackend") {}
 
   // This is the only thing that actually does anything here.
   virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
@@ -28,6 +31,8 @@
 
   // This class always works, but shouldn't be the default in most cases.
   static unsigned getModuleMatchQuality(const Module &M) { return 1; }
+  
+  virtual const TargetData       *getTargetData() const { return &DataLayout; }
 };
 
 } // End llvm namespace
diff --git a/lib/Target/IA64/IA64AsmPrinter.cpp b/lib/Target/IA64/IA64AsmPrinter.cpp
index 7caf573..d7f2fe1 100644
--- a/lib/Target/IA64/IA64AsmPrinter.cpp
+++ b/lib/Target/IA64/IA64AsmPrinter.cpp
@@ -277,7 +277,7 @@
 }
 
 bool IA64AsmPrinter::doFinalization(Module &M) {
-  const TargetData &TD = TM.getTargetData();
+  const TargetData *TD = TM.getTargetData();
   
   // Print out module-level global variables here.
   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
@@ -290,19 +290,19 @@
       O << "\n\n";
       std::string name = Mang->getValueName(I);
       Constant *C = I->getInitializer();
-      unsigned Size = TD.getTypeSize(C->getType());
-      unsigned Align = TD.getTypeAlignmentShift(C->getType());
+      unsigned Size = TD->getTypeSize(C->getType());
+      unsigned Align = TD->getTypeAlignmentShift(C->getType());
       
       if (C->isNullValue() &&
           (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
            I->hasWeakLinkage() /* FIXME: Verify correct */)) {
         SwitchSection(".data", I);
         if (I->hasInternalLinkage()) {
-          O << "\t.lcomm " << name << "#," << TD.getTypeSize(C->getType())
+          O << "\t.lcomm " << name << "#," << TD->getTypeSize(C->getType())
           << "," << (1 << Align);
           O << "\t\t// ";
         } else {
-          O << "\t.common " << name << "#," << TD.getTypeSize(C->getType())
+          O << "\t.common " << name << "#," << TD->getTypeSize(C->getType())
           << "," << (1 << Align);
           O << "\t\t// ";
         }
diff --git a/lib/Target/IA64/IA64TargetMachine.cpp b/lib/Target/IA64/IA64TargetMachine.cpp
index a03bda7..8e31a38 100644
--- a/lib/Target/IA64/IA64TargetMachine.cpp
+++ b/lib/Target/IA64/IA64TargetMachine.cpp
@@ -76,7 +76,7 @@
 /// IA64TargetMachine ctor - Create an LP64 architecture model
 ///
 IA64TargetMachine::IA64TargetMachine(const Module &M, const std::string &FS)
-  : TargetMachine("IA64", true),
+  : TargetMachine("IA64"), DataLayout("IA64", true),
     FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
     TLInfo(*this) { // FIXME? check this stuff
 }
diff --git a/lib/Target/IA64/IA64TargetMachine.h b/lib/Target/IA64/IA64TargetMachine.h
index 7b9342e..ad5c057 100644
--- a/lib/Target/IA64/IA64TargetMachine.h
+++ b/lib/Target/IA64/IA64TargetMachine.h
@@ -23,6 +23,7 @@
 namespace llvm {
 
 class IA64TargetMachine : public TargetMachine {
+  const TargetData DataLayout;       // Calculates type size & alignment
   IA64InstrInfo      InstrInfo;
   TargetFrameInfo    FrameInfo;
   //IA64JITInfo      JITInfo;
@@ -36,6 +37,7 @@
   virtual const MRegisterInfo    *getRegisterInfo() const {
     return &InstrInfo.getRegisterInfo();
   }
+  virtual const TargetData       *getTargetData() const { return &DataLayout; }
 
   virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
                                    CodeGenFileType FileType, bool Fast);
diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp
index f3a0311..cfcf4df 100644
--- a/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -582,7 +582,7 @@
 }
 
 bool DarwinAsmPrinter::doFinalization(Module &M) {
-  const TargetData &TD = TM.getTargetData();
+  const TargetData *TD = TM.getTargetData();
 
   // Print out module-level global variables here.
   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
@@ -595,7 +595,7 @@
     
     std::string name = Mang->getValueName(I);
     Constant *C = I->getInitializer();
-    unsigned Size = TD.getTypeSize(C->getType());
+    unsigned Size = TD->getTypeSize(C->getType());
     unsigned Align = getPreferredAlignmentLog(I);
 
     if (C->isNullValue() && /* FIXME: Verify correct */
@@ -761,7 +761,7 @@
 
 bool AIXAsmPrinter::doInitialization(Module &M) {
   SwitchSection("", 0);
-  const TargetData &TD = TM.getTargetData();
+  const TargetData *TD = TM.getTargetData();
 
   O << "\t.machine \"ppc64\"\n"
     << "\t.toc\n"
@@ -810,7 +810,7 @@
 }
 
 bool AIXAsmPrinter::doFinalization(Module &M) {
-  const TargetData &TD = TM.getTargetData();
+  const TargetData *TD = TM.getTargetData();
   // Print out module-level global variables
   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
        I != E; ++I) {
@@ -821,8 +821,8 @@
     if (I->hasInternalLinkage()) {
       O << "\t.lcomm " << Name << ",16,_global.bss_c";
     } else {
-      O << "\t.comm " << Name << "," << TD.getTypeSize(I->getType())
-        << "," << Log2_32((unsigned)TD.getTypeAlignment(I->getType()));
+      O << "\t.comm " << Name << "," << TD->getTypeSize(I->getType())
+        << "," << Log2_32((unsigned)TD->getTypeAlignment(I->getType()));
     }
     O << "\t\t" << CommentString << " ";
     WriteAsOperand(O, I, false, true, &M);
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index d35ceb1..fd9df20 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -58,7 +58,8 @@
 }
 
 PPCTargetMachine::PPCTargetMachine(const Module &M, const std::string &FS)
-: TargetMachine("PowerPC", false, 4, 4, 4, 4, 4, 4, 2, 1, 1),
+: TargetMachine("PowerPC"),
+  DataLayout("PowerPC", false, 4, 4, 4, 4, 4),
   Subtarget(M, FS), FrameInfo(*this, false), JITInfo(*this),
   TLInfo(*this), InstrItins(Subtarget.getInstrItineraryData()) {
   if (TargetDefault == PPCTarget) {
diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h
index 3b2e481..e4893a8 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/lib/Target/PowerPC/PPCTargetMachine.h
@@ -26,6 +26,7 @@
 class GlobalValue;
 
 class PPCTargetMachine : public TargetMachine {
+  const TargetData DataLayout;       // Calculates type size & alignment
   PPCInstrInfo           InstrInfo;
   PPCSubtarget           Subtarget;
   PPCFrameInfo           FrameInfo;
@@ -43,6 +44,7 @@
   virtual const MRegisterInfo    *getRegisterInfo() const {
     return &InstrInfo.getRegisterInfo();
   }
+  virtual const TargetData       *getTargetData() const { return &DataLayout; }
   virtual const InstrItineraryData getInstrItineraryData() const {  
     return InstrItins;
   }
diff --git a/lib/Target/Sparc/SparcAsmPrinter.cpp b/lib/Target/Sparc/SparcAsmPrinter.cpp
index b4c40f1..7033ab9 100644
--- a/lib/Target/Sparc/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/SparcAsmPrinter.cpp
@@ -232,7 +232,7 @@
 }
 
 bool SparcAsmPrinter::doFinalization(Module &M) {
-  const TargetData &TD = TM.getTargetData();
+  const TargetData *TD = TM.getTargetData();
 
   // Print out module-level global variables here.
   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
@@ -245,8 +245,8 @@
       O << "\n\n";
       std::string name = Mang->getValueName(I);
       Constant *C = I->getInitializer();
-      unsigned Size = TD.getTypeSize(C->getType());
-      unsigned Align = TD.getTypeAlignment(C->getType());
+      unsigned Size = TD->getTypeSize(C->getType());
+      unsigned Align = TD->getTypeAlignment(C->getType());
 
       if (C->isNullValue() &&
           (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
@@ -255,8 +255,8 @@
         if (I->hasInternalLinkage())
           O << "\t.local " << name << "\n";
 
-        O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
-          << "," << (unsigned)TD.getTypeAlignment(C->getType());
+        O << "\t.comm " << name << "," << TD->getTypeSize(C->getType())
+          << "," << (unsigned)TD->getTypeAlignment(C->getType());
         O << "\t\t! ";
         WriteAsOperand(O, I, true, true, &M);
         O << "\n";
diff --git a/lib/Target/Sparc/SparcTargetMachine.cpp b/lib/Target/Sparc/SparcTargetMachine.cpp
index 2b56be2..ad72cf7 100644
--- a/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -31,7 +31,8 @@
 /// SparcTargetMachine ctor - Create an ILP32 architecture model
 ///
 SparcTargetMachine::SparcTargetMachine(const Module &M, const std::string &FS)
-  : TargetMachine("Sparc", false, 4, 4),
+  : TargetMachine("Sparc"),
+    DataLayout("Sparc", false, 4, 4),
     Subtarget(M, FS), InstrInfo(Subtarget),
     FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
 }
diff --git a/lib/Target/Sparc/SparcTargetMachine.h b/lib/Target/Sparc/SparcTargetMachine.h
index 0cad652..7d30dd8 100644
--- a/lib/Target/Sparc/SparcTargetMachine.h
+++ b/lib/Target/Sparc/SparcTargetMachine.h
@@ -25,6 +25,7 @@
 class Module;
 
 class SparcTargetMachine : public TargetMachine {
+  const TargetData DataLayout;       // Calculates type size & alignment
   SparcSubtarget Subtarget;
   SparcInstrInfo InstrInfo;
   TargetFrameInfo FrameInfo;
@@ -37,7 +38,7 @@
   virtual const MRegisterInfo *getRegisterInfo() const {
     return &InstrInfo.getRegisterInfo();
   }
-
+  virtual const TargetData       *getTargetData() const { return &DataLayout; }
   static unsigned getModuleMatchQuality(const Module &M);
 
   virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp
index 74c90ed..24e1e5a 100644
--- a/lib/Target/TargetMachine.cpp
+++ b/lib/Target/TargetMachine.cpp
@@ -69,23 +69,9 @@
 //---------------------------------------------------------------------------
 // TargetMachine Class
 //
-TargetMachine::TargetMachine(const std::string &name, bool LittleEndian,
-                             unsigned char PtrSize, unsigned char PtrAl,
-                             unsigned char DoubleAl, unsigned char FloatAl,
-                             unsigned char LongAl, unsigned char IntAl,
-                             unsigned char ShortAl, unsigned char ByteAl,
-                             unsigned char BoolAl)
-  : Name(name), DataLayout(name, LittleEndian,
-                           PtrSize, PtrAl, DoubleAl, FloatAl, LongAl,
-                           IntAl, ShortAl, ByteAl, BoolAl) {
-}
-
-TargetMachine::TargetMachine(const std::string &name, const TargetData &TD)
-  : Name(name), DataLayout(TD) {
-}
 
 TargetMachine::TargetMachine(const std::string &name, const Module &M)
-  : Name(name), DataLayout(name, &M) {
+  : Name(name) {
 }
 
 TargetMachine::~TargetMachine() {
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index f12ba51..02df983 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -84,7 +84,7 @@
 }
 
 bool X86SharedAsmPrinter::doFinalization(Module &M) {
-  const TargetData &TD = TM.getTargetData();
+  const TargetData *TD = TM.getTargetData();
 
   // Print out module-level global variables here.
   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
@@ -97,7 +97,7 @@
     
     std::string name = Mang->getValueName(I);
     Constant *C = I->getInitializer();
-    unsigned Size = TD.getTypeSize(C->getType());
+    unsigned Size = TD->getTypeSize(C->getType());
     unsigned Align = getPreferredAlignmentLog(I);
 
     if (C->isNullValue() && /* FIXME: Verify correct */
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 9677645..7186fe5 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -3522,7 +3522,7 @@
   if ((Align & 3) != 0 ||
       (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) {
     MVT::ValueType IntPtr = getPointerTy();
-    const Type *IntPtrTy = getTargetData().getIntPtrType();
+    const Type *IntPtrTy = getTargetData()->getIntPtrType();
     std::vector<std::pair<SDOperand, const Type*> > Args;
     Args.push_back(std::make_pair(Op.getOperand(1), IntPtrTy));
     // Extend the ubyte argument to be an int value for the call.
@@ -3655,7 +3655,7 @@
   if ((Align & 3) != 0 ||
       (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) {
     MVT::ValueType IntPtr = getPointerTy();
-    const Type *IntPtrTy = getTargetData().getIntPtrType();
+    const Type *IntPtrTy = getTargetData()->getIntPtrType();
     std::vector<std::pair<SDOperand, const Type*> > Args;
     Args.push_back(std::make_pair(Op.getOperand(1), IntPtrTy));
     Args.push_back(std::make_pair(Op.getOperand(2), IntPtrTy));
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index b9dea3b..4791f02 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -68,7 +68,8 @@
 /// X86TargetMachine ctor - Create an ILP32 architecture model
 ///
 X86TargetMachine::X86TargetMachine(const Module &M, const std::string &FS)
-  : TargetMachine("X86", true, 4, 4, 4, 4, 4),
+  : TargetMachine("X86"),
+    DataLayout("X86", true, 4, 4, 4, 4, 4),
     Subtarget(M, FS),
     FrameInfo(TargetFrameInfo::StackGrowsDown,
               Subtarget.getStackAlignment(), -4),
diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h
index 4ad0722..2fe0173 100644
--- a/lib/Target/X86/X86TargetMachine.h
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -26,6 +26,7 @@
 namespace llvm {
 
 class X86TargetMachine : public TargetMachine {
+  const TargetData DataLayout;       // Calculates type size & alignment
   X86InstrInfo      InstrInfo;
   X86Subtarget      Subtarget;
   TargetFrameInfo   FrameInfo;
@@ -42,6 +43,7 @@
   virtual const MRegisterInfo    *getRegisterInfo() const {
     return &InstrInfo.getRegisterInfo();
   }
+  virtual const TargetData       *getTargetData() const { return &DataLayout; }
 
   virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
                                           MachineCodeEmitter &MCE);