Skip to content

Commit b67a200

Browse files
committed
fixup! [SPARC] Support reserving arbitrary general purpose registers
1 parent 490e64b commit b67a200

File tree

4 files changed

+46
-26
lines changed

4 files changed

+46
-26
lines changed

llvm/lib/Target/Sparc/SparcISelLowering.cpp

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

1414
#include "SparcISelLowering.h"
1515
#include "MCTargetDesc/SparcMCExpr.h"
16+
#include "MCTargetDesc/SparcMCTargetDesc.h"
1617
#include "SparcMachineFunctionInfo.h"
1718
#include "SparcRegisterInfo.h"
1819
#include "SparcTargetMachine.h"
@@ -28,6 +29,7 @@
2829
#include "llvm/CodeGen/SelectionDAGNodes.h"
2930
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
3031
#include "llvm/IR/DerivedTypes.h"
32+
#include "llvm/IR/DiagnosticInfo.h"
3133
#include "llvm/IR/Function.h"
3234
#include "llvm/IR/Module.h"
3335
#include "llvm/Support/ErrorHandling.h"
@@ -729,6 +731,30 @@ SDValue SparcTargetLowering::LowerFormalArguments_64(
729731
return Chain;
730732
}
731733

734+
// Check whether any of the argument registers are reserved
735+
static bool isAnyArgRegReserved(const SparcRegisterInfo *TRI,
736+
const MachineFunction &MF) {
737+
// The register window design means that outgoing parameters at O*
738+
// will appear in the callee as I*.
739+
// Be conservative and check both sides of the register names.
740+
bool Outgoing =
741+
llvm::any_of(SP::GPROutgoingArgRegClass, [TRI, &MF](MCPhysReg r) {
742+
return TRI->isReservedReg(MF, r);
743+
});
744+
bool Incoming =
745+
llvm::any_of(SP::GPRIncomingArgRegClass, [TRI, &MF](MCPhysReg r) {
746+
return TRI->isReservedReg(MF, r);
747+
});
748+
return Outgoing || Incoming;
749+
}
750+
751+
static void emitReservedArgRegCallError(const MachineFunction &MF) {
752+
const Function &F = MF.getFunction();
753+
F.getContext().diagnose(DiagnosticInfoUnsupported{
754+
F, ("SPARC doesn't support"
755+
" function calls if any of the argument registers is reserved.")});
756+
}
757+
732758
SDValue
733759
SparcTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
734760
SmallVectorImpl<SDValue> &InVals) const {
@@ -1057,8 +1083,8 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
10571083
? TRI->getRTCallPreservedMask(CallConv)
10581084
: TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv));
10591085

1060-
if (TRI->isAnyArgRegReserved(MF))
1061-
TRI->emitReservedArgRegCallError(MF);
1086+
if (isAnyArgRegReserved(TRI, MF))
1087+
emitReservedArgRegCallError(MF);
10621088

10631089
assert(Mask && "Missing call preserved mask for calling convention");
10641090
Ops.push_back(DAG.getRegisterMask(Mask));
@@ -1130,6 +1156,9 @@ Register SparcTargetLowering::getRegisterByName(const char* RegName, LLT VT,
11301156
.Case("g4", SP::G4).Case("g5", SP::G5).Case("g6", SP::G6).Case("g7", SP::G7)
11311157
.Default(0);
11321158

1159+
// If we're directly referencing register names
1160+
// (e.g in GCC C extension `register int r asm("g1");`),
1161+
// make sure that said register is in the reserve list.
11331162
const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo();
11341163
if (!TRI->isReservedReg(MF, Reg))
11351164
Reg = 0;
@@ -1383,8 +1412,8 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
13831412
: TRI->getCallPreservedMask(DAG.getMachineFunction(),
13841413
CLI.CallConv));
13851414

1386-
if (TRI->isAnyArgRegReserved(MF))
1387-
TRI->emitReservedArgRegCallError(MF);
1415+
if (isAnyArgRegReserved(TRI, MF))
1416+
emitReservedArgRegCallError(MF);
13881417

13891418
assert(Mask && "Missing call preserved mask for calling convention");
13901419
Ops.push_back(DAG.getRegisterMask(Mask));

llvm/lib/Target/Sparc/SparcRegisterInfo.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414
#include "Sparc.h"
1515
#include "SparcSubtarget.h"
1616
#include "llvm/ADT/BitVector.h"
17-
#include "llvm/ADT/STLExtras.h"
1817
#include "llvm/CodeGen/MachineFrameInfo.h"
1918
#include "llvm/CodeGen/MachineFunction.h"
2019
#include "llvm/CodeGen/MachineInstrBuilder.h"
2120
#include "llvm/CodeGen/TargetInstrInfo.h"
22-
#include "llvm/IR/DiagnosticInfo.h"
2321
#include "llvm/IR/Type.h"
2422
#include "llvm/Support/CommandLine.h"
2523
#include "llvm/Support/ErrorHandling.h"
@@ -126,24 +124,6 @@ bool SparcRegisterInfo::isReservedReg(const MachineFunction &MF,
126124
return getReservedRegs(MF)[Reg];
127125
}
128126

129-
bool SparcRegisterInfo::isAnyArgRegReserved(const MachineFunction &MF) const {
130-
bool Outgoing =
131-
llvm::any_of(SP::GPROutgoingArgRegClass,
132-
[this, &MF](MCPhysReg r) { return isReservedReg(MF, r); });
133-
bool Incoming =
134-
llvm::any_of(SP::GPRIncomingArgRegClass,
135-
[this, &MF](MCPhysReg r) { return isReservedReg(MF, r); });
136-
return Outgoing || Incoming;
137-
}
138-
139-
void SparcRegisterInfo::emitReservedArgRegCallError(
140-
const MachineFunction &MF) const {
141-
const Function &F = MF.getFunction();
142-
F.getContext().diagnose(DiagnosticInfoUnsupported{
143-
F, ("SPARC doesn't support"
144-
" function calls if any of the argument registers is reserved.")});
145-
}
146-
147127
const TargetRegisterClass*
148128
SparcRegisterInfo::getPointerRegClass(const MachineFunction &MF,
149129
unsigned Kind) const {

llvm/lib/Target/Sparc/SparcRegisterInfo.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo {
3131

3232
BitVector getReservedRegs(const MachineFunction &MF) const override;
3333
bool isReservedReg(const MachineFunction &MF, MCRegister Reg) const;
34-
bool isAnyArgRegReserved(const MachineFunction &MF) const;
35-
void emitReservedArgRegCallError(const MachineFunction &MF) const;
3634

3735
const TargetRegisterClass *getPointerRegClass(const MachineFunction &MF,
3836
unsigned Kind) const override;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: llc -mtriple=sparc64-linux-gnu -mattr=+reserve-l0 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVED-L0
2+
3+
;; Ensure explicit register references are catched as well.
4+
5+
; CHECK-RESERVED-L0: %l0
6+
define void @set_reg(i32 zeroext %x) {
7+
entry:
8+
tail call void @llvm.write_register.i32(metadata !0, i32 %x)
9+
ret void
10+
}
11+
12+
declare void @llvm.write_register.i32(metadata, i32)
13+
!0 = !{!"l0"}

0 commit comments

Comments
 (0)