-// ExpressionConvertableToType - Return true if it is possible
-static bool ExpressionConvertableToType(Value *V, const Type *Ty) {
- Instruction *I = dyn_cast<Instruction>(V);
- if (I == 0) return false; // Noninstructions can't convert
- if (I->getType() == Ty) return false; // Expression already correct type!
-
- switch (I->getOpcode()) {
- case Instruction::Cast:
- // We can convert the expr if the cast destination type is losslessly
- // convertable to the requested type.
- return losslessCastableTypes(Ty, I->getType());
-
- case Instruction::Add:
- case Instruction::Sub:
- return ExpressionConvertableToType(I->getOperand(0), Ty) &&
- ExpressionConvertableToType(I->getOperand(1), Ty);
- case Instruction::Shl:
- case Instruction::Shr:
- return ExpressionConvertableToType(I->getOperand(0), Ty);
- }
- return false;
-}
-
-
-static Instruction *ConvertExpressionToType(Value *V, const Type *Ty) {
- Instruction *I = cast<Instruction>(V);
- assert(ExpressionConvertableToType(I, Ty) && "Inst is not convertable!");
- BasicBlock *BB = I->getParent();
- BasicBlock::InstListType &BIL = BB->getInstList();
- string Name = I->getName(); if (!Name.empty()) I->setName("");
- Instruction *Res; // Result of conversion
-
- //cerr << endl << endl << "Type:\t" << Ty << "\nInst: " << I << "BB Before: " << BB << endl;
-
- switch (I->getOpcode()) {
- case Instruction::Cast:
- Res = new CastInst(I->getOperand(0), Ty, Name);
- break;
-
- case Instruction::Add:
- case Instruction::Sub:
- Res = BinaryOperator::create(cast<BinaryOperator>(I)->getOpcode(),
- ConvertExpressionToType(I->getOperand(0), Ty),
- ConvertExpressionToType(I->getOperand(1), Ty),
- Name);
- break;
-
- case Instruction::Shl:
- case Instruction::Shr:
- Res = new ShiftInst(cast<ShiftInst>(I)->getOpcode(),
- ConvertExpressionToType(I->getOperand(0), Ty),
- I->getOperand(1), Name);
- break;
-
- default:
- assert(0 && "Expression convertable, but don't know how to convert?");
- return 0;
- }
-
- BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
- assert(It != BIL.end() && "Instruction not in own basic block??");
- BIL.insert(It, Res);
-
- //cerr << "RInst: " << Res << "BB After: " << BB << endl << endl;
-
- return Res;
-}
-
-
-
-// DoInsertArrayCast - If the argument value has a pointer type, and if the
-// argument value is used as an array, insert a cast before the specified
-// basic block iterator that casts the value to an array pointer. Return the
-// new cast instruction (in the CastResult var), or null if no cast is inserted.
-//
-static bool DoInsertArrayCast(Method *CurMeth, Value *V, BasicBlock *BB,
- BasicBlock::iterator &InsertBefore,
- CastInst *&CastResult) {
- const PointerType *ThePtrType = dyn_cast<PointerType>(V->getType());
- if (!ThePtrType) return false;
- bool InsertCast = false;
-
- for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
- Instruction *Inst = cast<Instruction>(*I);
- switch (Inst->getOpcode()) {
- default: break; // Not an interesting use...
- case Instruction::Add: // It's being used as an array index!
- //case Instruction::Sub:
- InsertCast = true;
- break;
- case Instruction::Cast: // There is already a cast instruction!
- if (const PointerType *PT = dyn_cast<const PointerType>(Inst->getType()))
- if (const ArrayType *AT = dyn_cast<const ArrayType>(PT->getValueType()))
- if (AT->getElementType() == ThePtrType->getValueType()) {
- // Cast already exists! Return the existing one!
- CastResult = cast<CastInst>(Inst);
- return false; // No changes made to program though...
- }
- break;