llvm/llvm/lib/Transforms/Scalar/Float2Int.cpp

//===- Float2Int.cpp - Demote floating point ops to work on integers ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the Float2Int pass, which aims to demote floating
// point operations to work on integers, where that is losslessly possible.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar/Float2Int.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <deque>

#define DEBUG_TYPE

usingnamespacellvm;

// The algorithm is simple. Start at instructions that convert from the
// float to the int domain: fptoui, fptosi and fcmp. Walk up the def-use
// graph, using an equivalence datastructure to unify graphs that interfere.
//
// Mappable instructions are those with an integer corrollary that, given
// integer domain inputs, produce an integer output; fadd, for example.
//
// If a non-mappable instruction is seen, this entire def-use graph is marked
// as non-transformable. If we see an instruction that converts from the
// integer domain to FP domain (uitofp,sitofp), we terminate our walk.

/// The largest integer type worth dealing with.
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)"));

// Given a FCmp predicate, return a matching ICmp predicate if one
// exists, otherwise return BAD_ICMP_PREDICATE.
static CmpInst::Predicate mapFCmpPred(CmpInst::Predicate P) {}

// Given a floating point binary operator, return the matching
// integer version.
static Instruction::BinaryOps mapBinOpcode(unsigned Opcode) {}

// Find the roots - instructions that convert from the FP domain to
// integer domain.
void Float2IntPass::findRoots(Function &F, const DominatorTree &DT) {}

// Helper - mark I as having been traversed, having range R.
void Float2IntPass::seen(Instruction *I, ConstantRange R) {}

// Helper - get a range representing a poison value.
ConstantRange Float2IntPass::badRange() {}
ConstantRange Float2IntPass::unknownRange() {}
ConstantRange Float2IntPass::validateRange(ConstantRange R) {}

// The most obvious way to structure the search is a depth-first, eager
// search from each root. However, that require direct recursion and so
// can only handle small instruction sequences. Instead, we split the search
// up into two phases:
//   - walkBackwards:  A breadth-first walk of the use-def graph starting from
//                     the roots. Populate "SeenInsts" with interesting
//                     instructions and poison values if they're obvious and
//                     cheap to compute. Calculate the equivalance set structure
//                     while we're here too.
//   - walkForwards:  Iterate over SeenInsts in reverse order, so we visit
//                     defs before their uses. Calculate the real range info.

// Breadth-first walk of the use-def graph; determine the set of nodes
// we care about and eagerly determine if some of them are poisonous.
void Float2IntPass::walkBackwards() {}

// Calculate result range from operand ranges.
// Return std::nullopt if the range cannot be calculated yet.
std::optional<ConstantRange> Float2IntPass::calcRange(Instruction *I) {}

// Walk forwards down the list of seen instructions, so we visit defs before
// uses.
void Float2IntPass::walkForwards() {}

// If there is a valid transform to be done, do it.
bool Float2IntPass::validateAndTransform(const DataLayout &DL) {}

Value *Float2IntPass::convert(Instruction *I, Type *ToTy) {}

// Perform dead code elimination on the instructions we just modified.
void Float2IntPass::cleanup() {}

bool Float2IntPass::runImpl(Function &F, const DominatorTree &DT) {}

PreservedAnalyses Float2IntPass::run(Function &F, FunctionAnalysisManager &AM) {}