mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
[PM] Port float2int to the new pass manager
Differential Revision: http://reviews.llvm.org/D21704 llvm-svn: 273747
This commit is contained in:
parent
7fb830e3d2
commit
d6e7bd4a04
@ -124,7 +124,7 @@ void initializeExpandPostRAPass(PassRegistry&);
|
||||
void initializeExternalAAWrapperPassPass(PassRegistry&);
|
||||
void initializeFinalizeMachineBundlesPass(PassRegistry&);
|
||||
void initializeFlattenCFGPassPass(PassRegistry&);
|
||||
void initializeFloat2IntPass(PassRegistry&);
|
||||
void initializeFloat2IntLegacyPassPass(PassRegistry&);
|
||||
void initializeForceFunctionAttrsLegacyPassPass(PassRegistry&);
|
||||
void initializeForwardControlFlowIntegrityPass(PassRegistry&);
|
||||
void initializeFuncletLayoutPass(PassRegistry &);
|
||||
|
52
include/llvm/Transforms/Scalar/Float2Int.h
Normal file
52
include/llvm/Transforms/Scalar/Float2Int.h
Normal file
@ -0,0 +1,52 @@
|
||||
//===-- Float2Int.h - Demote floating point ops to work on integers -------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides the Float2Int pass, which aims to demote floating
|
||||
// point operations to work on integers, where that is losslessly possible.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TRANSFORMS_SCALAR_FLOAT2INT_H
|
||||
#define LLVM_TRANSFORMS_SCALAR_FLOAT2INT_H
|
||||
|
||||
#include "llvm/ADT/EquivalenceClasses.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/IR/ConstantRange.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
/// Pass to remove unused function declarations.
|
||||
class Float2IntPass : public PassInfoMixin<Float2IntPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
||||
// Glue for old PM.
|
||||
bool runImpl(Function &F);
|
||||
|
||||
private:
|
||||
void findRoots(Function &F, SmallPtrSet<Instruction *, 8> &Roots);
|
||||
ConstantRange seen(Instruction *I, ConstantRange R);
|
||||
ConstantRange badRange();
|
||||
ConstantRange unknownRange();
|
||||
ConstantRange validateRange(ConstantRange R);
|
||||
void walkBackwards(const SmallPtrSetImpl<Instruction *> &Roots);
|
||||
void walkForwards();
|
||||
bool validateAndTransform();
|
||||
Value *convert(Instruction *I, Type *ToTy);
|
||||
void cleanup();
|
||||
|
||||
MapVector<Instruction *, ConstantRange> SeenInsts;
|
||||
SmallPtrSet<Instruction *, 8> Roots;
|
||||
EquivalenceClasses<Instruction *> ECs;
|
||||
MapVector<Instruction *, Value *> ConvertedInsts;
|
||||
LLVMContext *Ctx;
|
||||
};
|
||||
}
|
||||
#endif // LLVM_TRANSFORMS_SCALAR_FLOAT2INT_H
|
@ -75,6 +75,7 @@
|
||||
#include "llvm/Transforms/Scalar/DCE.h"
|
||||
#include "llvm/Transforms/Scalar/DeadStoreElimination.h"
|
||||
#include "llvm/Transforms/Scalar/EarlyCSE.h"
|
||||
#include "llvm/Transforms/Scalar/Float2Int.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
#include "llvm/Transforms/Scalar/GuardWidening.h"
|
||||
#include "llvm/Transforms/Scalar/IndVarSimplify.h"
|
||||
|
@ -129,6 +129,7 @@ FUNCTION_PASS("dse", DSEPass())
|
||||
FUNCTION_PASS("early-cse", EarlyCSEPass())
|
||||
FUNCTION_PASS("instcombine", InstCombinePass())
|
||||
FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass())
|
||||
FUNCTION_PASS("float2int", Float2IntPass())
|
||||
FUNCTION_PASS("no-op-function", NoOpFunctionPass())
|
||||
FUNCTION_PASS("loweratomic", LowerAtomicPass())
|
||||
FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass())
|
||||
|
@ -13,14 +13,13 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "float2int"
|
||||
|
||||
#include "llvm/Transforms/Scalar/Float2Int.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/EquivalenceClasses.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/IR/ConstantRange.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InstIterator.h"
|
||||
@ -52,41 +51,31 @@ MaxIntegerBW("float2int-max-integer-bw", cl::init(64), cl::Hidden,
|
||||
"(default=64)"));
|
||||
|
||||
namespace {
|
||||
struct Float2Int : public FunctionPass {
|
||||
struct Float2IntLegacyPass : public FunctionPass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
Float2Int() : FunctionPass(ID) {
|
||||
initializeFloat2IntPass(*PassRegistry::getPassRegistry());
|
||||
Float2IntLegacyPass() : FunctionPass(ID) {
|
||||
initializeFloat2IntLegacyPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
return Impl.runImpl(F);
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) override;
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesCFG();
|
||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||
}
|
||||
|
||||
void findRoots(Function &F, SmallPtrSet<Instruction*,8> &Roots);
|
||||
ConstantRange seen(Instruction *I, ConstantRange R);
|
||||
ConstantRange badRange();
|
||||
ConstantRange unknownRange();
|
||||
ConstantRange validateRange(ConstantRange R);
|
||||
void walkBackwards(const SmallPtrSetImpl<Instruction*> &Roots);
|
||||
void walkForwards();
|
||||
bool validateAndTransform();
|
||||
Value *convert(Instruction *I, Type *ToTy);
|
||||
void cleanup();
|
||||
|
||||
MapVector<Instruction*, ConstantRange > SeenInsts;
|
||||
SmallPtrSet<Instruction*,8> Roots;
|
||||
EquivalenceClasses<Instruction*> ECs;
|
||||
MapVector<Instruction*, Value*> ConvertedInsts;
|
||||
LLVMContext *Ctx;
|
||||
private:
|
||||
Float2IntPass Impl;
|
||||
};
|
||||
}
|
||||
|
||||
char Float2Int::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(Float2Int, "float2int", "Float to int", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
|
||||
INITIALIZE_PASS_END(Float2Int, "float2int", "Float to int", false, false)
|
||||
char Float2IntLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS(Float2IntLegacyPass, "float2int", "Float to int", false, false)
|
||||
|
||||
// Given a FCmp predicate, return a matching ICmp predicate if one
|
||||
// exists, otherwise return BAD_ICMP_PREDICATE.
|
||||
@ -128,7 +117,7 @@ static Instruction::BinaryOps mapBinOpcode(unsigned Opcode) {
|
||||
|
||||
// Find the roots - instructions that convert from the FP domain to
|
||||
// integer domain.
|
||||
void Float2Int::findRoots(Function &F, SmallPtrSet<Instruction*,8> &Roots) {
|
||||
void Float2IntPass::findRoots(Function &F, SmallPtrSet<Instruction*,8> &Roots) {
|
||||
for (auto &I : instructions(F)) {
|
||||
if (isa<VectorType>(I.getType()))
|
||||
continue;
|
||||
@ -148,7 +137,7 @@ void Float2Int::findRoots(Function &F, SmallPtrSet<Instruction*,8> &Roots) {
|
||||
}
|
||||
|
||||
// Helper - mark I as having been traversed, having range R.
|
||||
ConstantRange Float2Int::seen(Instruction *I, ConstantRange R) {
|
||||
ConstantRange Float2IntPass::seen(Instruction *I, ConstantRange R) {
|
||||
DEBUG(dbgs() << "F2I: " << *I << ":" << R << "\n");
|
||||
if (SeenInsts.find(I) != SeenInsts.end())
|
||||
SeenInsts.find(I)->second = R;
|
||||
@ -158,13 +147,13 @@ ConstantRange Float2Int::seen(Instruction *I, ConstantRange R) {
|
||||
}
|
||||
|
||||
// Helper - get a range representing a poison value.
|
||||
ConstantRange Float2Int::badRange() {
|
||||
ConstantRange Float2IntPass::badRange() {
|
||||
return ConstantRange(MaxIntegerBW + 1, true);
|
||||
}
|
||||
ConstantRange Float2Int::unknownRange() {
|
||||
ConstantRange Float2IntPass::unknownRange() {
|
||||
return ConstantRange(MaxIntegerBW + 1, false);
|
||||
}
|
||||
ConstantRange Float2Int::validateRange(ConstantRange R) {
|
||||
ConstantRange Float2IntPass::validateRange(ConstantRange R) {
|
||||
if (R.getBitWidth() > MaxIntegerBW + 1)
|
||||
return badRange();
|
||||
return R;
|
||||
@ -184,7 +173,7 @@ ConstantRange Float2Int::validateRange(ConstantRange R) {
|
||||
|
||||
// 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 Float2Int::walkBackwards(const SmallPtrSetImpl<Instruction*> &Roots) {
|
||||
void Float2IntPass::walkBackwards(const SmallPtrSetImpl<Instruction*> &Roots) {
|
||||
std::deque<Instruction*> Worklist(Roots.begin(), Roots.end());
|
||||
while (!Worklist.empty()) {
|
||||
Instruction *I = Worklist.back();
|
||||
@ -245,7 +234,7 @@ void Float2Int::walkBackwards(const SmallPtrSetImpl<Instruction*> &Roots) {
|
||||
|
||||
// Walk forwards down the list of seen instructions, so we visit defs before
|
||||
// uses.
|
||||
void Float2Int::walkForwards() {
|
||||
void Float2IntPass::walkForwards() {
|
||||
for (auto &It : reverse(SeenInsts)) {
|
||||
if (It.second != unknownRange())
|
||||
continue;
|
||||
@ -356,7 +345,7 @@ void Float2Int::walkForwards() {
|
||||
}
|
||||
|
||||
// If there is a valid transform to be done, do it.
|
||||
bool Float2Int::validateAndTransform() {
|
||||
bool Float2IntPass::validateAndTransform() {
|
||||
bool MadeChange = false;
|
||||
|
||||
// Iterate over every disjoint partition of the def-use graph.
|
||||
@ -438,7 +427,7 @@ bool Float2Int::validateAndTransform() {
|
||||
return MadeChange;
|
||||
}
|
||||
|
||||
Value *Float2Int::convert(Instruction *I, Type *ToTy) {
|
||||
Value *Float2IntPass::convert(Instruction *I, Type *ToTy) {
|
||||
if (ConvertedInsts.find(I) != ConvertedInsts.end())
|
||||
// Already converted this instruction.
|
||||
return ConvertedInsts[I];
|
||||
@ -510,15 +499,12 @@ Value *Float2Int::convert(Instruction *I, Type *ToTy) {
|
||||
}
|
||||
|
||||
// Perform dead code elimination on the instructions we just modified.
|
||||
void Float2Int::cleanup() {
|
||||
void Float2IntPass::cleanup() {
|
||||
for (auto &I : reverse(ConvertedInsts))
|
||||
I.first->eraseFromParent();
|
||||
}
|
||||
|
||||
bool Float2Int::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
bool Float2IntPass::runImpl(Function &F) {
|
||||
DEBUG(dbgs() << "F2I: Looking at function " << F.getName() << "\n");
|
||||
// Clear out all state.
|
||||
ECs = EquivalenceClasses<Instruction*>();
|
||||
@ -539,4 +525,17 @@ bool Float2Int::runOnFunction(Function &F) {
|
||||
return Modified;
|
||||
}
|
||||
|
||||
FunctionPass *llvm::createFloat2IntPass() { return new Float2Int(); }
|
||||
namespace llvm {
|
||||
FunctionPass *createFloat2IntPass() { return new Float2IntLegacyPass(); }
|
||||
|
||||
PreservedAnalyses Float2IntPass::run(Function &F, FunctionAnalysisManager &) {
|
||||
if (!runImpl(F))
|
||||
return PreservedAnalyses::all();
|
||||
else {
|
||||
//FIXME: setPreservesCFG is not currently supported in the new PM.
|
||||
PreservedAnalyses PA;
|
||||
PA.preserve<GlobalsAA>();
|
||||
return PA;
|
||||
}
|
||||
}
|
||||
} // End namespace llvm
|
||||
|
@ -84,7 +84,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
|
||||
initializeLoadCombinePass(Registry);
|
||||
initializePlaceBackedgeSafepointsImplPass(Registry);
|
||||
initializePlaceSafepointsPass(Registry);
|
||||
initializeFloat2IntPass(Registry);
|
||||
initializeFloat2IntLegacyPassPass(Registry);
|
||||
initializeLoopDistributePass(Registry);
|
||||
initializeLoopLoadEliminationPass(Registry);
|
||||
initializeLoopSimplifyCFGLegacyPassPass(Registry);
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: opt < %s -float2int -S | FileCheck %s
|
||||
; RUN: opt < %s -passes='float2int' -S | FileCheck %s
|
||||
|
||||
;
|
||||
; Positive tests
|
||||
|
Loading…
Reference in New Issue
Block a user