From: David Greene Date: Wed, 31 Aug 2011 17:30:56 +0000 (+0000) Subject: Compress Repeated Byte Output X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=d92e2e4f88fccd4b3a497d8d9eade7bfd8564798 Compress Repeated Byte Output Emit a repeated sequence of bytes using .zero. This saves an enormous amount of asm file space for certain programs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138864 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 12c5684a9e5..e888985820e 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -44,6 +44,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Timer.h" using namespace llvm; @@ -1520,12 +1521,67 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { static void EmitGlobalConstantImpl(const Constant *C, unsigned AddrSpace, AsmPrinter &AP); +/// 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(V)) { + if (CI->getBitWidth() > 64) return -1; + + uint64_t Size = TM.getTargetData()->getTypeAllocSize(V->getType()); + uint64_t Value = CI->getZExtValue(); + + // Make sure the constant is at least 8 bits long and has a power + // of 2 bit width. This guarantees the constant bit width is + // always a multiple of 8 bits, avoiding issues with padding out + // to Size and other such corner cases. + if (CI->getBitWidth() < 8 || !isPowerOf2_64(CI->getBitWidth())) return -1; + + uint8_t Byte = static_cast(Value); + + for (unsigned i = 1; i < Size; ++i) { + Value >>= 8; + if (static_cast(Value) != Byte) return -1; + } + return Byte; + } + if (const ConstantArray *CA = dyn_cast(V)) { + // Make sure all array elements are sequences of the same repeated + // byte. + if (CA->getNumOperands() == 0) return -1; + + int Byte = isRepeatedByteSequence(CA->getOperand(0), TM); + if (Byte == -1) return -1; + + for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { + int ThisByte = isRepeatedByteSequence(CA->getOperand(i), TM); + if (ThisByte == -1) return -1; + if (Byte != ThisByte) return -1; + } + return Byte; + } + + return -1; +} + static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace, AsmPrinter &AP) { if (AddrSpace != 0 || !CA->isString()) { - // Not a string. Print the values in successive locations - for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) - EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP); + // Not a string. Print the values in successive locations. + + // See if we can aggregate some values. Make sure it can be + // represented as a series of bytes of the constant value. + int Value = isRepeatedByteSequence(CA, AP.TM); + + if (Value != -1) { + unsigned Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType()); + AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace); + } + else { + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) + EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP); + } return; } diff --git a/test/CodeGen/X86/2011-08-29-BlockConstant.ll b/test/CodeGen/X86/2011-08-29-BlockConstant.ll new file mode 100644 index 00000000000..83e4bcc6093 --- /dev/null +++ b/test/CodeGen/X86/2011-08-29-BlockConstant.ll @@ -0,0 +1,34 @@ +; RUN: llc -march=x86-64 < %s | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +@x = global [500 x i64] zeroinitializer, align 64 ; <[500 x i64]*> +; CHECK: x: +; CHECK: .zero 4000 + +@y = global [63 x i64] [ + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262, + i64 6799976246779207262, i64 6799976246779207262, i64 6799976246779207262], + align 64 ; <[63 x i64]*> 0x5e5e5e5e +; CHECK: y: +; CHECK: .zero 504,94