diff options
author | Chris Lattner <sabre@nondot.org> | 2012-01-24 09:31:43 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2012-01-24 09:31:43 +0000 |
commit | 9e631da253bff90d9da5ace21bd73f1c838e72eb (patch) | |
tree | ee0015a94cee5cd31296621542ba8eaf3ff82481 /lib/CodeGen | |
parent | 62339073127df4579905f551f61c132cf21d2aad (diff) | |
download | external_llvm-9e631da253bff90d9da5ace21bd73f1c838e72eb.zip external_llvm-9e631da253bff90d9da5ace21bd73f1c838e72eb.tar.gz external_llvm-9e631da253bff90d9da5ace21bd73f1c838e72eb.tar.bz2 |
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148793 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 123 |
1 files changed, 91 insertions, 32 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index eccd8fb..ff6da12 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1557,6 +1557,19 @@ static void EmitGlobalConstantImpl(const Constant *C, unsigned AddrSpace, /// 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 @@ static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) { 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 @@ static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) { } 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 @@ static void EmitGlobalConstantVector(const ConstantVector *CV, 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 @@ static void EmitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace, } } - 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 @@ static void EmitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace, 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), |