//===-- Constants.cpp - Implement Constant nodes --------------------------===////// The LLVM Compiler Infrastructure//// This file was developed by the LLVM research group and is distributed under// the University of Illinois Open Source License. See LICENSE.TXT for details.////===----------------------------------------------------------------------===////// This file implements the Constant* classes...////===----------------------------------------------------------------------===//#include"llvm/Constants.h"#include"ConstantFold.h"#include"llvm/DerivedTypes.h"#include"llvm/GlobalValue.h"#include"llvm/Instructions.h"#include"llvm/Module.h"#include"llvm/ADT/StringExtras.h"#include"llvm/Support/Compiler.h"#include"llvm/Support/Debug.h"#include"llvm/Support/ManagedStatic.h"#include"llvm/Support/MathExtras.h"#include"llvm/ADT/DenseMap.h"#include"llvm/ADT/SmallVector.h"#include<algorithm>#include<map>usingnamespacellvm;//===----------------------------------------------------------------------===//// Constant Class//===----------------------------------------------------------------------===//voidConstant::destroyConstantImpl(){// When a Constant is destroyed, there may be lingering// references to the constant by other constants in the constant pool. These// constants are implicitly dependent on the module that is being deleted,// but they don't know that. Because we only find out when the CPV is// deleted, we must now notify all of our users (that should only be// Constants) that they are, in fact, invalid now and should be deleted.//while(!use_empty()){Value*V=use_back();#ifndef NDEBUG // Only in -g mode...if(!isa<Constant>(V))DOUT<<"While deleting: "<<*this<<"\n\nUse still stuck around after Def is destroyed: "<<*V<<"\n\n";#endifassert(isa<Constant>(V)&&"References remain to Constant being destroyed");Constant*CV=cast<Constant>(V);CV->destroyConstant();// The constant should remove itself from our use list...assert((use_empty()||use_back()!=V)&&"Constant not removed!");}// Value has no outstanding references it is safe to delete it now...deletethis;}/// canTrap - Return true if evaluation of this constant could trap. This is/// true for things like constant expressions that could divide by zero.boolConstant::canTrap()const{assert(getType()->isFirstClassType()&&"Cannot evaluate aggregate vals!");// The only thing that could possibly trap are constant exprs.constConstantExpr*CE=dyn_cast<ConstantExpr>(this);if(!CE)returnfalse;// ConstantExpr traps if any operands can trap. for(unsignedi=0,e=getNumOperands();i!=e;++i)if(getOperand(i)->canTrap())returntrue;// Otherwise, only specific operations can trap.switch(CE->getOpcode()){default:returnfalse;caseInstruction::UDiv:caseInstruction::SDiv:caseInstruction::FDiv:caseInstruction::URem:caseInstruction::SRem:caseInstruction::FRem:// Div and rem can trap if the RHS is not known to be non-zero.if(!isa<ConstantInt>(getOperand(1))||getOperand(1)->isNullValue())returntrue;returnfalse;}}/// ContaintsRelocations - Return true if the constant value contains/// relocations which cannot be resolved at compile time.boolConstant::ContainsRelocations()const{if(isa<GlobalValue>(this))returntrue;for(unsignedi=0,e=getNumOperands();i!=e;++i)if(getOperand(i)->ContainsRelocations())returntrue;returnfalse;}// Static constructor to create a '0' constant of arbitrary type...Constant*Constant::getNullValue(constType*Ty){staticuint64_tzero[2]={0,0};switch(Ty->getTypeID()){caseType::IntegerTyID:returnConstantInt::get(Ty,0);caseType::FloatTyID:returnConstantFP::get(Ty,APFloat(APInt(32,0)));caseType::DoubleTyID:returnConstantFP::get(Ty,APFloat(APInt(64,0)));caseType::X86_FP80TyID:returnConstantFP::get(Ty,APFloat(APInt(80,2,zero)));caseType::FP128TyID:returnConstantFP::get(Ty,APFloat(APInt(128,2,zero),true));caseType::PPC_FP128TyID:returnConstantFP::get(Ty,APFloat(APInt(128,2,zero)));caseType::PointerTyID:returnConstantPointerNull::get(cast<PointerType>(Ty));caseType::StructTyID:caseType::ArrayTyID:caseType::VectorTyID:returnConstantAggregateZero::get(Ty);default:// Function, Label, or Opaque type?assert(!"Cannot create a null constant of that type!");return0;}}Constant*Constant::getAllOnesValue(constType*Ty){if(constIntegerType*ITy=dyn_cast<IntegerType>(Ty))returnConstantInt::get(APInt::getAllOnesValue(ITy->getBitWidth()));returnConstantVector::getAllOnesValue(cast<VectorType>(Ty));}// Static constructor to create an integral constant with all bits setConstantInt*ConstantInt::getAllOnesValue(constType*Ty){if(constIntegerType*ITy=dyn_cast<IntegerType>(Ty))returnConstantInt::get(APInt::getAllOnesValue(ITy->getBitWidth()));return0;}/// @returns the value for a vector integer constant of the given type that/// has all its bits set to true./// @brief Get the all ones valueConstantVector*ConstantVector::getAllOnesValue(constVectorType*Ty){std::vector<Constant*>Elts;Elts.resize(Ty->getNumElements(),ConstantInt::getAllOnesValue(Ty->getElementType()));assert(Elts[0]&&"Not a vector integer type!");returncast<ConstantVector>(ConstantVector::get(Elts));}//===----------------------------------------------------------------------===//// ConstantInt//===----------------------------------------------------------------------===//ConstantInt::ConstantInt(constIntegerType*Ty,constAPInt&V):Constant(Ty,ConstantIntVal,0,0),Val(V){assert(V.getBitWidth()==Ty->getBitWidth()&&"Invalid constant for type");}ConstantInt*ConstantInt::TheTrueVal=0;ConstantInt*ConstantInt::TheFalseVal=0;namespacellvm{voidCleanupTrueFalse(void*){ConstantInt::ResetTrueFalse();}}staticManagedCleanup<llvm::CleanupTrueFalse>TrueFalseCleanup;ConstantInt*ConstantInt::CreateTrueFalseVals(boolWhichOne){assert(TheTrueVal==0&&TheFalseVal==0);TheTrueVal=get(Type::Int1Ty,1);TheFalseVal=get(Type::Int1Ty,0);// Ensure that llvm_shutdown nulls out TheTrueVal/TheFalseVal.TrueFalseCleanup.Register();returnWhichOne?TheTrueVal:TheFalseVal;}namespace{structDenseMapAPIntKeyInfo{structKeyTy{APIntval;constType*type;KeyTy(constAPInt&V,constType*Ty):val(V),type(Ty){}KeyTy(constKeyTy&that):val(that.val),type(that.type){}booloperator==(constKeyTy&that)const{returntype==that.type&&this->val==that.val;}booloperator!=(constKeyTy&that)const{return!this->operator==(that);}};staticinlineKeyTygetEmptyKey(){returnKeyTy(APInt(1,0),0);}staticinlineKeyTygetTombstoneKey(){returnKeyTy(APInt(1,1),0);}staticunsignedgetHashValue(constKeyTy&Key){returnDenseMapInfo<void*>::getHashValue(Key.type)^Key.val.getHashValue();}staticboolisEqual(constKeyTy&LHS,constKeyTy&RHS){returnLHS==RHS;}staticboolisPod(){returnfalse;}};}typedefDenseMap<DenseMapAPIntKeyInfo::KeyTy,ConstantInt*,DenseMapAPIntKeyInfo>IntMapTy;staticManagedStatic<IntMapTy>IntConstants;ConstantInt*ConstantInt::get(constType*Ty,uint64_tV,boolisSigned){constIntegerType*ITy=cast<IntegerType>(Ty);returnget(APInt(ITy->getBitWidth(),V,isSigned));}// Get a ConstantInt from an APInt. Note that the value stored in the DenseMap // as the key, is a DensMapAPIntKeyInfo::KeyTy which has provided the// operator== and operator!= to ensure that the DenseMap doesn't attempt to// compare APInt's of different widths, which would violate an APInt class// invariant which generates an assertion.ConstantInt*ConstantInt::get(constAPInt&V){// Get the corresponding integer type for the bit width of the value.constIntegerType*ITy=IntegerType::get(V.getBitWidth());// get an existing value or the insertion positionDenseMapAPIntKeyInfo::KeyTyKey(V,ITy);ConstantInt*&Slot=(*IntConstants)[Key];// if it exists, return it.if(Slot)returnSlot;// otherwise create a new one, insert it, and return it.returnSlot=newConstantInt(ITy,V);}//===----------------------------------------------------------------------===//// ConstantFP//===----------------------------------------------------------------------===//ConstantFP::ConstantFP(constType*Ty,constAPFloat&V):Constant(Ty,ConstantFPVal,0,0),Val(V){// temporaryif(Ty==Type::FloatTy)assert(&V.getSemantics()==&APFloat::IEEEsingle);elseif(Ty==Type::DoubleTy)assert(&V.getSemantics()==&APFloat::IEEEdouble);elseif(Ty==Type::X86_FP80Ty)assert(&V.getSemantics()==&APFloat::x87DoubleExtended);elseif(Ty==Type::FP128Ty)assert(&V.getSemantics()==&APFloat::IEEEquad);elseif(Ty==Type::PPC_FP128Ty)assert(&V.getSemantics()==&APFloat::PPCDoubleDouble);elseassert(0);}boolConstantFP::isNullValue()const{returnVal.isZero()&&!Val.isNegative();}ConstantFP*ConstantFP::getNegativeZero(constType*Ty){APFloatapf=cast<ConstantFP>(Constant::getNullValue(Ty))->getValueAPF();apf.changeSign();returnConstantFP::get(Ty,apf);}boolConstantFP::isExactlyValue(constAPFloat&V)const{returnVal.bitwiseIsEqual(V);}namespace{structDenseMapAPFloatKeyInfo{structKeyTy{APFloatval;KeyTy(constAPFloat&V):val(V){}KeyTy(constKeyTy&that):val(that.val){}booloperator==(constKeyTy&that)const{returnthis->val.bitwiseIsEqual(that.val);}booloperator!=(constKeyTy&that)const{return!this->operator==(that);}};staticinlineKeyTygetEmptyKey(){returnKeyTy(APFloat(APFloat::Bogus,1));}staticinlineKeyTygetTombstoneKey(){returnKeyTy(APFloat(APFloat::Bogus,2));}staticunsignedgetHashValue(constKeyTy&Key){returnKey.val.getHashValue();}staticboolisEqual(constKeyTy&LHS,constKeyTy&RHS){returnLHS==RHS;}staticboolisPod(){returnfalse;}};}//---- ConstantFP::get() implementation...//typedefDenseMap<DenseMapAPFloatKeyInfo::KeyTy,ConstantFP*,DenseMapAPFloatKeyInfo>FPMapTy;staticManagedStatic<FPMapTy>FPConstants;ConstantFP*ConstantFP::get(constType*Ty,constAPFloat&V){// temporaryif(Ty==Type::FloatTy)assert(&V.getSemantics()==&APFloat::IEEEsingle);elseif(Ty==Type::DoubleTy)assert(&V.getSemantics()==&APFloat::IEEEdouble);elseif(Ty==Type::X86_FP80Ty)assert(&V.getSemantics()==&APFloat::x87DoubleExtended);elseif(Ty==Type::FP128Ty)assert(&V.getSemantics()==&APFloat::IEEEquad);elseif(Ty==Type::PPC_FP128Ty)assert(&V.getSemantics()==&APFloat::PPCDoubleDouble);elseassert(0);DenseMapAPFloatKeyInfo::KeyTyKey(V);ConstantFP*&Slot=(*FPConstants)[Key];if(Slot)returnSlot;returnSlot=newConstantFP(Ty,V);}//===----------------------------------------------------------------------===//// ConstantXXX Classes//===----------------------------------------------------------------------===//ConstantArray::ConstantArray(constArrayType*T,conststd::vector<Constant*>&V):Constant(T,ConstantArrayVal,newUse[V.size()],V.size()){assert(V.size()==T->getNumElements()&&"Invalid initializer vector for constant array");Use*OL=OperandList;for(std::vector<Constant*>::const_iteratorI=V.begin(),E=V.end();I!=E;++I,++OL){Constant*C=*I;assert((C->getType()==T->getElementType()||(T->isAbstract()&&C->getType()->getTypeID()==T->getElementType()->getTypeID()))&&"Initializer for array element doesn't match array element type!");OL->init(C,this);}}ConstantArray::~ConstantArray(){delete[]OperandList;}ConstantStruct::ConstantStruct(constStructType*T,conststd::vector<Constant*>&V):Constant(T,ConstantStructVal,newUse[V.size()],V.size()){assert(V.size()==T->getNumElements()&&"Invalid initializer vector for constant structure");Use*OL=OperandList;for(std::vector<Constant*>::const_iteratorI=V.begin(),E=V.end();I!=E;++I,++OL){Constant*C=*I;assert((C->getType()==T->getElementType(I-V.begin())||((T->getElementType(I-V.begin())->isAbstract()||C->getType()->isAbstract())&&T->getElementType(I-V.begin())->getTypeID()==C->getType()->getTypeID()))&&"Initializer for struct element doesn't match struct element type!");OL->init(C,this);}}ConstantStruct::~ConstantStruct(){delete[]OperandList;}ConstantVector::ConstantVector(constVectorType*T,conststd::vector<Constant*>&V):Constant(T,ConstantVectorVal,newUse[V.size()],V.size()){Use*OL=OperandList;for(std::vector<Constant*>::const_iteratorI=V.begin(),E=V.end();I!=E;++I,++OL){Constant*C=*I;assert((C->getType()==T->getElementType()||(T->isAbstract()&&C->getType()->getTypeID()==T->getElementType()->getTypeID()))&&"Initializer for vector element doesn't match vector element type!");OL->init(C,this);}}ConstantVector::~ConstantVector(){delete[]OperandList;}// We declare several classes private to this file, so use an anonymous// namespacenamespace{/// UnaryConstantExpr - This class is private to Constants.cpp, and is used/// behind the scenes to implement unary constant exprs.classVISIBILITY_HIDDENUnaryConstantExpr:publicConstantExpr{UseOp;public:UnaryConstantExpr(unsignedOpcode,Constant*C,constType*Ty):ConstantExpr(Ty,Opcode,&Op,1),Op(C,this){}};/// BinaryConstantExpr - This class is private to Constants.cpp, and is used/// behind the scenes to implement binary constant exprs.classVISIBILITY_HIDDENBinaryConstantExpr:publicConstantExpr{UseOps[2];public:BinaryConstantExpr(unsignedOpcode,Constant*C1,Constant*C2):ConstantExpr(C1->getType(),Opcode,Ops,2){Ops[0].init(C1,this);Ops[1].init(C2,this);}};/// SelectConstantExpr - This class is private to Constants.cpp, and is used/// behind the scenes to implement select constant exprs.classVISIBILITY_HIDDENSelectConstantExpr:publicConstantExpr{UseOps[3];public:SelectConstantExpr(Constant*C1,Constant*C2,Constant*C3):ConstantExpr(C2->getType(),Instruction::Select,Ops,3){Ops[0].init(C1,this);Ops[1].init(C2,this);Ops[2].init(C3,this);}};/// ExtractElementConstantExpr - This class is private to/// Constants.cpp, and is used behind the scenes to implement/// extractelement constant exprs.classVISIBILITY_HIDDENExtractElementConstantExpr:publicConstantExpr{UseOps[2];public:ExtractElementConstantExpr(Constant*C1,Constant*C2):ConstantExpr(cast<VectorType>(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.classVISIBILITY_HIDDENInsertElementConstantExpr:publicConstantExpr{UseOps[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);}};/// ShuffleVectorConstantExpr - This class is private to/// Constants.cpp, and is used behind the scenes to implement/// shufflevector constant exprs.classVISIBILITY_HIDDENShuffleVectorConstantExpr:publicConstantExpr{UseOps[3];public:ShuffleVectorConstantExpr(Constant*C1,Constant*C2,Constant*C3):ConstantExpr(C1->getType(),Instruction::ShuffleVector,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.structVISIBILITY_HIDDENGetElementPtrConstantExpr:publicConstantExpr{GetElementPtrConstantExpr(Constant*C,conststd::vector<Constant*>&IdxList,constType*DestTy):ConstantExpr(DestTy,Instruction::GetElementPtr,newUse[IdxList.size()+1],IdxList.size()+1){OperandList[0].init(C,this);for(unsignedi=0,E=IdxList.size();i!=E;++i)OperandList[i+1].init(IdxList[i],this);}~GetElementPtrConstantExpr(){delete[]OperandList;}};// CompareConstantExpr - This class is private to Constants.cpp, and is used// behind the scenes to implement ICmp and FCmp constant expressions. This is// needed in order to store the predicate value for these instructions.structVISIBILITY_HIDDENCompareConstantExpr:publicConstantExpr{unsignedshortpredicate;UseOps[2];CompareConstantExpr(Instruction::OtherOpsopc,unsignedshortpred,Constant*LHS,Constant*RHS):ConstantExpr(Type::Int1Ty,opc,Ops,2),predicate(pred){OperandList[0].init(LHS,this);OperandList[1].init(RHS,this);}};}// end anonymous namespace// Utility function for determining if a ConstantExpr is a CastOp or not. This// can't be inline because we don't want to #include Instruction.h into// Constant.hboolConstantExpr::isCast()const{returnInstruction::isCast(getOpcode());}boolConstantExpr::isCompare()const{returngetOpcode()==Instruction::ICmp||getOpcode()==Instruction::FCmp;}/// ConstantExpr::get* - Return some common constants without having to/// specify the full Instruction::OPCODE identifier.///Constant*ConstantExpr::getNeg(Constant*C){returnget(Instruction::Sub,ConstantExpr::getZeroValueForNegationExpr(C->getType()),C);}Constant*ConstantExpr::getNot(Constant*C){assert(isa<IntegerType>(C->getType())&&"Cannot NOT a nonintegral value!");returnget(Instruction::Xor,C,ConstantInt::getAllOnesValue(C->getType()));}Constant*ConstantExpr::getAdd(Constant*C1,Constant*C2){returnget(Instruction::Add,C1,C2);}Constant*ConstantExpr::getSub(Constant*C1,Constant*C2){returnget(Instruction::Sub,C1,C2);}Constant*ConstantExpr::getMul(Constant*C1,Constant*C2){returnget(Instruction::Mul,C1,C2);}Constant*ConstantExpr::getUDiv(Constant*C1,Constant*C2){returnget(Instruction::UDiv,C1,C2);}Constant*ConstantExpr::getSDiv(Constant*C1,Constant*C2){returnget(Instruction::SDiv,C1,C2);}Constant*ConstantExpr::getFDiv(Constant*C1,Constant*C2){returnget(Instruction::FDiv,C1,C2);}Constant*ConstantExpr::getURem(Constant*C1,Constant*C2){returnget(Instruction::URem,C1,C2);}Constant*ConstantExpr::getSRem(Constant*C1,Constant*C2){returnget(Instruction::SRem,C1,C2);}Constant*ConstantExpr::getFRem(Constant*C1,Constant*C2){returnget(Instruction::FRem,C1,C2);}Constant*ConstantExpr::getAnd(Constant*C1,Constant*C2){returnget(Instruction::And,C1,C2);}Constant*ConstantExpr::getOr(Constant*C1,Constant*C2){returnget(Instruction::Or,C1,C2);}Constant*ConstantExpr::getXor(Constant*C1,Constant*C2){returnget(Instruction::Xor,C1,C2);}unsignedConstantExpr::getPredicate()const{assert(getOpcode()==Instruction::FCmp||getOpcode()==Instruction::ICmp);return((constCompareConstantExpr*)this)->predicate;}Constant*ConstantExpr::getShl(Constant*C1,Constant*C2){returnget(Instruction::Shl,C1,C2);}Constant*ConstantExpr::getLShr(Constant*C1,Constant*C2){returnget(Instruction::LShr,C1,C2);}Constant*ConstantExpr::getAShr(Constant*C1,Constant*C2){returnget(Instruction::AShr,C1,C2);}/// getWithOperandReplaced - Return a constant expression identical to this/// one, but with the specified operand set to the specified value.Constant*ConstantExpr::getWithOperandReplaced(unsignedOpNo,Constant*Op)const{assert(OpNo<getNumOperands()&&"Operand num is out of range!");assert(Op->getType()==getOperand(OpNo)->getType()&&"Replacing operand with value of different type!");if(getOperand(OpNo)==Op)returnconst_cast<ConstantExpr*>(this);Constant*Op0,*Op1,*Op2;switch(getOpcode()){caseInstruction::Trunc:caseInstruction::ZExt:caseInstruction::SExt:caseInstruction::FPTrunc:caseInstruction::FPExt:caseInstruction::UIToFP:caseInstruction::SIToFP:caseInstruction::FPToUI:caseInstruction::FPToSI:caseInstruction::PtrToInt:caseInstruction::IntToPtr:caseInstruction::BitCast:returnConstantExpr::getCast(getOpcode(),Op,getType());caseInstruction::Select:Op0=(OpNo==0)?Op:getOperand(0);Op1=(OpNo==1)?Op:getOperand(1);Op2=(OpNo==2)?Op:getOperand(2);returnConstantExpr::getSelect(Op0,Op1,Op2);caseInstruction::InsertElement:Op0=(OpNo==0)?Op:getOperand(0);Op1=(OpNo==1)?Op:getOperand(1);Op2=(OpNo==2)?Op:getOperand(2);returnConstantExpr::getInsertElement(Op0,Op1,Op2);caseInstruction::ExtractElement:Op0=(OpNo==0)?Op:getOperand(0);Op1=(OpNo==1)?Op:getOperand(1);returnConstantExpr::getExtractElement(Op0,Op1);caseInstruction::ShuffleVector:Op0=(OpNo==0)?Op:getOperand(0);Op1=(OpNo==1)?Op:getOperand(1);Op2=(OpNo==2)?Op:getOperand(2);returnConstantExpr::getShuffleVector(Op0,Op1,Op2);caseInstruction::GetElementPtr:{SmallVector<Constant*,8>Ops;Ops.resize(getNumOperands());for(unsignedi=1,e=getNumOperands();i!=e;++i)Ops[i]=getOperand(i);if(OpNo==0)returnConstantExpr::getGetElementPtr(Op,&Ops[0],Ops.size());Ops[OpNo-1]=Op;returnConstantExpr::getGetElementPtr(getOperand(0),&Ops[0],Ops.size());}default:assert(getNumOperands()==2&&"Must be binary operator?");Op0=(OpNo==0)?Op:getOperand(0);Op1=(OpNo==1)?Op:getOperand(1);returnConstantExpr::get(getOpcode(),Op0,Op1);}}/// getWithOperands - This returns the current constant expression with the/// operands replaced with the specified values. The specified operands must/// match count and type with the existing ones.Constant*ConstantExpr::getWithOperands(conststd::vector<Constant*>&Ops)const{assert(Ops.size()==getNumOperands()&&"Operand count mismatch!");boolAnyChange=false;for(unsignedi=0,e=Ops.size();i!=e;++i){assert(Ops[i]->getType()==getOperand(i)->getType()&&"Operand type mismatch!");AnyChange|=Ops[i]!=getOperand(i);}if(!AnyChange)// No operands changed, return self.returnconst_cast<ConstantExpr*>(this);switch(getOpcode()){caseInstruction::Trunc:caseInstruction::ZExt:caseInstruction::SExt:caseInstruction::FPTrunc:caseInstruction::FPExt:caseInstruction::UIToFP:caseInstruction::SIToFP:caseInstruction::FPToUI:caseInstruction::FPToSI:caseInstruction::PtrToInt:caseInstruction::IntToPtr:caseInstruction::BitCast:returnConstantExpr::getCast(getOpcode(),Ops[0],getType());caseInstruction::Select:returnConstantExpr::getSelect(Ops[0],Ops[1],Ops[2]);caseInstruction::InsertElement:returnConstantExpr::getInsertElement(Ops[0],Ops[1],Ops[2]);caseInstruction::ExtractElement:returnConstantExpr::getExtractElement(Ops[0],Ops[1]);caseInstruction::ShuffleVector:returnConstantExpr::getShuffleVector(Ops[0],Ops[1],Ops[2]);caseInstruction::GetElementPtr:returnConstantExpr::getGetElementPtr(Ops[0],&Ops[1],Ops.size()-1);caseInstruction::ICmp:caseInstruction::FCmp:returnConstantExpr::getCompare(getPredicate(),Ops[0],Ops[1]);default:assert(getNumOperands()==2&&"Must be binary operator?");returnConstantExpr::get(getOpcode(),Ops[0],Ops[1]);}}//===----------------------------------------------------------------------===//// isValueValidForType implementationsboolConstantInt::isValueValidForType(constType*Ty,uint64_tVal){unsignedNumBits=cast<IntegerType>(Ty)->getBitWidth();// assert okayif(Ty==Type::Int1Ty)returnVal==0||Val==1;if(NumBits>=64)returntrue;// always true, has to fit in largest typeuint64_tMax=(1ll<<NumBits)-1;returnVal<=Max;}boolConstantInt::isValueValidForType(constType*Ty,int64_tVal){unsignedNumBits=cast<IntegerType>(Ty)->getBitWidth();// assert okayif(Ty==Type::Int1Ty)returnVal==0||Val==1||Val==-1;if(NumBits>=64)returntrue;// always true, has to fit in largest typeint64_tMin=-(1ll<<(NumBits-1));int64_tMax=(1ll<<(NumBits-1))-1;return(Val>=Min&&Val<=Max);}boolConstantFP::isValueValidForType(constType*Ty,constAPFloat&Val){// convert modifies in place, so make a copy.APFloatVal2=APFloat(Val);switch(Ty->getTypeID()){default:returnfalse;// These can't be represented as floating point!// FIXME rounding mode needs to be more flexiblecaseType::FloatTyID:return&Val2.getSemantics()==&APFloat::IEEEsingle||Val2.convert(APFloat::IEEEsingle,APFloat::rmNearestTiesToEven)==APFloat::opOK;caseType::DoubleTyID:return&Val2.getSemantics()==&APFloat::IEEEsingle||&Val2.getSemantics()==&APFloat::IEEEdouble||Val2.convert(APFloat::IEEEdouble,APFloat::rmNearestTiesToEven)==APFloat::opOK;caseType::X86_FP80TyID:return&Val2.getSemantics()==&APFloat::IEEEsingle||&Val2.getSemantics()==&APFloat::IEEEdouble||&Val2.getSemantics()==&APFloat::x87DoubleExtended;caseType::FP128TyID:return&Val2.getSemantics()==&APFloat::IEEEsingle||&Val2.getSemantics()==&APFloat::IEEEdouble||&Val2.getSemantics()==&APFloat::IEEEquad;caseType::PPC_FP128TyID:return&Val2.getSemantics()==&APFloat::IEEEsingle||&Val2.getSemantics()==&APFloat::IEEEdouble||&Val2.getSemantics()==&APFloat::PPCDoubleDouble;}}//===----------------------------------------------------------------------===//// Factory Function Implementation// ConstantCreator - A class that is used to create constants by// ValueMap*. This class should be partially specialized if there is// something strange that needs to be done to interface to the ctor for the// constant.//namespacellvm{template<classConstantClass,classTypeClass,classValType>structVISIBILITY_HIDDENConstantCreator{staticConstantClass*create(constTypeClass*Ty,constValType&V){returnnewConstantClass(Ty,V);}};template<classConstantClass,classTypeClass>structVISIBILITY_HIDDENConvertConstantType{staticvoidconvert(ConstantClass*OldC,constTypeClass*NewTy){assert(0&&"This type cannot be converted!\n");abort();}};template<classValType,classTypeClass,classConstantClass,boolHasLargeKey=false/*true for arrays and structs*/>classVISIBILITY_HIDDENValueMap:publicAbstractTypeUser{public:typedefstd::pair<constType*,ValType>MapKey;typedefstd::map<MapKey,Constant*>MapTy;typedefstd::map<Constant*,typenameMapTy::iterator>InverseMapTy;typedefstd::map<constType*,typenameMapTy::iterator>AbstractTypeMapTy;private:/// Map - This is the main map from the element descriptor to the Constants./// This is the primary way we avoid creating two of the same shape/// constant.MapTyMap;/// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping/// from the constants to their element in Map. This is important for/// removal of constants from the array, which would otherwise have to scan/// through the map with very large keys.InverseMapTyInverseMap;/// AbstractTypeMap - Map for abstract type constants.///AbstractTypeMapTyAbstractTypeMap;public:typenameMapTy::iteratormap_end(){returnMap.end();}/// InsertOrGetItem - Return an iterator for the specified element./// If the element exists in the map, the returned iterator points to the/// entry and Exists=true. If not, the iterator points to the newly/// inserted entry and returns Exists=false. Newly inserted entries have/// I->second == 0, and should be filled in.typenameMapTy::iteratorInsertOrGetItem(std::pair<MapKey,Constant*>&InsertVal,bool&Exists){std::pair<typenameMapTy::iterator,bool>IP=Map.insert(InsertVal);Exists=!IP.second;returnIP.first;}private:typenameMapTy::iteratorFindExistingElement(ConstantClass*CP){if(HasLargeKey){typenameInverseMapTy::iteratorIMI=InverseMap.find(CP);assert(IMI!=InverseMap.end()&&IMI->second!=Map.end()&&IMI->second->second==CP&&"InverseMap corrupt!");returnIMI->second;}typenameMapTy::iteratorI=Map.find(MapKey((TypeClass*)CP->getRawType(),getValType(CP)));if(I==Map.end()||I->second!=CP){// FIXME: This should not use a linear scan. If this gets to be a// performance problem, someone should look at this.for(I=Map.begin();I!=Map.end()&&I->second!=CP;++I)/* empty */;}returnI;}public:/// getOrCreate - Return the specified constant from the map, creating it if/// necessary.ConstantClass*getOrCreate(constTypeClass*Ty,constValType&V){MapKeyLookup(Ty,V);typenameMapTy::iteratorI=Map.lower_bound(Lookup);// Is it in the map? if(I!=Map.end()&&I->first==Lookup)returnstatic_cast<ConstantClass*>(I->second);// If no preexisting value, create one now...ConstantClass*Result=ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty,V);/// FIXME: why does this assert fail when loading 176.gcc?//assert(Result->getType() == Ty && "Type specified is not correct!");I=Map.insert(I,std::make_pair(MapKey(Ty,V),Result));if(HasLargeKey)// Remember the reverse mapping if needed.InverseMap.insert(std::make_pair(Result,I));// If the type of the constant is abstract, make sure that an entry exists// for it in the AbstractTypeMap.if(Ty->isAbstract()){typenameAbstractTypeMapTy::iteratorTI=AbstractTypeMap.lower_bound(Ty);if(TI==AbstractTypeMap.end()||TI->first!=Ty){// Add ourselves to the ATU list of the type.cast<DerivedType>(Ty)->addAbstractTypeUser(this);AbstractTypeMap.insert(TI,std::make_pair(Ty,I));}}returnResult;}voidremove(ConstantClass*CP){typenameMapTy::iteratorI=FindExistingElement(CP);assert(I!=Map.end()&&"Constant not found in constant table!");assert(I->second==CP&&"Didn't find correct element?");if(HasLargeKey)// Remember the reverse mapping if needed.InverseMap.erase(CP);// Now that we found the entry, make sure this isn't the entry that// the AbstractTypeMap points to.constTypeClass*Ty=static_cast<constTypeClass*>(I->first.first);if(Ty->isAbstract()){assert(AbstractTypeMap.count(Ty)&&"Abstract type not in AbstractTypeMap?");typenameMapTy::iterator&ATMEntryIt=AbstractTypeMap[Ty];if(ATMEntryIt==I){// Yes, we are removing the representative entry for this type.// See if there are any other entries of the same type.typenameMapTy::iteratorTmpIt=ATMEntryIt;// First check the entry before this one...if(TmpIt!=Map.begin()){--TmpIt;if(TmpIt->first.first!=Ty)// Not the same type, move back...++TmpIt;}// If we didn't find the same type, try to move forward...if(TmpIt==ATMEntryIt){++TmpIt;if(TmpIt==Map.end()||TmpIt->first.first!=Ty)--TmpIt;// No entry afterwards with the same type}// If there is another entry in the map of the same abstract type,// update the AbstractTypeMap entry now.if(TmpIt!=ATMEntryIt){ATMEntryIt=TmpIt;}else{// Otherwise, we are removing the last instance of this type// from the table. Remove from the ATM, and from user list.cast<DerivedType>(Ty)->removeAbstractTypeUser(this);AbstractTypeMap.erase(Ty);}}}Map.erase(I);}/// MoveConstantToNewSlot - If we are about to change C to be the element/// specified by I, update our internal data structures to reflect this/// fact.voidMoveConstantToNewSlot(ConstantClass*C,typenameMapTy::iteratorI){// First, remove the old location of the specified constant in the map.typenameMapTy::iteratorOldI=FindExistingElement(C);assert(OldI!=Map.end()&&"Constant not found in constant table!");assert(OldI->second==C&&"Didn't find correct element?");// If this constant is the representative element for its abstract type,// update the AbstractTypeMap so that the representative element is I.if(C->getType()->isAbstract()){typenameAbstractTypeMapTy::iteratorATI=AbstractTypeMap.find(C->getType());assert(ATI!=AbstractTypeMap.end()&&"Abstract type not in AbstractTypeMap?");if(ATI->second==OldI)ATI->second=I;}// Remove the old entry from the map.Map.erase(OldI);// Update the inverse map so that we know that this constant is now// located at descriptor I.if(HasLargeKey){assert(I->second==C&&"Bad inversemap entry!");InverseMap[C]=I;}}voidrefineAbstractType(constDerivedType*OldTy,constType*NewTy){typenameAbstractTypeMapTy::iteratorI=AbstractTypeMap.find(cast<Type>(OldTy));assert(I!=AbstractTypeMap.end()&&"Abstract type not in AbstractTypeMap?");// Convert a constant at a time until the last one is gone. The last one// leaving will remove() itself, causing the AbstractTypeMapEntry to be// eliminated eventually.do{ConvertConstantType<ConstantClass,TypeClass>::convert(static_cast<ConstantClass*>(I->second->second),cast<TypeClass>(NewTy));I=AbstractTypeMap.find(cast<Type>(OldTy));}while(I!=AbstractTypeMap.end());}// If the type became concrete without being refined to any other existing// type, we just remove ourselves from the ATU list.voidtypeBecameConcrete(constDerivedType*AbsTy){AbsTy->removeAbstractTypeUser(this);}voiddump()const{DOUT<<"Constant.cpp: ValueMap\n";}};}//---- ConstantAggregateZero::get() implementation...//namespacellvm{// ConstantAggregateZero does not take extra "value" argument...template<classValType>structConstantCreator<ConstantAggregateZero,Type,ValType>{staticConstantAggregateZero*create(constType*Ty,constValType&V){returnnewConstantAggregateZero(Ty);}};template<>structConvertConstantType<ConstantAggregateZero,Type>{staticvoidconvert(ConstantAggregateZero*OldC,constType*NewTy){// Make everyone now use a constant of the new type...Constant*New=ConstantAggregateZero::get(NewTy);assert(New!=OldC&&"Didn't replace constant??");OldC->uncheckedReplaceAllUsesWith(New);OldC->destroyConstant();// This constant is now dead, destroy it.}};}staticManagedStatic<ValueMap<char,Type,ConstantAggregateZero>>AggZeroConstants;staticchargetValType(ConstantAggregateZero*CPZ){return0;}Constant*ConstantAggregateZero::get(constType*Ty){assert((isa<StructType>(Ty)||isa<ArrayType>(Ty)||isa<VectorType>(Ty))&&"Cannot create an aggregate zero of non-aggregate type!");returnAggZeroConstants->getOrCreate(Ty,0);}// destroyConstant - Remove the constant from the constant table...//voidConstantAggregateZero::destroyConstant(){AggZeroConstants->remove(this);destroyConstantImpl();}//---- ConstantArray::get() implementation...//namespacellvm{template<>structConvertConstantType<ConstantArray,ArrayType>{staticvoidconvert(ConstantArray*OldC,constArrayType*NewTy){// Make everyone now use a constant of the new type...std::vector<Constant*>C;for(unsignedi=0,e=OldC->getNumOperands();i!=e;++i)C.push_back(cast<Constant>(OldC->getOperand(i)));Constant*New=ConstantArray::get(NewTy,C);assert(New!=OldC&&"Didn't replace constant??");OldC->uncheckedReplaceAllUsesWith(New);OldC->destroyConstant();// This constant is now dead, destroy it.}};}staticstd::vector<Constant*>getValType(ConstantArray*CA){std::vector<Constant*>Elements;Elements.reserve(CA->getNumOperands());for(unsignedi=0,e=CA->getNumOperands();i!=e;++i)Elements.push_back(cast<Constant>(CA->getOperand(i)));returnElements;}typedefValueMap<std::vector<Constant*>,ArrayType,ConstantArray,true/*largekey*/>ArrayConstantsTy;staticManagedStatic<ArrayConstantsTy>ArrayConstants;Constant*ConstantArray::get(constArrayType*Ty,conststd::vector<Constant*>&V){// If this is an all-zero array, return a ConstantAggregateZero objectif(!V.empty()){Constant*C=V[0];if(!C->isNullValue())returnArrayConstants->getOrCreate(Ty,V);for(unsignedi=1,e=V.size();i!=e;++i)if(V[i]!=C)returnArrayConstants->getOrCreate(Ty,V);}returnConstantAggregateZero::get(Ty);}// destroyConstant - Remove the constant from the constant table...//voidConstantArray::destroyConstant(){ArrayConstants->remove(this);destroyConstantImpl();}/// ConstantArray::get(const string&) - Return an array that is initialized to/// contain the specified string. If length is zero then a null terminator is /// added to the specified string so that it may be used in a natural way. /// Otherwise, the length parameter specifies how much of the string to use /// and it won't be null terminated.///Constant*ConstantArray::get(conststd::string&Str,boolAddNull){std::vector<Constant*>ElementVals;for(unsignedi=0;i<Str.length();++i)ElementVals.push_back(ConstantInt::get(Type::Int8Ty,Str[i]));// Add a null terminator to the string...if(AddNull){ElementVals.push_back(ConstantInt::get(Type::Int8Ty,0));}ArrayType*ATy=ArrayType::get(Type::Int8Ty,ElementVals.size());returnConstantArray::get(ATy,ElementVals);}/// isString - This method returns true if the array is an array of i8, and /// if the elements of the array are all ConstantInt's.boolConstantArray::isString()const{// Check the element type for i8...if(getType()->getElementType()!=Type::Int8Ty)returnfalse;// Check the elements to make sure they are all integers, not constant// expressions.for(unsignedi=0,e=getNumOperands();i!=e;++i)if(!isa<ConstantInt>(getOperand(i)))returnfalse;returntrue;}/// isCString - This method returns true if the array is a string (see/// isString) and it ends in a null byte \0 and does not contains any other/// null bytes except its terminator.boolConstantArray::isCString()const{// Check the element type for i8...if(getType()->getElementType()!=Type::Int8Ty)returnfalse;Constant*Zero=Constant::getNullValue(getOperand(0)->getType());// Last element must be a null.if(getOperand(getNumOperands()-1)!=Zero)returnfalse;// Other elements must be non-null integers.for(unsignedi=0,e=getNumOperands()-1;i!=e;++i){if(!isa<ConstantInt>(getOperand(i)))returnfalse;if(getOperand(i)==Zero)returnfalse;}returntrue;}// getAsString - If the sub-element type of this array is i8// then this method converts the array to an std::string and returns it.// Otherwise, it asserts out.//std::stringConstantArray::getAsString()const{assert(isString()&&"Not a string!");std::stringResult;for(unsignedi=0,e=getNumOperands();i!=e;++i)Result+=(char)cast<ConstantInt>(getOperand(i))->getZExtValue();returnResult;}//---- ConstantStruct::get() implementation...//namespacellvm{template<>structConvertConstantType<ConstantStruct,StructType>{staticvoidconvert(ConstantStruct*OldC,constStructType*NewTy){// Make everyone now use a constant of the new type...std::vector<Constant*>C;for(unsignedi=0,e=OldC->getNumOperands();i!=e;++i)C.push_back(cast<Constant>(OldC->getOperand(i)));Constant*New=ConstantStruct::get(NewTy,C);assert(New!=OldC&&"Didn't replace constant??");OldC->uncheckedReplaceAllUsesWith(New);OldC->destroyConstant();// This constant is now dead, destroy it.}};}typedefValueMap<std::vector<Constant*>,StructType,ConstantStruct,true/*largekey*/>StructConstantsTy;staticManagedStatic<StructConstantsTy>StructConstants;staticstd::vector<Constant*>getValType(ConstantStruct*CS){std::vector<Constant*>Elements;Elements.reserve(CS->getNumOperands());for(unsignedi=0,e=CS->getNumOperands();i!=e;++i)Elements.push_back(cast<Constant>(CS->getOperand(i)));returnElements;}Constant*ConstantStruct::get(constStructType*Ty,conststd::vector<Constant*>&V){// Create a ConstantAggregateZero value if all elements are zeros...for(unsignedi=0,e=V.size();i!=e;++i)if(!V[i]->isNullValue())returnStructConstants->getOrCreate(Ty,V);returnConstantAggregateZero::get(Ty);}Constant*ConstantStruct::get(conststd::vector<Constant*>&V,boolpacked){std::vector<constType*>StructEls;StructEls.reserve(V.size());for(unsignedi=0,e=V.size();i!=e;++i)StructEls.push_back(V[i]->getType());returnget(StructType::get(StructEls,packed),V);}// destroyConstant - Remove the constant from the constant table...//voidConstantStruct::destroyConstant(){StructConstants->remove(this);destroyConstantImpl();}//---- ConstantVector::get() implementation...//namespacellvm{template<>structConvertConstantType<ConstantVector,VectorType>{staticvoidconvert(ConstantVector*OldC,constVectorType*NewTy){// Make everyone now use a constant of the new type...std::vector<Constant*>C;for(unsignedi=0,e=OldC->getNumOperands();i!=e;++i)C.push_back(cast<Constant>(OldC->getOperand(i)));Constant*New=ConstantVector::get(NewTy,C);assert(New!=OldC&&"Didn't replace constant??");OldC->uncheckedReplaceAllUsesWith(New);OldC->destroyConstant();// This constant is now dead, destroy it.}};}staticstd::vector<Constant*>getValType(ConstantVector*CP){std::vector<Constant*>Elements;Elements.reserve(CP->getNumOperands());for(unsignedi=0,e=CP->getNumOperands();i!=e;++i)Elements.push_back(CP->getOperand(i));returnElements;}staticManagedStatic<ValueMap<std::vector<Constant*>,VectorType,ConstantVector>>VectorConstants;Constant*ConstantVector::get(constVectorType*Ty,conststd::vector<Constant*>&V){// If this is an all-zero vector, return a ConstantAggregateZero objectif(!V.empty()){Constant*C=V[0];if(!C->isNullValue())returnVectorConstants->getOrCreate(Ty,V);for(unsignedi=1,e=V.size();i!=e;++i)if(V[i]!=C)returnVectorConstants->getOrCreate(Ty,V);}returnConstantAggregateZero::get(Ty);}Constant*ConstantVector::get(conststd::vector<Constant*>&V){assert(!V.empty()&&"Cannot infer type if V is empty");returnget(VectorType::get(V.front()->getType(),V.size()),V);}// destroyConstant - Remove the constant from the constant table...//voidConstantVector::destroyConstant(){VectorConstants->remove(this);destroyConstantImpl();}/// This function will return true iff every element in this vector constant/// is set to all ones./// @returns true iff this constant's emements are all set to all ones./// @brief Determine if the value is all ones.boolConstantVector::isAllOnesValue()const{// Check out first element.constConstant*Elt=getOperand(0);constConstantInt*CI=dyn_cast<ConstantInt>(Elt);if(!CI||!CI->isAllOnesValue())returnfalse;// Then make sure all remaining elements point to the same value.for(unsignedI=1,E=getNumOperands();I<E;++I){if(getOperand(I)!=Elt)returnfalse;}returntrue;}/// getSplatValue - If this is a splat constant, where all of the/// elements have the same value, return that value. Otherwise return null.Constant*ConstantVector::getSplatValue(){// Check out first element.Constant*Elt=getOperand(0);// Then make sure all remaining elements point to the same value.for(unsignedI=1,E=getNumOperands();I<E;++I)if(getOperand(I)!=Elt)return0;returnElt;}//---- ConstantPointerNull::get() implementation...//namespacellvm{// ConstantPointerNull does not take extra "value" argument...template<classValType>structConstantCreator<ConstantPointerNull,PointerType,ValType>{staticConstantPointerNull*create(constPointerType*Ty,constValType&V){returnnewConstantPointerNull(Ty);}};template<>structConvertConstantType<ConstantPointerNull,PointerType>{staticvoidconvert(ConstantPointerNull*OldC,constPointerType*NewTy){// Make everyone now use a constant of the new type...Constant*New=ConstantPointerNull::get(NewTy);assert(New!=OldC&&"Didn't replace constant??");OldC->uncheckedReplaceAllUsesWith(New);OldC->destroyConstant();// This constant is now dead, destroy it.}};}staticManagedStatic<ValueMap<char,PointerType,ConstantPointerNull>>NullPtrConstants;staticchargetValType(ConstantPointerNull*){return0;}ConstantPointerNull*ConstantPointerNull::get(constPointerType*Ty){returnNullPtrConstants->getOrCreate(Ty,0);}// destroyConstant - Remove the constant from the constant table...//voidConstantPointerNull::destroyConstant(){NullPtrConstants->remove(this);destroyConstantImpl();}//---- UndefValue::get() implementation...//namespacellvm{// UndefValue does not take extra "value" argument...template<classValType>structConstantCreator<UndefValue,Type,ValType>{staticUndefValue*create(constType*Ty,constValType&V){returnnewUndefValue(Ty);}};template<>structConvertConstantType<UndefValue,Type>{staticvoidconvert(UndefValue*OldC,constType*NewTy){// Make everyone now use a constant of the new type.Constant*New=UndefValue::get(NewTy);assert(New!=OldC&&"Didn't replace constant??");OldC->uncheckedReplaceAllUsesWith(New);OldC->destroyConstant();// This constant is now dead, destroy it.}};}staticManagedStatic<ValueMap<char,Type,UndefValue>>UndefValueConstants;staticchargetValType(UndefValue*){return0;}UndefValue*UndefValue::get(constType*Ty){returnUndefValueConstants->getOrCreate(Ty,0);}// destroyConstant - Remove the constant from the constant table.//voidUndefValue::destroyConstant(){UndefValueConstants->remove(this);destroyConstantImpl();}//---- ConstantExpr::get() implementations...//structExprMapKeyType{explicitExprMapKeyType(unsignedopc,std::vector<Constant*>ops,unsignedshortpred=0):opcode(opc),predicate(pred),operands(ops){}uint16_topcode;uint16_tpredicate;std::vector<Constant*>operands;booloperator==(constExprMapKeyType&that)const{returnthis->opcode==that.opcode&&this->predicate==that.predicate&&this->operands==that.operands;}booloperator<(constExprMapKeyType&that)const{returnthis->opcode<that.opcode||(this->opcode==that.opcode&&this->predicate<that.predicate)||(this->opcode==that.opcode&&this->predicate==that.predicate&&this->operands<that.operands);}booloperator!=(constExprMapKeyType&that)const{return!(*this==that);}};namespacellvm{template<>structConstantCreator<ConstantExpr,Type,ExprMapKeyType>{staticConstantExpr*create(constType*Ty,constExprMapKeyType&V,unsignedshortpred=0){if(Instruction::isCast(V.opcode))returnnewUnaryConstantExpr(V.opcode,V.operands[0],Ty);if((V.opcode>=Instruction::BinaryOpsBegin&&V.opcode<Instruction::BinaryOpsEnd))returnnewBinaryConstantExpr(V.opcode,V.operands[0],V.operands[1]);if(V.opcode==Instruction::Select)returnnewSelectConstantExpr(V.operands[0],V.operands[1],V.operands[2]);if(V.opcode==Instruction::ExtractElement)returnnewExtractElementConstantExpr(V.operands[0],V.operands[1]);if(V.opcode==Instruction::InsertElement)returnnewInsertElementConstantExpr(V.operands[0],V.operands[1],V.operands[2]);if(V.opcode==Instruction::ShuffleVector)returnnewShuffleVectorConstantExpr(V.operands[0],V.operands[1],V.operands[2]);if(V.opcode==Instruction::GetElementPtr){std::vector<Constant*>IdxList(V.operands.begin()+1,V.operands.end());returnnewGetElementPtrConstantExpr(V.operands[0],IdxList,Ty);}// The compare instructions are weird. We have to encode the predicate// value and it is combined with the instruction opcode by multiplying// the opcode by one hundred. We must decode this to get the predicate.if(V.opcode==Instruction::ICmp)returnnewCompareConstantExpr(Instruction::ICmp,V.predicate,V.operands[0],V.operands[1]);if(V.opcode==Instruction::FCmp)returnnewCompareConstantExpr(Instruction::FCmp,V.predicate,V.operands[0],V.operands[1]);assert(0&&"Invalid ConstantExpr!");return0;}};template<>structConvertConstantType<ConstantExpr,Type>{staticvoidconvert(ConstantExpr*OldC,constType*NewTy){Constant*New;switch(OldC->getOpcode()){caseInstruction::Trunc:caseInstruction::ZExt:caseInstruction::SExt:caseInstruction::FPTrunc:caseInstruction::FPExt:caseInstruction::UIToFP:caseInstruction::SIToFP:caseInstruction::FPToUI:caseInstruction::FPToSI:caseInstruction::PtrToInt:caseInstruction::IntToPtr:caseInstruction::BitCast:New=ConstantExpr::getCast(OldC->getOpcode(),OldC->getOperand(0),NewTy);break;caseInstruction::Select:New=ConstantExpr::getSelectTy(NewTy,OldC->getOperand(0),OldC->getOperand(1),OldC->getOperand(2));break;default:assert(OldC->getOpcode()>=Instruction::BinaryOpsBegin&&OldC->getOpcode()<Instruction::BinaryOpsEnd);New=ConstantExpr::getTy(NewTy,OldC->getOpcode(),OldC->getOperand(0),OldC->getOperand(1));break;caseInstruction::GetElementPtr:// Make everyone now use a constant of the new type...std::vector<Value*>Idx(OldC->op_begin()+1,OldC->op_end());New=ConstantExpr::getGetElementPtrTy(NewTy,OldC->getOperand(0),&Idx[0],Idx.size());break;}assert(New!=OldC&&"Didn't replace constant??");OldC->uncheckedReplaceAllUsesWith(New);OldC->destroyConstant();// This constant is now dead, destroy it.}};}// end namespace llvmstaticExprMapKeyTypegetValType(ConstantExpr*CE){std::vector<Constant*>Operands;Operands.reserve(CE->getNumOperands());for(unsignedi=0,e=CE->getNumOperands();i!=e;++i)Operands.push_back(cast<Constant>(CE->getOperand(i)));returnExprMapKeyType(CE->getOpcode(),Operands,CE->isCompare()?CE->getPredicate():0);}staticManagedStatic<ValueMap<ExprMapKeyType,Type,ConstantExpr>>ExprConstants;/// This is a utility function to handle folding of casts and lookup of the/// cast in the ExprConstants map. It is usedby the various get* methods below.staticinlineConstant*getFoldedCast(Instruction::CastOpsopc,Constant*C,constType*Ty){assert(Ty->isFirstClassType()&&"Cannot cast to an aggregate type!");// Fold a few common casesif(Constant*FC=ConstantFoldCastInstruction(opc,C,Ty))returnFC;// Look up the constant in the table first to ensure uniquenessstd::vector<Constant*>argVec(1,C);ExprMapKeyTypeKey(opc,argVec);returnExprConstants->getOrCreate(Ty,Key);}Constant*ConstantExpr::getCast(unsignedoc,Constant*C,constType*Ty){Instruction::CastOpsopc=Instruction::CastOps(oc);assert(Instruction::isCast(opc)&&"opcode out of range");assert(C&&Ty&&"Null arguments to getCast");assert(Ty->isFirstClassType()&&"Cannot cast to an aggregate type!");switch(opc){default:assert(0&&"Invalid cast opcode");break;caseInstruction::Trunc:returngetTrunc(C,Ty);caseInstruction::ZExt:returngetZExt(C,Ty);caseInstruction::SExt:returngetSExt(C,Ty);caseInstruction::FPTrunc:returngetFPTrunc(C,Ty);caseInstruction::FPExt:returngetFPExtend(C,Ty);caseInstruction::UIToFP:returngetUIToFP(C,Ty);caseInstruction::SIToFP:returngetSIToFP(C,Ty);caseInstruction::FPToUI:returngetFPToUI(C,Ty);caseInstruction::FPToSI:returngetFPToSI(C,Ty);caseInstruction::PtrToInt:returngetPtrToInt(C,Ty);caseInstruction::IntToPtr:returngetIntToPtr(C,Ty);caseInstruction::BitCast:returngetBitCast(C,Ty);}return0;}Constant*ConstantExpr::getZExtOrBitCast(Constant*C,constType*Ty){if(C->getType()->getPrimitiveSizeInBits()==Ty->getPrimitiveSizeInBits())returngetCast(Instruction::BitCast,C,Ty);returngetCast(Instruction::ZExt,C,Ty);}Constant*ConstantExpr::getSExtOrBitCast(Constant*C,constType*Ty){if(C->getType()->getPrimitiveSizeInBits()==Ty->getPrimitiveSizeInBits())returngetCast(Instruction::BitCast,C,Ty);returngetCast(Instruction::SExt,C,Ty);}Constant*ConstantExpr::getTruncOrBitCast(Constant*C,constType*Ty){if(C->getType()->getPrimitiveSizeInBits()==Ty->getPrimitiveSizeInBits())returngetCast(Instruction::BitCast,C,Ty);returngetCast(Instruction::Trunc,C,Ty);}Constant*ConstantExpr::getPointerCast(Constant*S,constType*Ty){assert(isa<PointerType>(S->getType())&&"Invalid cast");assert((Ty->isInteger()||isa<PointerType>(Ty))&&"Invalid cast");if(Ty->isInteger())returngetCast(Instruction::PtrToInt,S,Ty);returngetCast(Instruction::BitCast,S,Ty);}Constant*ConstantExpr::getIntegerCast(Constant*C,constType*Ty,boolisSigned){assert(C->getType()->isInteger()&&Ty->isInteger()&&"Invalid cast");unsignedSrcBits=C->getType()->getPrimitiveSizeInBits();unsignedDstBits=Ty->getPrimitiveSizeInBits();Instruction::CastOpsopcode=(SrcBits==DstBits?Instruction::BitCast:(SrcBits>DstBits?Instruction::Trunc:(isSigned?Instruction::SExt:Instruction::ZExt)));returngetCast(opcode,C,Ty);}Constant*ConstantExpr::getFPCast(Constant*C,constType*Ty){assert(C->getType()->isFloatingPoint()&&Ty->isFloatingPoint()&&"Invalid cast");unsignedSrcBits=C->getType()->getPrimitiveSizeInBits();unsignedDstBits=Ty->getPrimitiveSizeInBits();if(SrcBits==DstBits)returnC;// Avoid a useless castInstruction::CastOpsopcode=(SrcBits>DstBits?Instruction::FPTrunc:Instruction::FPExt);returngetCast(opcode,C,Ty);}Constant*ConstantExpr::getTrunc(Constant*C,constType*Ty){assert(C->getType()->isInteger()&&"Trunc operand must be integer");assert(Ty->isInteger()&&"Trunc produces only integral");assert(C->getType()->getPrimitiveSizeInBits()>Ty->getPrimitiveSizeInBits()&&"SrcTy must be larger than DestTy for Trunc!");returngetFoldedCast(Instruction::Trunc,C,Ty);}Constant*ConstantExpr::getSExt(Constant*C,constType*Ty){assert(C->getType()->isInteger()&&"SEXt operand must be integral");assert(Ty->isInteger()&&"SExt produces only integer");assert(C->getType()->getPrimitiveSizeInBits()<Ty->getPrimitiveSizeInBits()&&"SrcTy must be smaller than DestTy for SExt!");returngetFoldedCast(Instruction::SExt,C,Ty);}Constant*ConstantExpr::getZExt(Constant*C,constType*Ty){assert(C->getType()->isInteger()&&"ZEXt operand must be integral");assert(Ty->isInteger()&&"ZExt produces only integer");assert(C->getType()->getPrimitiveSizeInBits()<Ty->getPrimitiveSizeInBits()&&"SrcTy must be smaller than DestTy for ZExt!");returngetFoldedCast(Instruction::ZExt,C,Ty);}Constant*ConstantExpr::getFPTrunc(Constant*C,constType*Ty){assert(C->getType()->isFloatingPoint()&&Ty->isFloatingPoint()&&C->getType()->getPrimitiveSizeInBits()>Ty->getPrimitiveSizeInBits()&&"This is an illegal floating point truncation!");returngetFoldedCast(Instruction::FPTrunc,C,Ty);}Constant*ConstantExpr::getFPExtend(Constant*C,constType*Ty){assert(C->getType()->isFloatingPoint()&&Ty->isFloatingPoint()&&C->getType()->getPrimitiveSizeInBits()<Ty->getPrimitiveSizeInBits()&&"This is an illegal floating point extension!");returngetFoldedCast(Instruction::FPExt,C,Ty);}Constant*ConstantExpr::getUIToFP(Constant*C,constType*Ty){boolfromVec=C->getType()->getTypeID()==Type::VectorTyID;booltoVec=Ty->getTypeID()==Type::VectorTyID;assert((fromVec==toVec)&&"Cannot convert from scalar to/from vector");assert(C->getType()->isIntOrIntVector()&&Ty->isFPOrFPVector()&&"This is an illegal uint to floating point cast!");returngetFoldedCast(Instruction::UIToFP,C,Ty);}Constant*ConstantExpr::getSIToFP(Constant*C,constType*Ty){boolfromVec=C->getType()->getTypeID()==Type::VectorTyID;booltoVec=Ty->getTypeID()==Type::VectorTyID;assert((fromVec==toVec)&&"Cannot convert from scalar to/from vector");assert(C->getType()->isIntOrIntVector()&&Ty->isFPOrFPVector()&&"This is an illegal sint to floating point cast!");returngetFoldedCast(Instruction::SIToFP,C,Ty);}Constant*ConstantExpr::getFPToUI(Constant*C,constType*Ty){boolfromVec=C->getType()->getTypeID()==Type::VectorTyID;booltoVec=Ty->getTypeID()==Type::VectorTyID;assert((fromVec==toVec)&&"Cannot convert from scalar to/from vector");assert(C->getType()->isFPOrFPVector()&&Ty->isIntOrIntVector()&&"This is an illegal floating point to uint cast!");returngetFoldedCast(Instruction::FPToUI,C,Ty);}Constant*ConstantExpr::getFPToSI(Constant*C,constType*Ty){boolfromVec=C->getType()->getTypeID()==Type::VectorTyID;booltoVec=Ty->getTypeID()==Type::VectorTyID;assert((fromVec==toVec)&&"Cannot convert from scalar to/from vector");assert(C->getType()->isFPOrFPVector()&&Ty->isIntOrIntVector()&&"This is an illegal floating point to sint cast!");returngetFoldedCast(Instruction::FPToSI,C,Ty);}Constant*ConstantExpr::getPtrToInt(Constant*C,constType*DstTy){assert(isa<PointerType>(C->getType())&&"PtrToInt source must be pointer");assert(DstTy->isInteger()&&"PtrToInt destination must be integral");returngetFoldedCast(Instruction::PtrToInt,C,DstTy);}Constant*ConstantExpr::getIntToPtr(Constant*C,constType*DstTy){assert(C->getType()->isInteger()&&"IntToPtr source must be integral");assert(isa<PointerType>(DstTy)&&"IntToPtr destination must be a pointer");returngetFoldedCast(Instruction::IntToPtr,C,DstTy);}Constant*ConstantExpr::getBitCast(Constant*C,constType*DstTy){// BitCast implies a no-op cast of type only. No bits change. However, you // can't cast pointers to anything but pointers.constType*SrcTy=C->getType();assert((isa<PointerType>(SrcTy)==isa<PointerType>(DstTy))&&"BitCast cannot cast pointer to non-pointer and vice versa");// Now we know we're not dealing with mismatched pointer casts (ptr->nonptr// or nonptr->ptr). For all the other types, the cast is okay if source and // destination bit widths are identical.unsignedSrcBitSize=SrcTy->getPrimitiveSizeInBits();unsignedDstBitSize=DstTy->getPrimitiveSizeInBits();assert(SrcBitSize==DstBitSize&&"BitCast requies types of same width");returngetFoldedCast(Instruction::BitCast,C,DstTy);}Constant*ConstantExpr::getSizeOf(constType*Ty){// sizeof is implemented as: (i64) gep (Ty*)null, 1Constant*GEPIdx=ConstantInt::get(Type::Int32Ty,1);Constant*GEP=getGetElementPtr(getNullValue(PointerType::getUnqual(Ty)),&GEPIdx,1);returngetCast(Instruction::PtrToInt,GEP,Type::Int64Ty);}Constant*ConstantExpr::getTy(constType*ReqTy,unsignedOpcode,Constant*C1,Constant*C2){// Check the operands for consistency firstassert(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");if(ReqTy==C1->getType()||ReqTy==Type::Int1Ty)if(Constant*FC=ConstantFoldBinaryInstruction(Opcode,C1,C2))returnFC;// Fold a few common cases...std::vector<Constant*>argVec(1,C1);argVec.push_back(C2);ExprMapKeyTypeKey(Opcode,argVec);returnExprConstants->getOrCreate(ReqTy,Key);}Constant*ConstantExpr::getCompareTy(unsignedshortpredicate,Constant*C1,Constant*C2){switch(predicate){default:assert(0&&"Invalid CmpInst predicate");caseFCmpInst::FCMP_FALSE:caseFCmpInst::FCMP_OEQ:caseFCmpInst::FCMP_OGT:caseFCmpInst::FCMP_OGE:caseFCmpInst::FCMP_OLT:caseFCmpInst::FCMP_OLE:caseFCmpInst::FCMP_ONE:caseFCmpInst::FCMP_ORD:caseFCmpInst::FCMP_UNO:caseFCmpInst::FCMP_UEQ:caseFCmpInst::FCMP_UGT:caseFCmpInst::FCMP_UGE:caseFCmpInst::FCMP_ULT:caseFCmpInst::FCMP_ULE:caseFCmpInst::FCMP_UNE:caseFCmpInst::FCMP_TRUE:returngetFCmp(predicate,C1,C2);caseICmpInst::ICMP_EQ:caseICmpInst::ICMP_NE:caseICmpInst::ICMP_UGT:caseICmpInst::ICMP_UGE:caseICmpInst::ICMP_ULT:caseICmpInst::ICMP_ULE:caseICmpInst::ICMP_SGT:caseICmpInst::ICMP_SGE:caseICmpInst::ICMP_SLT:caseICmpInst::ICMP_SLE:returngetICmp(predicate,C1,C2);}}Constant*ConstantExpr::get(unsignedOpcode,Constant*C1,Constant*C2){#ifndef NDEBUGswitch(Opcode){caseInstruction::Add:caseInstruction::Sub:caseInstruction::Mul:assert(C1->getType()==C2->getType()&&"Op types should be identical!");assert((C1->getType()->isInteger()||C1->getType()->isFloatingPoint()||isa<VectorType>(C1->getType()))&&"Tried to create an arithmetic operation on a non-arithmetic type!");break;caseInstruction::UDiv:caseInstruction::SDiv:assert(C1->getType()==C2->getType()&&"Op types should be identical!");assert((C1->getType()->isInteger()||(isa<VectorType>(C1->getType())&&cast<VectorType>(C1->getType())->getElementType()->isInteger()))&&"Tried to create an arithmetic operation on a non-arithmetic type!");break;caseInstruction::FDiv:assert(C1->getType()==C2->getType()&&"Op types should be identical!");assert((C1->getType()->isFloatingPoint()||(isa<VectorType>(C1->getType())&&cast<VectorType>(C1->getType())->getElementType()->isFloatingPoint()))&&"Tried to create an arithmetic operation on a non-arithmetic type!");break;caseInstruction::URem:caseInstruction::SRem:assert(C1->getType()==C2->getType()&&"Op types should be identical!");assert((C1->getType()->isInteger()||(isa<VectorType>(C1->getType())&&cast<VectorType>(C1->getType())->getElementType()->isInteger()))&&"Tried to create an arithmetic operation on a non-arithmetic type!");break;caseInstruction::FRem:assert(C1->getType()==C2->getType()&&"Op types should be identical!");assert((C1->getType()->isFloatingPoint()||(isa<VectorType>(C1->getType())&&cast<VectorType>(C1->getType())->getElementType()->isFloatingPoint()))&&"Tried to create an arithmetic operation on a non-arithmetic type!");break;caseInstruction::And:caseInstruction::Or:caseInstruction::Xor:assert(C1->getType()==C2->getType()&&"Op types should be identical!");assert((C1->getType()->isInteger()||isa<VectorType>(C1->getType()))&&"Tried to create a logical operation on a non-integral type!");break;caseInstruction::Shl:caseInstruction::LShr:caseInstruction::AShr:assert(C1->getType()==C2->getType()&&"Op types should be identical!");assert(C1->getType()->isInteger()&&"Tried to create a shift operation on a non-integer type!");break;default:break;}#endifreturngetTy(C1->getType(),Opcode,C1,C2);}Constant*ConstantExpr::getCompare(unsignedshortpred,Constant*C1,Constant*C2){assert(C1->getType()==C2->getType()&&"Op types should be identical!");returngetCompareTy(pred,C1,C2);}Constant*ConstantExpr::getSelectTy(constType*ReqTy,Constant*C,Constant*V1,Constant*V2){assert(C->getType()==Type::Int1Ty&&"Select condition must be i1!");assert(V1->getType()==V2->getType()&&"Select value types must match!");assert(V1->getType()->isFirstClassType()&&"Cannot select aggregate type!");if(ReqTy==V1->getType())if(Constant*SC=ConstantFoldSelectInstruction(C,V1,V2))returnSC;// Fold common casesstd::vector<Constant*>argVec(3,C);argVec[1]=V1;argVec[2]=V2;ExprMapKeyTypeKey(Instruction::Select,argVec);returnExprConstants->getOrCreate(ReqTy,Key);}Constant*ConstantExpr::getGetElementPtrTy(constType*ReqTy,Constant*C,Value*const*Idxs,unsignedNumIdx){assert(GetElementPtrInst::getIndexedType(C->getType(),Idxs,Idxs+NumIdx,true)&&"GEP indices invalid!");if(Constant*FC=ConstantFoldGetElementPtr(C,(Constant**)Idxs,NumIdx))returnFC;// Fold a few common cases...assert(isa<PointerType>(C->getType())&&"Non-pointer type for constant GetElementPtr expression");// Look up the constant in the table first to ensure uniquenessstd::vector<Constant*>ArgVec;ArgVec.reserve(NumIdx+1);ArgVec.push_back(C);for(unsignedi=0;i!=NumIdx;++i)ArgVec.push_back(cast<Constant>(Idxs[i]));constExprMapKeyTypeKey(Instruction::GetElementPtr,ArgVec);returnExprConstants->getOrCreate(ReqTy,Key);}Constant*ConstantExpr::getGetElementPtr(Constant*C,Value*const*Idxs,unsignedNumIdx){// Get the result type of the getelementptr!constType*Ty=GetElementPtrInst::getIndexedType(C->getType(),Idxs,Idxs+NumIdx,true);assert(Ty&&"GEP indices invalid!");unsignedAs=cast<PointerType>(C->getType())->getAddressSpace();returngetGetElementPtrTy(PointerType::get(Ty,As),C,Idxs,NumIdx);}Constant*ConstantExpr::getGetElementPtr(Constant*C,Constant*const*Idxs,unsignedNumIdx){returngetGetElementPtr(C,(Value*const*)Idxs,NumIdx);}Constant*ConstantExpr::getICmp(unsignedshortpred,Constant*LHS,Constant*RHS){assert(LHS->getType()==RHS->getType());assert(pred>=ICmpInst::FIRST_ICMP_PREDICATE&&pred<=ICmpInst::LAST_ICMP_PREDICATE&&"Invalid ICmp Predicate");if(Constant*FC=ConstantFoldCompareInstruction(pred,LHS,RHS))returnFC;// Fold a few common cases...// Look up the constant in the table first to ensure uniquenessstd::vector<Constant*>ArgVec;ArgVec.push_back(LHS);ArgVec.push_back(RHS);// Get the key type with both the opcode and predicateconstExprMapKeyTypeKey(Instruction::ICmp,ArgVec,pred);returnExprConstants->getOrCreate(Type::Int1Ty,Key);}Constant*ConstantExpr::getFCmp(unsignedshortpred,Constant*LHS,Constant*RHS){assert(LHS->getType()==RHS->getType());assert(pred<=FCmpInst::LAST_FCMP_PREDICATE&&"Invalid FCmp Predicate");if(Constant*FC=ConstantFoldCompareInstruction(pred,LHS,RHS))returnFC;// Fold a few common cases...// Look up the constant in the table first to ensure uniquenessstd::vector<Constant*>ArgVec;ArgVec.push_back(LHS);ArgVec.push_back(RHS);// Get the key type with both the opcode and predicateconstExprMapKeyTypeKey(Instruction::FCmp,ArgVec,pred);returnExprConstants->getOrCreate(Type::Int1Ty,Key);}Constant*ConstantExpr::getExtractElementTy(constType*ReqTy,Constant*Val,Constant*Idx){if(Constant*FC=ConstantFoldExtractElementInstruction(Val,Idx))returnFC;// Fold a few common cases...// Look up the constant in the table first to ensure uniquenessstd::vector<Constant*>ArgVec(1,Val);ArgVec.push_back(Idx);constExprMapKeyTypeKey(Instruction::ExtractElement,ArgVec);returnExprConstants->getOrCreate(ReqTy,Key);}Constant*ConstantExpr::getExtractElement(Constant*Val,Constant*Idx){assert(isa<VectorType>(Val->getType())&&"Tried to create extractelement operation on non-vector type!");assert(Idx->getType()==Type::Int32Ty&&"Extractelement index must be i32 type!");returngetExtractElementTy(cast<VectorType>(Val->getType())->getElementType(),Val,Idx);}Constant*ConstantExpr::getInsertElementTy(constType*ReqTy,Constant*Val,Constant*Elt,Constant*Idx){if(Constant*FC=ConstantFoldInsertElementInstruction(Val,Elt,Idx))returnFC;// Fold a few common cases...// Look up the constant in the table first to ensure uniquenessstd::vector<Constant*>ArgVec(1,Val);ArgVec.push_back(Elt);ArgVec.push_back(Idx);constExprMapKeyTypeKey(Instruction::InsertElement,ArgVec);returnExprConstants->getOrCreate(ReqTy,Key);}Constant*ConstantExpr::getInsertElement(Constant*Val,Constant*Elt,Constant*Idx){assert(isa<VectorType>(Val->getType())&&"Tried to create insertelement operation on non-vector type!");assert(Elt->getType()==cast<VectorType>(Val->getType())->getElementType()&&"Insertelement types must match!");assert(Idx->getType()==Type::Int32Ty&&"Insertelement index must be i32 type!");returngetInsertElementTy(cast<VectorType>(Val->getType())->getElementType(),Val,Elt,Idx);}Constant*ConstantExpr::getShuffleVectorTy(constType*ReqTy,Constant*V1,Constant*V2,Constant*Mask){if(Constant*FC=ConstantFoldShuffleVectorInstruction(V1,V2,Mask))returnFC;// Fold a few common cases...// Look up the constant in the table first to ensure uniquenessstd::vector<Constant*>ArgVec(1,V1);ArgVec.push_back(V2);ArgVec.push_back(Mask);constExprMapKeyTypeKey(Instruction::ShuffleVector,ArgVec);returnExprConstants->getOrCreate(ReqTy,Key);}Constant*ConstantExpr::getShuffleVector(Constant*V1,Constant*V2,Constant*Mask){assert(ShuffleVectorInst::isValidOperands(V1,V2,Mask)&&"Invalid shuffle vector constant expr operands!");returngetShuffleVectorTy(V1->getType(),V1,V2,Mask);}Constant*ConstantExpr::getZeroValueForNegationExpr(constType*Ty){if(constVectorType*PTy=dyn_cast<VectorType>(Ty))if(PTy->getElementType()->isFloatingPoint()){std::vector<Constant*>zeros(PTy->getNumElements(),ConstantFP::getNegativeZero(PTy->getElementType()));returnConstantVector::get(PTy,zeros);}if(Ty->isFloatingPoint())returnConstantFP::getNegativeZero(Ty);returnConstant::getNullValue(Ty);}// destroyConstant - Remove the constant from the constant table...//voidConstantExpr::destroyConstant(){ExprConstants->remove(this);destroyConstantImpl();}constchar*ConstantExpr::getOpcodeName()const{returnInstruction::getOpcodeName(getOpcode());}//===----------------------------------------------------------------------===//// replaceUsesOfWithOnConstant implementations/// replaceUsesOfWithOnConstant - Update this constant array to change uses of/// 'From' to be uses of 'To'. This must update the uniquing data structures/// etc.////// Note that we intentionally replace all uses of From with To here. Consider/// a large array that uses 'From' 1000 times. By handling this case all here,/// ConstantArray::replaceUsesOfWithOnConstant is only invoked once, and that/// single invocation handles all 1000 uses. Handling them one at a time would/// work, but would be really slow because it would have to unique each updated/// array instance.voidConstantArray::replaceUsesOfWithOnConstant(Value*From,Value*To,Use*U){assert(isa<Constant>(To)&&"Cannot make Constant refer to non-constant!");Constant*ToC=cast<Constant>(To);std::pair<ArrayConstantsTy::MapKey,Constant*>Lookup;Lookup.first.first=getType();Lookup.second=this;std::vector<Constant*>&Values=Lookup.first.second;Values.reserve(getNumOperands());// Build replacement array.// Fill values with the modified operands of the constant array. Also, // compute whether this turns into an all-zeros array.boolisAllZeros=false;unsignedNumUpdated=0;if(!ToC->isNullValue()){for(Use*O=OperandList,*E=OperandList+getNumOperands();O!=E;++O){Constant*Val=cast<Constant>(O->get());if(Val==From){Val=ToC;++NumUpdated;}Values.push_back(Val);}}else{isAllZeros=true;for(Use*O=OperandList,*E=OperandList+getNumOperands();O!=E;++O){Constant*Val=cast<Constant>(O->get());if(Val==From){Val=ToC;++NumUpdated;}Values.push_back(Val);if(isAllZeros)isAllZeros=Val->isNullValue();}}Constant*Replacement=0;if(isAllZeros){Replacement=ConstantAggregateZero::get(getType());}else{// Check to see if we have this array type already.boolExists;ArrayConstantsTy::MapTy::iteratorI=ArrayConstants->InsertOrGetItem(Lookup,Exists);if(Exists){Replacement=I->second;}else{// Okay, the new shape doesn't exist in the system yet. Instead of// creating a new constant array, inserting it, replaceallusesof'ing the// old with the new, then deleting the old... just update the current one// in place!ArrayConstants->MoveConstantToNewSlot(this,I);// Update to the new value. Optimize for the case when we have a single// operand that we're changing, but handle bulk updates efficiently.if(NumUpdated==1){unsignedOperandToUpdate=U-OperandList;assert(getOperand(OperandToUpdate)==From&&"ReplaceAllUsesWith broken!");setOperand(OperandToUpdate,ToC);}else{for(unsignedi=0,e=getNumOperands();i!=e;++i)if(getOperand(i)==From)setOperand(i,ToC);}return;}}// Otherwise, I do need to replace this with an existing value.assert(Replacement!=this&&"I didn't contain From!");// Everyone using this now uses the replacement.uncheckedReplaceAllUsesWith(Replacement);// Delete the old constant!destroyConstant();}voidConstantStruct::replaceUsesOfWithOnConstant(Value*From,Value*To,Use*U){assert(isa<Constant>(To)&&"Cannot make Constant refer to non-constant!");Constant*ToC=cast<Constant>(To);unsignedOperandToUpdate=U-OperandList;assert(getOperand(OperandToUpdate)==From&&"ReplaceAllUsesWith broken!");std::pair<StructConstantsTy::MapKey,Constant*>Lookup;Lookup.first.first=getType();Lookup.second=this;std::vector<Constant*>&Values=Lookup.first.second;Values.reserve(getNumOperands());// Build replacement struct.// Fill values with the modified operands of the constant struct. Also, // compute whether this turns into an all-zeros struct.boolisAllZeros=false;if(!ToC->isNullValue()){for(Use*O=OperandList,*E=OperandList+getNumOperands();O!=E;++O)Values.push_back(cast<Constant>(O->get()));}else{isAllZeros=true;for(Use*O=OperandList,*E=OperandList+getNumOperands();O!=E;++O){Constant*Val=cast<Constant>(O->get());Values.push_back(Val);if(isAllZeros)isAllZeros=Val->isNullValue();}}Values[OperandToUpdate]=ToC;Constant*Replacement=0;if(isAllZeros){Replacement=ConstantAggregateZero::get(getType());}else{// Check to see if we have this array type already.boolExists;StructConstantsTy::MapTy::iteratorI=StructConstants->InsertOrGetItem(Lookup,Exists);if(Exists){Replacement=I->second;}else{// Okay, the new shape doesn't exist in the system yet. Instead of// creating a new constant struct, inserting it, replaceallusesof'ing the// old with the new, then deleting the old... just update the current one// in place!StructConstants->MoveConstantToNewSlot(this,I);// Update to the new value.setOperand(OperandToUpdate,ToC);return;}}assert(Replacement!=this&&"I didn't contain From!");// Everyone using this now uses the replacement.uncheckedReplaceAllUsesWith(Replacement);// Delete the old constant!destroyConstant();}voidConstantVector::replaceUsesOfWithOnConstant(Value*From,Value*To,Use*U){assert(isa<Constant>(To)&&"Cannot make Constant refer to non-constant!");std::vector<Constant*>Values;Values.reserve(getNumOperands());// Build replacement array...for(unsignedi=0,e=getNumOperands();i!=e;++i){Constant*Val=getOperand(i);if(Val==From)Val=cast<Constant>(To);Values.push_back(Val);}Constant*Replacement=ConstantVector::get(getType(),Values);assert(Replacement!=this&&"I didn't contain From!");// Everyone using this now uses the replacement.uncheckedReplaceAllUsesWith(Replacement);// Delete the old constant!destroyConstant();}voidConstantExpr::replaceUsesOfWithOnConstant(Value*From,Value*ToV,Use*U){assert(isa<Constant>(ToV)&&"Cannot make Constant refer to non-constant!");Constant*To=cast<Constant>(ToV);Constant*Replacement=0;if(getOpcode()==Instruction::GetElementPtr){SmallVector<Constant*,8>Indices;Constant*Pointer=getOperand(0);Indices.reserve(getNumOperands()-1);if(Pointer==From)Pointer=To;for(unsignedi=1,e=getNumOperands();i!=e;++i){Constant*Val=getOperand(i);if(Val==From)Val=To;Indices.push_back(Val);}Replacement=ConstantExpr::getGetElementPtr(Pointer,&Indices[0],Indices.size());}elseif(isCast()){assert(getOperand(0)==From&&"Cast only has one use!");Replacement=ConstantExpr::getCast(getOpcode(),To,getType());}elseif(getOpcode()==Instruction::Select){Constant*C1=getOperand(0);Constant*C2=getOperand(1);Constant*C3=getOperand(2);if(C1==From)C1=To;if(C2==From)C2=To;if(C3==From)C3=To;Replacement=ConstantExpr::getSelect(C1,C2,C3);}elseif(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);}elseif(getOpcode()==Instruction::InsertElement){Constant*C1=getOperand(0);Constant*C2=getOperand(1);Constant*C3=getOperand(1);if(C1==From)C1=To;if(C2==From)C2=To;if(C3==From)C3=To;Replacement=ConstantExpr::getInsertElement(C1,C2,C3);}elseif(getOpcode()==Instruction::ShuffleVector){Constant*C1=getOperand(0);Constant*C2=getOperand(1);Constant*C3=getOperand(2);if(C1==From)C1=To;if(C2==From)C2=To;if(C3==From)C3=To;Replacement=ConstantExpr::getShuffleVector(C1,C2,C3);}elseif(isCompare()){Constant*C1=getOperand(0);Constant*C2=getOperand(1);if(C1==From)C1=To;if(C2==From)C2=To;if(getOpcode()==Instruction::ICmp)Replacement=ConstantExpr::getICmp(getPredicate(),C1,C2);elseReplacement=ConstantExpr::getFCmp(getPredicate(),C1,C2);}elseif(getNumOperands()==2){Constant*C1=getOperand(0);Constant*C2=getOperand(1);if(C1==From)C1=To;if(C2==From)C2=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.uncheckedReplaceAllUsesWith(Replacement);// Delete the old constant!destroyConstant();}/// 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::stringConstant::getStringValue(boolChop,unsignedOffset){if(GlobalVariable*GV=dyn_cast<GlobalVariable>(this)){if(GV->hasInitializer()&&isa<ConstantArray>(GV->getInitializer())){ConstantArray*Init=cast<ConstantArray>(GV->getInitializer());if(Init->isString()){std::stringResult=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_typeNullPos=Result.find_first_of((char)0);if(NullPos!=std::string::npos)Result.erase(Result.begin()+NullPos,Result.end());}returnResult;}}}}elseif(ConstantExpr*CE=dyn_cast<ConstantExpr>(this)){if(CE->getOpcode()==Instruction::GetElementPtr){// Turn a gep into the specified offset.if(CE->getNumOperands()==3&&cast<Constant>(CE->getOperand(1))->isNullValue()&&isa<ConstantInt>(CE->getOperand(2))){Offset+=cast<ConstantInt>(CE->getOperand(2))->getZExtValue();returnCE->getOperand(0)->getStringValue(Chop,Offset);}}}return"";}