mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-02 13:21:43 +00:00
[Hexagon] Allow redefinition with immediates for hw loop conversion
Normally, if the registers holding the induction variable's bounds are redefined inside of the loop's body, the loop cannot be converted to a hardware loop. However, if the redefining instruction is actually loading an immediate value into the register, this conversion is both possible and legal (since the immediate itself will be used in the loop setup in the preheader). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316218 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
268fcddc7a
commit
b99a8bcc2b
@ -111,9 +111,7 @@ namespace {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
HexagonHardwareLoops() : MachineFunctionPass(ID) {
|
||||
initializeHexagonHardwareLoopsPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
HexagonHardwareLoops() : MachineFunctionPass(ID) {}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
|
||||
@ -685,15 +683,21 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L,
|
||||
if (InitialValue->isReg()) {
|
||||
unsigned R = InitialValue->getReg();
|
||||
MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent();
|
||||
if (!MDT->properlyDominates(DefBB, Header))
|
||||
return nullptr;
|
||||
if (!MDT->properlyDominates(DefBB, Header)) {
|
||||
int64_t V;
|
||||
if (!checkForImmediate(*InitialValue, V))
|
||||
return nullptr;
|
||||
}
|
||||
OldInsts.push_back(MRI->getVRegDef(R));
|
||||
}
|
||||
if (EndValue->isReg()) {
|
||||
unsigned R = EndValue->getReg();
|
||||
MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent();
|
||||
if (!MDT->properlyDominates(DefBB, Header))
|
||||
return nullptr;
|
||||
if (!MDT->properlyDominates(DefBB, Header)) {
|
||||
int64_t V;
|
||||
if (!checkForImmediate(*EndValue, V))
|
||||
return nullptr;
|
||||
}
|
||||
OldInsts.push_back(MRI->getVRegDef(R));
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,7 @@ namespace llvm {
|
||||
void initializeHexagonEarlyIfConversionPass(PassRegistry&);
|
||||
void initializeHexagonExpandCondsetsPass(PassRegistry&);
|
||||
void initializeHexagonGenMuxPass(PassRegistry&);
|
||||
void initializeHexagonHardwareLoopsPass(PassRegistry&);
|
||||
void initializeHexagonLoopIdiomRecognizePass(PassRegistry&);
|
||||
void initializeHexagonVectorLoopCarriedReusePass(PassRegistry&);
|
||||
void initializeHexagonNewValueJumpPass(PassRegistry&);
|
||||
@ -184,6 +185,7 @@ extern "C" void LLVMInitializeHexagonTarget() {
|
||||
initializeHexagonConstExtendersPass(PR);
|
||||
initializeHexagonEarlyIfConversionPass(PR);
|
||||
initializeHexagonGenMuxPass(PR);
|
||||
initializeHexagonHardwareLoopsPass(PR);
|
||||
initializeHexagonLoopIdiomRecognizePass(PR);
|
||||
initializeHexagonVectorLoopCarriedReusePass(PR);
|
||||
initializeHexagonNewValueJumpPass(PR);
|
||||
|
63
test/CodeGen/Hexagon/hwloop-redef-imm.mir
Normal file
63
test/CodeGen/Hexagon/hwloop-redef-imm.mir
Normal file
@ -0,0 +1,63 @@
|
||||
# RUN: llc -march=hexagon -run-pass hwloops %s -o - | FileCheck %s
|
||||
|
||||
# Normally, if the registers holding the induction variable's bounds
|
||||
# are redefined inside of the loop's body, the loop cannot be converted
|
||||
# to a hardware loop. However, if the redefining instruction is actually
|
||||
# loading an immediate value into the register, this conversion is both
|
||||
# possible and legal (since the immediate itself will be used in the
|
||||
# loop setup in the preheader).
|
||||
|
||||
# CHECK: [[R0:%[0-9]+]] = A2_tfrsi 1920
|
||||
# CHECK: J2_loop0r %bb.1.b1, [[R0]]
|
||||
#
|
||||
# CHECK: bb.1.b1 (address-taken):
|
||||
# CHECK: ENDLOOP0 %bb.1.b1
|
||||
|
||||
|
||||
--- |
|
||||
define void @fred() {
|
||||
b0:
|
||||
br label %b1
|
||||
b1:
|
||||
br label %b2
|
||||
b2:
|
||||
ret void
|
||||
}
|
||||
...
|
||||
|
||||
---
|
||||
name: fred
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: intregs }
|
||||
- { id: 1, class: intregs }
|
||||
- { id: 2, class: intregs }
|
||||
- { id: 3, class: intregs }
|
||||
- { id: 4, class: intregs }
|
||||
- { id: 5, class: intregs }
|
||||
- { id: 6, class: intregs }
|
||||
- { id: 7, class: intregs }
|
||||
- { id: 8, class: predregs }
|
||||
body: |
|
||||
bb.0.b0:
|
||||
liveins: %r0
|
||||
successors: %bb.1
|
||||
%0 = A2_tfrsi 0
|
||||
%1 = A2_tfrsi 0
|
||||
%2 = COPY %r0
|
||||
|
||||
bb.1.b1:
|
||||
successors: %bb.1, %bb.2
|
||||
%3 = PHI %0, %bb.0, %6, %bb.1
|
||||
%4 = PHI %1, %bb.0, %5, %bb.1
|
||||
S4_storerh_rr %2, %4, 0, %3
|
||||
%5 = A2_addi %4, 2
|
||||
%6 = A2_addi %3, 1
|
||||
; This definition of %7 should not prevent conversion to hardware loop.
|
||||
%7 = A2_tfrsi 3840
|
||||
%8 = C2_cmpeq %5, %7
|
||||
J2_jumpf %8, %bb.1, implicit-def %pc
|
||||
J2_jump %bb.2, implicit-def %pc
|
||||
|
||||
bb.2.b2:
|
||||
...
|
Loading…
x
Reference in New Issue
Block a user