15 #define DEBUG_TYPE "float2int"
50 cl::desc(
"Max integer bitwidth to consider in float2int"
72 bool validateAndTransform();
119 case Instruction::FAdd:
return Instruction::Add;
120 case Instruction::FSub:
return Instruction::Sub;
121 case Instruction::FMul:
return Instruction::Mul;
129 switch (
I.getOpcode()) {
131 case Instruction::FPToUI:
132 case Instruction::FPToSI:
135 case Instruction::FCmp:
146 DEBUG(
dbgs() <<
"F2I: " << *I <<
":" << R <<
"\n");
147 if (SeenInsts.find(I) != SeenInsts.end())
148 SeenInsts.find(I)->second = R;
150 SeenInsts.insert(std::make_pair(I, R));
182 std::deque<Instruction*> Worklist(Roots.
begin(), Roots.
end());
183 while (!Worklist.empty()) {
187 if (SeenInsts.find(I) != SeenInsts.end())
198 case Instruction::UIToFP: {
207 case Instruction::SIToFP: {
216 case Instruction::FAdd:
217 case Instruction::FSub:
218 case Instruction::FMul:
219 case Instruction::FPToUI:
220 case Instruction::FPToSI:
221 case Instruction::FCmp:
222 seen(I, unknownRange());
229 ECs.unionSets(I, OI);
230 if (SeenInsts.find(I)->second != badRange())
231 Worklist.push_back(OI);
232 }
else if (!isa<ConstantFP>(O)) {
242 void Float2Int::walkForwards() {
243 for (
auto It = SeenInsts.rbegin(), E = SeenInsts.rend(); It != E; ++It) {
244 if (It->second != unknownRange())
248 std::function<ConstantRange(ArrayRef<ConstantRange>)> Op;
252 case Instruction::UIToFP:
253 case Instruction::SIToFP:
256 case Instruction::FAdd:
258 assert(Ops.size() == 2 &&
"FAdd is a binary operator!");
259 return Ops[0].add(Ops[1]);
263 case Instruction::FSub:
265 assert(Ops.size() == 2 &&
"FSub is a binary operator!");
266 return Ops[0].sub(Ops[1]);
270 case Instruction::FMul:
272 assert(Ops.size() == 2 &&
"FMul is a binary operator!");
273 return Ops[0].multiply(Ops[1]);
281 case Instruction::FPToUI:
282 case Instruction::FPToSI:
284 assert(Ops.size() == 1 &&
"FPTo[US]I is a unary operator!");
289 case Instruction::FCmp:
291 assert(Ops.size() == 2 &&
"FCmp is a binary operator!");
292 return Ops[0].unionWith(Ops[1]);
301 assert(SeenInsts.find(OI) != SeenInsts.end() &&
302 "def not seen before use!");
303 OpRanges.
push_back(SeenInsts.find(OI)->second);
304 }
else if (
ConstantFP *CF = dyn_cast<ConstantFP>(O)) {
337 CF->getValueAPF().convertToInteger(Int,
348 seen(I, Op(OpRanges));
353 bool Float2Int::validateAndTransform() {
354 bool MadeChange =
false;
357 for (
auto It = ECs.begin(), E = ECs.end(); It != E; ++It) {
360 Type *ConvertedToTy =
nullptr;
363 for (
auto MI = ECs.member_begin(It), ME = ECs.member_end();
366 auto SeenI = SeenInsts.find(I);
367 if (SeenI == SeenInsts.end())
375 if (Roots.
count(I) == 0) {
381 if (!UI || SeenInsts.find(UI) == SeenInsts.end()) {
382 DEBUG(
dbgs() <<
"F2I: Failing because of " << *U <<
"\n");
394 if (ECs.member_begin(It) == ECs.member_end() || Fail ||
397 assert(ConvertedToTy &&
"Must have set the convertedtoty by this point!");
403 DEBUG(
dbgs() <<
"F2I: MinBitwidth=" << MinBW <<
", R: " << R <<
"\n");
411 unsigned MaxRepresentableBits
413 if (MinBW > MaxRepresentableBits) {
414 DEBUG(
dbgs() <<
"F2I: Value not guaranteed to be representable!\n");
418 DEBUG(
dbgs() <<
"F2I: Value requires more than 64 bits to represent!\n");
426 for (
auto MI = ECs.member_begin(It), ME = ECs.member_end();
436 if (ConvertedInsts.find(I) != ConvertedInsts.end())
438 return ConvertedInsts[I];
443 if (I->
getOpcode() == Instruction::UIToFP ||
448 }
else if (
ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
451 CF->getValueAPF().convertToInteger(Val,
462 Value *NewV =
nullptr;
466 case Instruction::FPToUI:
467 NewV = IRB.CreateZExtOrTrunc(NewOperands[0], I->
getType());
470 case Instruction::FPToSI:
471 NewV = IRB.CreateSExtOrTrunc(NewOperands[0], I->
getType());
474 case Instruction::FCmp: {
477 NewV = IRB.CreateICmp(P, NewOperands[0], NewOperands[1], I->
getName());
481 case Instruction::UIToFP:
482 NewV = IRB.CreateZExtOrTrunc(NewOperands[0], ToTy);
485 case Instruction::SIToFP:
486 NewV = IRB.CreateSExtOrTrunc(NewOperands[0], ToTy);
489 case Instruction::FAdd:
490 case Instruction::FSub:
491 case Instruction::FMul:
493 NewOperands[0], NewOperands[1],
502 ConvertedInsts[
I] = NewV;
508 for (
auto I = ConvertedInsts.rbegin(), E = ConvertedInsts.rend();
513 bool Float2Int::runOnFunction(
Function &F) {
514 if (skipOptnoneFunction(F))
521 ConvertedInsts.clear();
528 walkBackwards(Roots);
531 bool Modified = validateAndTransform();
538 return new Float2Int();
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
This class is the base class for the comparison instructions.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
FunctionPass * createFloat2IntPass()
0 1 0 0 True if ordered and less than
1 1 1 0 True if unordered or not equal
This class implements a map that also provides access to all stored values in a deterministic order...
static void cleanup(BlockFrequencyInfoImplBase &BFI)
Clear all memory not needed downstream.
static IntegerType * getInt64Ty(LLVMContext &C)
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
StringRef getName() const
Return a constant reference to the value's name.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
1 0 0 1 True if unordered or equal
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
0 1 0 1 True if ordered and less than or equal
This file implements a class to represent arbitrary precision integral constant values and operations...
bool isFinite() const
Returns true if and only if the current value is zero, subnormal, or normal.
APInt LLVM_ATTRIBUTE_UNUSED_RESULT zextOrSelf(unsigned width) const
Zero extend or truncate to width.
ConstantRange unionWith(const ConstantRange &CR) const
Return the range that results from the union of this range with another range.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static unsigned int semanticsPrecision(const fltSemantics &)
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
unsigned getMinSignedBits() const
Get the minimum bit size for this signed APInt.
static CmpInst::Predicate mapFCmpPred(CmpInst::Predicate P)
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
initializer< Ty > init(const Ty &Val)
cmpResult compare(const APFloat &) const
IEEE comparison with another floating point number (NaNs compare unordered, 0==-0).
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type. ...
APInt LLVM_ATTRIBUTE_UNUSED_RESULT sextOrSelf(unsigned width) const
Sign extend or truncate to width.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
ConstantFP - Floating Point Values [float, double].
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
Represent the analysis usage information of a pass.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
1 1 0 1 True if unordered, less than, or equal
static cl::opt< unsigned > MaxIntegerBW("float2int-max-integer-bw", cl::init(64), cl::Hidden, cl::desc("Max integer bitwidth to consider in float2int""(default=64)"))
The largest integer type worth dealing with.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
0 0 1 0 True if ordered and greater than
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
bool isNegative() const
IEEE-754R isSignMinus: Returns true if and only if the current value is negative. ...
bool isSignWrappedSet() const
Return true if this set wraps around the INT_MIN of its bitwidth.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
1 1 0 0 True if unordered or less than
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
static APInt getMinValue(unsigned numBits)
Gets minimum unsigned value of APInt for a specific bit width.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
const fltSemantics & getFltSemantics() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Class for arbitrary precision integers.
iterator_range< user_iterator > users()
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
static Instruction::BinaryOps mapBinOpcode(unsigned Opcode)
static IntegerType * getInt32Ty(LLVMContext &C)
iterator_range< inst_iterator > inst_range(Function *F)
opStatus roundToIntegral(roundingMode)
0 1 1 0 True if ordered and operands are unequal
bool hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
1 0 1 0 True if unordered or greater than
const APInt & getUpper() const
Return the upper value for this range.
void initializeFloat2IntPass(PassRegistry &)
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
getPrimitiveSizeInBits - Return the basic size of this type if it is a primitive type.
0 0 0 1 True if ordered and equal
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
1 0 1 1 True if unordered, greater than, or equal
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
bool isZero() const
Returns true if and only if the float is plus or minus zero.
0 0 1 1 True if ordered and greater than or equal
LLVMContext & getContext() const
Get the global data context.