mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-27 02:31:09 +00:00
Add a new ConstantAggregateZero class, to fix PR239. This makes zero
initializers for constant structs and arrays take constant space, instead of space proportinal to the number of elements. This reduces the memory usage of the LLVM compiler by hundreds of megabytes when compiling some nasty SPEC95 benchmarks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11470 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
46ccf6d382
commit
40bbeb5d07
@ -309,6 +309,36 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//===---------------------------------------------------------------------------
|
||||||
|
/// ConstantAggregateZero - All zero aggregate value
|
||||||
|
///
|
||||||
|
class ConstantAggregateZero : public Constant {
|
||||||
|
friend struct ConstantCreator<ConstantAggregateZero, Type, char>;
|
||||||
|
ConstantAggregateZero(const ConstantAggregateZero &); // DO NOT IMPLEMENT
|
||||||
|
protected:
|
||||||
|
ConstantAggregateZero(const Type *Ty) : Constant(Ty) {}
|
||||||
|
public:
|
||||||
|
/// get() - static factory method for creating a null aggregate. It is
|
||||||
|
/// illegal to call this method with a non-aggregate type.
|
||||||
|
static Constant *get(const Type *Ty);
|
||||||
|
|
||||||
|
/// isNullValue - Return true if this is the value that would be returned by
|
||||||
|
/// getNullValue.
|
||||||
|
virtual bool isNullValue() const { return true; }
|
||||||
|
|
||||||
|
virtual void destroyConstant();
|
||||||
|
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To,
|
||||||
|
bool DisableChecking = false);
|
||||||
|
|
||||||
|
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||||
|
///
|
||||||
|
static inline bool classof(const ConstantAggregateZero *) { return true; }
|
||||||
|
static bool classof(const Constant *CPV);
|
||||||
|
static inline bool classof(const Value *V) {
|
||||||
|
return isa<Constant>(V) && classof(cast<Constant>(V));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//===---------------------------------------------------------------------------
|
//===---------------------------------------------------------------------------
|
||||||
/// ConstantArray - Constant Array Declarations
|
/// ConstantArray - Constant Array Declarations
|
||||||
@ -345,19 +375,9 @@ public:
|
|||||||
inline const std::vector<Use> &getValues() const { return Operands; }
|
inline const std::vector<Use> &getValues() const { return Operands; }
|
||||||
|
|
||||||
/// isNullValue - Return true if this is the value that would be returned by
|
/// isNullValue - Return true if this is the value that would be returned by
|
||||||
/// getNullValue.
|
/// getNullValue. This always returns false because zero arrays are always
|
||||||
virtual bool isNullValue() const {
|
/// created as ConstantAggregateZero objects.
|
||||||
// FIXME: This should be made to be MUCH faster. Just check against well
|
virtual bool isNullValue() const { return false; }
|
||||||
// known null value!
|
|
||||||
if (getNumOperands()) {
|
|
||||||
const Constant *First = cast<Constant>(getOperand(0));
|
|
||||||
if (!First->isNullValue()) return false;
|
|
||||||
for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
|
|
||||||
if (cast<Constant>(getOperand(i)) != First)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void destroyConstant();
|
virtual void destroyConstant();
|
||||||
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To,
|
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To,
|
||||||
@ -395,14 +415,10 @@ public:
|
|||||||
inline const std::vector<Use> &getValues() const { return Operands; }
|
inline const std::vector<Use> &getValues() const { return Operands; }
|
||||||
|
|
||||||
/// isNullValue - Return true if this is the value that would be returned by
|
/// isNullValue - Return true if this is the value that would be returned by
|
||||||
/// getNullValue.
|
/// getNullValue. This always returns false because zero structs are always
|
||||||
|
/// created as ConstantAggregateZero objects.
|
||||||
virtual bool isNullValue() const {
|
virtual bool isNullValue() const {
|
||||||
// FIXME: This should be made to be MUCH faster. Just check against well
|
|
||||||
// known null value!
|
|
||||||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
|
|
||||||
if (!cast<Constant>(getOperand(i))->isNullValue())
|
|
||||||
return false;
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void destroyConstant();
|
virtual void destroyConstant();
|
||||||
|
@ -64,8 +64,6 @@ void Constant::destroyConstantImpl() {
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::map<const Type *, Constant*> NullValues;
|
|
||||||
|
|
||||||
// Static constructor to create a '0' constant of arbitrary type...
|
// Static constructor to create a '0' constant of arbitrary type...
|
||||||
Constant *Constant::getNullValue(const Type *Ty) {
|
Constant *Constant::getNullValue(const Type *Ty) {
|
||||||
switch (Ty->getPrimitiveID()) {
|
switch (Ty->getPrimitiveID()) {
|
||||||
@ -118,35 +116,9 @@ Constant *Constant::getNullValue(const Type *Ty) {
|
|||||||
case Type::PointerTyID:
|
case Type::PointerTyID:
|
||||||
return ConstantPointerNull::get(cast<PointerType>(Ty));
|
return ConstantPointerNull::get(cast<PointerType>(Ty));
|
||||||
|
|
||||||
case Type::StructTyID: {
|
case Type::StructTyID:
|
||||||
if (!Ty->isAbstract())
|
case Type::ArrayTyID:
|
||||||
if (Constant *V = NullValues[Ty])
|
return ConstantAggregateZero::get(Ty);
|
||||||
return V;
|
|
||||||
|
|
||||||
const StructType *ST = cast<StructType>(Ty);
|
|
||||||
std::vector<Constant*> Elements;
|
|
||||||
Elements.resize(ST->getNumElements());
|
|
||||||
for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i)
|
|
||||||
Elements[i] = Constant::getNullValue(ST->getElementType(i));
|
|
||||||
Constant *Ret = ConstantStruct::get(ST, Elements);
|
|
||||||
if (!Ty->isAbstract())
|
|
||||||
NullValues[Ty] = Ret;
|
|
||||||
return Ret;
|
|
||||||
}
|
|
||||||
case Type::ArrayTyID: {
|
|
||||||
if (!Ty->isAbstract())
|
|
||||||
if (Constant *V = NullValues[Ty])
|
|
||||||
return V;
|
|
||||||
|
|
||||||
const ArrayType *AT = cast<ArrayType>(Ty);
|
|
||||||
Constant *El = Constant::getNullValue(AT->getElementType());
|
|
||||||
unsigned NumElements = AT->getNumElements();
|
|
||||||
Constant *Ret = ConstantArray::get(AT,
|
|
||||||
std::vector<Constant*>(NumElements, El));
|
|
||||||
if (!Ty->isAbstract())
|
|
||||||
NullValues[Ty] = Ret;
|
|
||||||
return Ret;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
// Function, Type, Label, or Opaque type?
|
// Function, Type, Label, or Opaque type?
|
||||||
assert(0 && "Cannot create a null constant of that type!");
|
assert(0 && "Cannot create a null constant of that type!");
|
||||||
@ -347,11 +319,15 @@ bool ConstantFP::classof(const Constant *CPV) {
|
|||||||
return ((Ty == Type::FloatTy || Ty == Type::DoubleTy) &&
|
return ((Ty == Type::FloatTy || Ty == Type::DoubleTy) &&
|
||||||
!isa<ConstantExpr>(CPV));
|
!isa<ConstantExpr>(CPV));
|
||||||
}
|
}
|
||||||
|
bool ConstantAggregateZero::classof(const Constant *CPV) {
|
||||||
|
return (isa<ArrayType>(CPV->getType()) || isa<StructType>(CPV->getType())) &&
|
||||||
|
CPV->isNullValue();
|
||||||
|
}
|
||||||
bool ConstantArray::classof(const Constant *CPV) {
|
bool ConstantArray::classof(const Constant *CPV) {
|
||||||
return isa<ArrayType>(CPV->getType()) && !isa<ConstantExpr>(CPV);
|
return isa<ArrayType>(CPV->getType()) && !CPV->isNullValue();
|
||||||
}
|
}
|
||||||
bool ConstantStruct::classof(const Constant *CPV) {
|
bool ConstantStruct::classof(const Constant *CPV) {
|
||||||
return isa<StructType>(CPV->getType()) && !isa<ConstantExpr>(CPV);
|
return isa<StructType>(CPV->getType()) && !CPV->isNullValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConstantPointerNull::classof(const Constant *CPV) {
|
bool ConstantPointerNull::classof(const Constant *CPV) {
|
||||||
@ -765,6 +741,50 @@ ConstantFP *ConstantFP::get(const Type *Ty, double V) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- ConstantAggregateZero::get() implementation...
|
||||||
|
//
|
||||||
|
namespace llvm {
|
||||||
|
// ConstantAggregateZero does not take extra "value" argument...
|
||||||
|
template<class ValType>
|
||||||
|
struct ConstantCreator<ConstantAggregateZero, Type, ValType> {
|
||||||
|
static ConstantAggregateZero *create(const Type *Ty, const ValType &V){
|
||||||
|
return new ConstantAggregateZero(Ty);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ConvertConstantType<ConstantAggregateZero, Type> {
|
||||||
|
static void convert(ConstantAggregateZero *OldC, const Type *NewTy) {
|
||||||
|
// Make everyone now use a constant of the new type...
|
||||||
|
Constant *New = ConstantAggregateZero::get(NewTy);
|
||||||
|
assert(New != OldC && "Didn't replace constant??");
|
||||||
|
OldC->uncheckedReplaceAllUsesWith(New);
|
||||||
|
OldC->destroyConstant(); // This constant is now dead, destroy it.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ValueMap<char, Type, ConstantAggregateZero> AggZeroConstants;
|
||||||
|
|
||||||
|
Constant *ConstantAggregateZero::get(const Type *Ty) {
|
||||||
|
return AggZeroConstants.getOrCreate(Ty, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// destroyConstant - Remove the constant from the constant table...
|
||||||
|
//
|
||||||
|
void ConstantAggregateZero::destroyConstant() {
|
||||||
|
AggZeroConstants.remove(this);
|
||||||
|
destroyConstantImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstantAggregateZero::replaceUsesOfWithOnConstant(Value *From, Value *To,
|
||||||
|
bool DisableChecking) {
|
||||||
|
assert(0 && "No uses!");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---- ConstantArray::get() implementation...
|
//---- ConstantArray::get() implementation...
|
||||||
//
|
//
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -788,7 +808,16 @@ static ValueMap<std::vector<Constant*>, ArrayType,
|
|||||||
|
|
||||||
Constant *ConstantArray::get(const ArrayType *Ty,
|
Constant *ConstantArray::get(const ArrayType *Ty,
|
||||||
const std::vector<Constant*> &V) {
|
const std::vector<Constant*> &V) {
|
||||||
|
// If this is an all-zero array, return a ConstantAggregateZero object
|
||||||
|
if (!V.empty()) {
|
||||||
|
Constant *C = V[0];
|
||||||
|
if (!C->isNullValue())
|
||||||
return ArrayConstants.getOrCreate(Ty, V);
|
return ArrayConstants.getOrCreate(Ty, V);
|
||||||
|
for (unsigned i = 1, e = V.size(); i != e; ++i)
|
||||||
|
if (V[i] != C)
|
||||||
|
return ArrayConstants.getOrCreate(Ty, V);
|
||||||
|
}
|
||||||
|
return ConstantAggregateZero::get(Ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroyConstant - Remove the constant from the constant table...
|
// destroyConstant - Remove the constant from the constant table...
|
||||||
@ -868,7 +897,12 @@ static ValueMap<std::vector<Constant*>, StructType,
|
|||||||
|
|
||||||
Constant *ConstantStruct::get(const StructType *Ty,
|
Constant *ConstantStruct::get(const StructType *Ty,
|
||||||
const std::vector<Constant*> &V) {
|
const std::vector<Constant*> &V) {
|
||||||
|
// Create a ConstantAggregateZero value if all elements are zeros...
|
||||||
|
for (unsigned i = 0, e = V.size(); i != e; ++i)
|
||||||
|
if (!V[i]->isNullValue())
|
||||||
return StructConstants.getOrCreate(Ty, V);
|
return StructConstants.getOrCreate(Ty, V);
|
||||||
|
|
||||||
|
return ConstantAggregateZero::get(Ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroyConstant - Remove the constant from the constant table...
|
// destroyConstant - Remove the constant from the constant table...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user