Skip to content

Commit 089c35e

Browse files
vladimirradosavljevichedgar2017
authored andcommitted
[EraVM] Add a pass to rewrite dead defs to R0
This patch adds a pass that rewrites dead register definitions to R0. PR: #494. Signed-off-by: Vladimir Radosavljevic <[email protected]>
1 parent 1e7bf66 commit 089c35e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+609
-467
lines changed

llvm/lib/Target/EraVM/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ add_llvm_target(EraVMCodeGen
6161
EraVMCombineFlagSetting.cpp
6262
EraVMCombineToIndexedMemops.cpp
6363
EraVMCSE.cpp
64+
EraVMDeadRegisterDefinitions.cpp
6465
EraVMExpandPseudoInsts.cpp
6566
EraVMExpandSelect.cpp
6667
EraVMFoldSimilarInstructions.cpp

llvm/lib/Target/EraVM/EraVM.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ FunctionPass *createEraVMOptimizeSelectPreRAPass();
9393
FunctionPass *createEraVMCSEPass();
9494
FunctionPass *createEraVMFoldSimilarInstructionsPass();
9595
FunctionPass *createEraVMPostCodegenPreparePass();
96+
FunctionPass *createEraVMDeadRegisterDefinitionsPass();
9697

9798
void initializeEraVMLowerIntrinsicsPass(PassRegistry &);
9899
void initializeEraVMAllocaHoistingPass(PassRegistry &);
@@ -120,6 +121,7 @@ void initializeEraVMOptimizeSelectPreRAPass(PassRegistry &);
120121
void initializeEraVMCSELegacyPassPass(PassRegistry &);
121122
void initializeEraVMFoldSimilarInstructionsPass(PassRegistry &);
122123
void initializeEraVMPostCodegenPreparePass(PassRegistry &);
124+
void initializeEraVMDeadRegisterDefinitionsPass(PassRegistry &);
123125

124126
struct EraVMLinkRuntimePass : PassInfoMixin<EraVMLinkRuntimePass> {
125127
explicit EraVMLinkRuntimePass(OptimizationLevel Level) : Level(Level) {}

llvm/lib/Target/EraVM/EraVMCombineAddressingMode.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,13 @@ bool EraVMCombineAddressingMode::combineDefSpill(MachineFunction &MF) {
430430
if (!isSpillInst(MI))
431431
continue;
432432
Register Spilled = EraVM::in0Iterator(MI)->getReg();
433+
434+
// If R0 is spilled, don't bother to try to combine it, since
435+
// it is read only register that holds zero value. Also, R0 is
436+
// used in cases where definitions are dead and not used.
437+
if (Spilled == EraVM::R0)
438+
continue;
439+
433440
SmallPtrSet<MachineInstr *, 4> ReachingDefs;
434441
RDA->getGlobalReachingDefs(&MI, Spilled, ReachingDefs);
435442
// TODO: CPR-1225 While the transformation is local, multiple reaching def
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//===-- EraVMDeadRegisterDefinitions.cpp - Replace dead defs ----*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This pass rewrites def regs to R0 for instrs whose return values are unused.
10+
// In high register pressure cases, this can help to reduce spills that were
11+
// previously needed to free up register so it can be used as a dead result of
12+
// instruction whose output is not used. Also, in some cases regalloc can assign
13+
// registers in such way that lowering of select instruction can be done in one
14+
// instruction while inverting condition:
15+
// Before:
16+
// add stack-[19], r0, r3
17+
// sub.s! @CPI3_11[0], r3, r2
18+
// add @CPI3_11[0], r0, r2
19+
// add.lt r3, r0, r2
20+
// After:
21+
// add stack-[19], r0, r2
22+
// sub.s! @CPI3_11[0], r2, r0
23+
// add.ge @CPI3_11[0], r0, r2
24+
//
25+
//===----------------------------------------------------------------------===//
26+
27+
#include "EraVM.h"
28+
#include "EraVMInstrInfo.h"
29+
#include "llvm/ADT/Statistic.h"
30+
31+
using namespace llvm;
32+
33+
#define DEBUG_TYPE "eravm-dead-defs"
34+
#define ERAVM_DEAD_REG_DEF_NAME "EraVM dead register definitions"
35+
36+
STATISTIC(NumDeadDefsReplaced, "Number of dead definitions replaced");
37+
38+
namespace {
39+
40+
class EraVMDeadRegisterDefinitions : public MachineFunctionPass {
41+
public:
42+
static char ID;
43+
EraVMDeadRegisterDefinitions() : MachineFunctionPass(ID) {
44+
initializeEraVMDeadRegisterDefinitionsPass(
45+
*PassRegistry::getPassRegistry());
46+
}
47+
48+
bool runOnMachineFunction(MachineFunction &MF) override;
49+
50+
StringRef getPassName() const override { return ERAVM_DEAD_REG_DEF_NAME; }
51+
};
52+
53+
char EraVMDeadRegisterDefinitions::ID = 0;
54+
} // namespace
55+
56+
INITIALIZE_PASS(EraVMDeadRegisterDefinitions, DEBUG_TYPE,
57+
ERAVM_DEAD_REG_DEF_NAME, false, false)
58+
59+
bool EraVMDeadRegisterDefinitions::runOnMachineFunction(MachineFunction &MF) {
60+
LLVM_DEBUG(dbgs() << "********** EraVM DEAD REGISTER DEFINITIONS **********\n"
61+
<< "********** Function: " << MF.getName() << '\n');
62+
63+
bool Changed = false;
64+
MachineRegisterInfo *RegInfo = &MF.getRegInfo();
65+
66+
for (MachineBasicBlock &MBB : MF) {
67+
for (MachineInstr &MI : MBB) {
68+
// We only handle EraVM specific instructions.
69+
if (MI.getOpcode() <= TargetOpcode::GENERIC_OP_END)
70+
continue;
71+
72+
for (unsigned I = 0, E = MI.getNumExplicitDefs(); I != E; ++I) {
73+
MachineOperand &MO = MI.getOperand(I);
74+
if (!MO.isReg() || !MO.isDef() || MO.isEarlyClobber())
75+
continue;
76+
77+
// Skip tied operands.
78+
if (MI.isRegTiedToUseOperand(I))
79+
continue;
80+
81+
// Just check for virtual registers that are dead.
82+
if (!MO.getReg().isVirtual() ||
83+
(!MO.isDead() && !RegInfo->use_nodbg_empty(MO.getReg())))
84+
continue;
85+
86+
LLVM_DEBUG(dbgs() << "== Dead def operand in:"; MI.dump());
87+
MO.setReg(EraVM::R0);
88+
MO.setIsDead();
89+
LLVM_DEBUG(dbgs() << " Replacing with R0:"; MI.dump());
90+
++NumDeadDefsReplaced;
91+
Changed = true;
92+
}
93+
}
94+
}
95+
return Changed;
96+
}
97+
98+
/// createEraVMDeadRegisterDefinitionsOperandsPass - returns an instance of the
99+
/// dead register definitions pass.
100+
FunctionPass *llvm::createEraVMDeadRegisterDefinitionsPass() {
101+
return new EraVMDeadRegisterDefinitions();
102+
}

llvm/lib/Target/EraVM/EraVMTargetMachine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeEraVMTarget() {
7272
initializeEraVMFoldSimilarInstructionsPass(PR);
7373
initializeEraVMCombineToIndexedMemopsPass(PR);
7474
initializeEraVMPostCodegenPreparePass(PR);
75+
initializeEraVMDeadRegisterDefinitionsPass(PR);
7576
}
7677

7778
static std::string computeDataLayout() {
@@ -295,6 +296,7 @@ void EraVMPassConfig::addPreRegAlloc() {
295296
addPass(createEraVMHoistFlagSettingPass());
296297
addPass(&LiveVariablesID);
297298
addPass(createEraVMTieSelectOperandsPass());
299+
addPass(createEraVMDeadRegisterDefinitionsPass());
298300
}
299301
}
300302

llvm/test/CodeGen/EraVM/O3-pipeline.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ target triple = "eravm"
138138
; CHECK-NEXT: Remove unreachable machine basic blocks
139139
; CHECK-NEXT: Live Variable Analysis
140140
; CHECK-NEXT: EraVM tie select operands pass
141+
; CHECK-NEXT: EraVM dead register definitions
141142
; CHECK-NEXT: Detect Dead Lanes
142143
; CHECK-NEXT: Process Implicit Definitions
143144
; CHECK-NEXT: Remove unreachable machine basic blocks

llvm/test/CodeGen/EraVM/addmod.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ target triple = "eravm"
55

66
define i256 @test(i256 %a) {
77
; CHECK-LABEL: test
8-
; CHECK: sub.s! @CPI0_0[0], r1, r2
8+
; CHECK: sub.s! @CPI0_0[0], r1, r0
99
; CHECK-NEXT: add.ge 5, r1, r1
1010
; CHECK-NEXT: shl.s 1, r1, r4
1111
; CHECK-NEXT: add 5, r4, r2
12-
; CHECK-NEXT: sub.s! @CPI0_0[0], r4, r3
12+
; CHECK-NEXT: sub.s! @CPI0_0[0], r4, r0
1313
; CHECK-NEXT: add r2, r0, r3
1414
; CHECK-NEXT: add.lt r4, r0, r3
15-
; CHECK-NEXT: sub! r4, r1, r1
15+
; CHECK-NEXT: sub! r4, r1, r0
1616
; CHECK-NEXT: add.ge r3, r0, r2
1717
; CHECK-NEXT: add r2, r0, r1
1818
; CHECK-NEXT: ret

llvm/test/CodeGen/EraVM/branch-on-zero.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ else:
2626
define i256 @lshr_not(i256 %a) {
2727
; CHECK-LABEL: lshr_not:
2828
; CHECK: ; %bb.0: ; %entry
29-
; CHECK-NEXT: sub.s! 7, r1, r2
29+
; CHECK-NEXT: sub.s! 7, r1, r0
3030
; CHECK-NEXT: shr.s.gt 4, r1, r1
3131
; CHECK-NEXT: add.le r0, r0, r1
3232
; CHECK-NEXT: ret
@@ -85,7 +85,7 @@ else:
8585
define i256 @add_not(i256 %a) {
8686
; CHECK-LABEL: add_not:
8787
; CHECK: ; %bb.0: ; %entry
88-
; CHECK-NEXT: sub.s! 10, r1, r2
88+
; CHECK-NEXT: sub.s! 10, r1, r0
8989
; CHECK-NEXT: add.ne 10, r1, r1
9090
; CHECK-NEXT: add.eq r0, r0, r1
9191
; CHECK-NEXT: ret
@@ -123,7 +123,7 @@ else:
123123
define i256 @sub_not(i256 %a) {
124124
; CHECK-LABEL: sub_not:
125125
; CHECK: ; %bb.0: ; %entry
126-
; CHECK-NEXT: sub.s! 10, r1, r2
126+
; CHECK-NEXT: sub.s! 10, r1, r0
127127
; CHECK-NEXT: add.ne 10, r1, r1
128128
; CHECK-NEXT: add.eq r0, r0, r1
129129
; CHECK-NEXT: ret

llvm/test/CodeGen/EraVM/brcc.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ target triple = "eravm"
77

88
; CHECK-LABEL: ugt
99
define i256 @ugt(i256 %p1, i256 %p2) nounwind {
10-
; CHECK: sub! r1, r2, r{{[0-9]+}}
10+
; CHECK: sub! r1, r2, r0
1111
; CHECK-NEXT: add.le 72, r0, r1
1212
; CHECK-NEXT: add.gt 42, r0, r1
1313
; CHECK-NEXT: ret
@@ -21,7 +21,7 @@ l2:
2121

2222
; CHECK-LABEL: uge
2323
define i256 @uge(i256 %p1, i256 %p2) nounwind {
24-
; CHECK: sub! r1, r2, r{{[0-9]+}}
24+
; CHECK: sub! r1, r2, r0
2525
; CHECK-NEXT: add.lt 72, r0, r1
2626
; CHECK-NEXT: add.ge 42, r0, r1
2727
; CHECK-NEXT: ret
@@ -35,7 +35,7 @@ l2:
3535

3636
; CHECK-LABEL: ult
3737
define i256 @ult(i256 %p1, i256 %p2) nounwind {
38-
; CHECK: sub! r1, r2, r{{[0-9]+}}
38+
; CHECK: sub! r1, r2, r0
3939
; CHECK-NEXT: add.ge 72, r0, r1
4040
; CHECK-NEXT: add.lt 42, r0, r1
4141
; CHECK-NEXT: ret
@@ -49,7 +49,7 @@ l2:
4949

5050
; CHECK-LABEL: ule
5151
define i256 @ule(i256 %p1, i256 %p2) nounwind {
52-
; CHECK: sub! r1, r2, r{{[0-9]+}}
52+
; CHECK: sub! r1, r2, r0
5353
; CHECK-NEXT: add.gt 72, r0, r1
5454
; CHECK-NEXT: add.le 42, r0, r1
5555
; CHECK-NEXT: ret
@@ -63,7 +63,7 @@ l2:
6363

6464
; CHECK-LABEL: eq
6565
define i256 @eq(i256 %p1, i256 %p2) nounwind {
66-
; CHECK: sub! r1, r2, r{{[0-9]+}}
66+
; CHECK: sub! r1, r2, r0
6767
; CHECK-NEXT: add.ne 72, r0, r1
6868
; CHECK-NEXT: add.eq 42, r0, r1
6969
; CHECK-NEXT: ret
@@ -77,7 +77,7 @@ l2:
7777

7878
; CHECK-LABEL: cmpne
7979
define i256 @cmpne(i256 %p1, i256 %p2) nounwind {
80-
; CHECK: sub! r1, r2, r{{[0-9]+}}
80+
; CHECK: sub! r1, r2, r0
8181
; CHECK-NEXT: add.eq 72, r0, r1
8282
; CHECK-NEXT: add.ne 42, r0, r1
8383
; CHECK-NEXT: ret
@@ -108,7 +108,7 @@ loop.exit:
108108

109109
; CHECK-LABEL: cmpir
110110
define i256 @cmpir(i256 %p1, i256 %p2) nounwind {
111-
; CHECK: sub.s! 43, r{{[0-9]+}}, r{{[0-9]+}}
111+
; CHECK: sub.s! 43, r{{[0-9]+}}, r0
112112
; CHECK-NEXT: add.lt 72, r0, r1
113113
; CHECK-NEXT: add.ge 42, r0, r1
114114
; CHECK-NEXT: ret
@@ -122,7 +122,7 @@ l2:
122122

123123
; CHECK-LABEL: cmpcr
124124
define i256 @cmpcr(i256 %p1, i256 %p2) nounwind {
125-
; CHECK: sub.s! @val[0], r1, r{{[0-9]+}}
125+
; CHECK: sub.s! @val[0], r1, r0
126126
; CHECK-NEXT: add.le 72, r0, r1
127127
; CHECK-NEXT: add.gt 42, r0, r1
128128
; CHECK-NEXT: ret
@@ -138,7 +138,7 @@ l2:
138138
; CHECK-LABEL: cmpsr
139139
define i256 @cmpsr(i256 %p1, i256 %p2) nounwind {
140140
%ptr = alloca i256
141-
; CHECK: sub.s! stack-[1], r1, r1
141+
; CHECK: sub.s! stack-[1], r1, r0
142142
%data = load i256, i256* %ptr
143143
%1 = icmp ugt i256 %p1, %data
144144
br i1 %1, label %l1, label %l2
@@ -150,7 +150,7 @@ l2:
150150

151151
; CHECK-LABEL: cmpri
152152
define i256 @cmpri(i256 %p1, i256 %p2) nounwind {
153-
; CHECK: sub.s! 41, r1, r1
153+
; CHECK: sub.s! 41, r1, r0
154154
; CHECK-NEXT: add.gt 72, r0, r1
155155
; CHECK-NEXT: add.le 42, r0, r1
156156
; CHECK-NEXT: ret
@@ -164,7 +164,7 @@ l2:
164164

165165
; CHECK-LABEL: cmprc
166166
define i256 @cmprc(i256 %p1, i256 %p2) nounwind {
167-
; CHECK: sub! @val[0], r1, r{{[0-9]+}}
167+
; CHECK: sub! @val[0], r1, r0
168168
; CHECK-NEXT: add.le 72, r0, r1
169169
; CHECK-NEXT: add.gt 42, r0, r1
170170
; CHECK-NEXT: ret
@@ -180,7 +180,7 @@ l2:
180180
; CHECK-LABEL: cmprs
181181
define i256 @cmprs(i256 %p1, i256 %p2) nounwind {
182182
%ptr = alloca i256
183-
; CHECK: sub! stack-[1], r1, r{{[0-9]+}}
183+
; CHECK: sub! stack-[1], r1, r0
184184
%data = load i256, i256* %ptr
185185
%1 = icmp ugt i256 %data, %p1
186186
br i1 %1, label %l1, label %l2

llvm/test/CodeGen/EraVM/brcond.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ target triple = "eravm"
55

66
; CHECK-LABEL: brcond:
77
define i256 @brcond(i256 %p1) nounwind {
8-
; CHECK: and! 1, r1, r1
8+
; CHECK: and! 1, r1, r0
99
; CHECK-NEXT: add.eq 43, r0, r1
1010
; CHECK-NEXT: add.ne 42, r0, r1
1111
; CHECK-NEXT: ret

0 commit comments

Comments
 (0)