Lots of the code/structure was based off `AMDGPUCombinerHelper`, `AMDGPUPreLegalizerCombiner`, etc. Tasks completed: - Create new `SPIRVCombinerHelper` inheriting from `CombinerHelper` - Move combiner logic in `SPIRVPreLegalizerCombiner` to helper methods in `SPIRVCombinerHelper` - Update `SPIRVPreLegalizerCombiner` to use the new helper class - Simplify `applySPIRVDistance` code
61 lines
2.2 KiB
C++
61 lines
2.2 KiB
C++
//===-- SPIRVCombinerHelper.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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "SPIRVCombinerHelper.h"
|
|
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
|
|
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
|
|
#include "llvm/IR/IntrinsicsSPIRV.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
|
|
using namespace llvm;
|
|
using namespace MIPatternMatch;
|
|
|
|
SPIRVCombinerHelper::SPIRVCombinerHelper(
|
|
GISelChangeObserver &Observer, MachineIRBuilder &B, bool IsPreLegalize,
|
|
GISelValueTracking *VT, MachineDominatorTree *MDT, const LegalizerInfo *LI,
|
|
const SPIRVSubtarget &STI)
|
|
: CombinerHelper(Observer, B, IsPreLegalize, VT, MDT, LI), STI(STI) {}
|
|
|
|
/// This match is part of a combine that
|
|
/// rewrites length(X - Y) to distance(X, Y)
|
|
/// (f32 (g_intrinsic length
|
|
/// (g_fsub (vXf32 X) (vXf32 Y))))
|
|
/// ->
|
|
/// (f32 (g_intrinsic distance
|
|
/// (vXf32 X) (vXf32 Y)))
|
|
///
|
|
bool SPIRVCombinerHelper::matchLengthToDistance(MachineInstr &MI) const {
|
|
if (MI.getOpcode() != TargetOpcode::G_INTRINSIC ||
|
|
cast<GIntrinsic>(MI).getIntrinsicID() != Intrinsic::spv_length)
|
|
return false;
|
|
|
|
// First operand of MI is `G_INTRINSIC` so start at operand 2.
|
|
Register SubReg = MI.getOperand(2).getReg();
|
|
MachineInstr *SubInstr = MRI.getVRegDef(SubReg);
|
|
if (SubInstr->getOpcode() != TargetOpcode::G_FSUB)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void SPIRVCombinerHelper::applySPIRVDistance(MachineInstr &MI) const {
|
|
// Extract the operands for X and Y from the match criteria.
|
|
Register SubDestReg = MI.getOperand(2).getReg();
|
|
MachineInstr *SubInstr = MRI.getVRegDef(SubDestReg);
|
|
Register SubOperand1 = SubInstr->getOperand(1).getReg();
|
|
Register SubOperand2 = SubInstr->getOperand(2).getReg();
|
|
Register ResultReg = MI.getOperand(0).getReg();
|
|
|
|
Builder.setInstrAndDebugLoc(MI);
|
|
Builder.buildIntrinsic(Intrinsic::spv_distance, ResultReg)
|
|
.addUse(SubOperand1)
|
|
.addUse(SubOperand2);
|
|
|
|
MI.eraseFromParent();
|
|
}
|