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; } }
bool LLVMVisitor::leaveAddExpression(AddExpression* expr) { if(expr->getRule() == AddExpressionEnum::Plus || expr->getRule() == AddExpressionEnum::Minus) { ASSERT_T_MSG(this->valueStack.size() >= 2u, format("%u stackSize(%u)", expr->getId(), this->valueStack.size()) ); auto rhs = this->valueStack.top(); auto rhsType = rhs->getType(); this->valueStack.pop(); auto lhs = this->valueStack.top(); auto lhsType = lhs->getType(); this->valueStack.pop(); LLVMDump(lhs); LLVMDump(rhs); ASSERT_EQ(valueStack.size(), 0u); if(rhsType->isIntegerTy() && rhsType->isIntegerTy()) { if(rhsType->getIntegerBitWidth() == lhsType->getIntegerBitWidth()) { this->valueStack.push( expr->getRule() == AddExpressionEnum::Plus ? this->builder.CreateAdd(lhs, rhs, "Add") : this->builder.CreateSub(lhs, rhs, "Sub") ); } else { throw LLVMVisitorException(format("%s operation" " between Integers of different size lhs(%u) rhs(%u)", expr->getRule() == AddExpressionEnum::Plus ? "Add" : "Minus", lhsType->getIntegerBitWidth(), rhsType->getIntegerBitWidth()), Loc()); } } if((rhsType->isFloatTy() || rhsType->isDoubleTy() || rhsType->isX86_FP80Ty()) && rhsType->getTypeID() == lhsType->getTypeID()) { this->valueStack.push( expr->getRule() == AddExpressionEnum::Plus ? this->builder.CreateFAdd(lhs, rhs, "Add") : this->builder.CreateFSub(lhs, rhs, "Sub") ); } else { throw LLVMVisitorException(format("%s operation" " between different float types of different size " "lhs(%u) rhs(%u)", expr->getRule() == AddExpressionEnum::Plus ? "Add" : "Minus", lhsType->getTypeID(), rhsType->getTypeID()), Loc()); } ASSERT_EQ(valueStack.size(), 1u); LLVMDump(this->valueStack.top()); } return true; }
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); } }
/// 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; }
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"; } } } }