Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
ExpandLargeDivRem.cpp
Go to the documentation of this file.
1//===--- ExpandLargeDivRem.cpp - Expand large div/rem ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass expands div/rem instructions with a bitwidth above a threshold
10// into a call to auto-generated functions.
11// This is useful for targets like x86_64 that cannot lower divisions
12// with more than 128 bits or targets like x86_32 that cannot lower divisions
13// with more than 64 bits.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/CodeGen/ExpandLargeDivRem.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/Analysis/GlobalsModRef.h"
20#include "llvm/CodeGen/Passes.h"
21#include "llvm/CodeGen/TargetLowering.h"
22#include "llvm/CodeGen/TargetPassConfig.h"
23#include "llvm/CodeGen/TargetSubtargetInfo.h"
24#include "llvm/IR/IRBuilder.h"
25#include "llvm/IR/InstIterator.h"
26#include "llvm/IR/PassManager.h"
27#include "llvm/InitializePasses.h"
28#include "llvm/Pass.h"
29#include "llvm/Support/CommandLine.h"
30#include "llvm/Target/TargetMachine.h"
31#include "llvm/Transforms/Utils/IntegerDivision.h"
32
33using namespacellvm;
34
35staticcl::opt<unsigned>
36ExpandDivRemBits("expand-div-rem-bits",cl::Hidden,
37cl::init(llvm::IntegerType::MAX_INT_BITS),
38cl::desc("div and rem instructions on integers with "
39"more than <N> bits are expanded."));
40
41staticboolisConstantPowerOfTwo(llvm::Value *V,bool SignedOp) {
42auto *C = dyn_cast<ConstantInt>(V);
43if (!C)
44returnfalse;
45
46APInt Val =C->getValue();
47if (SignedOp && Val.isNegative())
48 Val = -Val;
49return Val.isPowerOf2();
50}
51
52staticboolisSigned(unsignedint Opcode) {
53return Opcode == Instruction::SDiv || Opcode == Instruction::SRem;
54}
55
56staticvoidscalarize(BinaryOperator *BO,
57SmallVectorImpl<BinaryOperator *> &Replace) {
58VectorType *VTy = cast<FixedVectorType>(BO->getType());
59
60IRBuilder<> Builder(BO);
61
62unsigned NumElements = VTy->getElementCount().getFixedValue();
63Value *Result =PoisonValue::get(VTy);
64for (unsignedIdx = 0;Idx < NumElements; ++Idx) {
65Value *LHS = Builder.CreateExtractElement(BO->getOperand(0),Idx);
66Value *RHS = Builder.CreateExtractElement(BO->getOperand(1),Idx);
67Value *Op = Builder.CreateBinOp(BO->getOpcode(),LHS,RHS);
68 Result = Builder.CreateInsertElement(Result,Op,Idx);
69if (auto *NewBO = dyn_cast<BinaryOperator>(Op)) {
70 NewBO->copyIRFlags(Op,true);
71 Replace.push_back(NewBO);
72 }
73 }
74 BO->replaceAllUsesWith(Result);
75 BO->dropAllReferences();
76 BO->eraseFromParent();
77}
78
79staticboolrunImpl(Function &F,constTargetLowering &TLI) {
80SmallVector<BinaryOperator *, 4> Replace;
81SmallVector<BinaryOperator *, 4> ReplaceVector;
82boolModified =false;
83
84unsigned MaxLegalDivRemBitWidth = TLI.getMaxDivRemBitWidthSupported();
85if (ExpandDivRemBits !=llvm::IntegerType::MAX_INT_BITS)
86 MaxLegalDivRemBitWidth =ExpandDivRemBits;
87
88if (MaxLegalDivRemBitWidth >=llvm::IntegerType::MAX_INT_BITS)
89returnfalse;
90
91for (auto &I :instructions(F)) {
92switch (I.getOpcode()) {
93case Instruction::UDiv:
94case Instruction::SDiv:
95case Instruction::URem:
96case Instruction::SRem: {
97// TODO: This pass doesn't handle scalable vectors.
98if (I.getOperand(0)->getType()->isScalableTy())
99continue;
100
101auto *IntTy = dyn_cast<IntegerType>(I.getType()->getScalarType());
102if (!IntTy || IntTy->getIntegerBitWidth() <= MaxLegalDivRemBitWidth)
103continue;
104
105// The backend has peephole optimizations for powers of two.
106// TODO: We don't consider vectors here.
107if (isConstantPowerOfTwo(I.getOperand(1),isSigned(I.getOpcode())))
108continue;
109
110if (I.getOperand(0)->getType()->isVectorTy())
111 ReplaceVector.push_back(&cast<BinaryOperator>(I));
112else
113 Replace.push_back(&cast<BinaryOperator>(I));
114Modified =true;
115break;
116 }
117default:
118break;
119 }
120 }
121
122while (!ReplaceVector.empty()) {
123BinaryOperator *BO = ReplaceVector.pop_back_val();
124scalarize(BO, Replace);
125 }
126
127if (Replace.empty())
128returnfalse;
129
130while (!Replace.empty()) {
131BinaryOperator *I = Replace.pop_back_val();
132
133if (I->getOpcode() == Instruction::UDiv ||
134I->getOpcode() == Instruction::SDiv) {
135expandDivision(I);
136 }else {
137expandRemainder(I);
138 }
139 }
140
141returnModified;
142}
143
144namespace{
145classExpandLargeDivRemLegacyPass :publicFunctionPass {
146public:
147staticcharID;
148
149 ExpandLargeDivRemLegacyPass() :FunctionPass(ID) {
150initializeExpandLargeDivRemLegacyPassPass(*PassRegistry::getPassRegistry());
151 }
152
153boolrunOnFunction(Function &F) override{
154auto *TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
155auto *TLI =TM->getSubtargetImpl(F)->getTargetLowering();
156returnrunImpl(F, *TLI);
157 }
158
159voidgetAnalysisUsage(AnalysisUsage &AU) const override{
160 AU.addRequired<TargetPassConfig>();
161 AU.addPreserved<AAResultsWrapperPass>();
162 AU.addPreserved<GlobalsAAWrapperPass>();
163 }
164};
165}// namespace
166
167PreservedAnalysesExpandLargeDivRemPass::run(Function &F,
168FunctionAnalysisManager &FAM) {
169constTargetSubtargetInfo *STI = TM->getSubtargetImpl(F);
170returnrunImpl(F, *STI->getTargetLowering()) ?PreservedAnalyses::none()
171 :PreservedAnalyses::all();
172}
173
174char ExpandLargeDivRemLegacyPass::ID = 0;
175INITIALIZE_PASS_BEGIN(ExpandLargeDivRemLegacyPass,"expand-large-div-rem",
176"Expand large div/rem",false,false)
177INITIALIZE_PASS_END(ExpandLargeDivRemLegacyPass, "expand-large-div-rem",
178 "Expand large div/rem",false,false)
179
180FunctionPass *llvm::createExpandLargeDivRemPass() {
181returnnew ExpandLargeDivRemLegacyPass();
182}
instructions
Expand Atomic instructions
Definition:AtomicExpandPass.cpp:172
Passes.h
CommandLine.h
Idx
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Definition:DeadArgumentElimination.cpp:353
ExpandDivRemBits
static cl::opt< unsigned > ExpandDivRemBits("expand-div-rem-bits", cl::Hidden, cl::init(llvm::IntegerType::MAX_INT_BITS), cl::desc("div and rem instructions on integers with " "more than <N> bits are expanded."))
isSigned
static bool isSigned(unsigned int Opcode)
Definition:ExpandLargeDivRem.cpp:52
scalarize
static void scalarize(BinaryOperator *BO, SmallVectorImpl< BinaryOperator * > &Replace)
Definition:ExpandLargeDivRem.cpp:56
rem
expand large div rem
Definition:ExpandLargeDivRem.cpp:177
runImpl
static bool runImpl(Function &F, const TargetLowering &TLI)
Definition:ExpandLargeDivRem.cpp:79
isConstantPowerOfTwo
static bool isConstantPowerOfTwo(llvm::Value *V, bool SignedOp)
Definition:ExpandLargeDivRem.cpp:41
ExpandLargeDivRem.h
expand
static Expected< BitVector > expand(StringRef S, StringRef Original)
Definition:GlobPattern.cpp:21
GlobalsModRef.h
This is the interface for a simple mod/ref and alias analysis over globals.
IRBuilder.h
PassManager.h
This header defines various interfaces for pass management in LLVM.
InitializePasses.h
InstIterator.h
IntegerDivision.h
LoopDeletionResult::Modified
@ Modified
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
FAM
FunctionAnalysisManager FAM
Definition:PassBuilderBindings.cpp:61
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition:PassSupport.h:57
INITIALIZE_PASS_BEGIN
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition:PassSupport.h:52
Pass.h
SmallVector.h
This file defines the SmallVector class.
TargetLowering.h
This file describes how to lower LLVM code to machine code.
TargetPassConfig.h
Target-Independent Code Generator Pass Configuration Options pass.
TargetSubtargetInfo.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
VectorType
Definition:ItaniumDemangle.h:1173
llvm::AAResultsWrapperPass
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Definition:AliasAnalysis.h:981
llvm::APInt
Class for arbitrary precision integers.
Definition:APInt.h:78
llvm::APInt::isNegative
bool isNegative() const
Determine sign of this APInt.
Definition:APInt.h:329
llvm::APInt::isPowerOf2
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
Definition:APInt.h:440
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition:PassManager.h:253
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition:PassAnalysisSupport.h:47
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition:PassAnalysisSupport.h:75
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition:PassAnalysisSupport.h:98
llvm::BinaryOperator
Definition:InstrTypes.h:170
llvm::BinaryOperator::getOpcode
BinaryOps getOpcode() const
Definition:InstrTypes.h:370
llvm::DWARFExpression::Operation
This class represents an Operation in the Expression.
Definition:DWARFExpression.h:32
llvm::ExpandLargeDivRemPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition:ExpandLargeDivRem.cpp:167
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition:Pass.h:310
llvm::FunctionPass::runOnFunction
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
llvm::Function
Definition:Function.h:63
llvm::GlobalsAAWrapperPass
Legacy wrapper pass to provide the GlobalsAAResult object.
Definition:GlobalsModRef.h:142
llvm::IRBuilderBase::CreateInsertElement
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition:IRBuilder.h:2511
llvm::IRBuilderBase::CreateExtractElement
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition:IRBuilder.h:2499
llvm::IRBuilderBase::CreateBinOp
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition:IRBuilder.h:1671
llvm::IRBuilder
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition:IRBuilder.h:2705
llvm::Instruction::eraseFromParent
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition:Instruction.cpp:94
llvm::IntegerType::MAX_INT_BITS
@ MAX_INT_BITS
Maximum number of bits that can be specified.
Definition:DerivedTypes.h:54
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition:PassRegistry.cpp:24
llvm::Pass::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition:Pass.cpp:98
llvm::PoisonValue::get
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition:Constants.cpp:1878
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition:Analysis.h:111
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition:Analysis.h:114
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition:Analysis.h:117
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorImpl::pop_back_val
T pop_back_val()
Definition:SmallVector.h:673
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::TargetLoweringBase::getMaxDivRemBitWidthSupported
unsigned getMaxDivRemBitWidthSupported() const
Returns the size in bits of the maximum div/rem the backend supports.
Definition:TargetLowering.h:2146
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition:TargetLowering.h:3780
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition:TargetMachine.h:77
llvm::TargetMachine::getSubtargetImpl
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
Definition:TargetMachine.h:133
llvm::TargetPassConfig
Target-Independent Code Generator Pass Configuration Options.
Definition:TargetPassConfig.h:85
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition:TargetSubtargetInfo.h:63
llvm::TargetSubtargetInfo::getTargetLowering
virtual const TargetLowering * getTargetLowering() const
Definition:TargetSubtargetInfo.h:101
llvm::User::dropAllReferences
void dropAllReferences()
Drop all references to operands.
Definition:User.h:345
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition:User.h:228
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition:Value.h:255
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition:Value.cpp:534
llvm::cl::opt
Definition:CommandLine.h:1423
unsigned
TargetMachine.h
false
Definition:StackSlotColoring.cpp:193
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition:CallingConv.h:24
llvm::SystemZISD::TM
@ TM
Definition:SystemZISelLowering.h:66
llvm::cl::Hidden
@ Hidden
Definition:CommandLine.h:137
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition:CommandLine.h:443
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::expandDivision
bool expandDivision(BinaryOperator *Div)
Generate code to divide two integers, replacing Div with the generated code.
Definition:IntegerDivision.cpp:406
llvm::initializeExpandLargeDivRemLegacyPassPass
void initializeExpandLargeDivRemLegacyPassPass(PassRegistry &)
llvm::createExpandLargeDivRemPass
FunctionPass * createExpandLargeDivRemPass()
Definition:ExpandLargeDivRem.cpp:180
llvm::expandRemainder
bool expandRemainder(BinaryOperator *Rem)
Generate code to calculate the remainder of two integers, replacing Rem with the generated code.
Definition:IntegerDivision.cpp:354
llvm::cl::desc
Definition:CommandLine.h:409

Generated on Thu Jul 17 2025 11:18:07 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp