From 345e0cfb86b182c744e618ad39b5181f46110365 Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Sun, 14 Jul 2002 23:13:17 +0000 Subject: [PATCH] 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 --- lib/VMCore/Constants.cpp | 141 +++++++++++++++++++++++++++++++++++---- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index dcce830d16c..192f5f7c65f 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(V) && "References remain to ConstantPointerRef!"); + assert(isa(V) && "References remain to Constant being destroyed"); Constant *CPV = cast(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 &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& 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(CPV); } bool ConstantSInt::classof(const Constant *CPV) { - return CPV->getType()->isSigned(); + return CPV->getType()->isSigned() && ! isa(CPV); } bool ConstantUInt::classof(const Constant *CPV) { - return CPV->getType()->isUnsigned(); + return CPV->getType()->isUnsigned() && ! isa(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(CPV)); } bool ConstantArray::classof(const Constant *CPV) { - return isa(CPV->getType()); + return isa(CPV->getType()) && ! isa(CPV); } bool ConstantStruct::classof(const Constant *CPV) { - return isa(CPV->getType()); + return isa(CPV->getType()) && ! isa(CPV); } bool ConstantPointer::classof(const Constant *CPV) { - return isa(CPV->getType()); + return (isa(CPV->getType()) && ! isa(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& 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(C)) { + cerr << "Constant GelElementPtr expression using something other than a constant pointer" << endl; + return NULL; + } + if (!isa(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(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(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(NewV); + for (unsigned i=0, N = getNumOperands(); i < N; ++i) + if (Operands[i] == OldV) { + ++numReplaced; + Operands[i] = NewC; + } + return numReplaced; } -- 2.34.1