IR support for the new BlockAddress constant kind. This is

untested and there is no way to use it, next up: doing battle
with asmparser.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85349 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2009-10-28 00:01:44 +00:00
parent cd4f04d6bc
commit 2ee11eccdd
4 changed files with 115 additions and 6 deletions

View File

@ -549,7 +549,47 @@ public:
}
};
/// BlockAddress - The address of a basic block.
///
class BlockAddress : public Constant {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
void *operator new(size_t s) { return User::operator new(s, 2); }
BlockAddress(Function *F, BasicBlock *BB);
public:
/// get - Return a BlockAddress for the specified function and basic block.
static BlockAddress *get(Function *F, BasicBlock *BB);
/// get - Return a BlockAddress for the specified basic block. The basic
/// block must be embedded into a function.
static BlockAddress *get(BasicBlock *BB);
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
Function *getFunction() const { return (Function*)Op<0>().get(); }
BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); }
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue.
virtual bool isNullValue() const { return false; }
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const BlockAddress *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == BlockAddressVal;
}
};
template <>
struct OperandTraits<BlockAddress> : public FixedNumOperandTraits<2> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Constant)
//===----------------------------------------------------------------------===//
/// ConstantExpr - a constant value that is initialized with an expression using
/// other constant values.
///

View File

@ -210,6 +210,7 @@ public:
GlobalAliasVal, // This is an instance of GlobalAlias
GlobalVariableVal, // This is an instance of GlobalVariable
UndefValueVal, // This is an instance of UndefValue
BlockAddressVal, // This is an instance of BlockAddress
ConstantExprVal, // This is an instance of ConstantExpr
ConstantAggregateZeroVal, // This is an instance of ConstantAggregateNull
ConstantIntVal, // This is an instance of ConstantInt

View File

@ -987,7 +987,7 @@ Constant *ConstantVector::getSplatValue() {
return Elt;
}
//---- ConstantPointerNull::get() implementation...
//---- ConstantPointerNull::get() implementation.
//
ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) {
@ -1004,23 +1004,90 @@ void ConstantPointerNull::destroyConstant() {
}
//---- UndefValue::get() implementation...
//---- UndefValue::get() implementation.
//
UndefValue *UndefValue::get(const Type *Ty) {
// Implicitly locked.
return Ty->getContext().pImpl->UndefValueConstants.getOrCreate(Ty, 0);
}
// destroyConstant - Remove the constant from the constant table.
//
void UndefValue::destroyConstant() {
// Implicitly locked.
getType()->getContext().pImpl->UndefValueConstants.remove(this);
destroyConstantImpl();
}
//---- ConstantExpr::get() implementations...
//---- BlockAddress::get() implementation.
//
BlockAddress *BlockAddress::get(BasicBlock *BB) {
assert(BB->getParent() != 0 && "Block must have a parent");
return get(BB->getParent(), BB);
}
BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
BlockAddress *&BA =
F->getContext().pImpl->BlockAddresses[std::make_pair(F, BB)];
if (BA == 0)
BA = new BlockAddress(F, BB);
assert(BA->getFunction() == F && "Basic block moved between functions");
return BA;
}
BlockAddress::BlockAddress(Function *F, BasicBlock *BB)
: Constant(Type::getInt8PtrTy(F->getContext()), Value::BlockAddressVal,
&Op<0>(), 2) {
Op<0>() = F;
Op<1>() = BB;
}
// destroyConstant - Remove the constant from the constant table.
//
void BlockAddress::destroyConstant() {
getFunction()->getType()->getContext().pImpl
->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock()));
destroyConstantImpl();
}
void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) {
// This could be replacing either the Basic Block or the Function. In either
// case, we have to remove the map entry.
Function *NewF = getFunction();
BasicBlock *NewBB = getBasicBlock();
if (U == &Op<0>())
NewF = cast<Function>(To);
else
NewBB = cast<BasicBlock>(To);
// See if the 'new' entry already exists, if not, just update this in place
// and return early.
BlockAddress *&NewBA =
getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)];
if (NewBA == 0) {
// Remove the old entry, this can't cause the map to rehash (just a
// tombstone will get added).
getContext().pImpl->BlockAddresses.erase(std::make_pair(getFunction(),
getBasicBlock()));
NewBA = this;
Op<0>() = NewF;
Op<1>() = NewBB;
return;
}
// Otherwise, I do need to replace this with an existing value.
assert(NewBA != this && "I didn't contain From!");
// Everyone using this now uses the replacement.
uncheckedReplaceAllUsesWith(NewBA);
destroyConstant();
}
//---- ConstantExpr::get() implementations.
//
/// This is a utility function to handle folding of casts and lookup of the
@ -1838,7 +1905,7 @@ const char *ConstantExpr::getOpcodeName() const {
/// single invocation handles all 1000 uses. Handling them one at a time would
/// work, but would be really slow because it would have to unique each updated
/// array instance.
///
void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");

View File

@ -126,6 +126,7 @@ public:
ConstantUniqueMap<char, Type, UndefValue> UndefValueConstants;
DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
ConstantUniqueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants;
ConstantInt *TheTrueVal;