X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstants.cpp;h=55bc4aef04c071a321daf30af15a21c574497afa;hb=0bd135db5942c4cbd5bef11cf21814bf5d1d1037;hp=352e963eb441b2f01d3d93f8ca87b433b3af3ca4;hpb=a1e3f543965ee3ee8bc67273ccd4781861054102;p=oota-llvm.git diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 352e963eb44..55bc4aef04c 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -250,12 +250,12 @@ ConstantArray::ConstantArray(const ArrayType *T, Use *OL = OperandList; for (std::vector::const_iterator I = V.begin(), E = V.end(); I != E; ++I, ++OL) { - Constant *E = *I; - assert((E->getType() == T->getElementType() || + Constant *C = *I; + assert((C->getType() == T->getElementType() || (T->isAbstract() && - E->getType()->getTypeID() == T->getElementType()->getTypeID())) && + C->getType()->getTypeID() == T->getElementType()->getTypeID())) && "Initializer for array element doesn't match array element type!"); - OL->init(E, this); + OL->init(C, this); } } @@ -271,14 +271,14 @@ ConstantStruct::ConstantStruct(const StructType *T, Use *OL = OperandList; for (std::vector::const_iterator I = V.begin(), E = V.end(); I != E; ++I, ++OL) { - Constant *E = *I; - assert((E->getType() == T->getElementType(I-V.begin()) || + Constant *C = *I; + assert((C->getType() == T->getElementType(I-V.begin()) || ((T->getElementType(I-V.begin())->isAbstract() || - E->getType()->isAbstract()) && + C->getType()->isAbstract()) && T->getElementType(I-V.begin())->getTypeID() == - E->getType()->getTypeID())) && + C->getType()->getTypeID())) && "Initializer for struct element doesn't match struct element type!"); - OL->init(E, this); + OL->init(C, this); } } @@ -293,12 +293,12 @@ ConstantPacked::ConstantPacked(const PackedType *T, Use *OL = OperandList; for (std::vector::const_iterator I = V.begin(), E = V.end(); I != E; ++I, ++OL) { - Constant *E = *I; - assert((E->getType() == T->getElementType() || + Constant *C = *I; + assert((C->getType() == T->getElementType() || (T->isAbstract() && - E->getType()->getTypeID() == T->getElementType()->getTypeID())) && + C->getType()->getTypeID() == T->getElementType()->getTypeID())) && "Initializer for packed element doesn't match packed element type!"); - OL->init(E, this); + OL->init(C, this); } } @@ -347,6 +347,35 @@ public: } }; +/// ExtractElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// extractelement constant exprs. +class ExtractElementConstantExpr : public ConstantExpr { + Use Ops[2]; +public: + ExtractElementConstantExpr(Constant *C1, Constant *C2) + : ConstantExpr(cast(C1->getType())->getElementType(), + Instruction::ExtractElement, Ops, 2) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + } +}; + +/// InsertElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// insertelement constant exprs. +class InsertElementConstantExpr : public ConstantExpr { + Use Ops[3]; +public: + InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C1->getType(), Instruction::InsertElement, + Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); + } +}; + /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is /// used behind the scenes to implement getelementpr constant exprs. struct GetElementPtrConstantExpr : public ConstantExpr { @@ -1141,6 +1170,11 @@ namespace llvm { return new BinaryConstantExpr(V.first, V.second[0], V.second[1]); if (V.first == Instruction::Select) return new SelectConstantExpr(V.second[0], V.second[1], V.second[2]); + if (V.first == Instruction::ExtractElement) + return new ExtractElementConstantExpr(V.second[0], V.second[1]); + if (V.first == Instruction::InsertElement) + return new InsertElementConstantExpr(V.second[0], V.second[1], + V.second[2]); assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!"); @@ -1277,14 +1311,15 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { case Instruction::Mul: case Instruction::Div: case Instruction::Rem: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert((C1->getType()->isInteger() || C1->getType()->isFloatingPoint()) && + assert((C1->getType()->isInteger() || C1->getType()->isFloatingPoint() || + isa(C1->getType())) && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; case Instruction::And: case Instruction::Or: case Instruction::Xor: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isIntegral() && + assert((C1->getType()->isIntegral() || isa(C1->getType())) && "Tried to create a logical operation on a non-integral type!"); break; case Instruction::SetLT: case Instruction::SetGT: case Instruction::SetLE: @@ -1294,7 +1329,7 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { case Instruction::Shl: case Instruction::Shr: assert(C2->getType() == Type::UByteTy && "Shift should be by ubyte!"); - assert(C1->getType()->isInteger() && + assert((C1->getType()->isInteger() || isa(C1->getType())) && "Tried to create a shift operation on a non-integer type!"); break; default: @@ -1385,6 +1420,49 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, return getGetElementPtrTy(PointerType::get(Ty), C, IdxList); } +Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val, + Constant *Idx) { + if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx)) + return FC; // Fold a few common cases... + // Look up the constant in the table first to ensure uniqueness + std::vector ArgVec(1, Val); + ArgVec.push_back(Idx); + const ExprMapKeyType &Key = std::make_pair(Instruction::ExtractElement,ArgVec); + return ExprConstants.getOrCreate(ReqTy, Key); +} + +Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) { + assert(isa(Val->getType()) && + "Tried to create extractelement operation on non-packed type!"); + assert(Idx->getType() == Type::UIntTy && + "Extractelement index must be uint type!"); + return getExtractElementTy(cast(Val->getType())->getElementType(), + Val, Idx); +} + +Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, + Constant *Elt, Constant *Idx) { + if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx)) + return FC; // Fold a few common cases... + // Look up the constant in the table first to ensure uniqueness + std::vector ArgVec(1, Val); + ArgVec.push_back(Elt); + ArgVec.push_back(Idx); + const ExprMapKeyType &Key = std::make_pair(Instruction::InsertElement,ArgVec); + return ExprConstants.getOrCreate(ReqTy, Key); +} + +Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, + Constant *Idx) { + assert(isa(Val->getType()) && + "Tried to create insertelement operation on non-packed type!"); + assert(Elt->getType() == cast(Val->getType())->getElementType() + && "Insertelement types must match!"); + assert(Idx->getType() == Type::UIntTy && + "Insertelement index must be uint type!"); + return getInsertElementTy(cast(Val->getType())->getElementType(), + Val, Elt, Idx); +} // destroyConstant - Remove the constant from the constant table... // @@ -1580,6 +1658,12 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, if (C2 == From) C2 = To; if (C3 == From) C3 = To; Replacement = ConstantExpr::getSelect(C1, C2, C3); + } else if (getOpcode() == Instruction::ExtractElement) { + Constant *C1 = getOperand(0); + Constant *C2 = getOperand(1); + if (C1 == From) C1 = To; + if (C2 == From) C2 = To; + Replacement = ConstantExpr::getExtractElement(C1, C2); } else if (getNumOperands() == 2) { Constant *C1 = getOperand(0); Constant *C2 = getOperand(1); @@ -1628,3 +1712,47 @@ void Constant::clearAllValueMaps() { (*I)->destroyConstantImpl(); Constants.clear(); } + +/// getStringValue - Turn an LLVM constant pointer that eventually points to a +/// global into a string value. Return an empty string if we can't do it. +/// Parameter Chop determines if the result is chopped at the first null +/// terminator. +/// +std::string Constant::getStringValue(bool Chop, unsigned Offset) { + if (GlobalVariable *GV = dyn_cast(this)) { + if (GV->hasInitializer() && isa(GV->getInitializer())) { + ConstantArray *Init = cast(GV->getInitializer()); + if (Init->isString()) { + std::string Result = Init->getAsString(); + if (Offset < Result.size()) { + // If we are pointing INTO The string, erase the beginning... + Result.erase(Result.begin(), Result.begin()+Offset); + + // Take off the null terminator, and any string fragments after it. + if (Chop) { + std::string::size_type NullPos = Result.find_first_of((char)0); + if (NullPos != std::string::npos) + Result.erase(Result.begin()+NullPos, Result.end()); + } + return Result; + } + } + } + } else if (Constant *C = dyn_cast(this)) { + if (GlobalValue *GV = dyn_cast(C)) + return GV->getStringValue(Chop, Offset); + else if (ConstantExpr *CE = dyn_cast(C)) { + if (CE->getOpcode() == Instruction::GetElementPtr) { + // Turn a gep into the specified offset. + if (CE->getNumOperands() == 3 && + cast(CE->getOperand(1))->isNullValue() && + isa(CE->getOperand(2))) { + Offset += cast(CE->getOperand(2))->getRawValue(); + return CE->getOperand(0)->getStringValue(Chop, Offset); + } + } + } + } + return ""; +} +