Ejemplo n.º 1
0
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;
}