Index: include/llvm/CodeGen/MachineFunction.h =================================================================== --- include/llvm/CodeGen/MachineFunction.h +++ include/llvm/CodeGen/MachineFunction.h @@ -105,8 +105,8 @@ // that the property hold, but not that it does not hold. // Property descriptions: - // IsSSA (currently unused, intended to eventually replace - // MachineRegisterInfo::isSSA()) + // IsSSA: True when the machine function is in SSA form and virtual registers + // have a single def. // TracksLiveness: (currently unsued, intended to eventually replace // MachineRegisterInfo::tracksLiveness()) // AllVRegsAllocated: All virtual registers have been allocated; i.e. all Index: include/llvm/CodeGen/MachineRegisterInfo.h =================================================================== --- include/llvm/CodeGen/MachineRegisterInfo.h +++ include/llvm/CodeGen/MachineRegisterInfo.h @@ -43,10 +43,6 @@ const MachineFunction *MF; Delegate *TheDelegate; - /// IsSSA - True when the machine function is in SSA form and virtual - /// registers have a single def. - bool IsSSA; - /// TracksLiveness - True while register liveness is being tracked accurately. /// Basic block live-in lists, kill flags, and implicit defs may not be /// accurate when after this flag is cleared. @@ -153,18 +149,6 @@ // Function State //===--------------------------------------------------------------------===// - // isSSA - Returns true when the machine function is in SSA form. Early - // passes require the machine function to be in SSA form where every virtual - // register has a single defining instruction. - // - // The TwoAddressInstructionPass and PHIElimination passes take the machine - // function out of SSA form when they introduce multiple defs per virtual - // register. - bool isSSA() const { return IsSSA; } - - // leaveSSA - Indicates that the machine function is no longer in SSA form. - void leaveSSA() { IsSSA = false; } - /// tracksLiveness - Returns true when tracking register liveness accurately. /// /// While this flag is true, register liveness information in basic block Index: lib/CodeGen/IfConversion.cpp =================================================================== --- lib/CodeGen/IfConversion.cpp +++ lib/CodeGen/IfConversion.cpp @@ -290,7 +290,8 @@ if (!TII) return false; - PreRegAlloc = MRI->isSSA(); + PreRegAlloc = MF.getProperties().hasProperty( + MachineFunctionProperties::Property::IsSSA); bool BFChange = false; if (!PreRegAlloc) { Index: lib/CodeGen/LiveVariables.cpp =================================================================== --- lib/CodeGen/LiveVariables.cpp +++ lib/CodeGen/LiveVariables.cpp @@ -635,7 +635,8 @@ // FIXME: LiveIntervals will be updated to remove its dependence on // LiveVariables to improve compilation time and eliminate bizarre pass // dependencies. Until then, we can't change much in -O0. - if (!MRI->isSSA()) + if (!MF->getProperties().hasProperty( + MachineFunctionProperties::Property::IsSSA)) report_fatal_error("regalloc=... not currently supported with -O0"); analyzePHINodes(mf); Index: lib/CodeGen/MIRParser/MIRParser.cpp =================================================================== --- lib/CodeGen/MIRParser/MIRParser.cpp +++ lib/CodeGen/MIRParser/MIRParser.cpp @@ -337,10 +337,11 @@ bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF, const yaml::MachineFunction &YamlMF, PerFunctionMIParsingState &PFS) { + MachineFunctionProperties &MFProps = MF.getProperties(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); - assert(RegInfo.isSSA()); + assert(MFProps.hasProperty(MachineFunctionProperties::Property::IsSSA)); if (!YamlMF.IsSSA) - RegInfo.leaveSSA(); + MFProps.clear(MachineFunctionProperties::Property::IsSSA); assert(RegInfo.tracksLiveness()); if (!YamlMF.TracksRegLiveness) RegInfo.invalidateLiveness(); Index: lib/CodeGen/MIRPrinter.cpp =================================================================== --- lib/CodeGen/MIRPrinter.cpp +++ lib/CodeGen/MIRPrinter.cpp @@ -171,6 +171,8 @@ YamlMF.Alignment = MF.getAlignment(); YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); YamlMF.HasInlineAsm = MF.hasInlineAsm(); + YamlMF.IsSSA = MF.getProperties().hasProperty( + MachineFunctionProperties::Property::IsSSA); YamlMF.AllVRegsAllocated = MF.getProperties().hasProperty( MachineFunctionProperties::Property::AllVRegsAllocated); @@ -201,7 +203,6 @@ void MIRPrinter::convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo, const TargetRegisterInfo *TRI) { - MF.IsSSA = RegInfo.isSSA(); MF.TracksRegLiveness = RegInfo.tracksLiveness(); MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled(); Index: lib/CodeGen/MachineFunction.cpp =================================================================== --- lib/CodeGen/MachineFunction.cpp +++ lib/CodeGen/MachineFunction.cpp @@ -57,20 +57,17 @@ void MachineFunctionProperties::print(raw_ostream &ROS) const { // Leave this function even in NDEBUG as an out-of-line anchor. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - if (!Properties.any()) { - ROS << "(empty)"; - return; - } for (BitVector::size_type i = 0; i < Properties.size(); ++i) { - if (Properties[i]) { - switch(static_cast(i)) { - case Property::AllVRegsAllocated: - ROS << "AllVRegsAllocated "; - break; - default: - // TODO: Implement IsSSA/TracksLiveness when we make them properties. - llvm_unreachable("Unexpected value for property enum"); - } + bool HasProperty = Properties[i]; + switch(static_cast(i)) { + case Property::IsSSA: + ROS << (HasProperty ? "SSA, " : "Post SSA, "); + break; + case Property::AllVRegsAllocated: + ROS << (HasProperty ? "AllVRegsAllocated" : "HasVRegs"); + break; + default: + break; } } #endif @@ -91,6 +88,8 @@ unsigned FunctionNum, MachineModuleInfo &mmi) : Fn(F), Target(TM), STI(TM.getSubtargetImpl(*F)), Ctx(mmi.getContext()), MMI(mmi) { + // Assume the function starts in SSA form. + Properties.set(MachineFunctionProperties::Property::IsSSA); if (STI->getRegisterInfo()) RegInfo = new (Allocator) MachineRegisterInfo(this); else @@ -396,9 +395,8 @@ getProperties().print(OS); OS << "> : "; if (RegInfo) { - OS << (RegInfo->isSSA() ? "SSA" : "Post SSA"); if (!RegInfo->tracksLiveness()) - OS << ", not tracking liveness"; + OS << "not tracking liveness"; } OS << '\n'; Index: lib/CodeGen/MachineLICM.cpp =================================================================== --- lib/CodeGen/MachineLICM.cpp +++ lib/CodeGen/MachineLICM.cpp @@ -272,7 +272,8 @@ MRI = &MF.getRegInfo(); SchedModel.init(ST.getSchedModel(), &ST, TII); - PreRegAlloc = MRI->isSSA(); + PreRegAlloc = MF.getProperties().hasProperty( + MachineFunctionProperties::Property::IsSSA); if (PreRegAlloc) DEBUG(dbgs() << "******** Pre-regalloc Machine LICM: "); Index: lib/CodeGen/MachineRegisterInfo.cpp =================================================================== --- lib/CodeGen/MachineRegisterInfo.cpp +++ lib/CodeGen/MachineRegisterInfo.cpp @@ -25,7 +25,7 @@ void MachineRegisterInfo::Delegate::anchor() {} MachineRegisterInfo::MachineRegisterInfo(const MachineFunction *MF) - : MF(MF), TheDelegate(nullptr), IsSSA(true), TracksLiveness(true), + : MF(MF), TheDelegate(nullptr), TracksLiveness(true), TracksSubRegLiveness(false) { unsigned NumRegs = getTargetRegisterInfo()->getNumRegs(); VRegInfo.reserve(256); Index: lib/CodeGen/MachineVerifier.cpp =================================================================== --- lib/CodeGen/MachineVerifier.cpp +++ lib/CodeGen/MachineVerifier.cpp @@ -67,6 +67,7 @@ const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; const MachineRegisterInfo *MRI; + const MachineFunctionProperties *MFP; unsigned foundErrors; @@ -312,7 +313,7 @@ // If a pass has introduced virtual registers without clearing the // AllVRegsAllocated property (or set it without allocating the vregs) // then report an error. - if (MF.getProperties().hasProperty( + if (MFP->hasProperty( MachineFunctionProperties::Property::AllVRegsAllocated) && MRI->getNumVirtRegs()) { report( @@ -329,6 +330,7 @@ TII = MF.getSubtarget().getInstrInfo(); TRI = MF.getSubtarget().getRegisterInfo(); MRI = &MF.getRegInfo(); + MFP = &MF.getProperties(); LiveVars = nullptr; LiveInts = nullptr; @@ -571,7 +573,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { FirstTerminator = nullptr; - if (MRI->isSSA()) { + if (MFP->hasProperty(MachineFunctionProperties::Property::IsSSA)) { // If this block has allocatable physical registers live-in, check that // it is an entry block or landing pad. for (const auto &LI : MBB->liveins()) { @@ -960,8 +962,8 @@ // Verify two-address constraints after leaving SSA form. unsigned DefIdx; - if (!MRI->isSSA() && MO->isUse() && - MI->isRegTiedToDefOperand(MONum, &DefIdx) && + if (!MFP->hasProperty(MachineFunctionProperties::Property::IsSSA) && + MO->isUse() && MI->isRegTiedToDefOperand(MONum, &DefIdx) && Reg != MI->getOperand(DefIdx).getReg()) report("Two-address instruction operands must be identical", MO, MONum); @@ -1283,7 +1285,8 @@ addRegWithSubRegs(regsDefined, Reg); // Verify SSA form. - if (MRI->isSSA() && TargetRegisterInfo::isVirtualRegister(Reg) && + if (MFP->hasProperty(MachineFunctionProperties::Property::IsSSA) && + TargetRegisterInfo::isVirtualRegister(Reg) && std::next(MRI->def_begin(Reg)) != MRI->def_end()) report("Multiple virtual register defs in SSA form", MO, MONum); Index: lib/CodeGen/PHIElimination.cpp =================================================================== --- lib/CodeGen/PHIElimination.cpp +++ lib/CodeGen/PHIElimination.cpp @@ -64,6 +64,11 @@ } bool runOnMachineFunction(MachineFunction &Fn) override; + // This pass takes the function out of SSA form. + MachineFunctionProperties getClearedProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::IsSSA); + } void getAnalysisUsage(AnalysisUsage &AU) const override; private: @@ -136,9 +141,6 @@ bool Changed = false; - // This pass takes the function out of SSA form. - MRI->leaveSSA(); - // Split critical edges to help the coalescer. This does not yet support // updating LiveIntervals, so we disable it. if (!DisableEdgeSplitting && (LV || LIS)) { Index: lib/CodeGen/ProcessImplicitDefs.cpp =================================================================== --- lib/CodeGen/ProcessImplicitDefs.cpp +++ lib/CodeGen/ProcessImplicitDefs.cpp @@ -45,6 +45,10 @@ void getAnalysisUsage(AnalysisUsage &au) const override; bool runOnMachineFunction(MachineFunction &fn) override; + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::IsSSA); + } }; } // end anonymous namespace @@ -142,7 +146,6 @@ TII = MF.getSubtarget().getInstrInfo(); TRI = MF.getSubtarget().getRegisterInfo(); MRI = &MF.getRegInfo(); - assert(MRI->isSSA() && "ProcessImplicitDefs only works on SSA form."); assert(WorkList.empty() && "Inconsistent worklist state"); for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); Index: lib/CodeGen/RegAllocFast.cpp =================================================================== --- lib/CodeGen/RegAllocFast.cpp +++ lib/CodeGen/RegAllocFast.cpp @@ -1088,7 +1088,9 @@ UsedInInstr.clear(); UsedInInstr.setUniverse(TRI->getNumRegUnits()); - assert(!MRI->isSSA() && "regalloc requires leaving SSA"); + assert(!MF->getProperties().hasProperty( + MachineFunctionProperties::Property::IsSSA) + && "regalloc requires leaving SSA"); // initialize the virtual->physical register map to have a 'null' // mapping for all virtual registers Index: lib/CodeGen/TailDuplication.cpp =================================================================== --- lib/CodeGen/TailDuplication.cpp +++ lib/CodeGen/TailDuplication.cpp @@ -142,7 +142,9 @@ MMI = getAnalysisIfAvailable(); MBPI = &getAnalysis(); - PreRegAlloc = MRI->isSSA(); + PreRegAlloc = MF.getProperties().hasProperty( + MachineFunctionProperties::Property::IsSSA); + RS.reset(); if (MRI->tracksLiveness() && TRI->trackLivenessAfterRegAlloc(MF)) RS.reset(new RegScavenger()); Index: lib/CodeGen/TwoAddressInstructionPass.cpp =================================================================== --- lib/CodeGen/TwoAddressInstructionPass.cpp +++ lib/CodeGen/TwoAddressInstructionPass.cpp @@ -167,6 +167,11 @@ /// Pass entry point. bool runOnMachineFunction(MachineFunction&) override; + // This pass takes the function out of SSA form. + MachineFunctionProperties getClearedProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::IsSSA); + } }; } // end anonymous namespace @@ -1624,9 +1629,6 @@ DEBUG(dbgs() << "********** Function: " << MF->getName() << '\n'); - // This pass takes the function out of SSA form. - MRI->leaveSSA(); - TiedOperandMap TiedOperands; for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end(); MBBI != MBBE; ++MBBI) { Index: lib/Target/AMDGPU/SILoadStoreOptimizer.cpp =================================================================== --- lib/Target/AMDGPU/SILoadStoreOptimizer.cpp +++ lib/Target/AMDGPU/SILoadStoreOptimizer.cpp @@ -432,7 +432,8 @@ DEBUG(dbgs() << "Running SILoadStoreOptimizer\n"); - assert(!MRI->isSSA()); + assert(!MF.getProperties().hasProperty( + MachineFunctionProperties::Property::IsSSA)); bool Modified = false; Index: lib/Target/AMDGPU/SIShrinkInstructions.cpp =================================================================== --- lib/Target/AMDGPU/SIShrinkInstructions.cpp +++ lib/Target/AMDGPU/SIShrinkInstructions.cpp @@ -132,10 +132,12 @@ /// instruction and then folds the literal constant into the instruction if it /// can. This function assumes that \p MI is a VOP1, VOP2, or VOPC instruction /// and will only fold literal constants if we are still in SSA. -static void foldImmediates(MachineInstr &MI, const SIInstrInfo *TII, +static void foldImmediates(MachineFunction& MF, MachineInstr &MI, + const SIInstrInfo *TII, MachineRegisterInfo &MRI, bool TryToCommute = true) { - if (!MRI.isSSA()) + if (!MF.getProperties().hasProperty( + MachineFunctionProperties::Property::IsSSA)) return; assert(TII->isVOP1(MI) || TII->isVOP2(MI) || TII->isVOPC(MI)); @@ -179,7 +181,7 @@ // We have failed to fold src0, so commute the instruction and try again. if (TryToCommute && MI.isCommutable() && TII->commuteInstruction(&MI)) - foldImmediates(MI, TII, MRI, false); + foldImmediates(MF, MI, TII, MRI, false); } @@ -345,7 +347,7 @@ ++NumInstructionsShrunk; MI.eraseFromParent(); - foldImmediates(*Inst32, TII, MRI); + foldImmediates(MF, *Inst32, TII, MRI); DEBUG(dbgs() << "e32 MI = " << *Inst32 << '\n'); Index: lib/Target/WebAssembly/WebAssemblyStoreResults.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyStoreResults.cpp +++ lib/Target/WebAssembly/WebAssemblyStoreResults.cpp @@ -59,6 +59,11 @@ MachineFunctionPass::getAnalysisUsage(AU); } + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::IsSSA); + } + bool runOnMachineFunction(MachineFunction &MF) override; private: @@ -174,8 +179,6 @@ const auto &LibInfo = getAnalysis().getTLI(); bool Changed = false; - assert(MRI.isSSA() && "StoreResults depends on SSA form"); - for (auto &MBB : MF) { DEBUG(dbgs() << "Basic Block: " << MBB.getName() << '\n'); for (auto &MI : MBB)