mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Add support emiting for 2/4 byte mergable strings to the ".rodata.str*"
section on ELF targets. llvm-svn: 78066
This commit is contained in:
parent
b52306e490
commit
41ade57a63
@ -79,18 +79,33 @@ static bool isSuitableForBSS(const GlobalVariable *GV) {
|
||||
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 @@ static SectionKind SectionKindForGlobal(const GlobalValue *GV,
|
||||
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
|
||||
|
@ -85,3 +85,39 @@
|
||||
; DARWIN:_G6:
|
||||
; DARWIN: .ascii "\001"
|
||||
|
||||
|
||||
@G7 = constant [10 x i8] c"abcdefghi\00"
|
||||
|
||||
; DARWIN: .cstring
|
||||
; DARWIN: .globl _G7
|
||||
; DARWIN: _G7:
|
||||
; DARWIN: .asciz "abcdefghi"
|
||||
|
||||
; LINUX: .section .rodata.str1.1,"aMS",@progbits,1
|
||||
; LINUX: .globl G7
|
||||
; LINUX: G7:
|
||||
; LINUX: .asciz "abcdefghi"
|
||||
|
||||
|
||||
@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",@progbits,2
|
||||
; LINUX: .globl G8
|
||||
; LINUX:G8:
|
||||
|
||||
@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",@progbits,4
|
||||
; LINUX: .globl G9
|
||||
; LINUX:G9
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user