+
+Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
+ const Constant *V1,
+ const Constant *V2) {
+ Constant *C = 0;
+ switch (Opcode) {
+ default: break;
+ case Instruction::Add: C = ConstRules::get(V1, V2).add(V1, V2); break;
+ case Instruction::Sub: C = ConstRules::get(V1, V2).sub(V1, V2); break;
+ case Instruction::Mul: C = ConstRules::get(V1, V2).mul(V1, V2); break;
+ case Instruction::Div: C = ConstRules::get(V1, V2).div(V1, V2); break;
+ case Instruction::Rem: C = ConstRules::get(V1, V2).rem(V1, V2); break;
+ case Instruction::And: C = ConstRules::get(V1, V2).op_and(V1, V2); break;
+ case Instruction::Or: C = ConstRules::get(V1, V2).op_or (V1, V2); break;
+ case Instruction::Xor: C = ConstRules::get(V1, V2).op_xor(V1, V2); break;
+ case Instruction::Shl: C = ConstRules::get(V1, V2).shl(V1, V2); break;
+ case Instruction::Shr: C = ConstRules::get(V1, V2).shr(V1, V2); break;
+ case Instruction::SetEQ: C = ConstRules::get(V1, V2).equalto(V1, V2); break;
+ case Instruction::SetLT: C = ConstRules::get(V1, V2).lessthan(V1, V2);break;
+ case Instruction::SetGT: C = ConstRules::get(V1, V2).lessthan(V2, V1);break;
+ case Instruction::SetNE: // V1 != V2 === !(V1 == V2)
+ C = ConstRules::get(V1, V2).equalto(V1, V2);
+ if (C) return ConstantExpr::get(Instruction::Xor, C, ConstantBool::True);
+ break;
+ case Instruction::SetLE: // V1 <= V2 === !(V2 < V1)
+ C = ConstRules::get(V1, V2).lessthan(V2, V1);
+ if (C) return ConstantExpr::get(Instruction::Xor, C, ConstantBool::True);
+ break;
+ case Instruction::SetGE: // V1 >= V2 === !(V1 < V2)
+ C = ConstRules::get(V1, V2).lessthan(V1, V2);
+ if (C) return ConstantExpr::get(Instruction::Xor, C, ConstantBool::True);
+ break;
+ }
+
+ // If we successfully folded the expression, return it now.
+ if (C) return C;
+
+ if (SetCondInst::isRelational(Opcode))
+ switch (evaluateRelation(V1, V2)) {
+ default: assert(0 && "Unknown relational!");
+ case Instruction::BinaryOpsEnd:
+ break; // Couldn't determine anything about these constants.
+ case Instruction::SetEQ: // We know the constants are equal!
+ // If we know the constants are equal, we can decide the result of this
+ // computation precisely.
+ return ConstantBool::get(Opcode == Instruction::SetEQ ||
+ Opcode == Instruction::SetLE ||
+ Opcode == Instruction::SetGE);
+ case Instruction::SetLT:
+ // If we know that V1 < V2, we can decide the result of this computation
+ // precisely.
+ return ConstantBool::get(Opcode == Instruction::SetLT ||
+ Opcode == Instruction::SetNE ||
+ Opcode == Instruction::SetLE);
+ case Instruction::SetGT:
+ // If we know that V1 > V2, we can decide the result of this computation
+ // precisely.
+ return ConstantBool::get(Opcode == Instruction::SetGT ||
+ Opcode == Instruction::SetNE ||
+ Opcode == Instruction::SetGE);
+ case Instruction::SetLE:
+ // If we know that V1 <= V2, we can only partially decide this relation.
+ if (Opcode == Instruction::SetGT) return ConstantBool::False;
+ if (Opcode == Instruction::SetLT) return ConstantBool::True;
+ break;
+
+ case Instruction::SetGE:
+ // If we know that V1 >= V2, we can only partially decide this relation.
+ if (Opcode == Instruction::SetLT) return ConstantBool::False;
+ if (Opcode == Instruction::SetGT) return ConstantBool::True;
+ break;
+
+ case Instruction::SetNE:
+ // If we know that V1 != V2, we can only partially decide this relation.
+ if (Opcode == Instruction::SetEQ) return ConstantBool::False;
+ if (Opcode == Instruction::SetNE) return ConstantBool::True;
+ break;
+ }
+
+ if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(V1)) {
+ if (const ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2)) {
+ // There are many possible foldings we could do here. We should probably
+ // at least fold add of a pointer with an integer into the appropriate
+ // getelementptr. This will improve alias analysis a bit.
+
+
+
+
+ } else {
+ // Just implement a couple of simple identities.
+ switch (Opcode) {
+ case Instruction::Add:
+ if (V2->isNullValue()) return const_cast<Constant*>(V1); // X + 0 == X
+ break;
+ case Instruction::Sub:
+ if (V2->isNullValue()) return const_cast<Constant*>(V1); // X - 0 == X
+ break;
+ case Instruction::Mul:
+ if (V2->isNullValue()) return const_cast<Constant*>(V2); // X * 0 == 0
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V2))
+ if (CI->getRawValue() == 1)
+ return const_cast<Constant*>(V1); // X * 1 == X
+ break;
+ case Instruction::Div:
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V2))
+ if (CI->getRawValue() == 1)
+ return const_cast<Constant*>(V1); // X / 1 == X
+ break;
+ case Instruction::Rem:
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V2))
+ if (CI->getRawValue() == 1)
+ return Constant::getNullValue(CI->getType()); // X % 1 == 0
+ break;
+ case Instruction::And:
+ if (cast<ConstantIntegral>(V2)->isAllOnesValue())
+ return const_cast<Constant*>(V1); // X & -1 == X
+ if (V2->isNullValue()) return const_cast<Constant*>(V2); // X & 0 == 0
+ if (CE1->getOpcode() == Instruction::Cast &&
+ isa<GlobalValue>(CE1->getOperand(0))) {
+ GlobalValue *CPR =cast<GlobalValue>(CE1->getOperand(0));
+
+ // Functions are at least 4-byte aligned. If and'ing the address of a
+ // function with a constant < 4, fold it to zero.
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V2))
+ if (CI->getRawValue() < 4 && isa<Function>(CPR))
+ return Constant::getNullValue(CI->getType());
+ }
+ break;
+ case Instruction::Or:
+ if (V2->isNullValue()) return const_cast<Constant*>(V1); // X | 0 == X
+ if (cast<ConstantIntegral>(V2)->isAllOnesValue())
+ return const_cast<Constant*>(V2); // X | -1 == -1
+ break;
+ case Instruction::Xor:
+ if (V2->isNullValue()) return const_cast<Constant*>(V1); // X ^ 0 == X
+ break;
+ }
+ }
+
+ } else if (const ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2)) {
+ // If V2 is a constant expr and V1 isn't, flop them around and fold the
+ // other way if possible.
+ switch (Opcode) {
+ case Instruction::Add:
+ case Instruction::Mul:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
+ case Instruction::SetEQ:
+ case Instruction::SetNE:
+ // No change of opcode required.
+ return ConstantFoldBinaryInstruction(Opcode, V2, V1);
+
+ case Instruction::SetLT:
+ case Instruction::SetGT:
+ case Instruction::SetLE:
+ case Instruction::SetGE:
+ // Change the opcode as necessary to swap the operands.
+ Opcode = SetCondInst::getSwappedCondition((Instruction::BinaryOps)Opcode);
+ return ConstantFoldBinaryInstruction(Opcode, V2, V1);
+
+ case Instruction::Shl:
+ case Instruction::Shr:
+ case Instruction::Sub:
+ case Instruction::Div:
+ case Instruction::Rem:
+ default: // These instructions cannot be flopped around.
+ break;
+ }
+ }
+ return 0;
+}
+
+Constant *llvm::ConstantFoldGetElementPtr(const Constant *C,
+ const std::vector<Constant*> &IdxList) {
+ if (IdxList.size() == 0 ||
+ (IdxList.size() == 1 && IdxList[0]->isNullValue()))
+ return const_cast<Constant*>(C);
+
+ if (C->isNullValue()) {
+ bool isNull = true;
+ for (unsigned i = 0, e = IdxList.size(); i != e; ++i)
+ if (!IdxList[i]->isNullValue()) {
+ isNull = false;
+ break;
+ }
+ if (isNull) {
+ std::vector<Value*> VIdxList(IdxList.begin(), IdxList.end());
+ const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), VIdxList,
+ true);
+ assert(Ty != 0 && "Invalid indices for GEP!");
+ return ConstantPointerNull::get(PointerType::get(Ty));
+ }
+
+ if (IdxList.size() == 1) {
+ const Type *ElTy = cast<PointerType>(C->getType())->getElementType();
+ if (unsigned ElSize = ElTy->getPrimitiveSize()) {
+ // gep null, C is equal to C*sizeof(nullty). If nullty is a known llvm
+ // type, we can statically fold this.
+ Constant *R = ConstantUInt::get(Type::UIntTy, ElSize);
+ R = ConstantExpr::getCast(R, IdxList[0]->getType());
+ R = ConstantExpr::getMul(R, IdxList[0]);
+ return ConstantExpr::getCast(R, C->getType());
+ }
+ }
+ }
+
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(const_cast<Constant*>(C))) {
+ // Combine Indices - If the source pointer to this getelementptr instruction
+ // is a getelementptr instruction, combine the indices of the two
+ // getelementptr instructions into a single instruction.
+ //
+ if (CE->getOpcode() == Instruction::GetElementPtr) {
+ const Type *LastTy = 0;
+ for (gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
+ I != E; ++I)
+ LastTy = *I;
+
+ if ((LastTy && isa<ArrayType>(LastTy)) || IdxList[0]->isNullValue()) {
+ std::vector<Constant*> NewIndices;
+ NewIndices.reserve(IdxList.size() + CE->getNumOperands());
+ for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i)
+ NewIndices.push_back(cast<Constant>(CE->getOperand(i)));
+
+ // Add the last index of the source with the first index of the new GEP.
+ // Make sure to handle the case when they are actually different types.
+ Constant *Combined = CE->getOperand(CE->getNumOperands()-1);
+ if (!IdxList[0]->isNullValue()) { // Otherwise it must be an array
+ const Type *IdxTy = Combined->getType();
+ if (IdxTy != IdxList[0]->getType()) IdxTy = Type::LongTy;
+ Combined =
+ ConstantExpr::get(Instruction::Add,
+ ConstantExpr::getCast(IdxList[0], IdxTy),
+ ConstantExpr::getCast(Combined, IdxTy));
+ }
+
+ NewIndices.push_back(Combined);
+ NewIndices.insert(NewIndices.end(), IdxList.begin()+1, IdxList.end());
+ return ConstantExpr::getGetElementPtr(CE->getOperand(0), NewIndices);
+ }
+ }
+
+ // Implement folding of:
+ // int* getelementptr ([2 x int]* cast ([3 x int]* %X to [2 x int]*),
+ // long 0, long 0)
+ // To: int* getelementptr ([3 x int]* %X, long 0, long 0)
+ //
+ if (CE->getOpcode() == Instruction::Cast && IdxList.size() > 1 &&
+ IdxList[0]->isNullValue())
+ if (const PointerType *SPT =
+ dyn_cast<PointerType>(CE->getOperand(0)->getType()))
+ if (const ArrayType *SAT = dyn_cast<ArrayType>(SPT->getElementType()))
+ if (const ArrayType *CAT =
+ dyn_cast<ArrayType>(cast<PointerType>(C->getType())->getElementType()))
+ if (CAT->getElementType() == SAT->getElementType())
+ return ConstantExpr::getGetElementPtr(
+ (Constant*)CE->getOperand(0), IdxList);
+ }
+ return 0;
+}
+