summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2002-07-14 23:13:17 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2002-07-14 23:13:17 +0000
commit345e0cfb86b182c744e618ad39b5181f46110365 (patch)
treed1a660e5a4e94358d7296015547d76f77c31d13e /lib
parentc105645c16f77ee20b853baf717073ad393dd4aa (diff)
downloadllvm-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.cpp141
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;
}