llvm.org GIT mirror llvm / 29cc6cb
C++, CBE, and TLOF support for ConstantDataSequential git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148805 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 8 years ago
4 changed file(s) with 125 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
214214 bool printConstExprCast(const ConstantExpr *CE, bool Static);
215215 void printConstantArray(ConstantArray *CPA, bool Static);
216216 void printConstantVector(ConstantVector *CV, bool Static);
217 void printConstantDataSequential(ConstantDataSequential *CDS, bool Static);
218
217219
218220 /// isAddressExposed - Return true if the specified value's name needs to
219221 /// have its address taken in order to get a C value of the correct type.
555557 }
556558
557559 void CWriter::printConstantArray(ConstantArray *CPA, bool Static) {
558
559560 // As a special case, print the array as a string if it is an array of
560561 // ubytes or an array of sbytes with positive values.
561562 //
562 Type *ETy = CPA->getType()->getElementType();
563 bool isString = (ETy == Type::getInt8Ty(CPA->getContext()) ||
564 ETy == Type::getInt8Ty(CPA->getContext()));
565
566 // Make sure the last character is a null char, as automatically added by C
567 if (isString && (CPA->getNumOperands() == 0 ||
568 !cast(*(CPA->op_end()-1))->isNullValue()))
569 isString = false;
570
571 if (isString) {
563 if (CPA->isCString()) {
572564 Out << '\"';
573565 // Keep track of whether the last number was a hexadecimal escape.
574566 bool LastWasHex = false;
635627 }
636628 Out << " }";
637629 }
630
631 void CWriter::printConstantDataSequential(ConstantDataSequential *CDS,
632 bool Static) {
633 // As a special case, print the array as a string if it is an array of
634 // ubytes or an array of sbytes with positive values.
635 //
636 if (CDS->isCString()) {
637 Out << '\"';
638 // Keep track of whether the last number was a hexadecimal escape.
639 bool LastWasHex = false;
640
641 StringRef Bytes = CDS->getAsCString();
642
643 // Do not include the last character, which we know is null
644 for (unsigned i = 0, e = Bytes.size(); i != e; ++i) {
645 unsigned char C = Bytes[i];
646
647 // Print it out literally if it is a printable character. The only thing
648 // to be careful about is when the last letter output was a hex escape
649 // code, in which case we have to be careful not to print out hex digits
650 // explicitly (the C compiler thinks it is a continuation of the previous
651 // character, sheesh...)
652 //
653 if (isprint(C) && (!LastWasHex || !isxdigit(C))) {
654 LastWasHex = false;
655 if (C == '"' || C == '\\')
656 Out << "\\" << (char)C;
657 else
658 Out << (char)C;
659 } else {
660 LastWasHex = false;
661 switch (C) {
662 case '\n': Out << "\\n"; break;
663 case '\t': Out << "\\t"; break;
664 case '\r': Out << "\\r"; break;
665 case '\v': Out << "\\v"; break;
666 case '\a': Out << "\\a"; break;
667 case '\"': Out << "\\\""; break;
668 case '\'': Out << "\\\'"; break;
669 default:
670 Out << "\\x";
671 Out << (char)(( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A'));
672 Out << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
673 LastWasHex = true;
674 break;
675 }
676 }
677 }
678 Out << '\"';
679 } else {
680 Out << "{ ";
681 printConstant(CDS->getElementAsConstant(0), Static);
682 for (unsigned i = 1, e = CDS->getNumOperands(); i != e; ++i) {
683 Out << ", ";
684 printConstant(CDS->getElementAsConstant(i), Static);
685 }
686 Out << " }";
687 }
688 }
689
638690
639691 // isFPCSafeToPrint - Returns true if we may assume that CFP may be written out
640692 // textually as a double (rather than as a reference to a stack-allocated
10231075 Out << "{ "; // Arrays are wrapped in struct types.
10241076 if (ConstantArray *CA = dyn_cast(CPV)) {
10251077 printConstantArray(CA, Static);
1078 } else if (ConstantDataSequential *CDS =
1079 dyn_cast(CPV)) {
1080 printConstantDataSequential(CDS, Static);
10261081 } else {
10271082 assert(isa(CPV) || isa(CPV));
10281083 ArrayType *AT = cast(CPV->getType());
10501105 }
10511106 if (ConstantVector *CV = dyn_cast(CPV)) {
10521107 printConstantVector(CV, Static);
1108 } else if (ConstantDataSequential *CDS =
1109 dyn_cast(CPV)) {
1110 printConstantDataSequential(CDS, Static);
10531111 } else {
10541112 assert(isa(CPV) || isa(CPV));
10551113 VectorType *VT = cast(CPV->getType());
697697 printCFP(CFP);
698698 Out << ";";
699699 } else if (const ConstantArray *CA = dyn_cast(CV)) {
700 if (CA->isString() &&
701 CA->getType()->getElementType() ==
702 Type::getInt8Ty(CA->getContext())) {
700 if (CA->isString()) {
703701 Out << "Constant* " << constName <<
704702 " = ConstantArray::get(mod->getContext(), \"";
705703 std::string tmp = CA->getAsString();
756754 } else if (isa(CV)) {
757755 Out << "UndefValue* " << constName << " = UndefValue::get("
758756 << typeName << ");";
757 } else if (const ConstantDataSequential *CDS =
758 dyn_cast(CV)) {
759 if (CDS->isString()) {
760 Out << "Constant *" << constName <<
761 " = ConstantDataArray::getString(mod->getContext(), \"";
762 StringRef Str = CA->getAsString();
763 bool nullTerminate = false;
764 if (Str.back() == 0) {
765 Str = Str.drop_back();
766 nullTerminate = true;
767 }
768 printEscapedString(Str);
769 // Determine if we want null termination or not.
770 if (nullTerminate)
771 Out << "\", true);";
772 else
773 Out << "\", false);";// No null terminator
774 } else {
775 // TODO: Could generate more efficient code generating CDS calls instead.
776 Out << "std::vector " << constName << "_elems;";
777 nl(Out);
778 for (unsigned i = 0; i != CDS->getNumElements(); ++i) {
779 Constant *Elt = CDS->getElementAsConstant(i);
780 printConstant(Elt);
781 Out << constName << "_elems.push_back(" << getCppName(Elt) << ");";
782 nl(Out);
783 }
784 Out << "Constant* " << constName;
785
786 if (isa(CDS->getType()))
787 Out << " = ConstantArray::get(";
788 else
789 Out << " = ConstantVector::get(";
790 Out << typeName << ", " << constName << "_elems);";
791 }
759792 } else if (const ConstantExpr *CE = dyn_cast(CV)) {
760793 if (CE->getOpcode() == Instruction::GetElementPtr) {
761794 Out << "std::vector " << constName << "_indices;";
7272
7373 /// IsNullTerminatedString - Return true if the specified constant (which is
7474 /// known to have a type that is an array of 1/2/4 byte elements) ends with a
75 /// nul value and contains no other nuls in it.
75 /// nul value and contains no other nuls in it. Note that this is more general
76 /// than ConstantDataSequential::isString because we allow 2 & 4 byte strings.
7677 static bool IsNullTerminatedString(const Constant *C) {
77 ArrayType *ATy = cast(C->getType());
78
79 // First check: is we have constant array of i8 terminated with zero
78 // First check: is we have constant array terminated with zero
8079 if (const ConstantArray *CVA = dyn_cast(C)) {
80 ArrayType *ATy = cast(C->getType());
8181 if (ATy->getNumElements() == 0) return false;
8282
8383 ConstantInt *Null =
9393 return false;
9494 return true;
9595 }
96 if (const ConstantDataSequential *CDS = dyn_cast(C)) {
97 unsigned NumElts = CDS->getNumElements();
98 assert(NumElts != 0 && "Can't have an empty CDS");
99
100 if (CDS->getElementAsInteger(NumElts-1) != 0)
101 return false; // Not null terminated.
102
103 // Verify that the null doesn't occur anywhere else in the string.
104 for (unsigned i = 0; i != NumElts-1; ++i)
105 if (CDS->getElementAsInteger(i) == 0)
106 return false;
107 return true;
108 }
96109
97110 // Another possibility: [1 x i8] zeroinitializer
98111 if (isa(C))
99 return ATy->getNumElements() == 1;
112 return cast(C->getType())->getNumElements() == 1;
100113
101114 return false;
102115 }
20472047 /// we *want* an underlying "char*" to avoid TBAA type punning violations.
20482048 Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) {
20492049 assert(isElementTypeCompatible(cast(Ty)->getElementType()));
2050 // If the elements are all zero, return a CAZ, which is more dense.
2050 // If the elements are all zero or there are no elements, return a CAZ, which
2051 // is more dense and canonical.
20512052 if (isAllZeros(Elements))
20522053 return ConstantAggregateZero::get(Ty);
20532054