aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-10-28 00:01:44 +0000
committerChris Lattner <sabre@nondot.org>2009-10-28 00:01:44 +0000
commit2ee11eccdde14c95c78773be76b02bb5fd09d7ee (patch)
treefb35c2b746714f2074d1e391b04682b3080b625f
parentcd4f04d6bcb7aefa24d92582fbadfe17519f4756 (diff)
downloadexternal_llvm-2ee11eccdde14c95c78773be76b02bb5fd09d7ee.zip
external_llvm-2ee11eccdde14c95c78773be76b02bb5fd09d7ee.tar.gz
external_llvm-2ee11eccdde14c95c78773be76b02bb5fd09d7ee.tar.bz2
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
-rw-r--r--include/llvm/Constants.h40
-rw-r--r--include/llvm/Value.h1
-rw-r--r--lib/VMCore/Constants.cpp79
-rw-r--r--lib/VMCore/LLVMContextImpl.h1
4 files changed, 115 insertions, 6 deletions
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index 2855fdc..0b881dc 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -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.
///
diff --git a/include/llvm/Value.h b/include/llvm/Value.h
index c09fdfb..b485524 100644
--- a/include/llvm/Value.h
+++ b/include/llvm/Value.h
@@ -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
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 02c3352..c2402da 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -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!");
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index 68bd01f..fd39b0c 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -126,6 +126,7 @@ public:
ConstantUniqueMap<char, Type, UndefValue> UndefValueConstants;
+ DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
ConstantUniqueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants;
ConstantInt *TheTrueVal;