Skip to content

Commit ef9ee46

Browse files
author
Mikhail Gudim
committed
[RISCV][WIP] Let RA do the CSR saves.
We turn the problem of saving and restoring callee-saved registers efficiently into a register allocation problem. This has the advantage that the register allocator can essentialy do shrink-wrapping on per register basis. Currently, shrink-wrapping pass saves all CSR in the same place which may be suboptimal. Also, improvements to register allocation / coalescing will translate to improvements in shrink-wrapping. In finalizeLowering() we copy all callee-saved registers from a physical register to a virtual one. In all return blocks we copy do the reverse.
1 parent 28731f5 commit ef9ee46

25 files changed

+775
-187
lines changed

llvm/include/llvm/CodeGen/ReachingDefAnalysis.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,11 @@ class ReachingDefAnalysis : public MachineFunctionPass {
114114
private:
115115
MachineFunction *MF = nullptr;
116116
const TargetRegisterInfo *TRI = nullptr;
117+
const TargetInstrInfo *TII = nullptr;
117118
LoopTraversal::TraversalOrder TraversedMBBOrder;
118119
unsigned NumRegUnits = 0;
120+
unsigned NumStackObjects = 0;
121+
int ObjectIndexBegin = 0;
119122
/// Instruction that defined each register, relative to the beginning of the
120123
/// current basic block. When a LiveRegsDefInfo is used to represent a
121124
/// live-out register, this value is relative to the end of the basic block,
@@ -138,6 +141,9 @@ class ReachingDefAnalysis : public MachineFunctionPass {
138141
DenseMap<MachineInstr *, int> InstIds;
139142

140143
MBBReachingDefsInfo MBBReachingDefs;
144+
using MBBFrameObjsReachingDefsInfo =
145+
std::vector<std::vector<std::vector<int>>>;
146+
MBBFrameObjsReachingDefsInfo MBBFrameObjsReachingDefs;
141147

142148
/// Default values are 'nothing happened a long time ago'.
143149
const int ReachingDefDefaultVal = -(1 << 21);

llvm/include/llvm/CodeGen/TargetFrameLowering.h

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ namespace llvm {
2424
class CalleeSavedInfo;
2525
class MachineFunction;
2626
class RegScavenger;
27-
28-
namespace TargetStackID {
29-
enum Value {
30-
Default = 0,
31-
SGPRSpill = 1,
32-
ScalableVector = 2,
33-
WasmLocal = 3,
34-
NoAlloc = 255
35-
};
27+
class ReachingDefAnalysis;
28+
29+
namespace TargetStackID {
30+
enum Value {
31+
Default = 0,
32+
SGPRSpill = 1,
33+
ScalableVector = 2,
34+
WasmLocal = 3,
35+
NoAlloc = 255
36+
};
3637
}
3738

3839
/// Information about stack frame layout on the target. It holds the direction
@@ -210,6 +211,11 @@ class TargetFrameLowering {
210211
/// for noreturn nounwind functions.
211212
virtual bool enableCalleeSaveSkip(const MachineFunction &MF) const;
212213

214+
virtual void emitCFIsForCSRsHandledByRA(MachineFunction &MF,
215+
ReachingDefAnalysis *RDA) const {
216+
return;
217+
}
218+
213219
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
214220
/// the function.
215221
virtual void emitPrologue(MachineFunction &MF,

llvm/include/llvm/CodeGen/TargetSubtargetInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ class TargetSubtargetInfo : public MCSubtargetInfo {
328328
return false;
329329
}
330330

331+
virtual bool doCSRSavesInRA() const;
332+
331333
/// Classify a global function reference. This mainly used to fetch target
332334
/// special flags for lowering a function address. For example mark a function
333335
/// call should be plt or pc-related addressing.

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ class UnwindLocation {
7474
bool Dereference; /// If true, the resulting location must be dereferenced
7575
/// after the location value is computed.
7676

77-
// Constructors are private to force people to use the create static
78-
// functions.
77+
public:
7978
UnwindLocation(Location K)
8079
: Kind(K), RegNum(InvalidRegisterNumber), Offset(0),
8180
AddrSpace(std::nullopt), Dereference(false) {}
@@ -88,7 +87,6 @@ class UnwindLocation {
8887
: Kind(DWARFExpr), RegNum(InvalidRegisterNumber), Offset(0), Expr(E),
8988
Dereference(Deref) {}
9089

91-
public:
9290
/// Create a location whose rule is set to Unspecified. This means the
9391
/// register value might be in the same register but it wasn't specified in
9492
/// the unwind opcodes.
@@ -135,6 +133,7 @@ class UnwindLocation {
135133
assert(Kind == RegPlusOffset && AddrSpace);
136134
return *AddrSpace;
137135
}
136+
bool getDeref() const { return Dereference; }
138137
int32_t getConstant() const { return Offset; }
139138
/// Some opcodes will modify the CFA location's register only, so we need
140139
/// to be able to modify the CFA register when evaluating DWARF Call Frame
@@ -148,6 +147,11 @@ class UnwindLocation {
148147
/// the constant value (DW_CFA_GNU_window_save which is also known as
149148
// DW_CFA_AARCH64_negate_ra_state).
150149
void setConstant(int32_t Value) { Offset = Value; }
150+
void setDeref(bool NewDeref) { Dereference = NewDeref; }
151+
void setKind(Location NewKind) { Kind = NewKind; }
152+
bool isRegister() const {
153+
return ((Kind == RegPlusOffset) && !Dereference && (Offset == 0));
154+
}
151155

152156
std::optional<DWARFExpression> getDWARFExpressionBytes() const {
153157
return Expr;

llvm/include/llvm/MC/MCDwarf.h

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "llvm/ADT/MapVector.h"
1818
#include "llvm/ADT/SmallVector.h"
19+
#include "llvm/ADT/SmallString.h"
1920
#include "llvm/ADT/StringMap.h"
2021
#include "llvm/ADT/StringRef.h"
2122
#include "llvm/MC/StringTableBuilder.h"
@@ -504,6 +505,7 @@ class MCCFIInstruction {
504505
OpRestoreState,
505506
OpOffset,
506507
OpLLVMDefAspaceCfa,
508+
OpLLVMRegOffset,
507509
OpDefCfaRegister,
508510
OpDefCfaOffset,
509511
OpDefCfa,
@@ -518,7 +520,7 @@ class MCCFIInstruction {
518520
OpNegateRAStateWithPC,
519521
OpGnuArgsSize,
520522
OpLabel,
521-
OpValOffset,
523+
OpValOffset
522524
};
523525

524526
private:
@@ -537,6 +539,11 @@ class MCCFIInstruction {
537539
unsigned Register;
538540
unsigned Register2;
539541
} RR;
542+
struct {
543+
unsigned Register;
544+
unsigned Register2;
545+
int64_t Offset;
546+
} RRO;
540547
MCSymbol *CfiLabel;
541548
} U;
542549
OpType Operation;
@@ -569,6 +576,13 @@ class MCCFIInstruction {
569576
U.CfiLabel = CfiLabel;
570577
}
571578

579+
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, unsigned R2, int64_t O,
580+
SMLoc Loc, StringRef V, StringRef Comment = "")
581+
: Label(L), Operation(Op), Loc(Loc), Values(V.begin(), V.end()), Comment(Comment) {
582+
assert(Op == OpLLVMRegOffset);
583+
U.RRO = {R, R2, O};
584+
}
585+
572586
public:
573587
/// .cfi_def_cfa defines a rule for computing CFA as: take address from
574588
/// Register and add Offset to it.
@@ -707,6 +721,15 @@ class MCCFIInstruction {
707721
return MCCFIInstruction(OpValOffset, L, Register, Offset, Loc);
708722
}
709723

724+
static void createRegOffsetExpression(unsigned Reg, unsigned FrameReg, int64_t Offset, SmallString<64>& CFAExpr);
725+
static MCCFIInstruction createLLVMRegOffset(MCSymbol *L, unsigned Reg, unsigned FrameReg,
726+
int64_t Offset, SMLoc Loc = {}, StringRef Comment = "") {
727+
// Build up the expression (FrameRegister + Offset)
728+
SmallString<64> CFAExpr;
729+
createRegOffsetExpression(Reg, FrameReg, Offset, CFAExpr);
730+
return MCCFIInstruction(OpLLVMRegOffset, L, Reg, FrameReg, Offset, Loc, CFAExpr, Comment);
731+
}
732+
710733
OpType getOperation() const { return Operation; }
711734
MCSymbol *getLabel() const { return Label; }
712735

@@ -715,6 +738,8 @@ class MCCFIInstruction {
715738
return U.RR.Register;
716739
if (Operation == OpLLVMDefAspaceCfa)
717740
return U.RIA.Register;
741+
if (Operation == OpLLVMRegOffset)
742+
return U.RRO.Register;
718743
assert(Operation == OpDefCfa || Operation == OpOffset ||
719744
Operation == OpRestore || Operation == OpUndefined ||
720745
Operation == OpSameValue || Operation == OpDefCfaRegister ||
@@ -723,8 +748,10 @@ class MCCFIInstruction {
723748
}
724749

725750
unsigned getRegister2() const {
726-
assert(Operation == OpRegister);
727-
return U.RR.Register2;
751+
if (Operation == OpRegister)
752+
return U.RR.Register2;
753+
assert (Operation == OpLLVMRegOffset);
754+
return U.RRO.Register2;
728755
}
729756

730757
unsigned getAddressSpace() const {
@@ -735,6 +762,8 @@ class MCCFIInstruction {
735762
int64_t getOffset() const {
736763
if (Operation == OpLLVMDefAspaceCfa)
737764
return U.RIA.Offset;
765+
if (Operation == OpLLVMRegOffset)
766+
return U.RRO.Offset;
738767
assert(Operation == OpDefCfa || Operation == OpOffset ||
739768
Operation == OpRelOffset || Operation == OpDefCfaOffset ||
740769
Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize ||
@@ -748,7 +777,7 @@ class MCCFIInstruction {
748777
}
749778

750779
StringRef getValues() const {
751-
assert(Operation == OpEscape);
780+
assert(Operation == OpEscape || Operation == OpLLVMRegOffset);
752781
return StringRef(&Values[0], Values.size());
753782
}
754783

llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
223223
OutStreamer->emitCFILLVMDefAspaceCfa(Inst.getRegister(), Inst.getOffset(),
224224
Inst.getAddressSpace(), Loc);
225225
break;
226+
case MCCFIInstruction::OpLLVMRegOffset:
227+
OutStreamer->AddComment(Inst.getComment());
228+
OutStreamer->emitCFIEscape(Inst.getValues(), Loc);
229+
break;
226230
case MCCFIInstruction::OpOffset:
227231
OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset(), Loc);
228232
break;

0 commit comments

Comments
 (0)