[llvm-commits] [llvm] r61345 - in /llvm/trunk: include/llvm/CodeGen/AsmPrinter.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Dan Gohman gohman at apple.com
Mon Dec 22 13:14:27 PST 2008


Author: djg
Date: Mon Dec 22 15:14:27 2008
New Revision: 61345

URL: http://llvm.org/viewvc/llvm-project?rev=61345&view=rev
Log:
Refactor a bunch of code out of AsmPrinter::EmitGlobalConstant into separate
functions.

Modified:
    llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=61345&r1=61344&r2=61345&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Mon Dec 22 15:14:27 2008
@@ -25,6 +25,9 @@
   class GCStrategy;
   class Constant;
   class ConstantArray;
+  class ConstantInt;
+  class ConstantStruct;
+  class ConstantVector;
   class GCMetadataPrinter;
   class GlobalVariable;
   class GlobalAlias;
@@ -369,6 +372,11 @@
     const GlobalValue *findGlobalValue(const Constant* CV);
     void EmitLLVMUsedList(Constant *List);
     void EmitXXStructorList(Constant *List);
+    void EmitGlobalConstantStruct(const ConstantStruct* CVS);
+    void EmitGlobalConstantArray(const ConstantArray* CVA);
+    void EmitGlobalConstantVector(const ConstantVector* CP);
+    void EmitGlobalConstantFP(const ConstantFP* CFP);
+    void EmitGlobalConstantLargeInt(const ConstantInt* CI);
     GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
   };
 }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=61345&r1=61344&r2=61345&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Dec 22 15:14:27 2008
@@ -939,206 +939,231 @@
   O << '\n';
 }
 
+void AsmPrinter::EmitGlobalConstantArray(const ConstantArray *CVA) {
+  if (CVA->isString()) {
+    EmitString(CVA);
+  } else { // Not a string.  Print the values in successive locations
+    for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i)
+      EmitGlobalConstant(CVA->getOperand(i));
+  }
+}
+
+void AsmPrinter::EmitGlobalConstantVector(const ConstantVector *CP) {
+  const VectorType *PTy = CP->getType();
+  
+  for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I)
+    EmitGlobalConstant(CP->getOperand(I));
+}
+
+void AsmPrinter::EmitGlobalConstantStruct(const ConstantStruct *CVS) {
+  // Print the fields in successive locations. Pad to align if needed!
+  const TargetData *TD = TM.getTargetData();
+  unsigned Size = TD->getABITypeSize(CVS->getType());
+  const StructLayout *cvsLayout = TD->getStructLayout(CVS->getType());
+  uint64_t sizeSoFar = 0;
+  for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) {
+    const Constant* field = CVS->getOperand(i);
+
+    // Check if padding is needed and insert one or more 0s.
+    uint64_t fieldSize = TD->getABITypeSize(field->getType());
+    uint64_t padSize = ((i == e-1 ? Size : cvsLayout->getElementOffset(i+1))
+                        - cvsLayout->getElementOffset(i)) - fieldSize;
+    sizeSoFar += fieldSize + padSize;
+
+    // Now print the actual field value.
+    EmitGlobalConstant(field);
+
+    // Insert padding - this may include padding to increase the size of the
+    // current field up to the ABI size (if the struct is not packed) as well
+    // as padding to ensure that the next field starts at the right offset.
+    EmitZeros(padSize);
+  }
+  assert(sizeSoFar == cvsLayout->getSizeInBytes() &&
+         "Layout of constant struct may be incorrect!");
+}
+
+void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP) {
+  // FP Constants are printed as integer constants to avoid losing
+  // precision...
+  const TargetData *TD = TM.getTargetData();
+  if (CFP->getType() == Type::DoubleTy) {
+    double Val = CFP->getValueAPF().convertToDouble();  // for comment only
+    uint64_t i = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
+    if (TAI->getData64bitsDirective())
+      O << TAI->getData64bitsDirective() << i << '\t'
+        << TAI->getCommentString() << " double value: " << Val << '\n';
+    else if (TD->isBigEndian()) {
+      O << TAI->getData32bitsDirective() << unsigned(i >> 32)
+        << '\t' << TAI->getCommentString()
+        << " double most significant word " << Val << '\n';
+      O << TAI->getData32bitsDirective() << unsigned(i)
+        << '\t' << TAI->getCommentString()
+        << " double least significant word " << Val << '\n';
+    } else {
+      O << TAI->getData32bitsDirective() << unsigned(i)
+        << '\t' << TAI->getCommentString()
+        << " double least significant word " << Val << '\n';
+      O << TAI->getData32bitsDirective() << unsigned(i >> 32)
+        << '\t' << TAI->getCommentString()
+        << " double most significant word " << Val << '\n';
+    }
+    return;
+  } else if (CFP->getType() == Type::FloatTy) {
+    float Val = CFP->getValueAPF().convertToFloat();  // for comment only
+    O << TAI->getData32bitsDirective()
+      << CFP->getValueAPF().bitcastToAPInt().getZExtValue()
+      << '\t' << TAI->getCommentString() << " float " << Val << '\n';
+    return;
+  } else if (CFP->getType() == Type::X86_FP80Ty) {
+    // all long double variants are printed as hex
+    // api needed to prevent premature destruction
+    APInt api = CFP->getValueAPF().bitcastToAPInt();
+    const uint64_t *p = api.getRawData();
+    // Convert to double so we can print the approximate val as a comment.
+    APFloat DoubleVal = CFP->getValueAPF();
+    bool ignored;
+    DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
+                      &ignored);
+    if (TD->isBigEndian()) {
+      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
+        << '\t' << TAI->getCommentString()
+        << " long double most significant halfword of ~"
+        << DoubleVal.convertToDouble() << '\n';
+      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32)
+        << '\t' << TAI->getCommentString()
+        << " long double next halfword\n";
+      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16)
+        << '\t' << TAI->getCommentString()
+        << " long double next halfword\n";
+      O << TAI->getData16bitsDirective() << uint16_t(p[0])
+        << '\t' << TAI->getCommentString()
+        << " long double next halfword\n";
+      O << TAI->getData16bitsDirective() << uint16_t(p[1])
+        << '\t' << TAI->getCommentString()
+        << " long double least significant halfword\n";
+     } else {
+      O << TAI->getData16bitsDirective() << uint16_t(p[1])
+        << '\t' << TAI->getCommentString()
+        << " long double least significant halfword of ~"
+        << DoubleVal.convertToDouble() << '\n';
+      O << TAI->getData16bitsDirective() << uint16_t(p[0])
+        << '\t' << TAI->getCommentString()
+        << " long double next halfword\n";
+      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16)
+        << '\t' << TAI->getCommentString()
+        << " long double next halfword\n";
+      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32)
+        << '\t' << TAI->getCommentString()
+        << " long double next halfword\n";
+      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
+        << '\t' << TAI->getCommentString()
+        << " long double most significant halfword\n";
+    }
+    EmitZeros(TD->getABITypeSize(Type::X86_FP80Ty) -
+              TD->getTypeStoreSize(Type::X86_FP80Ty));
+    return;
+  } else if (CFP->getType() == Type::PPC_FP128Ty) {
+    // all long double variants are printed as hex
+    // api needed to prevent premature destruction
+    APInt api = CFP->getValueAPF().bitcastToAPInt();
+    const uint64_t *p = api.getRawData();
+    if (TD->isBigEndian()) {
+      O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
+        << '\t' << TAI->getCommentString()
+        << " long double most significant word\n";
+      O << TAI->getData32bitsDirective() << uint32_t(p[0])
+        << '\t' << TAI->getCommentString()
+        << " long double next word\n";
+      O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
+        << '\t' << TAI->getCommentString()
+        << " long double next word\n";
+      O << TAI->getData32bitsDirective() << uint32_t(p[1])
+        << '\t' << TAI->getCommentString()
+        << " long double least significant word\n";
+     } else {
+      O << TAI->getData32bitsDirective() << uint32_t(p[1])
+        << '\t' << TAI->getCommentString()
+        << " long double least significant word\n";
+      O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
+        << '\t' << TAI->getCommentString()
+        << " long double next word\n";
+      O << TAI->getData32bitsDirective() << uint32_t(p[0])
+        << '\t' << TAI->getCommentString()
+        << " long double next word\n";
+      O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
+        << '\t' << TAI->getCommentString()
+        << " long double most significant word\n";
+    }
+    return;
+  } else assert(0 && "Floating point constant type not handled");
+}
+
+void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI) {
+  const TargetData *TD = TM.getTargetData();
+  unsigned BitWidth = CI->getBitWidth();
+  assert(isPowerOf2_32(BitWidth) &&
+         "Non-power-of-2-sized integers not handled!");
+
+  // We don't expect assemblers to support integer data directives
+  // for more than 64 bits, so we emit the data in at most 64-bit
+  // quantities at a time.
+  const uint64_t *RawData = CI->getValue().getRawData();
+  for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {
+    uint64_t Val;
+    if (TD->isBigEndian())
+      Val = RawData[e - i - 1];
+    else
+      Val = RawData[i];
+
+    if (TAI->getData64bitsDirective())
+      O << TAI->getData64bitsDirective() << Val << '\n';
+    else if (TD->isBigEndian()) {
+      O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+        << '\t' << TAI->getCommentString()
+        << " Double-word most significant word " << Val << '\n';
+      O << TAI->getData32bitsDirective() << unsigned(Val)
+        << '\t' << TAI->getCommentString()
+        << " Double-word least significant word " << Val << '\n';
+    } else {
+      O << TAI->getData32bitsDirective() << unsigned(Val)
+        << '\t' << TAI->getCommentString()
+        << " Double-word least significant word " << Val << '\n';
+      O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+        << '\t' << TAI->getCommentString()
+        << " Double-word most significant word " << Val << '\n';
+    }
+  }
+}
+
 /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
 void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
   const TargetData *TD = TM.getTargetData();
-  unsigned Size = TD->getABITypeSize(CV->getType());
+  const Type *type = CV->getType();
+  unsigned Size = TD->getABITypeSize(type);
 
   if (CV->isNullValue() || isa<UndefValue>(CV)) {
     EmitZeros(Size);
     return;
   } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
-    if (CVA->isString()) {
-      EmitString(CVA);
-    } else { // Not a string.  Print the values in successive locations
-      for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i)
-        EmitGlobalConstant(CVA->getOperand(i));
-    }
+    EmitGlobalConstantArray(CVA);
     return;
   } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
-    // Print the fields in successive locations. Pad to align if needed!
-    const StructLayout *cvsLayout = TD->getStructLayout(CVS->getType());
-    uint64_t sizeSoFar = 0;
-    for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) {
-      const Constant* field = CVS->getOperand(i);
-
-      // Check if padding is needed and insert one or more 0s.
-      uint64_t fieldSize = TD->getABITypeSize(field->getType());
-      uint64_t padSize = ((i == e-1 ? Size : cvsLayout->getElementOffset(i+1))
-                          - cvsLayout->getElementOffset(i)) - fieldSize;
-      sizeSoFar += fieldSize + padSize;
-
-      // Now print the actual field value.
-      EmitGlobalConstant(field);
-
-      // Insert padding - this may include padding to increase the size of the
-      // current field up to the ABI size (if the struct is not packed) as well
-      // as padding to ensure that the next field starts at the right offset.
-      EmitZeros(padSize);
-    }
-    assert(sizeSoFar == cvsLayout->getSizeInBytes() &&
-           "Layout of constant struct may be incorrect!");
+    EmitGlobalConstantStruct(CVS);
     return;
   } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
-    // FP Constants are printed as integer constants to avoid losing
-    // precision...
-    if (CFP->getType() == Type::DoubleTy) {
-      double Val = CFP->getValueAPF().convertToDouble();  // for comment only
-      uint64_t i = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
-      if (TAI->getData64bitsDirective())
-        O << TAI->getData64bitsDirective() << i << '\t'
-          << TAI->getCommentString() << " double value: " << Val << '\n';
-      else if (TD->isBigEndian()) {
-        O << TAI->getData32bitsDirective() << unsigned(i >> 32)
-          << '\t' << TAI->getCommentString()
-          << " double most significant word " << Val << '\n';
-        O << TAI->getData32bitsDirective() << unsigned(i)
-          << '\t' << TAI->getCommentString()
-          << " double least significant word " << Val << '\n';
-      } else {
-        O << TAI->getData32bitsDirective() << unsigned(i)
-          << '\t' << TAI->getCommentString()
-          << " double least significant word " << Val << '\n';
-        O << TAI->getData32bitsDirective() << unsigned(i >> 32)
-          << '\t' << TAI->getCommentString()
-          << " double most significant word " << Val << '\n';
-      }
-      return;
-    } else if (CFP->getType() == Type::FloatTy) {
-      float Val = CFP->getValueAPF().convertToFloat();  // for comment only
-      O << TAI->getData32bitsDirective()
-        << CFP->getValueAPF().bitcastToAPInt().getZExtValue()
-        << '\t' << TAI->getCommentString() << " float " << Val << '\n';
-      return;
-    } else if (CFP->getType() == Type::X86_FP80Ty) {
-      // all long double variants are printed as hex
-      // api needed to prevent premature destruction
-      APInt api = CFP->getValueAPF().bitcastToAPInt();
-      const uint64_t *p = api.getRawData();
-      // Convert to double so we can print the approximate val as a comment.
-      APFloat DoubleVal = CFP->getValueAPF();
-      bool ignored;
-      DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
-                        &ignored);
-      if (TD->isBigEndian()) {
-        O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
-          << '\t' << TAI->getCommentString()
-          << " long double most significant halfword of ~"
-          << DoubleVal.convertToDouble() << '\n';
-        O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32)
-          << '\t' << TAI->getCommentString()
-          << " long double next halfword\n";
-        O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16)
-          << '\t' << TAI->getCommentString()
-          << " long double next halfword\n";
-        O << TAI->getData16bitsDirective() << uint16_t(p[0])
-          << '\t' << TAI->getCommentString()
-          << " long double next halfword\n";
-        O << TAI->getData16bitsDirective() << uint16_t(p[1])
-          << '\t' << TAI->getCommentString()
-          << " long double least significant halfword\n";
-       } else {
-        O << TAI->getData16bitsDirective() << uint16_t(p[1])
-          << '\t' << TAI->getCommentString()
-          << " long double least significant halfword of ~"
-          << DoubleVal.convertToDouble() << '\n';
-        O << TAI->getData16bitsDirective() << uint16_t(p[0])
-          << '\t' << TAI->getCommentString()
-          << " long double next halfword\n";
-        O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16)
-          << '\t' << TAI->getCommentString()
-          << " long double next halfword\n";
-        O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32)
-          << '\t' << TAI->getCommentString()
-          << " long double next halfword\n";
-        O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
-          << '\t' << TAI->getCommentString()
-          << " long double most significant halfword\n";
-      }
-      EmitZeros(Size - TD->getTypeStoreSize(Type::X86_FP80Ty));
-      return;
-    } else if (CFP->getType() == Type::PPC_FP128Ty) {
-      // all long double variants are printed as hex
-      // api needed to prevent premature destruction
-      APInt api = CFP->getValueAPF().bitcastToAPInt();
-      const uint64_t *p = api.getRawData();
-      if (TD->isBigEndian()) {
-        O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
-          << '\t' << TAI->getCommentString()
-          << " long double most significant word\n";
-        O << TAI->getData32bitsDirective() << uint32_t(p[0])
-          << '\t' << TAI->getCommentString()
-          << " long double next word\n";
-        O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
-          << '\t' << TAI->getCommentString()
-          << " long double next word\n";
-        O << TAI->getData32bitsDirective() << uint32_t(p[1])
-          << '\t' << TAI->getCommentString()
-          << " long double least significant word\n";
-       } else {
-        O << TAI->getData32bitsDirective() << uint32_t(p[1])
-          << '\t' << TAI->getCommentString()
-          << " long double least significant word\n";
-        O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
-          << '\t' << TAI->getCommentString()
-          << " long double next word\n";
-        O << TAI->getData32bitsDirective() << uint32_t(p[0])
-          << '\t' << TAI->getCommentString()
-          << " long double next word\n";
-        O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
-          << '\t' << TAI->getCommentString()
-          << " long double most significant word\n";
-      }
-      return;
-    } else assert(0 && "Floating point constant type not handled");
-  } else if (CV->getType()->isInteger() &&
-             cast<IntegerType>(CV->getType())->getBitWidth() >= 64) {
-    if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
-      unsigned BitWidth = CI->getBitWidth();
-      assert(isPowerOf2_32(BitWidth) &&
-             "Non-power-of-2-sized integers not handled!");
-
-      // We don't expect assemblers to support integer data directives
-      // for more than 64 bits, so we emit the data in at most 64-bit
-      // quantities at a time.
-      const uint64_t *RawData = CI->getValue().getRawData();
-      for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {
-        uint64_t Val;
-        if (TD->isBigEndian())
-          Val = RawData[e - i - 1];
-        else
-          Val = RawData[i];
-
-        if (TAI->getData64bitsDirective())
-          O << TAI->getData64bitsDirective() << Val << '\n';
-        else if (TD->isBigEndian()) {
-          O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
-            << '\t' << TAI->getCommentString()
-            << " Double-word most significant word " << Val << '\n';
-          O << TAI->getData32bitsDirective() << unsigned(Val)
-            << '\t' << TAI->getCommentString()
-            << " Double-word least significant word " << Val << '\n';
-        } else {
-          O << TAI->getData32bitsDirective() << unsigned(Val)
-            << '\t' << TAI->getCommentString()
-            << " Double-word least significant word " << Val << '\n';
-          O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
-            << '\t' << TAI->getCommentString()
-            << " Double-word most significant word " << Val << '\n';
-        }
-      }
+    EmitGlobalConstantFP(CFP);
+    return;
+  } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+    // Small integers are handled below; large integers are handled here.
+    if (Size > 4) {
+      EmitGlobalConstantLargeInt(CI);
       return;
     }
   } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
-    const VectorType *PTy = CP->getType();
-    
-    for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I)
-      EmitGlobalConstant(CP->getOperand(I));
-    
+    EmitGlobalConstantVector(CP);
     return;
   }
 
-  const Type *type = CV->getType();
   printDataDirective(type);
   EmitConstantValueOnly(CV);
   if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {





More information about the llvm-commits mailing list