From 3979119db0240475647d273785114c0dbe543d73 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 27 Sep 2016 18:18:44 +0000 Subject: [PATCH] [RDF] Special treatment of exception handling registers A landing pad can have live-in registers that are defined by the runtime, not the program (exception pointer register and exception selector register). Make sure to recognize that case and not link these registers with any defs in the program. Each landing pad will have phi nodes added at the beginning to provide definitions of these registers, but the uses of those phi nodes will not have any reaching defs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282519 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/RDFGraph.cpp | 66 +++++++++++++++++++++++++++++++-- lib/Target/Hexagon/RDFGraph.h | 2 + 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/lib/Target/Hexagon/RDFGraph.cpp b/lib/Target/Hexagon/RDFGraph.cpp index dd39dcfdb1c..72a55f2b9de 100644 --- a/lib/Target/Hexagon/RDFGraph.cpp +++ b/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 DataFlowGraph::getLandingPadLiveIns() const { + std::vector 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 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 EHRegs = getLandingPadLiveIns(); + if (!EHRegs.empty()) { + for (NodeAddr 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 PA = newPhi(BA); + uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving; + // Add def: + NodeAddr DA = newDef(PA, {R,0}, PhiFlags); + PA.Addr->addMember(DA, *this); + // Add uses (no reaching defs for phi uses): + for (NodeAddr PBA : Preds) { + NodeAddr 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 BA : Blocks) recordDefsForDF(PhiM, RefM, BA); for (NodeAddr BA : Blocks) @@ -1676,10 +1724,22 @@ void DataFlowGraph::linkBlockRefs(DefStackMap &DefM, NodeAddr BA) { NodeAddr PUA = NA; return PUA.Addr->getPredecessor() == BA.Id; }; + + std::vector EHLiveIns = getLandingPadLiveIns(); MachineBasicBlock *MBB = BA.Addr->getCode(); + for (auto SB : MBB->successors()) { - auto SBA = findBlock(SB); + bool IsEHPad = SB->isEHPad(); + NodeAddr SBA = findBlock(SB); for (NodeAddr 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 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 PUA = U; diff --git a/lib/Target/Hexagon/RDFGraph.h b/lib/Target/Hexagon/RDFGraph.h index 3403b649d56..596bf342885 100644 --- a/lib/Target/Hexagon/RDFGraph.h +++ b/lib/Target/Hexagon/RDFGraph.h @@ -821,6 +821,8 @@ namespace rdf { private: void reset(); + std::vector getLandingPadLiveIns() const; + NodeAddr newNode(uint16_t Attrs); NodeAddr cloneNode(const NodeAddr B); NodeAddr newUse(NodeAddr Owner, -- 2.50.1