Skip to content

Commit 2823340

Browse files
authored
[CodeGen] [ARM] Make RISC-V Init Undef Pass Target Independent and add support for the ARM Architecture. (#77770)
When using Greedy Register Allocation, there are times where early-clobber values are ignored, and assigned the same register. This is illeagal behaviour for these intructions. To get around this, using Pseudo instructions for early-clobber registers gives them a definition and allows Greedy to assign them to a different register. This then meets the ARM Architecture Reference Manual and matches the defined behaviour. This patch takes the existing RISC-V patch and makes it target independent, then adds support for the ARM Architecture. Doing this will ensure early-clobber restraints are followed when using the ARM Architecture. Making the pass target independent will also open up possibility that support other architectures can be added in the future.
1 parent 3d084e3 commit 2823340

38 files changed

+333
-171
lines changed

llvm/include/llvm/CodeGen/Passes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ namespace llvm {
196196
/// This pass reads flow sensitive profile.
197197
extern char &MIRProfileLoaderPassID;
198198

199+
// This pass gives undef values a Pseudo Instruction definition for
200+
// Instructions to ensure early-clobber is followed when using the greedy
201+
// register allocator.
202+
extern char &InitUndefID;
203+
199204
/// FastRegisterAllocation Pass - This pass register allocates as fast as
200205
/// possible. It is best suited for debug code where live ranges are short.
201206
///

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2223,6 +2223,15 @@ class TargetInstrInfo : public MCInstrInfo {
22232223
llvm_unreachable("unknown number of operands necessary");
22242224
}
22252225

2226+
/// Gets the opcode for the Pseudo Instruction used to initialize
2227+
/// the undef value. If no Instruction is available, this will
2228+
/// fail compilation.
2229+
virtual unsigned getUndefInitOpcode(unsigned RegClassID) const {
2230+
(void)RegClassID;
2231+
2232+
llvm_unreachable("Unexpected register class.");
2233+
}
2234+
22262235
private:
22272236
mutable std::unique_ptr<MIRFormatter> Formatter;
22282237
unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,28 @@ class TargetRegisterInfo : public MCRegisterInfo {
11721172
virtual bool isNonallocatableRegisterCalleeSave(MCRegister Reg) const {
11731173
return false;
11741174
}
1175+
1176+
/// Returns the Largest Super Class that is being initialized. There
1177+
/// should be a Pseudo Instruction implemented for the super class
1178+
/// that is being returned to ensure that Init Undef can apply the
1179+
/// initialization correctly.
1180+
virtual const TargetRegisterClass *
1181+
getLargestSuperClass(const TargetRegisterClass *RC) const {
1182+
llvm_unreachable("Unexpected target register class.");
1183+
}
1184+
1185+
/// Returns if the architecture being targeted has the required Pseudo
1186+
/// Instructions for initializing the register. By default this returns false,
1187+
/// but where it is overriden for an architecture, the behaviour will be
1188+
/// different. This can either be a check to ensure the Register Class is
1189+
/// present, or to return true as an indication the architecture supports the
1190+
/// pass. If using the method that does not check for the Register Class, it
1191+
/// is imperative to ensure all required Pseudo Instructions are implemented,
1192+
/// otherwise compilation may fail with an `Unexpected register class` error.
1193+
virtual bool
1194+
doesRegClassHavePseudoInitUndef(const TargetRegisterClass *RC) const {
1195+
return false;
1196+
}
11751197
};
11761198

11771199
//===----------------------------------------------------------------------===//

llvm/include/llvm/CodeGen/TargetSubtargetInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,12 @@ class TargetSubtargetInfo : public MCSubtargetInfo {
327327

328328
/// Get the list of MacroFusion predicates.
329329
virtual std::vector<MacroFusionPredTy> getMacroFusions() const { return {}; };
330+
331+
/// supportsInitUndef is used to determine if an architecture supports
332+
/// the Init Undef Pass. By default, it is assumed that it will not support
333+
/// the pass, with architecture specific overrides providing the information
334+
/// where they are implemented.
335+
virtual bool supportsInitUndef() const { return false; }
330336
};
331337

332338
} // end namespace llvm

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ void initializeTLSVariableHoistLegacyPassPass(PassRegistry &);
300300
void initializeTwoAddressInstructionPassPass(PassRegistry&);
301301
void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
302302
void initializeTypePromotionLegacyPass(PassRegistry&);
303+
void initializeInitUndefPass(PassRegistry &);
303304
void initializeUniformityInfoWrapperPassPass(PassRegistry &);
304305
void initializeUnifyLoopExitsLegacyPassPass(PassRegistry &);
305306
void initializeUnpackMachineBundlesPass(PassRegistry&);

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,8 @@ void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
10661066
AddMachinePass &addPass) const {
10671067
addPass(DetectDeadLanesPass());
10681068

1069+
addPass(InitUndefPass());
1070+
10691071
addPass(ProcessImplicitDefsPass());
10701072

10711073
// Edge splitting is smarter with machine loop info.

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ DUMMY_MACHINE_FUNCTION_PASS("fs-profile-loader", MIRProfileLoaderNewPass)
173173
DUMMY_MACHINE_FUNCTION_PASS("funclet-layout", FuncletLayoutPass)
174174
DUMMY_MACHINE_FUNCTION_PASS("gc-empty-basic-blocks", GCEmptyBasicBlocksPass)
175175
DUMMY_MACHINE_FUNCTION_PASS("implicit-null-checks", ImplicitNullChecksPass)
176+
DUMMY_MACHINE_FUNCTION_PASS("init-undef-pass", InitUndefPass)
176177
DUMMY_MACHINE_FUNCTION_PASS("instruction-select", InstructionSelectPass)
177178
DUMMY_MACHINE_FUNCTION_PASS("irtranslator", IRTranslatorPass)
178179
DUMMY_MACHINE_FUNCTION_PASS("kcfi", MachineKCFIPass)

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ add_llvm_component_library(LLVMCodeGen
7575
IfConversion.cpp
7676
ImplicitNullChecks.cpp
7777
IndirectBrExpandPass.cpp
78+
InitUndef.cpp
7879
InlineSpiller.cpp
7980
InterferenceCache.cpp
8081
InterleavedAccessPass.cpp

llvm/lib/CodeGen/CodeGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
5454
initializeIfConverterPass(Registry);
5555
initializeImplicitNullChecksPass(Registry);
5656
initializeIndirectBrExpandLegacyPassPass(Registry);
57+
initializeInitUndefPass(Registry);
5758
initializeInterleavedLoadCombinePass(Registry);
5859
initializeInterleavedAccessPass(Registry);
5960
initializeJMCInstrumenterPass(Registry);

0 commit comments

Comments
 (0)