diff options
author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-07-14 23:13:17 +0000 |
---|---|---|
committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-07-14 23:13:17 +0000 |
commit | 345e0cfb86b182c744e618ad39b5181f46110365 (patch) | |
tree | d1a660e5a4e94358d7296015547d76f77c31d13e /lib | |
parent | c105645c16f77ee20b853baf717073ad393dd4aa (diff) | |
download | llvm-345e0cfb86b182c744e618ad39b5181f46110365.tar.gz llvm-345e0cfb86b182c744e618ad39b5181f46110365.tar.bz2 llvm-345e0cfb86b182c744e618ad39b5181f46110365.tar.xz |
Added subclass ConstantExpr to represent expressions consructed from
constants using operators such as cast, getelementptr, add, shl, etc.
Note that a ConstantExpr can be of any type, so classof() in most
other subclasses (that discriminate by type) have to check that it
is also not a ConstantExpr.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2901 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VMCore/Constants.cpp | 141 |
1 files changed, 129 insertions, 12 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index dcce830d16..192f5f7c65 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -7,6 +7,7 @@ #define __STDC_LIMIT_MACROS // Get defs for INT64_MAX and friends... #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/iMemory.h" #include "llvm/SymbolTable.h" #include "llvm/Module.h" #include "llvm/SlotCalculator.h" @@ -75,12 +76,12 @@ void Constant::destroyConstantImpl() { std::cerr << "\n"; } #endif - assert(isa<Constant>(V) && "References remain to ConstantPointerRef!"); + assert(isa<Constant>(V) && "References remain to Constant being destroyed"); Constant *CPV = cast<Constant>(V); CPV->destroyConstant(); // The constant should remove itself from our use list... - assert((use_empty() || use_back() == V) && "Constant not removed!"); + assert((use_empty() || use_back() != V) && "Constant not removed!"); } // Value has no outstanding references it is safe to delete it now... @@ -126,7 +127,8 @@ ConstantArray::ConstantArray(const ArrayType *T, ConstantStruct::ConstantStruct(const StructType *T, const std::vector<Constant*> &V) : Constant(T) { const StructType::ElementTypes &ETypes = T->getElementTypes(); - + assert(V.size() == ETypes.size() && + "Invalid initializer vector for constant structure"); for (unsigned i = 0; i < V.size(); i++) { assert(V[i]->getType() == ETypes[i]); Operands.push_back(Use(V[i], this)); @@ -138,35 +140,58 @@ ConstantPointerRef::ConstantPointerRef(GlobalValue *GV) Operands.push_back(Use(GV, this)); } +ConstantExpr::ConstantExpr(unsigned opCode, Constant *C, const Type *Ty) + : Constant(Ty), iType(opCode) { + Operands.push_back(Use(C, this)); +} + +ConstantExpr::ConstantExpr(unsigned opCode, Constant* C1, + Constant* C2, const Type *Ty) + : Constant(Ty), iType(opCode) { + Operands.push_back(Use(C1, this)); + Operands.push_back(Use(C2, this)); +} + +ConstantExpr::ConstantExpr(unsigned opCode, Constant* C, + const std::vector<Value*>& IdxList, const Type *Ty) + : Constant(Ty), iType(opCode) { + Operands.reserve(1+IdxList.size()); + Operands.push_back(Use(C, this)); + for (unsigned i = 0, E = IdxList.size(); i != E; ++i) + Operands.push_back(Use(IdxList[i], this)); +} + //===----------------------------------------------------------------------===// // classof implementations bool ConstantInt::classof(const Constant *CPV) { - return CPV->getType()->isIntegral(); + return CPV->getType()->isIntegral() && ! isa<ConstantExpr>(CPV); } bool ConstantSInt::classof(const Constant *CPV) { - return CPV->getType()->isSigned(); + return CPV->getType()->isSigned() && ! isa<ConstantExpr>(CPV); } bool ConstantUInt::classof(const Constant *CPV) { - return CPV->getType()->isUnsigned(); + return CPV->getType()->isUnsigned() && ! isa<ConstantExpr>(CPV); } bool ConstantFP::classof(const Constant *CPV) { const Type *Ty = CPV->getType(); - return Ty == Type::FloatTy || Ty == Type::DoubleTy; + return ((Ty == Type::FloatTy || Ty == Type::DoubleTy) && + ! isa<ConstantExpr>(CPV)); } bool ConstantArray::classof(const Constant *CPV) { - return isa<ArrayType>(CPV->getType()); + return isa<ArrayType>(CPV->getType()) && ! isa<ConstantExpr>(CPV); } bool ConstantStruct::classof(const Constant *CPV) { - return isa<StructType>(CPV->getType()); + return isa<StructType>(CPV->getType()) && ! isa<ConstantExpr>(CPV); } bool ConstantPointer::classof(const Constant *CPV) { - return isa<PointerType>(CPV->getType()); + return (isa<PointerType>(CPV->getType()) && ! isa<ConstantExpr>(CPV)); } + //===----------------------------------------------------------------------===// // isValueValidForType implementations @@ -357,13 +382,105 @@ ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) { // ConstantPointerRef *ConstantPointerRef::get(GlobalValue *GV) { assert(GV->getParent() && "Global Value must be attached to a module!"); - + // The Module handles the pointer reference sharing... return GV->getParent()->getConstantPointerRef(GV); } +//---- ConstantExpr::get() implementations... +// Return NULL on invalid expressions. +// +ConstantExpr* +ConstantExpr::get(unsigned opCode, Constant *C, const Type *Ty) { + if (opCode != Instruction::Cast && + (opCode < Instruction::FirstUnaryOp || + opCode >= Instruction::NumUnaryOps)) { + cerr << "Invalid opcode " << ConstantExpr::getOpcodeName(opCode) + << " in unary constant expression" << endl; + return NULL; // Not Cast or other unary opcode + } + // type of operand will not match result for Cast operation + if (opCode != Instruction::Cast && Ty != C->getType()) { + cerr << "Type of operand in unary constant expression should match result" << endl; + return NULL; + } + return new ConstantExpr(opCode, C, Ty); +} + +ConstantExpr* +ConstantExpr::get(unsigned opCode, Constant *C1, Constant *C2,const Type *Ty) { + if (opCode < Instruction::FirstBinaryOp || + opCode >= Instruction::NumBinaryOps) { + cerr << "Invalid opcode " << ConstantExpr::getOpcodeName(opCode) + << " in binary constant expression" << endl; + return NULL; + } + if (Ty != C1->getType() || Ty != C2->getType()) { + cerr << "Types of both operands in binary constant expression should match result" << endl; + return NULL; + } + return new ConstantExpr(opCode, C1, C2, Ty); +} -void ConstantPointerRef::mutateReference(GlobalValue *NewGV) { +ConstantExpr* +ConstantExpr::get(unsigned opCode, Constant*C, + const std::vector<Value*>& idxList, const Type *Ty) { + // Must be a getElementPtr. Check for valid getElementPtr expression. + // + if (opCode != Instruction::GetElementPtr) { + cerr << "operator other than GetElementPtr used with an index list" << endl; + return NULL; + } + if (!isa<ConstantPointer>(C)) { + cerr << "Constant GelElementPtr expression using something other than a constant pointer" << endl; + return NULL; + } + if (!isa<PointerType>(Ty)) { + cerr << "Non-pointer type for constant GelElementPtr expression" << endl; + return NULL; + } + const Type* fldType = GetElementPtrInst::getIndexedType(C->getType(), + idxList, true); + if (!fldType) { + cerr << "Invalid index list for constant GelElementPtr expression" << endl; + return NULL; + } + if (cast<PointerType>(Ty)->getElementType() != fldType) { + cerr << "Type for constant GelElementPtr expression does not match field type" << endl; + return NULL; + } + + return new ConstantExpr(opCode, C, idxList, Ty); +} + +const char* +ConstantExpr::getOpcodeName(unsigned opCode) { + return Instruction::getOpcodeName(opCode); +} + + +//---- ConstantPointerRef::mutateReferences() implementation... +// +unsigned +ConstantPointerRef::mutateReferences(Value* OldV, Value *NewV) { + assert(getValue() == OldV && "Cannot mutate old value if I'm not using it!"); + GlobalValue* NewGV = cast<GlobalValue>(NewV); getValue()->getParent()->mutateConstantPointerRef(getValue(), NewGV); Operands[0] = NewGV; + return 1; +} + + +//---- ConstantPointerExpr::mutateReferences() implementation... +// +unsigned +ConstantExpr::mutateReferences(Value* OldV, Value *NewV) { + unsigned numReplaced = 0; + Constant* NewC = cast<Constant>(NewV); + for (unsigned i=0, N = getNumOperands(); i < N; ++i) + if (Operands[i] == OldV) { + ++numReplaced; + Operands[i] = NewC; + } + return numReplaced; } |