#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Target/TargetInstrInfo.h"
-
-#include <map>
+#include "llvm/CodeGen/MachineRegisterInfo.h"
namespace llvm {
-
+ class LiveVariables;
+
/// Lower PHI instructions to copies.
class PHIElimination : public MachineFunctionPass {
MachineRegisterInfo *MRI; // Machine register information
///
void analyzePHINodes(const MachineFunction& Fn);
- // FindCopyInsertPoint - Find a safe place in MBB to insert a copy from
- // SrcReg. This needs to be after any def or uses of SrcReg, but before
- // any subsequent point where control flow might jump out of the basic
- // block.
+ /// Split critical edges where necessary for good coalescer performance.
+ bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB,
+ LiveVariables &LV);
+
+ /// SplitCriticalEdge - Split a critical edge from A to B by
+ /// inserting a new MBB. Update branches in A and PHI instructions
+ /// in B. Return the new block.
+ MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *A,
+ MachineBasicBlock *B);
+
+ /// FindCopyInsertPoint - Find a safe place in MBB to insert a copy from
+ /// SrcReg when following the CFG edge to SuccMBB. This needs to be after
+ /// any def of SrcReg, but before any subsequent point where control flow
+ /// might jump out of the basic block.
MachineBasicBlock::iterator FindCopyInsertPoint(MachineBasicBlock &MBB,
+ MachineBasicBlock &SuccMBB,
unsigned SrcReg);
// SkipPHIsAndLabels - Copies need to be inserted after phi nodes and
MachineBasicBlock::iterator I) {
// Rather than assuming that EH labels come before other kinds of labels,
// just skip all labels.
- while (I != MBB.end() &&
- (I->getOpcode() == TargetInstrInfo::PHI || I->isLabel()))
+ while (I != MBB.end() && (I->isPHI() || I->isLabel()))
++I;
return I;
}
- typedef std::pair<const MachineBasicBlock*, unsigned> BBVRegPair;
- typedef std::map<BBVRegPair, unsigned> VRegPHIUse;
+ typedef std::pair<unsigned, unsigned> BBVRegPair;
+ typedef DenseMap<BBVRegPair, unsigned> VRegPHIUse;
VRegPHIUse VRegPHIUseCount;
PHIDefMap PHIDefs;
// Defs of PHI sources which are implicit_def.
SmallPtrSet<MachineInstr*, 4> ImpDefs;
+
+ // Lowered PHI nodes may be reused. We provide special DenseMap traits to
+ // match PHI nodes with identical arguments.
+ struct PHINodeTraits : public DenseMapInfo<MachineInstr*> {
+ static unsigned getHashValue(const MachineInstr *PtrVal);
+ static bool isEqual(const MachineInstr *LHS, const MachineInstr *RHS);
+ };
+
+ // Map reusable lowered PHI node -> incoming join register.
+ typedef DenseMap<MachineInstr*, unsigned, PHINodeTraits> LoweredPHIMap;
+ LoweredPHIMap LoweredPHIs;
};
}
-#endif /* PHIELIMINATION_H */
+#endif /* LLVM_CODEGEN_PHIELIMINATION_HPP */