Index: llvm/trunk/include/llvm/CodeGen/MachineFunction.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunction.h +++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h @@ -92,6 +92,7 @@ // Property descriptions: // IsSSA: True when the machine function is in SSA form and virtual registers // have a single def. + // NoPHIs: The machine function does not contain any PHI instruction. // TracksLiveness: True when tracking register liveness accurately. // While this property is set, register liveness information in basic block // live-in lists and machine instruction operands (e.g. kill flags, implicit @@ -117,6 +118,7 @@ // all sizes attached to them have been eliminated. enum class Property : unsigned { IsSSA, + NoPHIs, TracksLiveness, AllVRegsAllocated, Legalized, Index: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp @@ -160,6 +160,8 @@ /// /// Return null if the name isn't a register bank. const RegisterBank *getRegBank(const MachineFunction &MF, StringRef Name); + + void computeFunctionProperties(MachineFunction &MF); }; } // end namespace llvm @@ -279,6 +281,19 @@ new UnreachableInst(Context, BB); } +static bool hasPHI(const MachineFunction &MF) { + for (const MachineBasicBlock &MBB : MF) + for (const MachineInstr &MI : MBB) + if (MI.isPHI()) + return true; + return false; +} + +void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) { + if (!hasPHI(MF)) + MF.getProperties().set(MachineFunctionProperties::Property::NoPHIs); +} + bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) { auto It = Functions.find(MF.getName()); if (It == Functions.end()) @@ -353,6 +368,9 @@ PFS.SM = &SM; inferRegisterInfo(PFS, YamlMF); + + computeFunctionProperties(MF); + // FIXME: This is a temporary workaround until the reserved registers can be // serialized. MF.getRegInfo().freezeReservedRegs(MF); Index: llvm/trunk/lib/CodeGen/MachineFunction.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineFunction.cpp +++ llvm/trunk/lib/CodeGen/MachineFunction.cpp @@ -60,6 +60,7 @@ case P::AllVRegsAllocated: return "AllVRegsAllocated"; case P::IsSSA: return "IsSSA"; case P::Legalized: return "Legalized"; + case P::NoPHIs: return "NoPHIs"; case P::RegBankSelected: return "RegBankSelected"; case P::Selected: return "Selected"; case P::TracksLiveness: return "TracksLiveness"; Index: llvm/trunk/lib/CodeGen/MachineVerifier.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineVerifier.cpp +++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp @@ -858,6 +858,10 @@ << MI->getNumOperands() << " given.\n"; } + if (MI->isPHI() && MF->getProperties().hasProperty( + MachineFunctionProperties::Property::NoPHIs)) + report("Found PHI instruction with NoPHIs property set", MI); + // Check the tied operands. if (MI->isInlineAsm()) verifyInlineAsm(MI); Index: llvm/trunk/lib/CodeGen/PHIElimination.cpp =================================================================== --- llvm/trunk/lib/CodeGen/PHIElimination.cpp +++ llvm/trunk/lib/CodeGen/PHIElimination.cpp @@ -175,6 +175,8 @@ ImpDefs.clear(); VRegPHIUseCount.clear(); + MF.getProperties().set(MachineFunctionProperties::Property::NoPHIs); + return Changed; } Index: llvm/trunk/lib/CodeGen/RegAllocBasic.cpp =================================================================== --- llvm/trunk/lib/CodeGen/RegAllocBasic.cpp +++ llvm/trunk/lib/CodeGen/RegAllocBasic.cpp @@ -105,6 +105,11 @@ /// Perform register allocation. bool runOnMachineFunction(MachineFunction &mf) override; + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::NoPHIs); + } + // Helper for spilling all live virtual registers currently unified under preg // that interfere with the most recently queried lvr. Return true if spilling // was successful, and append any new spilled/split intervals to splitLVRs. Index: llvm/trunk/lib/CodeGen/RegAllocFast.cpp =================================================================== --- llvm/trunk/lib/CodeGen/RegAllocFast.cpp +++ llvm/trunk/lib/CodeGen/RegAllocFast.cpp @@ -158,6 +158,11 @@ MachineFunctionPass::getAnalysisUsage(AU); } + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::NoPHIs); + } + MachineFunctionProperties getSetProperties() const override { return MachineFunctionProperties().set( MachineFunctionProperties::Property::AllVRegsAllocated); @@ -1093,8 +1098,6 @@ UsedInInstr.clear(); UsedInInstr.setUniverse(TRI->getNumRegUnits()); - assert(!MRI->isSSA() && "regalloc requires leaving SSA"); - // initialize the virtual->physical register map to have a 'null' // mapping for all virtual registers StackSlotForVirtReg.resize(MRI->getNumVirtRegs()); Index: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp =================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp @@ -334,6 +334,11 @@ /// Perform register allocation. bool runOnMachineFunction(MachineFunction &mf) override; + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::NoPHIs); + } + static char ID; private: Index: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp =================================================================== --- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp +++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp @@ -109,6 +109,11 @@ /// Perform register allocation bool runOnMachineFunction(MachineFunction &MF) override; + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::NoPHIs); + } + private: typedef std::map LI2NodeMap; Index: llvm/trunk/lib/Target/AMDGPU/SILoadStoreOptimizer.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/SILoadStoreOptimizer.cpp +++ llvm/trunk/lib/Target/AMDGPU/SILoadStoreOptimizer.cpp @@ -98,6 +98,11 @@ return "SI Load / Store Optimizer"; } + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::NoPHIs); + } + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); AU.addPreserved(); @@ -425,8 +430,6 @@ DEBUG(dbgs() << "Running SILoadStoreOptimizer\n"); - assert(!MRI->isSSA()); - bool Modified = false; for (MachineBasicBlock &MBB : MF)