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

Chris Lattner sabre at nondot.org
Tue Jan 24 01:31:43 PST 2012


Author: lattner
Date: Tue Jan 24 03:31:43 2012
New Revision: 148793

URL: http://llvm.org/viewvc/llvm-project?rev=148793&view=rev
Log:
Add AsmPrinter (aka MCLowering) support for ConstantDataSequential, 
and clean up some other misc stuff.  Unlike ConstantArray, we will
prefer to emit .fill directives for "String" arrays that all have
the same value, since they are denser than emitting a .ascii

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

Modified: llvm/trunk/include/llvm/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=148793&r1=148792&r2=148793&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Constants.h (original)
+++ llvm/trunk/include/llvm/Constants.h Tue Jan 24 03:31:43 2012
@@ -640,7 +640,10 @@
   /// getAsString - If this array is isString(), then this method returns the
   /// array as a StringRef.  Otherwise, it asserts out.
   ///
-  StringRef getAsString() const;
+  StringRef getAsString() const {
+    assert(isString() && "Not a string");
+    return getRawDataValues();
+  }
   
   /// getAsCString - If this array is isCString(), then this method returns the
   /// array (without the trailing null byte) as a StringRef. Otherwise, it
@@ -652,6 +655,10 @@
     return Str.substr(0, Str.size()-1);
   }
   
+  /// getRawDataValues - Return the raw, underlying, bytes of this data.  Note
+  /// that this is an extremely tricky thing to work with, as it exposes the
+  /// host endianness of the data elements.
+  StringRef getRawDataValues() const;
   
   virtual void destroyConstant();
   

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=148793&r1=148792&r2=148793&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue Jan 24 03:31:43 2012
@@ -1557,6 +1557,19 @@
 /// isRepeatedByteSequence - Determine whether the given value is
 /// composed of a repeated sequence of identical bytes and return the
 /// byte value.  If it is not a repeated sequence, return -1.
+static int isRepeatedByteSequence(const ConstantDataSequential *V) {
+  StringRef Data = V->getRawDataValues();
+  assert(!Data.empty() && "Empty aggregates should be CAZ node");
+  char C = Data[0];
+  for (unsigned i = 1, e = Data.size(); i != e; ++i)
+    if (Data[i] != C) return -1;
+  return C;
+}
+
+
+/// isRepeatedByteSequence - Determine whether the given value is
+/// composed of a repeated sequence of identical bytes and return the
+/// byte value.  If it is not a repeated sequence, return -1.
 static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) {
 
   if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
@@ -1582,8 +1595,7 @@
   if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) {
     // Make sure all array elements are sequences of the same repeated
     // byte.
-    if (CA->getNumOperands() == 0) return -1;
-
+    assert(CA->getNumOperands() != 0 && "Should be a CAZ");
     int Byte = isRepeatedByteSequence(CA->getOperand(0), TM);
     if (Byte == -1) return -1;
 
@@ -1594,10 +1606,70 @@
     }
     return Byte;
   }
+  
+  if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V))
+    return isRepeatedByteSequence(CDS);
 
   return -1;
 }
 
+static void EmitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
+                                             unsigned AddrSpace,AsmPrinter &AP){
+  
+  // See if we can aggregate this into a .fill, if so, emit it as such.
+  int Value = isRepeatedByteSequence(CDS, AP.TM);
+  if (Value != -1) {
+    uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CDS->getType());
+    return AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
+  }
+  
+  // If this can be emitted with .ascii/.asciz, emit it as such.
+  if (CDS->isString())
+    return AP.OutStreamer.EmitBytes(CDS->getAsString(), AddrSpace);
+
+  // Otherwise, emit the values in successive locations.
+  unsigned ElementByteSize = CDS->getElementByteSize();
+  if (isa<IntegerType>(CDS->getElementType())) {
+    for (unsigned i = 0, e = CDS->getType()->getNumElements(); i != e; ++i) {
+      AP.OutStreamer.EmitIntValue(CDS->getElementAsInteger(i),
+                                  ElementByteSize, AddrSpace);
+    }
+    return;
+  }
+
+  // FP Constants are printed as integer constants to avoid losing
+  // precision.
+  assert(CDS->getElementType()->isFloatTy() ||
+         CDS->getElementType()->isDoubleTy());
+
+  if (ElementByteSize == 4) {
+    for (unsigned i = 0, e = CDS->getType()->getNumElements(); i != e; ++i) {
+      union {
+        float F;
+        uint32_t I;
+      };
+      
+      F = CDS->getElementAsFloat(i);
+      if (AP.isVerbose())
+        AP.OutStreamer.GetCommentOS() << "float " << F << '\n';
+      AP.OutStreamer.EmitIntValue(I, 4, AddrSpace);
+    }
+    return;
+  }
+
+  for (unsigned i = 0, e = CDS->getType()->getNumElements(); i != e; ++i) {
+    union {
+      double F;
+      uint64_t I;
+    };
+    
+    F = CDS->getElementAsDouble(i);
+    if (AP.isVerbose())
+      AP.OutStreamer.GetCommentOS() << "double " << F << '\n';
+    AP.OutStreamer.EmitIntValue(I, 8, AddrSpace);
+  }
+}
+
 static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace,
                                     AsmPrinter &AP) {
   if (AddrSpace != 0 || !CA->isString()) {
@@ -1640,28 +1712,6 @@
     AP.OutStreamer.EmitZeros(Padding, AddrSpace);
 }
 
-static void LowerVectorConstant(const Constant *CV, unsigned AddrSpace,
-                                AsmPrinter &AP) {
-  // Look through bitcasts
-  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV))
-    if (CE->getOpcode() == Instruction::BitCast)
-      CV = CE->getOperand(0);
-
-  if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
-    return EmitGlobalConstantVector(V, AddrSpace, AP);
-
-  // If we get here, we're stuck; report the problem to the user.
-  // FIXME: Are there any other useful tricks for vectors?
-  {
-    std::string S;
-    raw_string_ostream OS(S);
-    OS << "Unsupported vector expression in static initializer: ";
-    WriteAsOperand(OS, CV, /*PrintType=*/false,
-                   !AP.MF ? 0 : AP.MF->getFunction()->getParent());
-    report_fatal_error(OS.str());
-  }
-}
-
 static void EmitGlobalConstantStruct(const ConstantStruct *CS,
                                      unsigned AddrSpace, AsmPrinter &AP) {
   // Print the fields in successive locations. Pad to align if needed!
@@ -1812,12 +1862,6 @@
     }
   }
 
-  if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
-    return EmitGlobalConstantArray(CVA, AddrSpace, AP);
-
-  if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
-    return EmitGlobalConstantStruct(CVS, AddrSpace, AP);
-
   if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
     return EmitGlobalConstantFP(CFP, AddrSpace, AP);
 
@@ -1827,9 +1871,24 @@
     return;
   }
 
-  if (CV->getType()->isVectorTy())
-    return LowerVectorConstant(CV, AddrSpace, AP);
+  if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(CV))
+    return EmitGlobalConstantDataSequential(CDS, AddrSpace, AP);
+  
+  if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
+    return EmitGlobalConstantArray(CVA, AddrSpace, AP);
 
+  if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
+    return EmitGlobalConstantStruct(CVS, AddrSpace, AP);
+
+  // Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of
+  // vectors).
+  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV))
+    if (CE->getOpcode() == Instruction::BitCast)
+      return EmitGlobalConstantImpl(CE->getOperand(0), AddrSpace, AP);
+  
+  if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
+    return EmitGlobalConstantVector(V, AddrSpace, AP);
+    
   // Otherwise, it must be a ConstantExpr.  Lower it to an MCExpr, then emit it
   // thread the streamer with EmitValue.
   AP.OutStreamer.EmitValue(LowerConstant(CV, AP),

Modified: llvm/trunk/lib/VMCore/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=148793&r1=148792&r2=148793&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Constants.cpp (original)
+++ llvm/trunk/lib/VMCore/Constants.cpp Tue Jan 24 03:31:43 2012
@@ -1994,6 +1994,11 @@
   return getType()->getElementType();
 }
 
+StringRef ConstantDataSequential::getRawDataValues() const {
+  return StringRef(DataElements,
+                   getType()->getNumElements()*getElementByteSize());
+}
+
 /// isElementTypeCompatible - Return true if a ConstantDataSequential can be
 /// formed with a vector or array of the specified element type.
 /// ConstantDataArray only works with normal float and int types that are
@@ -2067,14 +2072,12 @@
 }
 
 void ConstantDataSequential::destroyConstant() {
-  uint64_t ByteSize = getElementByteSize() * getElementType()->getNumElements();
-  
   // Remove the constant from the StringMap.
   StringMap<ConstantDataSequential*> &CDSConstants = 
     getType()->getContext().pImpl->CDSConstants;
   
   StringMap<ConstantDataSequential*>::iterator Slot =
-    CDSConstants.find(StringRef(DataElements, ByteSize));
+    CDSConstants.find(getRawDataValues());
 
   assert(Slot != CDSConstants.end() && "CDS not found in uniquing table");
 
@@ -2226,15 +2229,6 @@
   return isa<ArrayType>(getType()) && getElementType()->isIntegerTy(8);
 }
 
-/// getAsString - If this array is isString(), then this method returns the
-/// array as a StringRef.  Otherwise, it asserts out.
-///
-StringRef ConstantDataSequential::getAsString() const {
-  assert(isString() && "Not a string");
-  return StringRef(DataElements, getType()->getNumElements());
-}
-
-
 /// isCString - This method returns true if the array "isString", ends with a
 /// nul byte, and does not contains any other nul bytes.
 bool ConstantDataSequential::isCString() const {





More information about the llvm-commits mailing list