AllocaInst* Variables::changeLocal(Value* value, PointerType* newType) { AllocaInst *oldTarget = dyn_cast<AllocaInst>(value); PointerType* oldPointerType = dyn_cast<PointerType>(oldTarget->getType()); PointerType *oldType = dyn_cast<PointerType>(oldPointerType->getElementType()); AllocaInst *newTarget = NULL; errs() << "Changing the precision of pointer variable \"" << oldTarget->getName() << "\" from " << *oldType << " to " << *newType << ".\n"; if (diffTypes(newType, oldType)) { newTarget = new AllocaInst(newType, getInt32(1), "", oldTarget); // we are not calling getAlignment because in this case double requires 16. Investigate further. unsigned alignment; switch(newType->getElementType()->getTypeID()) { case Type::FloatTyID: alignment = 4; break; case Type::DoubleTyID: alignment = 8; break; case Type::X86_FP80TyID: alignment = 16; break; default: alignment = 0; } newTarget->setAlignment(alignment); // depends on type? 8 for float? 16 for double? newTarget->takeName(oldTarget); // iterating through instructions using old AllocaInst vector<Instruction*> erase; Value::use_iterator it = oldTarget->use_begin(); #ifdef DEBUG errs() << "\nOld target: "; oldTarget->dump(); #endif for(; it != oldTarget->use_end(); it++) { #ifdef DEBUG errs() << "\nA use: "; it->dump(); errs() << "\n===============================\n"; errs() << "\nTransforming use\n"; #endif bool is_erased = Transformer::transform(it, newTarget, oldTarget, newType, oldType, alignment); if (!is_erased) { erase.push_back(dyn_cast<Instruction>(*it)); } #ifdef DEBUG errs() << "\nDone transforming use\n"; #endif } // erasing uses of old instructions for(unsigned int i = 0; i < erase.size(); i++) { erase[i]->eraseFromParent(); } // erase old instruction //oldTarget->eraseFromParent(); #ifdef DEBUG errs() << "DONE ALL TRANSFORMATION FOR POINTER\n"; #endif } else { errs() << "\tNo changes required.\n"; } return newTarget; }