summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-09-27 18:18:44 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-09-27 18:18:44 +0000
commit1d3222072111953cf5ebb16de5ca0fd680bc3fff (patch)
tree3207d39a57fa24fcf395ccebf522dbe13bf61cda /llvm
parent0775a2326e39c0a1c3112f16f4e0ee408c3b97bb (diff)
downloadbcm5719-llvm-1d3222072111953cf5ebb16de5ca0fd680bc3fff.tar.gz
bcm5719-llvm-1d3222072111953cf5ebb16de5ca0fd680bc3fff.zip
[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. llvm-svn: 282519
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/Hexagon/RDFGraph.cpp66
-rw-r--r--llvm/lib/Target/Hexagon/RDFGraph.h2
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,
OpenPOWER on IntegriCloud