1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

AMDGPU/GlobalISel/Emitter Recognize additional 'same operand checks'

The "name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is
"MY_PAT:op1:op2" and the ones with same "name" represent same operand.
Add 'same operand check' for this case.

Differential Revision: https://reviews.llvm.org/D87351
This commit is contained in:
Petar Avramovic 2020-09-14 11:37:14 +02:00
parent c5275c6e58
commit 8865fe468c
4 changed files with 42 additions and 19 deletions

View File

@ -25,8 +25,7 @@ body: |
; CHECK: [[COPY3:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]]
; CHECK: [[COPY4:%[0-9]+]]:vreg_64 = COPY [[S_LOAD_DWORDX2_IMM]]
; CHECK: %12:vreg_64 = nofpexcept V_ADD_F64 0, [[COPY3]], 1, [[COPY4]], 0, 0, implicit $mode, implicit $exec
; CHECK: %13:vreg_64 = nofpexcept V_FLOOR_F64_e64 0, %12, 0, 0, implicit $mode, implicit $exec
; CHECK: %15:vreg_64 = nofpexcept V_ADD_F64 0, %12, 1, %13, 0, 0, implicit $mode, implicit $exec
; CHECK: %15:vreg_64 = nofpexcept V_FRACT_F64_e64 0, %12, 0, 0, implicit $mode, implicit $exec
; CHECK: [[COPY5:%[0-9]+]]:vreg_64 = COPY [[COPY1]]
; CHECK: GLOBAL_STORE_DWORDX2 [[COPY5]], %15, 0, 0, 0, 0, implicit $exec :: (store 8, addrspace 1)
; CHECK: S_ENDPGM 0
@ -76,8 +75,7 @@ body: |
; CHECK: [[COPY3:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]]
; CHECK: [[COPY4:%[0-9]+]]:vreg_64 = COPY [[S_LOAD_DWORDX2_IMM]]
; CHECK: %13:vreg_64 = nofpexcept V_ADD_F64 0, [[COPY3]], 3, [[COPY4]], 0, 0, implicit $mode, implicit $exec
; CHECK: %14:vreg_64 = nofpexcept V_FLOOR_F64_e64 0, %13, 0, 0, implicit $mode, implicit $exec
; CHECK: %16:vreg_64 = nofpexcept V_ADD_F64 0, %13, 1, %14, 0, 0, implicit $mode, implicit $exec
; CHECK: %16:vreg_64 = nofpexcept V_FRACT_F64_e64 0, %13, 0, 0, implicit $mode, implicit $exec
; CHECK: [[COPY5:%[0-9]+]]:vreg_64 = COPY [[COPY1]]
; CHECK: GLOBAL_STORE_DWORDX2 [[COPY5]], %16, 0, 0, 0, 0, implicit $exec :: (store 8, addrspace 1)
; CHECK: S_ENDPGM 0

View File

@ -255,7 +255,7 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
// R19N-NEXT: // MIs[0] src1
// R19N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
// R19N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
// R19N-NEXT: // MIs[0] Operand 2
// R19N-NEXT: // MIs[0] complex_rr:src2a:src2b
// R19N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
//
// R19N-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex_rr,
@ -274,7 +274,7 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
// R19N-NEXT: // MIs[1] src4
// R19N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
// R19N-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/2, /*Renderer*/1, GICP_gi_complex,
// R19N-NEXT: // MIs[1] Operand 3
// R19N-NEXT: // MIs[1] complex:src5a:src5b
// R19N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/3, /*Type*/GILLT_s32,
// R19N-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/3, /*Renderer*/2, GICP_gi_complex,
// R19O-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,

View File

@ -23,7 +23,7 @@ def INSN : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>;
//===- Bail out when we define a variable twice wrt complex suboperands. -===//
// CHECK: warning: Skipped pattern: Complex suboperand referenced more than once (Operand: x)
// CHECK: warning: Skipped pattern: Error: Complex suboperand x referenced by different operands: complex_rr:x:y and complex_rr:x:z.
def : Pat<(add (complex_rr GPR32:$x, GPR32:$y),
(complex_rr GPR32:$x, GPR32:$z)),
(INSN GPR32:$z, complex:$y)>;

View File

@ -856,6 +856,11 @@ protected:
DefinedComplexPatternSubOperandMap;
/// A map of Symbolic Names to ComplexPattern sub-operands.
DefinedComplexPatternSubOperandMap ComplexSubOperands;
/// A map used to for multiple referenced error check of ComplexSubOperand.
/// ComplexSubOperand can't be referenced multiple from different operands,
/// however multiple references from same operand are allowed since that is
/// how 'same operand checks' are generated.
StringMap<std::string> ComplexSubOperandsParentName;
uint64_t RuleID;
static uint64_t NextRuleID;
@ -921,14 +926,24 @@ public:
void definePhysRegOperand(Record *Reg, OperandMatcher &OM);
Error defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
unsigned RendererID, unsigned SubOperandID) {
if (ComplexSubOperands.count(SymbolicName))
return failedImport(
"Complex suboperand referenced more than once (Operand: " +
SymbolicName + ")");
unsigned RendererID, unsigned SubOperandID,
StringRef ParentSymbolicName) {
std::string ParentName(ParentSymbolicName);
if (ComplexSubOperands.count(SymbolicName)) {
auto RecordedParentName = ComplexSubOperandsParentName[SymbolicName];
if (RecordedParentName.compare(ParentName) != 0)
return failedImport("Error: Complex suboperand " + SymbolicName +
" referenced by different operands: " +
RecordedParentName + " and " + ParentName + ".");
// Complex suboperand referenced more than once from same the operand is
// used to generate 'same operand check'. Emitting of
// GIR_ComplexSubOperandRenderer for them is already handled.
return Error::success();
}
ComplexSubOperands[SymbolicName] =
std::make_tuple(ComplexPattern, RendererID, SubOperandID);
ComplexSubOperandsParentName[SymbolicName] = ParentName;
return Error::success();
}
@ -4100,12 +4115,22 @@ Error GlobalISelEmitter::importChildMatcher(
bool OperandIsImmArg, unsigned OpIdx, unsigned &TempOpIdx) {
Record *PhysReg = nullptr;
StringRef SrcChildName = getSrcChildName(SrcChild, PhysReg);
std::string SrcChildName = std::string(getSrcChildName(SrcChild, PhysReg));
if (!SrcChild->isLeaf() &&
SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
// The "name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is
// "MY_PAT:op1:op2" and the ones with same "name" represent same operand.
std::string PatternName = std::string(SrcChild->getOperator()->getName());
for (unsigned i = 0; i < SrcChild->getNumChildren(); ++i) {
PatternName += ":";
PatternName += SrcChild->getChild(i)->getName();
}
SrcChildName = PatternName;
}
OperandMatcher &OM =
PhysReg
? InsnMatcher.addPhysRegInput(PhysReg, OpIdx, TempOpIdx)
: InsnMatcher.addOperand(OpIdx, std::string(SrcChildName), TempOpIdx);
PhysReg ? InsnMatcher.addPhysRegInput(PhysReg, OpIdx, TempOpIdx)
: InsnMatcher.addOperand(OpIdx, SrcChildName, TempOpIdx);
if (OM.isSameAsAnotherOperand())
return Error::success();
@ -4152,9 +4177,9 @@ Error GlobalISelEmitter::importChildMatcher(
for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
auto *SubOperand = SrcChild->getChild(i);
if (!SubOperand->getName().empty()) {
if (auto Error = Rule.defineComplexSubOperand(SubOperand->getName(),
SrcChild->getOperator(),
RendererID, i))
if (auto Error = Rule.defineComplexSubOperand(
SubOperand->getName(), SrcChild->getOperator(), RendererID, i,
SrcChildName))
return Error;
}
}