1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

sink the Instruction::HasMetadata bit into SubclassData.

llvm-svn: 92240
This commit is contained in:
Chris Lattner 2009-12-29 02:46:09 +00:00
parent 2c82be93e6
commit 692c53dbf0
6 changed files with 97 additions and 65 deletions

View File

@ -733,11 +733,11 @@ public:
/// @brief Return the predicate for this instruction. /// @brief Return the predicate for this instruction.
Predicate getPredicate() const { Predicate getPredicate() const {
return Predicate(getSubclassDataFromValue()); return Predicate(getSubclassDataFromInstruction());
} }
/// @brief Set the predicate for this instruction to the specified value. /// @brief Set the predicate for this instruction to the specified value.
void setPredicate(Predicate P) { setValueSubclassData(P); } void setPredicate(Predicate P) { setInstructionSubclassData(P); }
static bool isFPPredicate(Predicate P) { static bool isFPPredicate(Predicate P) {
return P >= FIRST_FCMP_PREDICATE && P <= LAST_FCMP_PREDICATE; return P >= FIRST_FCMP_PREDICATE && P <= LAST_FCMP_PREDICATE;

View File

@ -33,18 +33,11 @@ class Instruction : public User, public ilist_node<Instruction> {
BasicBlock *Parent; BasicBlock *Parent;
// FIXME: Bitfieldize this. enum {
bool HasMetadata; /// HasMetadataBit - This is a bit stored in the SubClassData field which
friend class MetadataContextImpl; /// indicates whether this instruction has metadata attached to it or not.
HasMetadataBit = 1 << 15
friend class SymbolTableListTraits<Instruction, BasicBlock>; };
void setParent(BasicBlock *P);
protected:
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
Instruction *InsertBefore = 0);
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
BasicBlock *InsertAtEnd);
virtual Instruction *clone_impl() const = 0;
public: public:
// Out of line virtual method, so the vtable, etc has a home. // Out of line virtual method, so the vtable, etc has a home.
~Instruction(); ~Instruction();
@ -131,7 +124,7 @@ public:
/// hasMetadata() - Return true if this instruction has any metadata attached /// hasMetadata() - Return true if this instruction has any metadata attached
/// to it. /// to it.
bool hasMetadata() const { bool hasMetadata() const {
return HasMetadata; return (getSubclassDataFromValue() & HasMetadataBit) != 0;
} }
/// getMetadata - Get the metadata of given kind attached to this Instruction. /// getMetadata - Get the metadata of given kind attached to this Instruction.
@ -312,6 +305,44 @@ public:
#define LAST_OTHER_INST(N) OtherOpsEnd = N+1 #define LAST_OTHER_INST(N) OtherOpsEnd = N+1
#include "llvm/Instruction.def" #include "llvm/Instruction.def"
}; };
private:
// Shadow Value::setValueSubclassData with a private forwarding method so that
// subclasses cannot accidentally use it.
void setValueSubclassData(unsigned short D) {
Value::setValueSubclassData(D);
}
unsigned short getSubclassDataFromValue() const {
return Value::getSubclassDataFromValue();
}
friend class MetadataContextImpl;
void setHasMetadata(bool V) {
setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) |
(V ? HasMetadataBit : 0));
}
friend class SymbolTableListTraits<Instruction, BasicBlock>;
void setParent(BasicBlock *P);
protected:
// Instruction subclasses can stick up to 15 bits of stuff into the
// SubclassData field of instruction with these members.
// Verify that only the low 15 bits are used.
void setInstructionSubclassData(unsigned short D) {
assert((D & HasMetadataBit) == 0 && "Out of range value put into field");
setValueSubclassData((getSubclassDataFromValue() & HasMetadataBit) | D);
}
unsigned getSubclassDataFromInstruction() const {
return getSubclassDataFromValue() & ~HasMetadataBit;
}
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
Instruction *InsertBefore = 0);
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
BasicBlock *InsertAtEnd);
virtual Instruction *clone_impl() const = 0;
}; };
// Instruction* is only 4-byte aligned. // Instruction* is only 4-byte aligned.

View File

@ -83,7 +83,7 @@ public:
/// by the instruction. /// by the instruction.
/// ///
unsigned getAlignment() const { unsigned getAlignment() const {
return (1u << getSubclassDataFromValue()) >> 1; return (1u << getSubclassDataFromInstruction()) >> 1;
} }
void setAlignment(unsigned Align); void setAlignment(unsigned Align);
@ -101,10 +101,10 @@ public:
return isa<Instruction>(V) && classof(cast<Instruction>(V)); return isa<Instruction>(V) && classof(cast<Instruction>(V));
} }
private: private:
// Shadow Value::setValueSubclassData with a private forwarding method so that // Shadow Instruction::setInstructionSubclassData with a private forwarding
// subclasses cannot accidentally use it. // method so that subclasses cannot accidentally use it.
void setValueSubclassData(unsigned short D) { void setInstructionSubclassData(unsigned short D) {
Value::setValueSubclassData(D); Instruction::setInstructionSubclassData(D);
} }
}; };
@ -142,18 +142,19 @@ public:
/// isVolatile - Return true if this is a load from a volatile memory /// isVolatile - Return true if this is a load from a volatile memory
/// location. /// location.
/// ///
bool isVolatile() const { return getSubclassDataFromValue() & 1; } bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
/// setVolatile - Specify whether this is a volatile load or not. /// setVolatile - Specify whether this is a volatile load or not.
/// ///
void setVolatile(bool V) { void setVolatile(bool V) {
setValueSubclassData((getSubclassDataFromValue() & ~1) | (V ? 1 : 0)); setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
(V ? 1 : 0));
} }
/// getAlignment - Return the alignment of the access that is being performed /// getAlignment - Return the alignment of the access that is being performed
/// ///
unsigned getAlignment() const { unsigned getAlignment() const {
return (1 << (getSubclassDataFromValue() >> 1)) >> 1; return (1 << (getSubclassDataFromInstruction() >> 1)) >> 1;
} }
void setAlignment(unsigned Align); void setAlignment(unsigned Align);
@ -176,10 +177,10 @@ public:
return isa<Instruction>(V) && classof(cast<Instruction>(V)); return isa<Instruction>(V) && classof(cast<Instruction>(V));
} }
private: private:
// Shadow Value::setValueSubclassData with a private forwarding method so that // Shadow Instruction::setInstructionSubclassData with a private forwarding
// subclasses cannot accidentally use it. // method so that subclasses cannot accidentally use it.
void setValueSubclassData(unsigned short D) { void setInstructionSubclassData(unsigned short D) {
Value::setValueSubclassData(D); Instruction::setInstructionSubclassData(D);
} }
}; };
@ -214,12 +215,13 @@ public:
/// isVolatile - Return true if this is a load from a volatile memory /// isVolatile - Return true if this is a load from a volatile memory
/// location. /// location.
/// ///
bool isVolatile() const { return getSubclassDataFromValue() & 1; } bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
/// setVolatile - Specify whether this is a volatile load or not. /// setVolatile - Specify whether this is a volatile load or not.
/// ///
void setVolatile(bool V) { void setVolatile(bool V) {
setValueSubclassData((getSubclassDataFromValue() & ~1) | (V ? 1 : 0)); setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
(V ? 1 : 0));
} }
/// Transparently provide more efficient getOperand methods. /// Transparently provide more efficient getOperand methods.
@ -228,7 +230,7 @@ public:
/// getAlignment - Return the alignment of the access that is being performed /// getAlignment - Return the alignment of the access that is being performed
/// ///
unsigned getAlignment() const { unsigned getAlignment() const {
return (1 << (getSubclassDataFromValue() >> 1)) >> 1; return (1 << (getSubclassDataFromInstruction() >> 1)) >> 1;
} }
void setAlignment(unsigned Align); void setAlignment(unsigned Align);
@ -250,10 +252,10 @@ public:
return isa<Instruction>(V) && classof(cast<Instruction>(V)); return isa<Instruction>(V) && classof(cast<Instruction>(V));
} }
private: private:
// Shadow Value::setValueSubclassData with a private forwarding method so that // Shadow Instruction::setInstructionSubclassData with a private forwarding
// subclasses cannot accidentally use it. // method so that subclasses cannot accidentally use it.
void setValueSubclassData(unsigned short D) { void setInstructionSubclassData(unsigned short D) {
Value::setValueSubclassData(D); Instruction::setInstructionSubclassData(D);
} }
}; };
@ -929,9 +931,10 @@ public:
~CallInst(); ~CallInst();
bool isTailCall() const { return getSubclassDataFromValue() & 1; } bool isTailCall() const { return getSubclassDataFromInstruction() & 1; }
void setTailCall(bool isTC = true) { void setTailCall(bool isTC = true) {
setValueSubclassData((getSubclassDataFromValue() & ~1) | unsigned(isTC)); setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
unsigned(isTC));
} }
/// Provide fast operand accessors /// Provide fast operand accessors
@ -940,11 +943,11 @@ public:
/// getCallingConv/setCallingConv - Get or set the calling convention of this /// getCallingConv/setCallingConv - Get or set the calling convention of this
/// function call. /// function call.
CallingConv::ID getCallingConv() const { CallingConv::ID getCallingConv() const {
return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 1); return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 1);
} }
void setCallingConv(CallingConv::ID CC) { void setCallingConv(CallingConv::ID CC) {
setValueSubclassData((getSubclassDataFromValue() & 1) | setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
(static_cast<unsigned>(CC) << 1)); (static_cast<unsigned>(CC) << 1));
} }
/// getAttributes - Return the parameter attributes for this call. /// getAttributes - Return the parameter attributes for this call.
@ -1043,10 +1046,10 @@ public:
return isa<Instruction>(V) && classof(cast<Instruction>(V)); return isa<Instruction>(V) && classof(cast<Instruction>(V));
} }
private: private:
// Shadow Value::setValueSubclassData with a private forwarding method so that // Shadow Instruction::setInstructionSubclassData with a private forwarding
// subclasses cannot accidentally use it. // method so that subclasses cannot accidentally use it.
void setValueSubclassData(unsigned short D) { void setInstructionSubclassData(unsigned short D) {
Value::setValueSubclassData(D); Instruction::setInstructionSubclassData(D);
} }
}; };
@ -2425,10 +2428,10 @@ public:
/// getCallingConv/setCallingConv - Get or set the calling convention of this /// getCallingConv/setCallingConv - Get or set the calling convention of this
/// function call. /// function call.
CallingConv::ID getCallingConv() const { CallingConv::ID getCallingConv() const {
return static_cast<CallingConv::ID>(getSubclassDataFromValue()); return static_cast<CallingConv::ID>(getSubclassDataFromInstruction());
} }
void setCallingConv(CallingConv::ID CC) { void setCallingConv(CallingConv::ID CC) {
setValueSubclassData(static_cast<unsigned>(CC)); setInstructionSubclassData(static_cast<unsigned>(CC));
} }
/// getAttributes - Return the parameter attributes for this invoke. /// getAttributes - Return the parameter attributes for this invoke.
@ -2553,10 +2556,10 @@ private:
virtual unsigned getNumSuccessorsV() const; virtual unsigned getNumSuccessorsV() const;
virtual void setSuccessorV(unsigned idx, BasicBlock *B); virtual void setSuccessorV(unsigned idx, BasicBlock *B);
// Shadow Value::setValueSubclassData with a private forwarding method so that // Shadow Instruction::setInstructionSubclassData with a private forwarding
// subclasses cannot accidentally use it. // method so that subclasses cannot accidentally use it.
void setValueSubclassData(unsigned short D) { void setInstructionSubclassData(unsigned short D) {
Value::setValueSubclassData(D); Instruction::setInstructionSubclassData(D);
} }
}; };

View File

@ -24,8 +24,7 @@ using namespace llvm;
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
Instruction *InsertBefore) Instruction *InsertBefore)
: User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0), : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) {
HasMetadata(false) {
// Make sure that we get added to a basicblock // Make sure that we get added to a basicblock
LeakDetector::addGarbageObject(this); LeakDetector::addGarbageObject(this);
@ -39,8 +38,7 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
BasicBlock *InsertAtEnd) BasicBlock *InsertAtEnd)
: User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0), : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) {
HasMetadata(false) {
// Make sure that we get added to a basicblock // Make sure that we get added to a basicblock
LeakDetector::addGarbageObject(this); LeakDetector::addGarbageObject(this);
@ -53,7 +51,7 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
// Out of line virtual method, so the vtable, etc has a home. // Out of line virtual method, so the vtable, etc has a home.
Instruction::~Instruction() { Instruction::~Instruction() {
assert(Parent == 0 && "Instruction still linked in the program!"); assert(Parent == 0 && "Instruction still linked in the program!");
if (HasMetadata) if (hasMetadata())
getContext().pImpl->TheMetadata.ValueIsDeleted(this); getContext().pImpl->TheMetadata.ValueIsDeleted(this);
} }
@ -464,7 +462,7 @@ bool Instruction::isSafeToSpeculativelyExecute() const {
Instruction *Instruction::clone() const { Instruction *Instruction::clone() const {
Instruction *New = clone_impl(); Instruction *New = clone_impl();
New->SubclassOptionalData = SubclassOptionalData; New->SubclassOptionalData = SubclassOptionalData;
if (HasMetadata) if (hasMetadata())
getContext().pImpl->TheMetadata.ValueIsCloned(this, New); getContext().pImpl->TheMetadata.ValueIsCloned(this, New);
return New; return New;
} }

View File

@ -959,7 +959,7 @@ AllocaInst::~AllocaInst() {
void AllocaInst::setAlignment(unsigned Align) { void AllocaInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
setValueSubclassData(Log2_32(Align) + 1); setInstructionSubclassData(Log2_32(Align) + 1);
assert(getAlignment() == Align && "Alignment representation error!"); assert(getAlignment() == Align && "Alignment representation error!");
} }
@ -1094,8 +1094,8 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile,
void LoadInst::setAlignment(unsigned Align) { void LoadInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
setValueSubclassData((getSubclassDataFromValue() & 1) | setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
((Log2_32(Align)+1)<<1)); ((Log2_32(Align)+1)<<1));
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -1190,8 +1190,8 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
void StoreInst::setAlignment(unsigned Align) { void StoreInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
setValueSubclassData((getSubclassDataFromValue() & 1) | setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
((Log2_32(Align)+1) << 1)); ((Log2_32(Align)+1) << 1));
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -355,9 +355,9 @@ void MetadataContextImpl::setMetadata(Instruction *Inst, unsigned Kind,
// Handle the case when we're adding/updating metadata on an instruction. // Handle the case when we're adding/updating metadata on an instruction.
if (Node) { if (Node) {
MDMapTy &Info = MetadataStore[Inst]; MDMapTy &Info = MetadataStore[Inst];
assert(!Info.empty() == Inst->HasMetadata && "HasMetadata bit is wonked"); assert(!Info.empty() == Inst->hasMetadata() && "HasMetadata bit is wonked");
if (Info.empty()) { if (Info.empty()) {
Inst->HasMetadata = true; Inst->setHasMetadata(true);
} else { } else {
// Handle replacement of an existing value. // Handle replacement of an existing value.
for (unsigned i = 0, e = Info.size(); i != e; ++i) for (unsigned i = 0, e = Info.size(); i != e; ++i)
@ -373,14 +373,14 @@ void MetadataContextImpl::setMetadata(Instruction *Inst, unsigned Kind,
} }
// Otherwise, we're removing metadata from an instruction. // Otherwise, we're removing metadata from an instruction.
assert(Inst->HasMetadata && MetadataStore.count(Inst) && assert(Inst->hasMetadata() && MetadataStore.count(Inst) &&
"HasMetadata bit out of date!"); "HasMetadata bit out of date!");
MDMapTy &Info = MetadataStore[Inst]; MDMapTy &Info = MetadataStore[Inst];
// Common case is removing the only entry. // Common case is removing the only entry.
if (Info.size() == 1 && Info[0].first == Kind) { if (Info.size() == 1 && Info[0].first == Kind) {
MetadataStore.erase(Inst); MetadataStore.erase(Inst);
Inst->HasMetadata = false; Inst->setHasMetadata(false);
return; return;
} }
@ -398,7 +398,7 @@ void MetadataContextImpl::setMetadata(Instruction *Inst, unsigned Kind,
/// removeAllMetadata - Remove all metadata attached with an instruction. /// removeAllMetadata - Remove all metadata attached with an instruction.
void MetadataContextImpl::removeAllMetadata(Instruction *Inst) { void MetadataContextImpl::removeAllMetadata(Instruction *Inst) {
MetadataStore.erase(Inst); MetadataStore.erase(Inst);
Inst->HasMetadata = false; Inst->setHasMetadata(false);
} }