Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}