Ejemplo n.º 1
0
		llvm::Value* getSingleTranslatedArgument(Function& functionGenerator,
		                                         llvm::Value* const argValue,
		                                         const SEM::Type* const parameterType,
		                                         const SEM::Type* const translatedParameterType) {
			auto& builder = functionGenerator.getBuilder();
			auto& module = functionGenerator.module();
			
			const auto llvmParameterType = genArgType(module, parameterType);
			const auto llvmTranslatedParameterType = genArgType(module, translatedParameterType);
			
			// Being able to pass the inner parameter type by value must imply
			// that the outer parameter type can be passed by value.
			assert(checkImplies(canPassByValue(module, parameterType), canPassByValue(module, translatedParameterType)));
			
			if (!canPassByValue(module, parameterType) && canPassByValue(module, translatedParameterType)) {
				// Create an alloca to hinner the parameter so it can be passed by pointer
				// into the target function.
				const auto argAlloca = genAlloca(functionGenerator, translatedParameterType);
				genStore(functionGenerator, argValue, argAlloca, translatedParameterType);
				return builder.CreatePointerCast(argAlloca, llvmParameterType);
			} else if (llvmParameterType->isPointerTy() && llvmTranslatedParameterType->isPointerTy()) {
				// Make sure our pointers have the right type.
				return builder.CreatePointerCast(argValue, llvmParameterType);
			} else {
				return argValue;
			}
		}
Ejemplo n.º 2
0
bool FunctionState::hasValue(llvm::Instruction const *ForInstruction) const
{
  if (!isDominatedByActive(ForInstruction))
    return false;

  auto const Type = ForInstruction->getType();

  if (Type->isIntegerTy()) {
    return ValuesUInt64.count(ForInstruction);
  }
  else if (Type->isPointerTy()) {
    return ValuesPtr.count(ForInstruction);
  }
  else if (Type->isFloatTy()) {
    return ValuesFloat.count(ForInstruction);
  }
  else if (Type->isDoubleTy()) {
    return ValuesDouble.count(ForInstruction);
  }
  else if (Type->isX86_FP80Ty() || Type->isFP128Ty() || Type->isPPC_FP128Ty()) {
    return ValuesAPFloat.count(ForInstruction);
  }
  else {
    return false;
  }
}
Ejemplo n.º 3
0
 llvm::Type *emit_alloc_type(T const& t)
 {
     auto const ty = emit(t);
     if (ty->isPointerTy()) {
         return ty->getPointerElementType();
     } else {
         return ty;
     }
 }
Ejemplo n.º 4
0
void FunctionState::clearValue(llvm::Instruction const *ForInstruction)
{
  auto const Type = ForInstruction->getType();

  if (Type->isIntegerTy()) {
    ValuesUInt64.erase(ForInstruction);
  }
  else if (Type->isPointerTy()) {
    ValuesPtr.erase(ForInstruction);
  }
  else if (Type->isFloatTy()) {
    ValuesFloat.erase(ForInstruction);
  }
  else if (Type->isDoubleTy()) {
    ValuesDouble.erase(ForInstruction);
  }
  else if (Type->isX86_FP80Ty() || Type->isFP128Ty() || Type->isPPC_FP128Ty()) {
    ValuesAPFloat.erase(ForInstruction);
  }
}
Ejemplo n.º 5
0
/// Print a textual description of a FunctionState.
llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,
                              FunctionState const &State) {
  Out << "  Function [Index=" << State.getIndex() << "]\n";

  Out << "   Allocas:\n";
  for (auto const &Alloca : State.getAllocas()) {
    Out << "    " << Alloca.getInstructionIndex()
        <<  " =[" << Alloca.getElementCount()
        <<    "x" << Alloca.getElementSize()
        <<  "] @" << Alloca.getAddress()
        << "\n";
  }

  Out << "   Instruction values [Active=";
  if (State.getActiveInstructionIndex().assigned(0))
    Out << State.getActiveInstructionIndex().get<0>();
  else
    Out << "unassigned";
  Out << "]:\n";
  
  auto const InstructionCount = State.getInstructionCount();
  for (std::size_t i = 0; i < InstructionCount; ++i) {
    auto const Instruction = State.getInstruction(i);
    auto const Type = Instruction->getType();
    
    if (llvm::isa<llvm::IntegerType>(Type)) {
      auto const Value = State.getValueUInt64(Instruction);
      if (Value.assigned<uint64_t>()) {
        Out << "    " << i << " = (uint64_t)" << Value.get<uint64_t>() << "\n";
      }
    }
    else if (Type->isPointerTy()) {
      auto const Value = State.getValuePtr(Instruction);
      if (Value.assigned<stateptr_ty>()) {
        Out << "    " << i << " = (? *)" << Value.get<stateptr_ty>() << "\n";
      }
    }
    else if (Type->isFloatTy()) {
      auto const Value = State.getValueFloat(Instruction);
      if (Value.assigned<float>()) {
        Out << "    " << i << " = (float)" << Value.get<float>() << "\n";
      }
    }
    else if (Type->isDoubleTy()) {
      auto const Value = State.getValueDouble(Instruction);
      if (Value.assigned<double>()) {
        Out << "    " << i << " = (double)" << Value.get<double>() << "\n";
      }
    }
    else if (Type->isX86_FP80Ty() || Type->isFP128Ty() || Type->isPPC_FP128Ty())
    {
      auto const Value = State.getValueAPFloat(Instruction);
      if (Value.assigned<llvm::APFloat>()) {
        llvm::SmallString<32> Buffer;
        Value.get<llvm::APFloat>().toString(Buffer);
        Out << "    " << i << " = (long double)" << Buffer << "\n";
      }
    }
  }

  return Out;
}
Ejemplo n.º 6
0
void printComparable(llvm::raw_ostream &Out, FunctionState const &State)
{
  Out << "  Function [Index=" << State.getIndex() << "]\n";

  Out << "   Allocas:\n";
  for (auto const &Alloca : State.getAllocas()) {
    Out << "    " << Alloca.getInstructionIndex()
        <<  " =[" << Alloca.getElementCount()
        <<    "x" << Alloca.getElementSize()
        <<  "]\n";
  }

  Out << "   Instruction values [Active=";
  if (State.getActiveInstructionIndex().assigned(0))
    Out << State.getActiveInstructionIndex().get<0>();
  else
    Out << "unassigned";
  Out << "]:\n";

  auto const InstructionCount = State.getInstructionCount();
  for (std::size_t i = 0; i < InstructionCount; ++i) {
    auto const Instruction = State.getInstruction(i);
    auto const Type = Instruction->getType();

    if (llvm::isa<llvm::IntegerType>(Type)) {
      auto const UValue = State.getValueUInt64(Instruction);
      if (UValue.assigned<uint64_t>()) {
        auto const SValue = State.getValueInt64(Instruction);
        assert(SValue.assigned<int64_t>());

        Out << "    " << i << " = (int64_t)" << SValue.get< int64_t>()
                           << ", (uint64_t)" << UValue.get<uint64_t>() << "\n";
      }
    }
    else if (Type->isPointerTy()) {
      auto const Value = State.getValuePtr(Instruction);
      if (Value.assigned<stateptr_ty>()) {
        Out << "    " << i << " = \n";
        // TODO: a comparable pointer representation (this requires us to
        //       determine the allocation that a pointer references, and then
        //       display the pointer value relative to that allocation).
      }
    }
    else if (Type->isFloatTy()) {
      auto const Value = State.getValueFloat(Instruction);
      if (Value.assigned<float>()) {
        Out << "    " << i << " = (float)" << Value.get<float>() << "\n";
      }
    }
    else if (Type->isDoubleTy()) {
      auto const Value = State.getValueDouble(Instruction);
      if (Value.assigned<double>()) {
        Out << "    " << i << " = (double)" << Value.get<double>() << "\n";
      }
    }
    else if (Type->isX86_FP80Ty() || Type->isFP128Ty() || Type->isPPC_FP128Ty())
    {
      auto const Value = State.getValueAPFloat(Instruction);
      if (Value.assigned<llvm::APFloat>()) {
        llvm::SmallString<32> Buffer;
        Value.get<llvm::APFloat>().toString(Buffer);
        Out << "    " << i << " = (long double)" << Buffer << "\n";
      }
    }
  }
}