Skip to content

Commit 34d4f28

Browse files
committed
[CodeGen] Convert RISCV Init Undef pass to support any architecture
Currently this pass is designed for RISC-V only, however this is not the only architecture with the bug reported in issue #50157. We can convert the exisiting pass to be generic, using some of the existing Parent classes rather than RISC-V specific classes to bring the same functionality to other Architectures. The pass has been refactored, removing the RISC-V specific functions and data-types and replacing them with datatypes that will support all architectures and virtual functions in the respecitive classes that allow support for the pass to be added. By default, this pass will not run on on all architectures, only those that have the `supportsInitUndef` function impletmented. This commit will only refactor the exisiting code and add the pass in as a CodeGen pass rather than target specific. To add support for other architectures, this should be done in new, following commits. This will allow for the pass to be used by any architecture. With the correct overriding functions, other architectures can be supported to provide the same functionality as was added to fix issue that was reported in Issue #50157. This is still a temporary measure, and a better more permenant fix should be found, but for the time being this will allow for the correct early-clobber contraint to be followed when defined in vector instructions.
1 parent 0e16950 commit 34d4f28

29 files changed

+170
-108
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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,27 @@ class TargetRegisterInfo : public MCRegisterInfo {
11721172
virtual bool isNonallocatableRegisterCalleeSave(MCRegister Reg) const {
11731173
return false;
11741174
}
1175+
1176+
/// Returns the Register Class that is being initialized. There
1177+
/// should be a Pseudo Instruction for the different register
1178+
/// classes for the different register types that are introduced.
1179+
virtual const TargetRegisterClass *
1180+
getTargetRegisterClass(const TargetRegisterClass *RC) const {
1181+
llvm_unreachable("Unexpected target register class.");
1182+
}
1183+
1184+
/// Returns if the architecture being targeted has the required Pseudo
1185+
/// Instructions for initializing the register. By default this returns false,
1186+
/// but where it is overriden for an architecture, the behaviour will be
1187+
/// different. This can either be a check to ensure the Register Class is
1188+
/// present, or to return true as an indication the architecture supports the
1189+
/// pass. If using the method that does not check for the Register Class, it
1190+
/// is imperative to ensure all required Pseudo Instructions are implemented,
1191+
/// otherwise compilation may fail with an `Unexpected register class` error.
1192+
virtual bool
1193+
doesRegClassHavePseudoInitUndef(const TargetRegisterClass *RC) const {
1194+
return false;
1195+
}
11751196
};
11761197

11771198
//===----------------------------------------------------------------------===//

llvm/include/llvm/CodeGen/TargetSubtargetInfo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,14 @@ 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. This was originally used in RISC-V's Init
335+
/// Undef pass but has been moved to be a virtual function when the pass was
336+
/// refactored to support multiple architectures.
337+
virtual bool supportsInitUndef() const { return false; }
330338
};
331339

332340
} // end namespace llvm

llvm/include/llvm/InitializePasses.h

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

llvm/include/llvm/Passes/CodeGenPassBuilder.h

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

1035+
addPass(InitUndefPass());
1036+
10351037
addPass(ProcessImplicitDefsPass());
10361038

10371039
// 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)