mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
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
This commit is contained in:
parent
0f3abd8d68
commit
d92e2e4f88
@ -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;
|
||||
}
|
||||
|
||||
|
34
test/CodeGen/X86/2011-08-29-BlockConstant.ll
Normal file
34
test/CodeGen/X86/2011-08-29-BlockConstant.ll
Normal 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
|
Loading…
Reference in New Issue
Block a user