Skip to content

Commit

Permalink
[SystemZ, RegAlloc] Favor 3-address instructions during instruction s…
Browse files Browse the repository at this point in the history
…election.

This patch aims to reduce spilling and register moves by using the 3-address
versions of instructions per default instead of the 2-address equivalent
ones. It seems that both spilling and register moves are improved noticeably
generally.

Regalloc hints are passed to increase conversions to 2-address instructions
which are done in SystemZShortenInst.cpp (after regalloc).

Since the SystemZ reg/mem instructions are 2-address (dst and lhs regs are
the same), foldMemoryOperandImpl() can no longer trivially fold a spilled
source register since the reg/reg instruction is now 3-address. In order to
remedy this, new 3-address pseudo memory instructions are used to perform the
folding only when the dst and lhs virtual registers are known to be allocated
to the same physreg. In order to not let MachineCopyPropagation run and
change registers on these transformed instructions (making it 3-address), a
new target pass called SystemZPostRewrite.cpp is run just after
VirtRegRewriter, that immediately lowers the pseudo to a target instruction.

If it would have been possibe to insert a COPY instruction and change a
register operand (convert to 2-address) in foldMemoryOperandImpl() while
trusting that the caller (e.g. InlineSpiller) would update/repair the
involved LiveIntervals, the solution involving pseudo instructions would not
have been needed. This is perhaps a potential improvement (see Phabricator
post).

Common code changes:

* A new hook TargetPassConfig::addPostRewrite() is utilized to be able to run a
target pass immediately before MachineCopyPropagation.

* VirtRegMap is passed as an argument to foldMemoryOperand().

Review: Ulrich Weigand, Quentin Colombet
https://reviews.llvm.org/D60888

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362868 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
JonPsson committed Jun 8, 2019
1 parent 878711a commit ff136c7
Show file tree
Hide file tree
Showing 26 changed files with 515 additions and 217 deletions.
9 changes: 7 additions & 2 deletions include/llvm/CodeGen/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineOutliner.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/ErrorHandling.h"
Expand Down Expand Up @@ -932,9 +933,12 @@ class TargetInstrInfo : public MCInstrInfo {
/// operand folded, otherwise NULL is returned.
/// The new instruction is inserted before MI, and the client is responsible
/// for removing the old instruction.
/// If VRM is passed, the assigned physregs can be inspected by target to
/// decide on using an opcode (note that those assignments can still change).
MachineInstr *foldMemoryOperand(MachineInstr &MI, ArrayRef<unsigned> Ops,
int FI,
LiveIntervals *LIS = nullptr) const;
LiveIntervals *LIS = nullptr,
VirtRegMap *VRM = nullptr) const;

/// Same as the previous version except it allows folding of any load and
/// store from / to any address, not just from a specific stack slot.
Expand Down Expand Up @@ -1024,7 +1028,8 @@ class TargetInstrInfo : public MCInstrInfo {
foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
ArrayRef<unsigned> Ops,
MachineBasicBlock::iterator InsertPt, int FrameIndex,
LiveIntervals *LIS = nullptr) const {
LiveIntervals *LIS = nullptr,
VirtRegMap *VRM = nullptr) const {
return nullptr;
}

Expand Down
4 changes: 4 additions & 0 deletions include/llvm/CodeGen/TargetPassConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ class TargetPassConfig : public ImmutablePass {
return false;
}

/// Add passes to be run immediately after virtual registers are rewritten
/// to physical registers.
virtual void addPostRewrite() { }

/// This method may be implemented by targets that want to run passes after
/// register allocation pass pipeline but before prolog-epilog insertion.
virtual void addPostRegAlloc() { }
Expand Down
2 changes: 1 addition & 1 deletion lib/CodeGen/InlineSpiller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,

MachineInstr *FoldMI =
LoadMI ? TII.foldMemoryOperand(*MI, FoldOps, *LoadMI, &LIS)
: TII.foldMemoryOperand(*MI, FoldOps, StackSlot, &LIS);
: TII.foldMemoryOperand(*MI, FoldOps, StackSlot, &LIS, &VRM);
if (!FoldMI)
return false;

Expand Down
5 changes: 3 additions & 2 deletions lib/CodeGen/TargetInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,8 @@ static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,

MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineInstr &MI,
ArrayRef<unsigned> Ops, int FI,
LiveIntervals *LIS) const {
LiveIntervals *LIS,
VirtRegMap *VRM) const {
auto Flags = MachineMemOperand::MONone;
for (unsigned OpIdx : Ops)
Flags |= MI.getOperand(OpIdx).isDef() ? MachineMemOperand::MOStore
Expand Down Expand Up @@ -570,7 +571,7 @@ MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineInstr &MI,
MBB->insert(MI, NewMI);
} else {
// Ask the target to do the actual folding.
NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, FI, LIS);
NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, FI, LIS, VRM);
}

if (NewMI) {
Expand Down
4 changes: 4 additions & 0 deletions lib/CodeGen/TargetPassConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,10 @@ void TargetPassConfig::addOptimizedRegAlloc() {
addPass(&MachineSchedulerID);

if (addRegAssignmentOptimized()) {
// Allow targets to expand pseudo instructions depending on the choice of
// registers before MachineCopyPropagation.
addPostRewrite();

// Copy propagate to forward register uses and try to eliminate COPYs that
// were not coalesced.
addPass(&MachineCopyPropagationID);
Expand Down
2 changes: 1 addition & 1 deletion lib/Target/AArch64/AArch64InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3049,7 +3049,7 @@ void llvm::emitFrameOffset(MachineBasicBlock &MBB,
MachineInstr *AArch64InstrInfo::foldMemoryOperandImpl(
MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,
MachineBasicBlock::iterator InsertPt, int FrameIndex,
LiveIntervals *LIS) const {
LiveIntervals *LIS, VirtRegMap *VRM) const {
// This is a bit of a hack. Consider this instruction:
//
// %0 = COPY %sp; GPR64all:%0
Expand Down
3 changes: 2 additions & 1 deletion lib/Target/AArch64/AArch64InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
ArrayRef<unsigned> Ops,
MachineBasicBlock::iterator InsertPt, int FrameIndex,
LiveIntervals *LIS = nullptr) const override;
LiveIntervals *LIS = nullptr,
VirtRegMap *VRM = nullptr) const override;

/// \returns true if a branch from an instruction with opcode \p BranchOpc
/// bytes is capable of jumping to a position \p BrOffset bytes away.
Expand Down
1 change: 1 addition & 0 deletions lib/Target/SystemZ/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ add_llvm_target(SystemZCodeGen
SystemZMCInstLower.cpp
SystemZRegisterInfo.cpp
SystemZSelectionDAGInfo.cpp
SystemZPostRewrite.cpp
SystemZShortenInst.cpp
SystemZSubtarget.cpp
SystemZTargetMachine.cpp
Expand Down
1 change: 1 addition & 0 deletions lib/Target/SystemZ/SystemZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ FunctionPass *createSystemZExpandPseudoPass(SystemZTargetMachine &TM);
FunctionPass *createSystemZShortenInstPass(SystemZTargetMachine &TM);
FunctionPass *createSystemZLongBranchPass(SystemZTargetMachine &TM);
FunctionPass *createSystemZLDCleanupPass(SystemZTargetMachine &TM);
FunctionPass *createSystemZPostRewritePass(SystemZTargetMachine &TM);
FunctionPass *createSystemZTDCPass();
} // end namespace llvm

Expand Down
Loading

0 comments on commit ff136c7

Please sign in to comment.