
New register bank select for AMDGPU will be split in two passes: - AMDGPURegBankSelect: select banks based on machine uniformity analysis - AMDGPURegBankLegalize: lower instructions that can't be inst-selected with register banks assigned by AMDGPURegBankSelect. AMDGPURegBankLegalize is similar to legalizer but with context of uniformity analysis. Does not change already assigned banks. Main goal of AMDGPURegBankLegalize is to provide high level table-like overview of how to lower generic instructions based on available target features and uniformity info (uniform vs divergent). See RegBankLegalizeRules. Summary of new features: At the moment register bank select assigns register bank to output register using simple algorithm: - one of the inputs is vgpr output is vgpr - all inputs are sgpr output is sgpr. When function does not contain divergent control flow propagating register banks like this works. In general, first point is still correct but second is not when function contains divergent control flow. Examples: - Phi with uniform inputs that go through divergent branch - Instruction with temporal divergent use. To fix this AMDGPURegBankSelect will use machine uniformity analysis to assign vgpr to each divergent and sgpr to each uniform instruction. But some instructions are only available on VALU (for example floating point instructions before gfx1150) and we need to assign vgpr to them. Since we are no longer propagating register banks we need to ensure that uniform instructions get their inputs in sgpr in some way. In AMDGPURegBankLegalize uniform instructions that are only available on VALU will be reassigned to vgpr on all operands and read-any-lane vgpr output to original sgpr output.
75 lines
2.4 KiB
C++
75 lines
2.4 KiB
C++
//===-- AMDGPURegBankSelect.cpp -------------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// Assign register banks to all register operands of G_ instructions using
|
|
/// machine uniformity analysis.
|
|
/// Sgpr - uniform values and some lane masks
|
|
/// Vgpr - divergent, non S1, values
|
|
/// Vcc - divergent S1 values(lane masks)
|
|
/// However in some cases G_ instructions with this register bank assignment
|
|
/// can't be inst-selected. This is solved in AMDGPURegBankLegalize.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "AMDGPU.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/InitializePasses.h"
|
|
|
|
#define DEBUG_TYPE "amdgpu-regbankselect"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
|
|
class AMDGPURegBankSelect : public MachineFunctionPass {
|
|
public:
|
|
static char ID;
|
|
|
|
AMDGPURegBankSelect() : MachineFunctionPass(ID) {
|
|
initializeAMDGPURegBankSelectPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
|
|
bool runOnMachineFunction(MachineFunction &MF) override;
|
|
|
|
StringRef getPassName() const override {
|
|
return "AMDGPU Register Bank Select";
|
|
}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
MachineFunctionPass::getAnalysisUsage(AU);
|
|
}
|
|
|
|
// This pass assigns register banks to all virtual registers, and we maintain
|
|
// this property in subsequent passes
|
|
MachineFunctionProperties getSetProperties() const override {
|
|
return MachineFunctionProperties().set(
|
|
MachineFunctionProperties::Property::RegBankSelected);
|
|
}
|
|
};
|
|
|
|
} // End anonymous namespace.
|
|
|
|
INITIALIZE_PASS_BEGIN(AMDGPURegBankSelect, DEBUG_TYPE,
|
|
"AMDGPU Register Bank Select", false, false)
|
|
INITIALIZE_PASS_END(AMDGPURegBankSelect, DEBUG_TYPE,
|
|
"AMDGPU Register Bank Select", false, false)
|
|
|
|
char AMDGPURegBankSelect::ID = 0;
|
|
|
|
char &llvm::AMDGPURegBankSelectID = AMDGPURegBankSelect::ID;
|
|
|
|
FunctionPass *llvm::createAMDGPURegBankSelectPass() {
|
|
return new AMDGPURegBankSelect();
|
|
}
|
|
|
|
bool AMDGPURegBankSelect::runOnMachineFunction(MachineFunction &MF) {
|
|
if (MF.getProperties().hasProperty(
|
|
MachineFunctionProperties::Property::FailedISel))
|
|
return false;
|
|
return true;
|
|
}
|