MachineFunction: Introduce NoPHIs property

I want to compute the SSA property of .mir files automatically in
upcoming patches. The problem with this is that some inputs will be
reported as static single assignment with some passes claiming not to
support SSA form.  In reality though those passes do not support PHI
instructions => Track the presence of PHI instructions separate from the
SSA property.

Differential Revision: https://reviews.llvm.org/D22719

llvm-svn: 279573
This commit is contained in:
Matthias Braun 2016-08-23 21:19:49 +00:00
parent f46d50e360
commit 90799ce8b2
10 changed files with 52 additions and 4 deletions

View File

@ -92,6 +92,7 @@ public:
// 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 @@ public:
// all sizes attached to them have been eliminated.
enum class Property : unsigned {
IsSSA,
NoPHIs,
TracksLiveness,
AllVRegsAllocated,
Legalized,

View File

@ -160,6 +160,8 @@ private:
///
/// 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 @@ void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
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 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
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);

View File

@ -60,6 +60,7 @@ static const char *getPropertyName(MachineFunctionProperties::Property Prop) {
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";

View File

@ -858,6 +858,10 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
<< 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);

View File

@ -175,6 +175,8 @@ bool PHIElimination::runOnMachineFunction(MachineFunction &MF) {
ImpDefs.clear();
VRegPHIUseCount.clear();
MF.getProperties().set(MachineFunctionProperties::Property::NoPHIs);
return Changed;
}

View File

@ -105,6 +105,11 @@ public:
/// 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.

View File

@ -158,6 +158,11 @@ namespace {
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 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) {
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());

View File

@ -334,6 +334,11 @@ public:
/// Perform register allocation.
bool runOnMachineFunction(MachineFunction &mf) override;
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoPHIs);
}
static char ID;
private:

View File

@ -109,6 +109,11 @@ public:
/// Perform register allocation
bool runOnMachineFunction(MachineFunction &MF) override;
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoPHIs);
}
private:
typedef std::map<const LiveInterval*, unsigned> LI2NodeMap;

View File

@ -98,6 +98,11 @@ public:
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<SlotIndexes>();
@ -425,8 +430,6 @@ bool SILoadStoreOptimizer::runOnMachineFunction(MachineFunction &MF) {
DEBUG(dbgs() << "Running SILoadStoreOptimizer\n");
assert(!MRI->isSSA());
bool Modified = false;
for (MachineBasicBlock &MBB : MF)