+Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
+
+ if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
+ return FC; // Fold a few common cases...
+
+ // Look up the constant in the table first to ensure uniqueness
+ vector<Constant*> argVec(1, C1); argVec.push_back(C2);
+ const ExprMapKeyType &Key = make_pair(Opcode, argVec);
+ ConstantExpr *Result = ExprConstants.get(C1->getType(), Key);
+ if (Result) return Result;
+
+ // Its not in the table so create a new one and put it in the table.
+ // Check the operands for consistency first
+ assert((Opcode >= Instruction::BinaryOpsBegin &&
+ Opcode < Instruction::BinaryOpsEnd) &&
+ "Invalid opcode in binary constant expression");
+
+ assert(C1->getType() == C2->getType() &&
+ "Operand types in binary constant expression should match");
+
+ Result = new ConstantExpr(Opcode, C1, C2);
+ ExprConstants.add(C1->getType(), Key, Result);
+ return Result;
+}
+
+Constant *ConstantExpr::getGetElementPtr(Constant *C,
+ const std::vector<Constant*> &IdxList){
+ if (Constant *FC = ConstantFoldGetElementPtr(C, IdxList))
+ return FC; // Fold a few common cases...
+ const Type *Ty = C->getType();
+
+ // Look up the constant in the table first to ensure uniqueness
+ vector<Constant*> argVec(1, C);
+ argVec.insert(argVec.end(), IdxList.begin(), IdxList.end());
+
+ const ExprMapKeyType &Key = make_pair(Instruction::GetElementPtr, argVec);
+ ConstantExpr *Result = ExprConstants.get(Ty, Key);
+ if (Result) return Result;
+
+ // Its not in the table so create a new one and put it in the table.
+ // Check the operands for consistency first
+ //
+ assert(isa<PointerType>(Ty) &&
+ "Non-pointer type for constant GelElementPtr expression");
+
+ // Check that the indices list is valid...
+ std::vector<Value*> ValIdxList(IdxList.begin(), IdxList.end());
+ const Type *DestTy = GetElementPtrInst::getIndexedType(Ty, ValIdxList, true);
+ assert(DestTy && "Invalid index list for constant GelElementPtr expression");
+
+ Result = new ConstantExpr(C, IdxList, PointerType::get(DestTy));
+ ExprConstants.add(Ty, Key, Result);
+ return Result;
+}
+
+// destroyConstant - Remove the constant from the constant table...
+//
+void ConstantExpr::destroyConstant() {
+ ExprConstants.remove(this);
+ destroyConstantImpl();
+}
+
+const char *ConstantExpr::getOpcodeName() const {
+ return Instruction::getOpcodeName(getOpcode());
+}
+
+unsigned Constant::mutateReferences(Value *OldV, Value *NewV) {
+ // Uses of constant pointer refs are global values, not constants!
+ if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(this)) {
+ GlobalValue *NewGV = cast<GlobalValue>(NewV);
+ GlobalValue *OldGV = CPR->getValue();
+
+ assert(OldGV == OldV && "Cannot mutate old value if I'm not using it!");
+
+ OldGV->getParent()->mutateConstantPointerRef(OldGV, NewGV);
+ Operands[0] = NewGV;
+ return 1;
+ } else {
+ Constant *NewC = cast<Constant>(NewV);
+ unsigned NumReplaced = 0;
+ for (unsigned i = 0, N = getNumOperands(); i != N; ++i)
+ if (Operands[i] == OldV) {
+ ++NumReplaced;
+ Operands[i] = NewC;
+ }
+ return NumReplaced;
+ }