X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstants.cpp;h=c519da36a861ecaee3b26f4c775ebca72fc03c79;hb=893af8c058aad683027c604d6cbe818c59e0eda8;hp=fe6af758bd713fc174a3a94e911766945d76a333;hpb=562219de55f007b0dbd3aeffad888e530a8faad4;p=oota-llvm.git diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index fe6af758bd7..c519da36a86 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -4,13 +4,12 @@ // //===----------------------------------------------------------------------===// -#define __STDC_LIMIT_MACROS // Get defs for INT64_MAX and friends... #include "llvm/Constants.h" +#include "llvm/ConstantHandling.h" #include "llvm/DerivedTypes.h" #include "llvm/iMemory.h" #include "llvm/SymbolTable.h" #include "llvm/Module.h" -#include "llvm/SlotCalculator.h" #include "Support/StringExtras.h" #include @@ -81,7 +80,25 @@ Constant *Constant::getNullValue(const Type *Ty) { case Type::PointerTyID: return ConstantPointerNull::get(cast(Ty)); + case Type::StructTyID: { + const StructType *ST = cast(Ty); + + const StructType::ElementTypes &ETs = ST->getElementTypes(); + std::vector Elements; + Elements.resize(ETs.size()); + for (unsigned i = 0, e = ETs.size(); i != e; ++i) + Elements[i] = Constant::getNullValue(ETs[i]); + return ConstantStruct::get(ST, Elements); + } + case Type::ArrayTyID: { + const ArrayType *AT = cast(Ty); + Constant *El = Constant::getNullValue(AT->getElementType()); + unsigned NumElements = AT->getNumElements(); + return ConstantArray::get(AT, std::vector(NumElements, El)); + } default: + // Function, Type, Label, or Opaque type? + assert(0 && "Cannot create a null constant of that type!"); return 0; } } @@ -157,6 +174,13 @@ ConstantIntegral *ConstantIntegral::getAllOnesValue(const Type *Ty) { } } +bool ConstantUInt::isAllOnesValue() const { + unsigned TypeBits = getType()->getPrimitiveSize()*8; + uint64_t Val = ~0ULL; // All ones + Val >>= 64-TypeBits; // Shift out inappropriate bits + return getValue() == Val; +} + //===----------------------------------------------------------------------===// // ConstantXXX Classes @@ -192,7 +216,8 @@ ConstantFP::ConstantFP(const Type *Ty, double V) : Constant(Ty) { ConstantArray::ConstantArray(const ArrayType *T, const std::vector &V) : Constant(T) { - for (unsigned i = 0; i < V.size(); i++) { + Operands.reserve(V.size()); + for (unsigned i = 0, e = V.size(); i != e; ++i) { assert(V[i]->getType() == T->getElementType()); Operands.push_back(Use(V[i], this)); } @@ -203,7 +228,8 @@ ConstantStruct::ConstantStruct(const StructType *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++) { + Operands.reserve(V.size()); + for (unsigned i = 0, e = V.size(); i != e; ++i) { assert(V[i]->getType() == ETypes[i]); Operands.push_back(Use(V[i], this)); } @@ -325,6 +351,112 @@ bool ConstantFP::isValueValidForType(const Type *Ty, double Val) { } }; +//===----------------------------------------------------------------------===// +// replaceUsesOfWithOnConstant implementations + +void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To) { + assert(isa(To) && "Cannot make Constant refer to non-constant!"); + + std::vector Values; + Values.reserve(getValues().size()); // Build replacement array... + for (unsigned i = 0, e = getValues().size(); i != e; ++i) { + Constant *Val = cast(getValues()[i]); + if (Val == From) Val = cast(To); + Values.push_back(Val); + } + + ConstantArray *Replacement = ConstantArray::get(getType(), Values); + assert(Replacement != this && "I didn't contain From!"); + + // Everyone using this now uses the replacement... + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); +} + +void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To) { + assert(isa(To) && "Cannot make Constant refer to non-constant!"); + + std::vector Values; + Values.reserve(getValues().size()); + for (unsigned i = 0, e = getValues().size(); i != e; ++i) { + Constant *Val = cast(getValues()[i]); + if (Val == From) Val = cast(To); + Values.push_back(Val); + } + + ConstantStruct *Replacement = ConstantStruct::get(getType(), Values); + assert(Replacement != this && "I didn't contain From!"); + + // Everyone using this now uses the replacement... + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); +} + +void ConstantPointerRef::replaceUsesOfWithOnConstant(Value *From, Value *To) { + if (isa(To)) { + assert(From == getOperand(0) && "Doesn't contain from!"); + ConstantPointerRef *Replacement = + ConstantPointerRef::get(cast(To)); + + // Everyone using this now uses the replacement... + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); + } else { + // Just replace ourselves with the To value specified. + replaceAllUsesWith(To); + + // Delete the old constant! + destroyConstant(); + } +} + +void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *To) { + assert(isa(To) && "Cannot make Constant refer to non-constant!"); + + Constant *Replacement = 0; + if (getOpcode() == Instruction::GetElementPtr) { + std::vector Indices; + Constant *Pointer = cast(getOperand(0)); + Indices.reserve(getNumOperands()-1); + if (Pointer == From) Pointer = cast(To); + + for (unsigned i = 1, e = getNumOperands(); i != e; ++i) { + Constant *Val = cast(getOperand(i)); + if (Val == From) Val = cast(To); + Indices.push_back(Val); + } + Replacement = ConstantExpr::getGetElementPtr(Pointer, Indices); + } else if (getOpcode() == Instruction::Cast) { + assert(getOperand(0) == From && "Cast only has one use!"); + Replacement = ConstantExpr::getCast(cast(To), getType()); + } else if (getNumOperands() == 2) { + Constant *C1 = cast(getOperand(0)); + Constant *C2 = cast(getOperand(1)); + if (C1 == From) C1 = cast(To); + if (C2 == From) C2 = cast(To); + Replacement = ConstantExpr::get(getOpcode(), C1, C2); + } else { + assert(0 && "Unknown ConstantExpr type!"); + return; + } + + assert(Replacement != this && "I didn't contain From!"); + + // Everyone using this now uses the replacement... + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); +} + + + //===----------------------------------------------------------------------===// // Factory Function Implementation @@ -504,7 +636,9 @@ void ConstantPointerRef::destroyConstant() { typedef pair > ExprMapKeyType; static ValueMap ExprConstants; -ConstantExpr *ConstantExpr::getCast(Constant *C, const Type *Ty) { +Constant *ConstantExpr::getCast(Constant *C, const Type *Ty) { + if (Constant *FC = ConstantFoldCastInstruction(C, Ty)) + return FC; // Fold a few common cases... // Look up the constant in the table first to ensure uniqueness vector argVec(1, C); @@ -518,7 +652,11 @@ ConstantExpr *ConstantExpr::getCast(Constant *C, const Type *Ty) { return Result; } -ConstantExpr *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { +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 argVec(1, C1); argVec.push_back(C2); const ExprMapKeyType &Key = make_pair(Opcode, argVec); @@ -527,8 +665,8 @@ ConstantExpr *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { // 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::FirstBinaryOp && - Opcode < Instruction::NumBinaryOps) && + assert((Opcode >= Instruction::BinaryOpsBegin && + Opcode < Instruction::BinaryOpsEnd) && "Invalid opcode in binary constant expression"); assert(C1->getType() == C2->getType() && @@ -539,8 +677,10 @@ ConstantExpr *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { return Result; } -ConstantExpr *ConstantExpr::getGetElementPtr(Constant *C, - const std::vector &IdxList) { +Constant *ConstantExpr::getGetElementPtr(Constant *C, + const std::vector &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 @@ -578,27 +718,25 @@ const char *ConstantExpr::getOpcodeName() const { return Instruction::getOpcodeName(getOpcode()); } - -//---- 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; +unsigned Constant::mutateReferences(Value *OldV, Value *NewV) { + // Uses of constant pointer refs are global values, not constants! + if (ConstantPointerRef *CPR = dyn_cast(this)) { + GlobalValue *NewGV = cast(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(NewV); + unsigned NumReplaced = 0; + for (unsigned i = 0, N = getNumOperands(); i != N; ++i) + if (Operands[i] == OldV) { + ++NumReplaced; + Operands[i] = NewC; + } + return NumReplaced; + } }