[llvm-commits] [llvm] r78066 - in /llvm/trunk: lib/Target/TargetLoweringObjectFile.cpp test/CodeGen/X86/global-sections.ll

Chris Lattner sabre at nondot.org
Tue Aug 4 09:13:10 PDT 2009


Author: lattner
Date: Tue Aug  4 11:13:09 2009
New Revision: 78066

URL: http://llvm.org/viewvc/llvm-project?rev=78066&view=rev
Log:
Add support emiting for 2/4 byte mergable strings to the ".rodata.str*"
section on ELF targets.

Modified:
    llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp
    llvm/trunk/test/CodeGen/X86/global-sections.ll

Modified: llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp?rev=78066&r1=78065&r2=78066&view=diff

==============================================================================
--- llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp (original)
+++ llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp Tue Aug  4 11:13:09 2009
@@ -79,18 +79,33 @@
   return true;
 }
 
-static bool isConstantString(const Constant *C) {
+/// IsNullTerminatedString - Return true if the specified constant (which is
+/// known to have a type that is an array of 1/2/4 byte elements) ends with a
+/// nul value and contains no other nuls in it.
+static bool IsNullTerminatedString(const Constant *C) {
+  const ArrayType *ATy = cast<ArrayType>(C->getType());
+  
   // First check: is we have constant array of i8 terminated with zero
-  const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
-  // Check, if initializer is a null-terminated string
-  if (CVA && CVA->isCString())
+  if (const ConstantArray *CVA = dyn_cast<ConstantArray>(C)) {
+    if (ATy->getNumElements() == 0) return false;
+
+    ConstantInt *Null =
+      dyn_cast<ConstantInt>(CVA->getOperand(ATy->getNumElements()-1));
+    if (Null == 0 || Null->getZExtValue() != 0)
+      return false; // Not null terminated.
+    
+    // Verify that the null doesn't occur anywhere else in the string.
+    for (unsigned i = 0, e = ATy->getNumElements()-1; i != e; ++i)
+      // Reject constantexpr elements etc.
+      if (!isa<ConstantInt>(CVA->getOperand(i)) ||
+          CVA->getOperand(i) == Null)
+        return false;
     return true;
+  }
 
   // Another possibility: [1 x i8] zeroinitializer
   if (isa<ConstantAggregateZero>(C))
-    if (const ArrayType *Ty = dyn_cast<ArrayType>(C->getType()))
-      return (Ty->getElementType() == Type::Int8Ty &&
-              Ty->getNumElements() == 1);
+    return ATy->getNumElements() == 1;
 
   return false;
 }
@@ -133,11 +148,23 @@
     default: llvm_unreachable("unknown relocation info kind");
     case Constant::NoRelocation:
       // If initializer is a null-terminated string, put it in a "cstring"
-      // section if the target has it.
-      if (isConstantString(C))
-        return SectionKind::getMergeable1ByteCString();
-      
-      // FIXME: Detect 2/4 byte strings.
+      // section of the right width.
+      if (const ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
+        if (const IntegerType *ITy = 
+              dyn_cast<IntegerType>(ATy->getElementType())) {
+          if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 ||
+               ITy->getBitWidth() == 32) &&
+              IsNullTerminatedString(C)) {
+            if (ITy->getBitWidth() == 8)
+              return SectionKind::getMergeable1ByteCString();
+            if (ITy->getBitWidth() == 16)
+              return SectionKind::getMergeable2ByteCString();
+                                         
+            assert(ITy->getBitWidth() == 32 && "Unknown width");
+            return SectionKind::getMergeable4ByteCString();
+          }
+        }
+      }
         
       // Otherwise, just drop it into a mergable constant section.  If we have
       // a section for this size, use it, otherwise use the arbitrary sized

Modified: llvm/trunk/test/CodeGen/X86/global-sections.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/global-sections.ll?rev=78066&r1=78065&r2=78066&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/X86/global-sections.ll (original)
+++ llvm/trunk/test/CodeGen/X86/global-sections.ll Tue Aug  4 11:13:09 2009
@@ -85,3 +85,39 @@
 ; DARWIN:_G6:
 ; DARWIN:  .ascii "\001"
 
+
+ at G7 = constant [10 x i8] c"abcdefghi\00"
+
+; DARWIN:	.cstring
+; DARWIN:	.globl _G7
+; DARWIN: _G7:
+; DARWIN:	.asciz	"abcdefghi"
+
+; LINUX:	.section		.rodata.str1.1,"aMS", at progbits,1
+; LINUX:	.globl G7
+; LINUX: G7:
+; LINUX:	.asciz	"abcdefghi"
+
+
+ at G8 = constant [4 x i16] [ i16 1, i16 2, i16 3, i16 0 ]
+
+; DARWIN:	.const
+; DARWIN:	.globl _G8
+; DARWIN: _G8:
+
+; LINUX:	.section		.rodata.str2.2,"aMS", at progbits,2
+; LINUX:	.globl G8
+; LINUX:G8:
+
+ at G9 = constant [4 x i32] [ i32 1, i32 2, i32 3, i32 0 ]
+
+; ARWIN:	.const   [[ already in const section]]
+; DARWIN:	.globl _G9
+; DARWIN: _G9:
+
+; LINUX:	.section		.rodata.str4.4,"aMS", at progbits,4
+; LINUX:	.globl G9
+; LINUX:G9
+
+
+





More information about the llvm-commits mailing list