Also remove new-pass-manager version of ExpandLargeDivRem because there is no way
yet to access TargetLowering in the new pass manager.
Differential Revision: https://reviews.llvm.org/D133691
/// would typically be allowed using throughput or size cost models.
bool hasDivRemOp(Type *DataType, bool IsSigned) const;
- /// Returns the maximum bitwidth of legal div and rem instructions.
- unsigned maxLegalDivRemBitWidth() const;
-
/// Return true if the given instruction (assumed to be a memory access
/// instruction) has a volatile variant. If that's the case then we can avoid
/// addrspacecast to generic AS for volatile loads/stores. Default
const SmallBitVector &OpcodeMask) const = 0;
virtual bool enableOrderedReductions() = 0;
virtual bool hasDivRemOp(Type *DataType, bool IsSigned) = 0;
- virtual unsigned maxLegalDivRemBitWidth() = 0;
virtual bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) = 0;
virtual bool prefersVectorizedAddressing() = 0;
virtual InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
bool hasDivRemOp(Type *DataType, bool IsSigned) override {
return Impl.hasDivRemOp(DataType, IsSigned);
}
- unsigned maxLegalDivRemBitWidth() override {
- return Impl.maxLegalDivRemBitWidth();
- }
bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) override {
return Impl.hasVolatileVariant(I, AddrSpace);
}
bool hasDivRemOp(Type *DataType, bool IsSigned) const { return false; }
- unsigned maxLegalDivRemBitWidth() const {
- return llvm::IntegerType::MAX_INT_BITS;
- }
-
bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const {
return false;
}
+++ /dev/null
-//===----- ExpandLargeDivRem.h - Expand large div/rem ---------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_EXPANDLARGEDIVREM_H
-#define LLVM_CODEGEN_EXPANDLARGEDIVREM_H
-
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-/// Expands div/rem instructions with a bitwidth above a threshold
-/// into a loop.
-/// This is useful for backends like x86 that cannot lower divisions
-/// with more than 128 bits.
-class ExpandLargeDivRemPass : public PassInfoMixin<ExpandLargeDivRemPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-
- // The backend asserts when seeing large div/rem instructions.
- static bool isRequired() { return true; }
-};
-} // end namespace llvm
-
-#endif // LLVM_CODEGEN_EXPANDLARGEDIVREM_H
return MaxAtomicSizeInBitsSupported;
}
+ /// Returns the size in bits of the maximum div/rem the backend supports.
+ /// Larger operations will be expanded by ExpandLargeDivRem.
+ unsigned getMaxDivRemBitWidthSupported() const {
+ return MaxDivRemBitWidthSupported;
+ }
+
/// Returns the size of the smallest cmpxchg or ll/sc instruction
/// the backend supports. Any smaller operations are widened in
/// AtomicExpandPass.
MaxAtomicSizeInBitsSupported = SizeInBits;
}
+ /// Set the size in bits of the maximum div/rem the backend supports.
+ /// Larger operations will be expanded by ExpandLargeDivRem.
+ void setMaxDivRemBitWidthSupported(unsigned SizeInBits) {
+ MaxDivRemBitWidthSupported = SizeInBits;
+ }
+
/// Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setMinCmpXchgSizeInBits(unsigned SizeInBits) {
MinCmpXchgSizeInBits = SizeInBits;
/// Accesses larger than this will be expanded by AtomicExpandPass.
unsigned MaxAtomicSizeInBitsSupported;
+ /// Size in bits of the maximum div/rem size the backend supports.
+ /// Larger operations will be expanded by ExpandLargeDivRem.
+ unsigned MaxDivRemBitWidthSupported;
+
/// Size in bits of the minimum cmpxchg or ll/sc operation the
/// backend supports.
unsigned MinCmpXchgSizeInBits;
//===--------------------------------------------------------------------===//
// Div utility functions
//
+
SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
SmallVectorImpl<SDNode *> &Created) const;
SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
return TTIImpl->hasDivRemOp(DataType, IsSigned);
}
-unsigned TargetTransformInfo::maxLegalDivRemBitWidth() const {
- return TTIImpl->maxLegalDivRemBitWidth();
-}
-
bool TargetTransformInfo::hasVolatileVariant(Instruction *I,
unsigned AddrSpace) const {
return TTIImpl->hasVolatileVariant(I, AddrSpace);
//
//===----------------------------------------------------------------------===//
-#include "llvm/CodeGen/ExpandLargeDivRem.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/GlobalsModRef.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/IntegerDivision.h"
using namespace llvm;
return Opcode == Instruction::SDiv || Opcode == Instruction::SRem;
}
-static bool runImpl(Function &F, const TargetTransformInfo &TTI) {
+static bool runImpl(Function &F, const TargetLowering &TLI) {
SmallVector<BinaryOperator *, 4> Replace;
bool Modified = false;
- unsigned MaxLegalDivRemBitWidth = TTI.maxLegalDivRemBitWidth();
+ unsigned MaxLegalDivRemBitWidth = TLI.getMaxDivRemBitWidthSupported();
if (ExpandDivRemBits != llvm::IntegerType::MAX_INT_BITS)
MaxLegalDivRemBitWidth = ExpandDivRemBits;
return Modified;
}
-PreservedAnalyses ExpandLargeDivRemPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- TargetTransformInfo &TTI = AM.getResult<TargetIRAnalysis>(F);
- bool Changed = runImpl(F, TTI);
-
- if (Changed)
- return PreservedAnalyses::none();
-
- return PreservedAnalyses::all();
-}
-
class ExpandLargeDivRemLegacyPass : public FunctionPass {
public:
static char ID;
}
bool runOnFunction(Function &F) override {
- auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- return runImpl(F, TTI);
+ auto *TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
+ auto *TLI = TM->getSubtargetImpl(F)->getTargetLowering();
+ return runImpl(F, *TLI);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<TargetTransformInfoWrapperPass>();
+ AU.addRequired<TargetPassConfig>();
AU.addPreserved<AAResultsWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
}
// with the Target-specific changes necessary.
MaxAtomicSizeInBitsSupported = 1024;
+ MaxDivRemBitWidthSupported = llvm::IntegerType::MAX_INT_BITS;
+
MinCmpXchgSizeInBits = 0;
SupportsUnalignedAtomics = false;
setHasExtractBitsInsn(true);
+ setMaxDivRemBitWidthSupported(128);
+
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
if (Subtarget->hasNEON()) {
bool enableOrderedReductions() const { return true; }
- unsigned maxLegalDivRemBitWidth() const { return 128; }
-
InstructionCost getInterleavedMemoryOpCost(
unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
setMaxAtomicSizeInBitsSupported(0);
}
+ setMaxDivRemBitWidthSupported(64);
+
setOperationAction(ISD::PREFETCH, MVT::Other, Custom);
// Requires SXTB/SXTH, available on v6 and up in both ARM and Thumb modes.
return isLegalMaskedGather(Ty, Alignment);
}
- unsigned maxLegalDivRemBitWidth() const { return 64; }
-
InstructionCost getMemcpyCost(const Instruction *I);
int getNumMemOps(const IntrinsicInst *I) const;
if (!Subtarget.canUseCMPXCHG8B())
setMaxAtomicSizeInBitsSupported(32);
+ setMaxDivRemBitWidthSupported(Subtarget.is64Bit() ? 128 : 64);
+
// Set up the register classes.
addRegisterClass(MVT::i8, &X86::GR8RegClass);
addRegisterClass(MVT::i16, &X86::GR16RegClass);
return BaseT::isExpensiveToSpeculativelyExecute(I);
}
-unsigned X86TTIImpl::maxLegalDivRemBitWidth() const {
- return ST->is64Bit() ? 128 : 64;
-}
-
bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) {
return false;
}
const SmallBitVector &OpcodeMask) const;
bool hasDivRemOp(Type *DataType, bool IsSigned);
bool isExpensiveToSpeculativelyExecute(const Instruction *I);
- unsigned maxLegalDivRemBitWidth() const;
bool isFCmpOrdCheaperThanFCmpZero(Type *Ty);
bool areInlineCompatible(const Function *Caller,
const Function *Callee) const;
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s
+; RUN: opt -S -mtriple=x86_64-- -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s
define void @sdiv129(i129* %ptr, i129* %out) nounwind {
; CHECK-LABEL: @sdiv129(
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s
+; RUN: opt -S -mtriple=x86_64-- -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s
define void @test(i129* %ptr, i129* %out) nounwind {
; CHECK-LABEL: @test(
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s
+; RUN: opt -S -mtriple=x86_64-- -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s
define void @test(i129* %ptr, i129* %out) nounwind {
; CHECK-LABEL: @test(
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s
+; RUN: opt -S -mtriple=x86_64-- -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s
define void @test(i129* %ptr, i129* %out) nounwind {
; CHECK-LABEL: @test(