AllocaInst* Variables::changeLocal(Value* value, ArrayType* newType) { AllocaInst* oldTarget = dyn_cast<AllocaInst>(value); PointerType* oldPointerType = dyn_cast<PointerType>(oldTarget->getType()); ArrayType* oldType = dyn_cast<ArrayType>(oldPointerType->getElementType()); AllocaInst* newTarget = NULL; errs() << "Changing the precision of variable \"" << oldTarget->getName() << "\" from " << *oldType << " to " << *newType << ".\n"; if (newType->getElementType()->getTypeID() != oldType->getElementType()->getTypeID()) { 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 = 16; 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(); for(; it != oldTarget->use_end(); it++) { bool is_erased = Transformer::transform(it, newTarget, oldTarget, newType, oldType, alignment); if (!is_erased) erase.push_back(dyn_cast<Instruction>(*it)); } // erasing uses of old instructions for(unsigned int i = 0; i < erase.size(); i++) { erase[i]->eraseFromParent(); } // erase old instruction //oldTarget->eraseFromParent(); } else { errs() << "\tNo changes required.\n"; } return newTarget; }
AllocaInst* Variables::changeLocal(Value* value, StructType* newType/*, int field*/) { errs() << "At changeLocalStruct\n"; AllocaInst* newTarget = NULL; vector<Instruction*> erase; if (AllocaInst *oldTarget = dyn_cast<AllocaInst>(value)) { if (PointerType *oldPointer = dyn_cast<PointerType>(oldTarget->getType())) { if (StructType *oldType = dyn_cast<StructType>(oldPointer->getElementType())) { errs() << "Changing the precision of variable \"" << oldTarget->getName() << "\" from " << *oldType << " to " << *newType << ".\n"; if (diffStructTypes(oldType, newType)) { unsigned alignment = oldTarget->getAlignment(); newTarget = new AllocaInst(newType, 0, alignment, "new", oldTarget); newTarget->takeName(oldTarget); // iterating through instructions using old getelementptr instructions Value::use_iterator it = oldTarget->use_begin(); for(; it != oldTarget->use_end(); it++) { if (GetElementPtrInst *getElementPtrInst = dyn_cast<GetElementPtrInst>(*it)) { if (ConstantInt *constantIntIndex = dyn_cast<ConstantInt>(getElementPtrInst->getOperand(2))) { unsigned int index = constantIntIndex->getLimitedValue(); // the index of the field accessed by this use Type *newFieldType = newType->getElementType(index); Type *oldFieldType = oldType->getElementType(index); unsigned alignment = getAlignment(newFieldType); // 4 hard coded for now bool is_erased = Transformer::transform(it, newTarget, oldTarget, newFieldType, oldFieldType, alignment); if (!is_erased) { erase.push_back(dyn_cast<Instruction>(*it)); } } } else { errs() << "WARNING: unexpected use of struct\n"; } } // erasing uses of old instructions for(unsigned int i = 0; i < erase.size(); i++) { erase[i]->eraseFromParent(); } } else { errs() << "\tNo changes required.\n"; } } } } return newTarget; }
AllocaInst* Variables::changeLocal(Value* value, Type* newType) { AllocaInst* newTarget = NULL; vector<Instruction*> erase; if (AllocaInst *oldTarget = dyn_cast<AllocaInst>(value)) { Type* oldType = oldTarget->getType()->getElementType(); errs() << "Changing the precision of variable \"" << oldTarget->getName() << "\" from " << *oldType << " to " << *newType << ".\n"; if (diffTypes(oldType, newType)) { unsigned alignment = getAlignment(newType); newTarget = new AllocaInst(newType, 0, alignment, "new", oldTarget); newTarget->takeName(oldTarget); // iterating through instructions using old AllocaInst Value::use_iterator it = oldTarget->use_begin(); for(; it != oldTarget->use_end(); it++) { bool is_erased = Transformer::transform(it, newTarget, oldTarget, newType, oldType, alignment); if (!is_erased) { erase.push_back(dyn_cast<Instruction>(*it)); } } // erasing old uses of instructions for(unsigned int i = 0; i < erase.size(); i++) { erase[i]->eraseFromParent(); } // erase old instruction //oldTarget->eraseFromParent(); } else { errs() << "\tNo changes required.\n"; } } else if (Argument *argument = dyn_cast<Argument>(value)){ errs() << "WARNING: Function argument instead of Alloca for: " << argument->getName() << ".\n"; } return newTarget; }