Skip to content

Commit

Permalink
[AIE2P] Optimize G_PHI regbankselect for fifo/acc
Browse files Browse the repository at this point in the history
  • Loading branch information
andcarminati committed Jan 28, 2025
1 parent 0b93802 commit 436679d
Show file tree
Hide file tree
Showing 2 changed files with 246 additions and 0 deletions.
40 changes: 40 additions & 0 deletions llvm/lib/Target/AIE/aie2p/AIE2PRegisterBankInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,16 @@ static bool isAccReg(const Register Reg) {
return false;
}

static bool isAccCompatibleType(const LLT &Ty) {
const unsigned Size = Ty.getSizeInBits();
return Ty.isVector() && (Size == 512 || Size == 1024 || Size == 2048);
}

static bool isFifoCompatibleType(const LLT &Ty) {
const unsigned Size = Ty.getSizeInBits();
return Ty.isVector() && (Size == 512 || Size == 1024);
}

RegisterBankInfo::InstructionMappings
AIE2PRegisterBankInfo::getInstrAlternativeMappings(
const MachineInstr &MI) const {
Expand Down Expand Up @@ -931,6 +941,36 @@ AIE2PRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
}
return AIEBaseRegisterBankInfo::getInstrMapping(MI);
}
case TargetOpcode::G_PHI: {
Register UseCandidate = MI.getOperand(0).getReg();
const LLT Type = MRI.getType(UseCandidate);
auto MapPHIInst =
[&](AIEBaseRegisterBankInfo::PartialMappingIdx PartialMapping)
-> const InstructionMapping & {
SmallVector<unsigned, 4> OpSize(1);
SmallVector<PartialMappingIdx, 4> OpRegBankIdx(1);

const ValueMapping *ValMapping =
getValueMapping(PartialMapping, Type.getSizeInBits());

SmallVector<const ValueMapping *, 8> OperandsMapping(1);
OperandsMapping[0] = ValMapping;
return getInstructionMapping(
DefaultMappingID, /*Cost*/ 1,
/*OperandsMapping*/ getOperandsMapping(OperandsMapping), 1);
};
// We consider only vector types, otherwise we can match things like:
// %21:_(p0) = G_PHI %14:ptrregbank(p0), %bb.6, %25:_(p0), %bb.9
// G_STORE %17:accregbank(<32 x s32>), %21:_(p0) <- uses accregbank
// TODO: move to getPreferredRegBankForOperand once available.
if (isFifoCompatibleType(Type) && isUseFifoInsn(MRI, TRI, UseCandidate)) {
return MapPHIInst(getFifoPartialMappingIdx(Type));
} else if (isAccCompatibleType(Type) &&
isUseAccInsn(MRI, TRI, UseCandidate)) {
return MapPHIInst(getAccPartialMappingIdx(Type));
}
return getInstrMappingImpl(MI);
}
default:
// Base class implementation for others
return AIEBaseRegisterBankInfo::getInstrMapping(MI);
Expand Down
206 changes: 206 additions & 0 deletions llvm/test/CodeGen/AIE/aie2p/GlobalIsel/regbankselect-phi.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
#
# This file is licensed 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
#
# (c) Copyright 2025 Advanced Micro Devices, Inc. or its affiliates
# RUN: llc -mtriple aie2p -run-pass=regbankselect -regbankselect-fast %s -verify-machineinstrs -o - | FileCheck %s
# RUN: llc -mtriple aie2p -run-pass=regbankselect -regbankselect-greedy %s -verify-machineinstrs -o - | FileCheck %s


# Test 1: The instruction %23:_(<32 x s32>) = G_PHI %66(<32 x s32>), %bb.0, %28(<32 x s32>), %bb.1
# should be mapped to fiforegbank to avoid copies to and from the vector bank.

---
name: test_fifo.ld.fill
legalized: true
regBankSelected: false
tracksRegLiveness: true
body: |
; CHECK-LABEL: name: test_fifo.ld.fill
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.1(0x80000000)
; CHECK-NEXT: liveins: $p0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:ptrregbank(p0) = COPY $p0
; CHECK-NEXT: [[C:%[0-9]+]]:gprregbank(s32) = G_CONSTANT i32 10
; CHECK-NEXT: [[C1:%[0-9]+]]:gprregbank(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[DEF:%[0-9]+]]:vregbank(<32 x s32>) = G_IMPLICIT_DEF
; CHECK-NEXT: [[C2:%[0-9]+]]:gprregbank(s32) = G_CONSTANT i32 1
; CHECK-NEXT: G_BR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors: %bb.1(0x04000000), %bb.2(0x7c000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[PHI:%[0-9]+]]:gprregbank(s32) = G_PHI [[C2]](s32), %bb.0, %6(s32), %bb.1
; CHECK-NEXT: [[PHI1:%[0-9]+]]:ptrregbank(p0) = G_PHI [[COPY]](p0), %bb.0, %8(p0), %bb.1
; CHECK-NEXT: [[PHI2:%[0-9]+]]:gprregbank(s32) = G_PHI [[C]](s32), %bb.0, %10(s32), %bb.1
; CHECK-NEXT: [[PHI3:%[0-9]+]]:fiforegbank(<32 x s32>) = G_PHI [[DEF]](<32 x s32>), %bb.0, %12(<32 x s32>), %bb.1
; CHECK-NEXT: [[INT:%[0-9]+]]:ptrregbank(p0), [[INT1:%[0-9]+]]:fiforegbank(<32 x s32>), [[INT2:%[0-9]+]]:gprregbank(s32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.fifo.ld.fill), [[PHI1]](p0), [[PHI3]](<32 x s32>), [[PHI2]](s32)
; CHECK-NEXT: [[ADD:%[0-9]+]]:gprregbank(s32) = G_ADD [[PHI]], [[C1]]
; CHECK-NEXT: [[ICMP:%[0-9]+]]:gprregbank(s32) = G_ICMP intpred(eq), [[ADD]](s32), [[C]]
; CHECK-NEXT: G_BRCOND [[ICMP]](s32), %bb.1
; CHECK-NEXT: G_BR %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: PseudoRET implicit $lr
bb.0:
successors: %bb.1
liveins: $p0
%0:_(p0) = COPY $p0
%4:_(s32) = G_CONSTANT i32 10
%63:_(s32) = G_CONSTANT i32 1
%66:_(<32 x s32>) = G_IMPLICIT_DEF
%3:_(s32) = G_CONSTANT i32 1
G_BR %bb.1
bb.1:
successors: %bb.1(0x04000000), %bb.2(0x7c000000)
%18:_(s32) = G_PHI %3(s32), %bb.0, %64(s32), %bb.1
%19:_(p0) = G_PHI %0(p0), %bb.0, %27(p0), %bb.1
%21:_(s32) = G_PHI %4(s32), %bb.0, %29(s32), %bb.1
%23:_(<32 x s32>) = G_PHI %66(<32 x s32>), %bb.0, %28(<32 x s32>), %bb.1
%27:_(p0), %28:_(<32 x s32>), %29:_(s32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.fifo.ld.fill), %19(p0), %23(<32 x s32>), %21(s32)
%64:_(s32) = G_ADD %18, %63
%69:_(s32) = G_ICMP intpred(eq), %64(s32), %4
G_BRCOND %69(s32), %bb.1
G_BR %bb.2
bb.2:
PseudoRET implicit $lr
...

# Test 2: The instruction %23:_(<32 x s32>) = G_PHI %66(<32 x s32>), %bb.0, %100(<32 x s32>), %bb.1
# should be mapped to accregbank to avoid copies to and from the vector bank.

---
name: test_acc.vmac
legalized: true
regBankSelected: false
tracksRegLiveness: true
body: |
; CHECK-LABEL: name: test_acc.vmac
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.1(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[C:%[0-9]+]]:gprregbank(s32) = G_CONSTANT i32 10
; CHECK-NEXT: [[C1:%[0-9]+]]:gprregbank(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[DEF:%[0-9]+]]:vregbank(<32 x s32>) = G_IMPLICIT_DEF
; CHECK-NEXT: [[DEF1:%[0-9]+]]:vregbank(<32 x s16>) = G_IMPLICIT_DEF
; CHECK-NEXT: [[C2:%[0-9]+]]:gprregbank(s32) = G_CONSTANT i32 1
; CHECK-NEXT: G_BR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors: %bb.1(0x04000000), %bb.2(0x7c000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[PHI:%[0-9]+]]:gprregbank(s32) = G_PHI [[C2]](s32), %bb.0, %6(s32), %bb.1
; CHECK-NEXT: [[PHI1:%[0-9]+]]:accregbank(<32 x s32>) = G_PHI [[DEF]](<32 x s32>), %bb.0, %8(<32 x s32>), %bb.1
; CHECK-NEXT: [[INT:%[0-9]+]]:accregbank(<32 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.I512.I512.ACC1024.bf.mac.conf), [[DEF1]](<32 x s16>), [[DEF1]](<32 x s16>), [[PHI1]](<32 x s32>), [[C]](s32)
; CHECK-NEXT: [[ADD:%[0-9]+]]:gprregbank(s32) = G_ADD [[PHI]], [[C1]]
; CHECK-NEXT: [[ICMP:%[0-9]+]]:gprregbank(s32) = G_ICMP intpred(eq), [[ADD]](s32), [[C]]
; CHECK-NEXT: G_BRCOND [[ICMP]](s32), %bb.1
; CHECK-NEXT: G_BR %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: PseudoRET implicit $lr
bb.0:
successors: %bb.1
%4:_(s32) = G_CONSTANT i32 10
%63:_(s32) = G_CONSTANT i32 1
%66:_(<32 x s32>) = G_IMPLICIT_DEF
%77:_(<32 x s16>) = G_IMPLICIT_DEF
%3:_(s32) = G_CONSTANT i32 1
G_BR %bb.1
bb.1:
successors: %bb.1(0x04000000), %bb.2(0x7c000000)
%18:_(s32) = G_PHI %3(s32), %bb.0, %64(s32), %bb.1
%23:_(<32 x s32>) = G_PHI %66(<32 x s32>), %bb.0, %100(<32 x s32>), %bb.1
%100:_(<32 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.I512.I512.ACC1024.bf.mac.conf), %77(<32 x s16>), %77(<32 x s16>), %23(<32 x s32>), %4(s32)
%64:_(s32) = G_ADD %18, %63
%69:_(s32) = G_ICMP intpred(eq), %64(s32), %4
G_BRCOND %69(s32), %bb.1
G_BR %bb.2
bb.2:
PseudoRET implicit $lr
...

# Test 3: The instruction %19:_(p0) = G_PHI %0(p0), %bb.0, %27(p0), %bb.1
# should not be mapped to accregbank. The result of the PHI node is used by an instruction
# that is considered an `accululator-use instruction` but the considered result is just a scalar
# pointer.

---
name: neg_test_acc.vmac_store
legalized: true
regBankSelected: false
tracksRegLiveness: true
body: |
; CHECK-LABEL: name: neg_test_acc.vmac_store
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.1(0x80000000)
; CHECK-NEXT: liveins: $p0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:ptrregbank(p0) = COPY $p0
; CHECK-NEXT: [[C:%[0-9]+]]:gprregbank(s32) = G_CONSTANT i32 10
; CHECK-NEXT: [[C1:%[0-9]+]]:gprregbank(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[DEF:%[0-9]+]]:accregbank(<32 x s32>) = G_IMPLICIT_DEF
; CHECK-NEXT: [[DEF1:%[0-9]+]]:vregbank(<32 x s16>) = G_IMPLICIT_DEF
; CHECK-NEXT: [[C2:%[0-9]+]]:gprregbank(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[C3:%[0-9]+]]:modregbank(s20) = G_CONSTANT i20 32
; CHECK-NEXT: [[INT:%[0-9]+]]:accregbank(<32 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.I512.I512.ACC1024.bf.mac.conf), [[DEF1]](<32 x s16>), [[DEF1]](<32 x s16>), [[DEF]](<32 x s32>), [[C]](s32)
; CHECK-NEXT: G_BR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors: %bb.1(0x04000000), %bb.2(0x7c000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[PHI:%[0-9]+]]:gprregbank(s32) = G_PHI [[C2]](s32), %bb.0, %9(s32), %bb.1
; CHECK-NEXT: [[PHI1:%[0-9]+]]:ptrregbank(p0) = G_PHI [[COPY]](p0), %bb.0, %11(p0), %bb.1
; CHECK-NEXT: G_STORE [[INT]](<32 x s32>), [[PHI1]](p0) :: (store (<32 x s32>))
; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:ptrregbank(p0) = G_PTR_ADD [[PHI1]], [[C3]](s20)
; CHECK-NEXT: [[ADD:%[0-9]+]]:gprregbank(s32) = G_ADD [[PHI]], [[C1]]
; CHECK-NEXT: [[ICMP:%[0-9]+]]:gprregbank(s32) = G_ICMP intpred(eq), [[ADD]](s32), [[C]]
; CHECK-NEXT: G_BRCOND [[ICMP]](s32), %bb.1
; CHECK-NEXT: G_BR %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: PseudoRET implicit $lr
bb.0:
successors: %bb.1
liveins: $p0
%0:_(p0) = COPY $p0
%4:_(s32) = G_CONSTANT i32 10
%63:_(s32) = G_CONSTANT i32 1
%66:_(<32 x s32>) = G_IMPLICIT_DEF
%77:_(<32 x s16>) = G_IMPLICIT_DEF
%3:_(s32) = G_CONSTANT i32 1
%5:_(s20) = G_CONSTANT i20 32
%100:_(<32 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.I512.I512.ACC1024.bf.mac.conf), %77(<32 x s16>), %77(<32 x s16>), %66(<32 x s32>), %4(s32)
G_BR %bb.1
bb.1:
successors: %bb.1(0x04000000), %bb.2(0x7c000000)
%18:_(s32) = G_PHI %3(s32), %bb.0, %64(s32), %bb.1
%19:_(p0) = G_PHI %0(p0), %bb.0, %27(p0), %bb.1
G_STORE %100, %19(p0) :: (store (<32 x s32>))
%27:_(p0) = G_PTR_ADD %19, %5
%64:_(s32) = G_ADD %18, %63
%69:_(s32) = G_ICMP intpred(eq), %64(s32), %4
G_BRCOND %69(s32), %bb.1
G_BR %bb.2
bb.2:
PseudoRET implicit $lr
...

0 comments on commit 436679d

Please sign in to comment.