Skip to content

Commit bf37fab

Browse files
committed
Retry memory folding after SSA is lost to optimize certain pseudos.
1 parent 8338aa8 commit bf37fab

File tree

5 files changed

+129
-0
lines changed

5 files changed

+129
-0
lines changed

llvm/lib/Target/Z80/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ set(sources
3333
Z80MCInstLower.cpp
3434
Z80MachineEarlyOptimization.cpp
3535
Z80MachineLateOptimization.cpp
36+
Z80MachinePreRAOptimization.cpp
3637
Z80PostSelectCombiner.cpp
3738
Z80RegisterInfo.cpp
3839
Z80Subtarget.cpp

llvm/lib/Target/Z80/Z80.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ InstructionSelector *createZ80InstructionSelector(const Z80TargetMachine &TM,
3131
Z80RegisterBankInfo &);
3232
FunctionPass *createZ80PostSelectCombiner();
3333
FunctionPass *createZ80MachineEarlyOptimizationPass();
34+
FunctionPass *createZ80MachinePreRAOptimizationPass();
3435
FunctionPass *createZ80MachineLateOptimizationPass();
3536

3637
void initializeZ80PreLegalizerCombinerPass(PassRegistry &);
3738
void initializeZ80PostLegalizerCombinerPass(PassRegistry &);
3839
void initializeZ80PostSelectCombinerPass(PassRegistry &);
3940
void initializeZ80MachineEarlyOptimizationPass(PassRegistry &);
41+
void initializeZ80MachinePreRAOptimizationPass(PassRegistry &);
4042
void initializeZ80MachineLateOptimizationPass(PassRegistry &);
4143

4244
} // namespace llvm

llvm/lib/Target/Z80/Z80InstrInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,6 +1744,7 @@ MachineInstr *Z80InstrInfo::foldMemoryOperandImpl(
17441744
case Z80::XOR8ar: Opc = IsOff ? Z80::XOR8ao : Z80::XOR8ap; break;
17451745
case Z80:: OR8ar: Opc = IsOff ? Z80:: OR8ao : Z80:: OR8ap; break;
17461746
case Z80::TST8ar: Opc = IsOff ? Z80::TST8ao : Z80::TST8ap; break;
1747+
case TargetOpcode::COPY: Opc = IsOff ? Z80::LD8ro : Z80::LD8rp; break;
17471748
default: return nullptr;
17481749
}
17491750

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//=== lib/Target/Z80/Z80MachinePreRAOptimization.cpp ----------------------===//
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 does combining of machine instructions at the generic MI level,
10+
// before register allocation.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "MCTargetDesc/Z80MCTargetDesc.h"
15+
#include "Z80.h"
16+
#include "Z80InstrInfo.h"
17+
#include "llvm/CodeGen/LiveRegUnits.h"
18+
#include "llvm/CodeGen/MachineDominators.h"
19+
#include "llvm/CodeGen/TargetInstrInfo.h"
20+
#include "llvm/CodeGen/TargetRegisterInfo.h"
21+
#include "llvm/CodeGen/TargetSubtargetInfo.h"
22+
#include "llvm/IR/Constants.h"
23+
#include "llvm/Support/Debug.h"
24+
25+
#define DEBUG_TYPE "z80-machine-prera-opt"
26+
27+
using namespace llvm;
28+
29+
namespace {
30+
class Z80MachinePreRAOptimization : public MachineFunctionPass {
31+
public:
32+
static char ID;
33+
34+
Z80MachinePreRAOptimization() : MachineFunctionPass(ID) {}
35+
36+
StringRef getPassName() const override {
37+
return "Z80 Machine Pre-RA Optimization";
38+
}
39+
40+
bool runOnMachineFunction(MachineFunction &MF) override;
41+
};
42+
} // end anonymous namespace
43+
44+
bool Z80MachinePreRAOptimization::runOnMachineFunction(MachineFunction &MF) {
45+
bool Changed = false;
46+
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
47+
MachineRegisterInfo &MRI = MF.getRegInfo();
48+
SmallSet<Register, 16> FoldAsLoadDefCandidates;
49+
50+
for (MachineBasicBlock &MBB : MF) {
51+
for (auto MII = MBB.begin(), MIE = MBB.end(); MII != MIE;) {
52+
MachineInstr *MI = &*MII;
53+
++MII;
54+
55+
if (MI->canFoldAsLoad() && MI->mayLoad() &&
56+
MI->getNumExplicitDefs() == 1) {
57+
MachineOperand &DefMO = MI->getOperand(0);
58+
if (DefMO.isReg()) {
59+
Register DefReg = DefMO.getReg();
60+
if (DefReg.isVirtual() && !DefMO.getSubReg() &&
61+
MRI.hasOneNonDBGUser(DefReg)) {
62+
FoldAsLoadDefCandidates.insert(DefReg);
63+
continue;
64+
}
65+
}
66+
}
67+
68+
if (!FoldAsLoadDefCandidates.empty()) {
69+
for (MachineOperand &MO : MI->operands()) {
70+
if (!MO.isReg())
71+
continue;
72+
Register Reg = MO.getReg();
73+
if (MO.isDef()) {
74+
FoldAsLoadDefCandidates.erase(Reg);
75+
continue;
76+
}
77+
if (!FoldAsLoadDefCandidates.count(Reg))
78+
continue;
79+
MachineInstr *DefMI = nullptr;
80+
Register FoldAsLoadDefReg = Reg;
81+
if (MachineInstr *FoldMI =
82+
TII.optimizeLoadInstr(*MI, &MRI, FoldAsLoadDefReg, DefMI)) {
83+
// Update LocalMIs since we replaced MI with FoldMI and deleted
84+
// DefMI.
85+
LLVM_DEBUG(dbgs() << "Replacing: " << *MI);
86+
LLVM_DEBUG(dbgs() << " With: " << *FoldMI);
87+
// Update the call site info.
88+
if (MI->shouldUpdateCallSiteInfo())
89+
MF.moveCallSiteInfo(MI, FoldMI);
90+
MI->eraseFromParent();
91+
DefMI->eraseFromParent();
92+
MRI.markUsesInDebugValueAsUndef(Reg);
93+
FoldAsLoadDefCandidates.erase(Reg);
94+
95+
// MI is replaced with FoldMI so we can continue trying to fold
96+
Changed = true;
97+
MI = FoldMI;
98+
}
99+
}
100+
}
101+
102+
if (MI->isLoadFoldBarrier()) {
103+
LLVM_DEBUG(dbgs() << "Encountered load fold barrier on " << *MI);
104+
FoldAsLoadDefCandidates.clear();
105+
}
106+
}
107+
}
108+
return Changed;
109+
}
110+
111+
char Z80MachinePreRAOptimization::ID = 0;
112+
INITIALIZE_PASS(Z80MachinePreRAOptimization, DEBUG_TYPE,
113+
"Optimize Z80 machine instrs before regalloc", false, false)
114+
115+
namespace llvm {
116+
FunctionPass *createZ80MachinePreRAOptimizationPass() {
117+
return new Z80MachinePreRAOptimization();
118+
}
119+
} // end namespace llvm

llvm/lib/Target/Z80/Z80TargetMachine.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class Z80PassConfig : public TargetPassConfig {
148148
bool addGlobalInstructionSelect() override;
149149
void addMachineSSAOptimization() override;
150150
void addFastRegAlloc() override;
151+
bool addRegAssignAndRewriteOptimized() override;
151152
void addMachineLateOptimization() override;
152153

153154
std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
@@ -205,6 +206,11 @@ void Z80PassConfig::addFastRegAlloc() {
205206
TargetPassConfig::addFastRegAlloc();
206207
}
207208

209+
bool Z80PassConfig::addRegAssignAndRewriteOptimized() {
210+
addPass(createZ80MachinePreRAOptimizationPass());
211+
return TargetPassConfig::addRegAssignAndRewriteOptimized();
212+
}
213+
208214
void Z80PassConfig::addMachineLateOptimization() {
209215
TargetPassConfig::addMachineLateOptimization();
210216
addPass(createZ80MachineLateOptimizationPass());

0 commit comments

Comments
 (0)