mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
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:
parent
cd4f04d6bc
commit
2ee11eccdd
@ -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.
|
||||
///
|
||||
|
@ -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
|
||||
|
@ -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!");
|
||||
|
@ -126,6 +126,7 @@ public:
|
||||
|
||||
ConstantUniqueMap<char, Type, UndefValue> UndefValueConstants;
|
||||
|
||||
DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
|
||||
ConstantUniqueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants;
|
||||
|
||||
ConstantInt *TheTrueVal;
|
||||
|
Loading…
Reference in New Issue
Block a user