[llvm] r282519 - [RDF] Special treatment of exception handling registers

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 27 11:18:45 PDT 2016


Author: kparzysz
Date: Tue Sep 27 13:18:44 2016
New Revision: 282519

URL: http://llvm.org/viewvc/llvm-project?rev=282519&view=rev
Log:
[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.

Modified:
    llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
    llvm/trunk/lib/Target/Hexagon/RDFGraph.h

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=282519&r1=282518&r2=282519&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Tue Sep 27 13:18:44 2016
@@ -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::nextDo
   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 Optio
     }
   }
 
-  // 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 Optio
     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(DefSta
     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;

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.h?rev=282519&r1=282518&r2=282519&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.h Tue Sep 27 13:18:44 2016
@@ -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,




More information about the llvm-commits mailing list