diff options
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFGraph.cpp | 66 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFGraph.h | 2 |
2 files changed, 65 insertions, 3 deletions
diff --git a/llvm/lib/Target/Hexagon/RDFGraph.cpp b/llvm/lib/Target/Hexagon/RDFGraph.cpp index dd39dcfdb1c..72a55f2b9de 100644 --- a/llvm/lib/Target/Hexagon/RDFGraph.cpp +++ b/llvm/lib/Target/Hexagon/RDFGraph.cpp @@ -18,6 +18,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; @@ -876,6 +877,19 @@ unsigned DataFlowGraph::DefStack::nextDown(unsigned P) const { return P; } +std::vector<uint32_t> DataFlowGraph::getLandingPadLiveIns() const { + std::vector<uint32_t> LR; + const Function &F = *MF.getFunction(); + const Constant *PF = F.hasPersonalityFn() ? F.getPersonalityFn() + : nullptr; + const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering(); + if (uint32_t EPReg = TLI.getExceptionPointerRegister(PF)) + LR.push_back(EPReg); + if (uint32_t ESReg = TLI.getExceptionSelectorRegister(PF)) + LR.push_back(ESReg); + return LR; +} + // Node management functions. // Get the pointer to the node with the id N. @@ -999,8 +1013,10 @@ void DataFlowGraph::build(unsigned Options) { } } - // Collect information about block references. NodeAddr<BlockNode*> EA = Func.Addr->getEntryBlock(*this); + NodeList Blocks = Func.Addr->members(*this); + + // Collect information about block references. BlockRefsMap RefM; buildBlockRefs(EA, RefM); @@ -1014,10 +1030,42 @@ void DataFlowGraph::build(unsigned Options) { PA.Addr->addMember(DA, *this); } + // Add phis for landing pads. + // Landing pads, unlike usual backs blocks, are not entered through + // branches in the program, or fall-throughs from other blocks. They + // are entered from the exception handling runtime and target's ABI + // may define certain registers as defined on entry to such a block. + std::vector<uint32_t> EHRegs = getLandingPadLiveIns(); + if (!EHRegs.empty()) { + for (NodeAddr<BlockNode*> BA : Blocks) { + const MachineBasicBlock &B = *BA.Addr->getCode(); + if (!B.isEHPad()) + continue; + + // Prepare a list of NodeIds of the block's predecessors. + NodeList Preds; + for (MachineBasicBlock *PB : B.predecessors()) + Preds.push_back(findBlock(PB)); + + // Build phi nodes for each live-in. + for (uint32_t R : EHRegs) { + NodeAddr<PhiNode*> PA = newPhi(BA); + uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving; + // Add def: + NodeAddr<DefNode*> DA = newDef(PA, {R,0}, PhiFlags); + PA.Addr->addMember(DA, *this); + // Add uses (no reaching defs for phi uses): + for (NodeAddr<BlockNode*> PBA : Preds) { + NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, {R,0}, PBA); + PA.Addr->addMember(PUA, *this); + } + } + } + } + // Build a map "PhiM" which will contain, for each block, the set // of references that will require phi definitions in that block. BlockRefsMap PhiM; - auto Blocks = Func.Addr->members(*this); for (NodeAddr<BlockNode*> BA : Blocks) recordDefsForDF(PhiM, RefM, BA); for (NodeAddr<BlockNode*> BA : Blocks) @@ -1676,10 +1724,22 @@ void DataFlowGraph::linkBlockRefs(DefStackMap &DefM, NodeAddr<BlockNode*> BA) { NodeAddr<PhiUseNode*> PUA = NA; return PUA.Addr->getPredecessor() == BA.Id; }; + + std::vector<uint32_t> EHLiveIns = getLandingPadLiveIns(); MachineBasicBlock *MBB = BA.Addr->getCode(); + for (auto SB : MBB->successors()) { - auto SBA = findBlock(SB); + bool IsEHPad = SB->isEHPad(); + NodeAddr<BlockNode*> SBA = findBlock(SB); for (NodeAddr<InstrNode*> IA : SBA.Addr->members_if(IsPhi, *this)) { + // Do not link phi uses for landing pad live-ins. + if (IsEHPad) { + // Find what register this phi is for. + NodeAddr<RefNode*> RA = IA.Addr->getFirstMember(*this); + assert(RA.Id != 0); + if (find(EHLiveIns, RA.Addr->getRegRef().Reg) != EHLiveIns.end()) + continue; + } // Go over each phi use associated with MBB, and link it. for (auto U : IA.Addr->members_if(IsUseForBA, *this)) { NodeAddr<PhiUseNode*> PUA = U; diff --git a/llvm/lib/Target/Hexagon/RDFGraph.h b/llvm/lib/Target/Hexagon/RDFGraph.h index 3403b649d56..596bf342885 100644 --- a/llvm/lib/Target/Hexagon/RDFGraph.h +++ b/llvm/lib/Target/Hexagon/RDFGraph.h @@ -821,6 +821,8 @@ namespace rdf { private: void reset(); + std::vector<uint32_t> getLandingPadLiveIns() const; + NodeAddr<NodeBase*> newNode(uint16_t Attrs); NodeAddr<NodeBase*> cloneNode(const NodeAddr<NodeBase*> B); NodeAddr<UseNode*> newUse(NodeAddr<InstrNode*> Owner, |