blob: 8b88f3a2addf8f947e381aa6833a920c2629c0d5 [file] [log] [blame]
Krzysztof Parzyszekacdff462016-01-12 15:56:33 +00001//===--- RDFLiveness.h ----------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Recalculate the liveness information given a data flow graph.
11// This includes block live-ins and kill flags.
12
13#ifndef RDF_LIVENESS_H
14#define RDF_LIVENESS_H
15
16#include "RDFGraph.h"
17#include "llvm/ADT/DenseMap.h"
18#include <map>
19
20using namespace llvm;
21
22namespace llvm {
23 class MachineBasicBlock;
24 class MachineFunction;
25 class MachineRegisterInfo;
26 class TargetRegisterInfo;
27 class MachineDominatorTree;
28 class MachineDominanceFrontier;
Krzysztof Parzyszekacdff462016-01-12 15:56:33 +000029
30namespace rdf {
31 struct Liveness {
32 public:
33 typedef std::map<MachineBasicBlock*,RegisterSet> LiveMapType;
34 typedef std::map<RegisterRef,NodeSet> RefMap;
35
36 Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
37 : DFG(g), TRI(g.getTRI()), MDT(g.getDT()), MDF(g.getDF()),
Krzysztof Parzyszek445bd122016-10-14 17:57:55 +000038 MRI(mri), Empty(), NoRegs(g.getTRI()), Trace(false) {}
Krzysztof Parzyszekacdff462016-01-12 15:56:33 +000039
40 NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
Krzysztof Parzyszeka77fe4e2016-10-03 17:14:48 +000041 bool FullChain, const RegisterAggr &DefRRs);
42 NodeList getAllReachingDefs(NodeAddr<RefNode*> RefA) {
Krzysztof Parzyszek445bd122016-10-14 17:57:55 +000043 return getAllReachingDefs(RefA.Addr->getRegRef(DFG), RefA, false, NoRegs);
Krzysztof Parzyszeka77fe4e2016-10-03 17:14:48 +000044 }
45 NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA) {
46 return getAllReachingDefs(RefRR, RefA, false, NoRegs);
47 }
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +000048 NodeSet getAllReachingDefsRec(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
49 NodeSet &Visited, const NodeSet &Defs);
50 NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA,
Krzysztof Parzyszeka77fe4e2016-10-03 17:14:48 +000051 const RegisterAggr &DefRRs);
52 NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA) {
53 return getAllReachedUses(RefRR, DefA, NoRegs);
54 }
Krzysztof Parzyszekacdff462016-01-12 15:56:33 +000055
56 LiveMapType &getLiveMap() { return LiveMap; }
57 const LiveMapType &getLiveMap() const { return LiveMap; }
58 const RefMap &getRealUses(NodeId P) const {
59 auto F = RealUseMap.find(P);
60 return F == RealUseMap.end() ? Empty : F->second;
61 }
62
63 void computePhiInfo();
64 void computeLiveIns();
65 void resetLiveIns();
66 void resetKills();
67 void resetKills(MachineBasicBlock *B);
68
69 void trace(bool T) { Trace = T; }
70
71 private:
72 const DataFlowGraph &DFG;
73 const TargetRegisterInfo &TRI;
74 const MachineDominatorTree &MDT;
75 const MachineDominanceFrontier &MDF;
Krzysztof Parzyszekacdff462016-01-12 15:56:33 +000076 MachineRegisterInfo &MRI;
77 LiveMapType LiveMap;
78 const RefMap Empty;
Krzysztof Parzyszeka77fe4e2016-10-03 17:14:48 +000079 const RegisterAggr NoRegs;
Krzysztof Parzyszekacdff462016-01-12 15:56:33 +000080 bool Trace;
81
82 // Cache of mapping from node ids (for RefNodes) to the containing
83 // basic blocks. Not computing it each time for each node reduces
84 // the liveness calculation time by a large fraction.
85 typedef DenseMap<NodeId,MachineBasicBlock*> NodeBlockMap;
86 NodeBlockMap NBMap;
87
88 // Phi information:
89 //
90 // map: NodeId -> (map: RegisterRef -> NodeSet)
91 // phi id -> (map: register -> set of reached non-phi uses)
92 std::map<NodeId, RefMap> RealUseMap;
93
94 // Inverse iterated dominance frontier.
95 std::map<MachineBasicBlock*,std::set<MachineBasicBlock*>> IIDF;
96
97 // Live on entry.
98 std::map<MachineBasicBlock*,RefMap> PhiLON;
99
100 // Phi uses are considered to be located at the end of the block that
101 // they are associated with. The reaching def of a phi use dominates the
102 // block that the use corresponds to, but not the block that contains
103 // the phi itself. To include these uses in the liveness propagation (up
104 // the dominator tree), create a map: block -> set of uses live on exit.
105 std::map<MachineBasicBlock*,RefMap> PhiLOX;
106
Krzysztof Parzyszek2db0c8b2016-09-07 20:37:05 +0000107 bool isRestrictedToRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
Krzysztof Parzyszekacdff462016-01-12 15:56:33 +0000108 RegisterRef RR) const;
109 RegisterRef getRestrictedRegRef(NodeAddr<RefNode*> RA) const;
Krzysztof Parzyszekacdff462016-01-12 15:56:33 +0000110 MachineBasicBlock *getBlockWithRef(NodeId RN) const;
111 void traverse(MachineBasicBlock *B, RefMap &LiveIn);
112 void emptify(RefMap &M);
113 };
Benjamin Kramer922efd72016-05-27 10:06:40 +0000114} // namespace rdf
115} // namespace llvm
Krzysztof Parzyszekacdff462016-01-12 15:56:33 +0000116
117#endif // RDF_LIVENESS_H