Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
SPIRVPostLegalizer.cpp
Go to the documentation of this file.
1//===-- SPIRVPostLegalizer.cpp - ammend info after legalization -*- C++ -*-===//
2//
3// which may appear after the legalizer pass
4//
5// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6// See https://llvm.org/LICENSE.txt for license information.
7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8//
9//===----------------------------------------------------------------------===//
10//
11// The pass partially apply pre-legalization logic to new instructions inserted
12// as a result of legalization:
13// - assigns SPIR-V types to registers for new instructions.
14//
15//===----------------------------------------------------------------------===//
16
17#include "SPIRV.h"
18#include "SPIRVSubtarget.h"
19#include "SPIRVUtils.h"
20#include "llvm/ADT/PostOrderIterator.h"
21#include "llvm/Analysis/OptimizationRemarkEmitter.h"
22#include "llvm/CodeGen/MachinePostDominators.h"
23#include "llvm/IR/Attributes.h"
24#include "llvm/IR/Constants.h"
25#include "llvm/IR/DebugInfoMetadata.h"
26#include "llvm/IR/IntrinsicsSPIRV.h"
27#include "llvm/Target/TargetIntrinsicInfo.h"
28#include <stack>
29
30#define DEBUG_TYPE "spirv-postlegalizer"
31
32using namespacellvm;
33
34namespace{
35classSPIRVPostLegalizer :publicMachineFunctionPass {
36public:
37staticcharID;
38 SPIRVPostLegalizer() :MachineFunctionPass(ID) {
39initializeSPIRVPostLegalizerPass(*PassRegistry::getPassRegistry());
40 }
41boolrunOnMachineFunction(MachineFunction &MF)override;
42};
43}// namespace
44
45// Defined in SPIRVLegalizerInfo.cpp.
46externboolisTypeFoldingSupported(unsigned Opcode);
47
48namespacellvm {
49// Defined in SPIRVPreLegalizer.cpp.
50externRegisterinsertAssignInstr(Register Reg,Type *Ty,SPIRVType *SpirvTy,
51SPIRVGlobalRegistry *GR,
52MachineIRBuilder &MIB,
53MachineRegisterInfo &MRI);
54externvoidprocessInstr(MachineInstr &MI,MachineIRBuilder &MIB,
55MachineRegisterInfo &MRI,SPIRVGlobalRegistry *GR);
56}// namespace llvm
57
58staticboolmayBeInserted(unsigned Opcode) {
59switch (Opcode) {
60case TargetOpcode::G_SMAX:
61case TargetOpcode::G_UMAX:
62case TargetOpcode::G_SMIN:
63case TargetOpcode::G_UMIN:
64case TargetOpcode::G_FMINNUM:
65case TargetOpcode::G_FMINIMUM:
66case TargetOpcode::G_FMAXNUM:
67case TargetOpcode::G_FMAXIMUM:
68returntrue;
69default:
70returnisTypeFoldingSupported(Opcode);
71 }
72}
73
74staticvoidprocessNewInstrs(MachineFunction &MF,SPIRVGlobalRegistry *GR,
75MachineIRBuilder MIB) {
76MachineRegisterInfo &MRI = MF.getRegInfo();
77
78for (MachineBasicBlock &MBB : MF) {
79for (MachineInstr &I :MBB) {
80constunsigned Opcode =I.getOpcode();
81if (Opcode == TargetOpcode::G_UNMERGE_VALUES) {
82unsigned ArgI =I.getNumOperands() - 1;
83Register SrcReg =I.getOperand(ArgI).isReg()
84 ?I.getOperand(ArgI).getReg()
85 :Register(0);
86SPIRVType *DefType =
87 SrcReg.isValid() ? GR->getSPIRVTypeForVReg(SrcReg) :nullptr;
88if (!DefType || DefType->getOpcode() != SPIRV::OpTypeVector)
89report_fatal_error(
90"cannot select G_UNMERGE_VALUES with a non-vector argument");
91SPIRVType *ScalarType =
92 GR->getSPIRVTypeForVReg(DefType->getOperand(1).getReg());
93for (unsigned i = 0; i <I.getNumDefs(); ++i) {
94Register ResVReg =I.getOperand(i).getReg();
95SPIRVType *ResType = GR->getSPIRVTypeForVReg(ResVReg);
96if (!ResType) {
97// There was no "assign type" actions, let's fix this now
98 ResType = ScalarType;
99setRegClassType(ResVReg, ResType, GR, &MRI, *GR->CurMF,true);
100 }
101 }
102 }elseif (mayBeInserted(Opcode) &&I.getNumDefs() == 1 &&
103I.getNumOperands() > 1 &&I.getOperand(1).isReg()) {
104// Legalizer may have added a new instructions and introduced new
105// registers, we must decorate them as if they were introduced in a
106// non-automatic way
107Register ResVReg =I.getOperand(0).getReg();
108// Check if the register defined by the instruction is newly generated
109// or already processed
110if (MRI.getRegClassOrNull(ResVReg))
111continue;
112assert(GR->getSPIRVTypeForVReg(ResVReg) ==nullptr);
113// Check if we have type defined for operands of the new instruction
114SPIRVType *ResVType = GR->getSPIRVTypeForVReg(I.getOperand(1).getReg());
115if (!ResVType)
116continue;
117// Set type & class
118setRegClassType(ResVReg, ResVType, GR, &MRI, *GR->CurMF,true);
119// If this is a simple operation that is to be reduced by TableGen
120// definition we must apply some of pre-legalizer rules here
121if (isTypeFoldingSupported(Opcode)) {
122insertAssignInstr(ResVReg,nullptr, ResVType, GR, MIB,MRI);
123processInstr(I, MIB,MRI, GR);
124 }
125 }
126 }
127 }
128}
129
130// Do a preorder traversal of the CFG starting from the BB |Start|.
131// point. Calls |op| on each basic block encountered during the traversal.
132voidvisit(MachineFunction &MF,MachineBasicBlock &Start,
133 std::function<void(MachineBasicBlock *)>op) {
134 std::stack<MachineBasicBlock *> ToVisit;
135SmallPtrSet<MachineBasicBlock *, 8> Seen;
136
137 ToVisit.push(&Start);
138 Seen.insert(ToVisit.top());
139while (ToVisit.size() != 0) {
140MachineBasicBlock *MBB = ToVisit.top();
141 ToVisit.pop();
142
143op(MBB);
144
145for (auto Succ :MBB->successors()) {
146if (Seen.contains(Succ))
147continue;
148 ToVisit.push(Succ);
149 Seen.insert(Succ);
150 }
151 }
152}
153
154// Do a preorder traversal of the CFG starting from the given function's entry
155// point. Calls |op| on each basic block encountered during the traversal.
156voidvisit(MachineFunction &MF, std::function<void(MachineBasicBlock *)>op) {
157visit(MF, *MF.begin(),op);
158}
159
160bool SPIRVPostLegalizer::runOnMachineFunction(MachineFunction &MF) {
161// Initialize the type registry.
162constSPIRVSubtarget &ST = MF.getSubtarget<SPIRVSubtarget>();
163SPIRVGlobalRegistry *GR =ST.getSPIRVGlobalRegistry();
164 GR->setCurrentFunc(MF);
165MachineIRBuilder MIB(MF);
166
167processNewInstrs(MF, GR, MIB);
168
169returntrue;
170}
171
172INITIALIZE_PASS(SPIRVPostLegalizer,DEBUG_TYPE,"SPIRV post legalizer",false,
173false)
174
175char SPIRVPostLegalizer::ID = 0;
176
177FunctionPass *llvm::createSPIRVPostLegalizerPass() {
178returnnew SPIRVPostLegalizer();
179}
MRI
unsigned const MachineRegisterInfo * MRI
Definition:AArch64AdvSIMDScalarPass.cpp:105
MBB
MachineBasicBlock & MBB
Definition:ARMSLSHardening.cpp:71
Attributes.h
This file contains the simple types necessary to represent the attributes associated with functions a...
Constants.h
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DebugInfoMetadata.h
op
#define op(i)
MI
IRTranslator LLVM IR MI
Definition:IRTranslator.cpp:112
I
#define I(x, y, z)
Definition:MD5.cpp:58
MachinePostDominators.h
OptimizationRemarkEmitter.h
INITIALIZE_PASS
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition:PassSupport.h:38
PostOrderIterator.h
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
visit
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
Definition:SPIRVPostLegalizer.cpp:132
isTypeFoldingSupported
bool isTypeFoldingSupported(unsigned Opcode)
Definition:SPIRVLegalizerInfo.cpp:60
DEBUG_TYPE
#define DEBUG_TYPE
Definition:SPIRVPostLegalizer.cpp:30
mayBeInserted
static bool mayBeInserted(unsigned Opcode)
Definition:SPIRVPostLegalizer.cpp:58
processNewInstrs
static void processNewInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
Definition:SPIRVPostLegalizer.cpp:74
SPIRVSubtarget.h
SPIRVUtils.h
SPIRV.h
TargetIntrinsicInfo.h
char
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition:Pass.h:310
llvm::MachineBasicBlock
Definition:MachineBasicBlock.h:125
llvm::MachineBasicBlock::successors
iterator_range< succ_iterator > successors()
Definition:MachineBasicBlock.h:444
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition:MachineFunctionPass.h:30
llvm::MachineFunctionPass::runOnMachineFunction
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
llvm::MachineFunction
Definition:MachineFunction.h:267
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition:MachineFunction.h:733
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition:MachineFunction.h:743
llvm::MachineFunction::begin
iterator begin()
Definition:MachineFunction.h:947
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition:MachineIRBuilder.h:235
llvm::MachineInstr
Representation of each machine instruction.
Definition:MachineInstr.h:71
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition:MachineInstr.h:577
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition:MachineInstr.h:587
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition:MachineOperand.h:369
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition:MachineRegisterInfo.h:51
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition:PassRegistry.cpp:24
llvm::Register
Wrapper class representing virtual and physical registers.
Definition:Register.h:19
llvm::Register::isValid
constexpr bool isValid() const
Definition:Register.h:115
llvm::SPIRVGlobalRegistry
Definition:SPIRVGlobalRegistry.h:30
llvm::SPIRVGlobalRegistry::getSPIRVTypeForVReg
SPIRVType * getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
Definition:SPIRVGlobalRegistry.cpp:1106
llvm::SPIRVGlobalRegistry::CurMF
MachineFunction * CurMF
Definition:SPIRVGlobalRegistry.h:119
llvm::SPIRVSubtarget
Definition:SPIRVSubtarget.h:38
llvm::SmallPtrSetImpl::insert
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition:SmallPtrSet.h:384
llvm::SmallPtrSetImpl::contains
bool contains(ConstPtrType Ptr) const
Definition:SmallPtrSet.h:458
llvm::SmallPtrSet
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition:SmallPtrSet.h:519
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
unsigned
llvm::ARM_MB::ST
@ ST
Definition:ARMBaseInfo.h:73
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition:CallingConv.h:24
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::insertAssignInstr
Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy, SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB, MachineRegisterInfo &MRI)
Helper external function for inserting ASSIGN_TYPE instuction between Reg and its definition,...
Definition:SPIRVPreLegalizer.cpp:429
llvm::createSPIRVPostLegalizerPass
FunctionPass * createSPIRVPostLegalizerPass()
llvm::setRegClassType
void setRegClassType(Register Reg, SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF, bool Force)
Definition:SPIRVUtils.cpp:727
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition:Error.cpp:167
llvm::initializeSPIRVPostLegalizerPass
void initializeSPIRVPostLegalizerPass(PassRegistry &)
llvm::processInstr
void processInstr(MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR)
Definition:SPIRVPreLegalizer.cpp:466

Generated on Thu Jul 17 2025 15:37:20 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp