Go to the documentation of this file.
29 #define DEBUG_TYPE "spirv-module-analysis"
43 if (MdNode && OpIndex < MdNode->getNumOperands()) {
44 const auto &
Op = MdNode->getOperand(
OpIndex);
45 return mdconst::extract<ConstantInt>(
Op)->getZExtValue();
50 void SPIRVModuleAnalysis::setBaseInfo(
const Module &M) {
69 if (
auto VerNode =
M.getNamedMetadata(
"opencl.ocl.version")) {
71 auto VersionMD = VerNode->getOperand(0);
72 unsigned MajorNum = getMetadataUInt(VersionMD, 0, 2);
73 unsigned MinorNum = getMetadataUInt(VersionMD, 1);
74 unsigned RevNum = getMetadataUInt(VersionMD, 2);
85 bool UpdateRegAliases,
86 unsigned StartOpIndex = 0) {
87 for (
const auto *
B : MAI.
MS[MSType]) {
88 const unsigned NumAOps =
A.getNumOperands();
89 if (NumAOps ==
B->getNumOperands() &&
A.getNumDefs() ==
B->getNumDefs()) {
90 bool AllOpsMatch =
true;
91 for (
unsigned i = StartOpIndex;
i < NumAOps && AllOpsMatch; ++
i) {
92 if (
A.getOperand(
i).isReg() &&
B->getOperand(
i).isReg()) {
98 AllOpsMatch =
A.getOperand(
i).isIdenticalTo(
B->getOperand(
i));
102 if (UpdateRegAliases) {
103 assert(
A.getOperand(0).isReg() &&
B->getOperand(0).isReg());
104 Register LocalReg =
A.getOperand(0).getReg();
122 if (
MI.getOpcode() == SPIRV::OpDecorate) {
124 auto Dec =
MI.getOperand(1).getImm();
126 auto Lnk =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
135 }
else if (
MI.getOpcode() == SPIRV::OpFunction) {
150 bool IsConstOrType =
false) {
152 if (findSameInstrInMS(
MI, MSType, MAI, IsConstOrType, IsConstOrType ? 1 : 0))
155 MAI.
MS[MSType].push_back(&
MI);
160 void SPIRVModuleAnalysis::processOtherInstrs(
const Module &M) {
161 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
162 if ((*F).isDeclaration())
166 unsigned FCounter = 0;
169 if (
MI.getOpcode() == SPIRV::OpFunction)
173 const unsigned OpCode =
MI.getOpcode();
174 const bool IsFuncOrParm =
175 OpCode == SPIRV::OpFunction || OpCode == SPIRV::OpFunctionParameter;
176 const bool IsConstOrType =
178 if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
180 }
else if (OpCode == SPIRV::OpEntryPoint) {
184 collectFuncNames(
MI, *
F);
185 }
else if (IsConstOrType || (FCounter > 1 && IsFuncOrParm)) {
190 collectOtherInstr(
MI,
MAI,
Type, IsConstOrType);
191 }
else if (OpCode == SPIRV::OpFunction) {
192 collectFuncNames(
MI, *
F);
200 void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
201 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
202 if ((*F).isDeclaration())
232 ST =
TM.getSubtargetImpl();
233 GR = ST->getSPIRVGlobalRegistry();
234 TII = ST->getInstrInfo();
236 MMI = &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
244 numberRegistersGlobally(
M);
247 processOtherInstrs(
M);
void setRegisterAlias(const MachineFunction *MF, Register Reg, Register AliasReg)
unsigned unsigned DefaultVal
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
bool isDecorationInstr(const MachineInstr &MI) const
Target - Wrapper for Target specific information.
Reg
All possible values of the reg field in the ModR/M byte.
The instances of the Type class are immutable: once they are created, they are never changed.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
bool isConstantInstr(const MachineInstr &MI) const
INITIALIZE_PASS(SPIRVModuleAnalysis, DEBUG_TYPE, "SPIRV module analysis", true, true) static unsigned getMetadataUInt(MDNode *MdNode
void initializeSPIRVModuleAnalysisPass(PassRegistry &)
void setSkipEmission(MachineInstr *MI)
SPIRV::AddressingModel Addr
bool isTypeDeclInstr(const MachineInstr &MI) const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static struct SPIRV::ModuleAnalysisInfo MAI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
RegisterAliasMapTy RegisterAliasTable
bool getSkipEmission(const MachineInstr *MI)
Target-Independent Code Generator Pass Configuration Options.
bool hasRegisterAlias(const MachineFunction *MF, Register Reg)
Representation of each machine instruction.
SmallVector< MachineInstr *, 4 > GlobalVarList
unsigned getPointerSize() const
StringMap< Register > FuncNameMap
InstrList MS[NUM_MODULE_SECTIONS]
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A Module instance is used to store all the information related to an LLVM module.
SPIRV::SourceLanguage SrcLang
Register getRegisterAlias(const MachineFunction *MF, Register Reg)
Wrapper class representing virtual and physical registers.
MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
const char LLVMTargetMachineRef TM
DenseSet< MachineInstr * > InstrsToDelete
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...