Compress Repeated Byte Output

Emit a repeated sequence of bytes using .zero.  This saves an enormous
amount of asm file space for certain programs.

llvm-svn: 138864
This commit is contained in:
David Greene 2011-08-31 17:30:56 +00:00
parent edce1f3f7d
commit cdef71f4f3
2 changed files with 93 additions and 3 deletions

View File

@ -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<ConstantInt>(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<uint8_t>(Value);
for (unsigned i = 1; i < Size; ++i) {
Value >>= 8;
if (static_cast<uint8_t>(Value) != Byte) return -1;
}
return Byte;
}
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;
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;
}

View File

@ -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