OpenASIP  2.0
VirtRegIndependenceGraph.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2010 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file VirtRegIndependenceGraph.cc
26  *
27  * @author Pekka Jääskeläinen 2010
28  * @note rating: red
29  */
30 #include "hash_set.hh"
31 #include "llvm/Target/TargetRegisterInfo.h"
32 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
33 #include "llvm/CodeGen/MachineInstr.h"
34 #include "llvm/CodeGen/MachineFunction.h"
35 #include "llvm/Function.h"
36 #include "boost/graph/graphviz.hpp"
37 #include "VirtRegMap.h"
39 #include "MachineInstrDDG.hh"
40 #include "MapTools.hh"
41 
42 // #define DEBUG_FDPG
43 /**
44  * Constructs the graph from an LLVM MachineFunction.
45  */
47  llvm::MachineFunction& mf, llvm::VirtRegMap& vrm) :
48  vrm_(vrm) {
49 
50  MachineInstrDDG tddg(*vrm.TII, *vrm.TRI, mf, true);
52 #ifdef DEBUG_FDPG
53  Application::logStream() << "building FDPG" << std::endl;
54 #endif
55  // add the virtual regs as nodes
56  for (MachineInstrDDG::RegisterSet::const_iterator i = regs.begin();
57  i != regs.end(); ++i) {
59 
60  if (llvm::TargetRegisterInfo::isPhysicalRegister(reg))
61  continue;
62 
63  addNode(reg);
64  }
65 
66 #ifdef DEBUG_FDPG
67  Application::logStream() << "finding TDDG paths" << std::endl;
68 #endif
69  // this should speed up hasPath() as all known paths are
70  // computed only once
71  tddg.findAllPaths();
72 #ifdef DEBUG_FDPG
73  Application::logStream() << "finding TDDG paths done" << std::endl;
74 #endif
75  MachineInstrDDG::RegisterSet unhandledRegs = regs;
76  for (MachineInstrDDG::RegisterSet::const_iterator i = regs.begin();
77  i != regs.end(); ++i) {
79  MIDDGNode* instrA = tddg.vregDefiner(reg);
80  for (MachineInstrDDG::RegisterSet::const_iterator u =
81  unhandledRegs.begin();
82  u != unhandledRegs.end(); ++u) {
83  MachineInstrDDG::Register otherReg = *u;
84  MIDDGNode* instrB = tddg.vregDefiner(otherReg);
85  if (instrB == NULL) {
87  << "could not find definer for " << otherReg << std::endl;
88  abortWithError("Cannot proceed.");
89  }
90  if (!tddg.hasPath(*instrA, *instrB) &&
91  !tddg.hasPath(*instrB, *instrA)) {
92  addEdge(reg, otherReg);
93  }
94  }
95  unhandledRegs.erase(reg);
96  }
97 #ifdef DEBUG_FDPG
98  Application::logStream() << "building FDPG done" << std::endl;
99 #endif
100 #if 0
101  // this is exremely slow as there are often huge number of edges in FDPG
102  std::string s(mf.getFunction()->getNameStr() + "_fdpg.dot");
103  std::ofstream o(s.c_str());
104  boost::write_graphviz(
105  o, fdpg_, make_label_writer(get(boost::vertex_name, fdpg_)));
106 #endif
107 }
108 
109 /**
110  * Returns the number of new false deps introduced by assigning the given
111  * physical register to the given live interval.
112  */
113 int
115  llvm::LiveInterval* interval, MachineInstrDDG::Register physReg) {
116 
117  if (llvm::TargetRegisterInfo::isPhysicalRegister(interval->reg)) {
119  << "Should not see assigned intervals here. Got: "
120  << interval->reg
121  << std::endl;
122  return true;
123  }
124 
125  // look at all connected live Intervals in the FDPG and see if they have
126  // been assigned the same PhysReg we are trying to assign this one
127 
128  int foundFalseDeps = 0;
129  std::set<MachineInstrDDG::Register> adjacent = adjacentNodes(interval->reg);
130  for (std::set<MachineInstrDDG::Register>::const_iterator i =
131  adjacent.begin(); i != adjacent.end(); ++i) {
132  MachineInstrDDG::Register virtReg = *i;
133  bool isPhysRegAssigned = vrm_.hasPhys(virtReg);
134  if (isPhysRegAssigned && vrm_.getPhys(virtReg) == physReg) {
135  ++foundFalseDeps;
136  }
137  }
138  return foundFalseDeps;
139 }
140 
141 void
143  vertexMap_[virtReg] = boost::add_vertex(fdpg_);
144  vregMap_[vertexMap_[virtReg]] = virtReg;
145  boost::put(boost::vertex_name, fdpg_, vertexMap_[virtReg], virtReg);
146 }
147 
148 void
151  boost::add_edge(vertexMap_[nodeA], vertexMap_[nodeB], fdpg_);
152 }
153 
154 std::set<MachineInstrDDG::Register>
156  std::set<MachineInstrDDG::Register> nodes;
157 
158  boost::graph_traits<FDPG>::adjacency_iterator i, end;
159  i = boost::adjacent_vertices(vertexMap_[node], fdpg_).first;
160  end = boost::adjacent_vertices(vertexMap_[node], fdpg_).second;
161  for (; i != end; ++i) {
162  MachineInstrDDG::Register virtReg = vregMap_[*i];
163  nodes.insert(virtReg);
164  }
165 
166  return nodes;
167 }
VirtRegIndependenceGraph::vrm_
llvm::VirtRegMap & vrm_
Definition: VirtRegIndependenceGraph.hh:102
BoostGraph::hasPath
bool hasPath(GraphNode &src, const GraphNode &dest) const
MachineInstrDDG::allRegisters
RegisterSet allRegisters() const
Definition: MachineInstrDDG.hh:154
BoostGraph::findAllPaths
void findAllPaths() const
MapTools.hh
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
MachineInstrDDG.hh
hash_set.hh
MachineInstrDDG::RegisterSet
std::set< Register > RegisterSet
Definition: MachineInstrDDG.hh:144
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
VirtRegIndependenceGraph.hh
MachineInstrDDG
Definition: MachineInstrDDG.hh:140
MIDDGNode
Definition: MachineInstrDDG.hh:58
VirtRegIndependenceGraph::adjacentNodes
std::set< MachineInstrDDG::Register > adjacentNodes(MachineInstrDDG::Register node)
Definition: VirtRegIndependenceGraph.cc:155
VirtRegIndependenceGraph::addNode
void addNode(MachineInstrDDG::Register virtReg)
Definition: VirtRegIndependenceGraph.cc:142
VirtRegIndependenceGraph::vregMap_
std::map< FDPG::vertex_descriptor, MachineInstrDDG::Register > vregMap_
Definition: VirtRegIndependenceGraph.hh:107
VirtRegIndependenceGraph::addEdge
void addEdge(MachineInstrDDG::Register nodeA, MachineInstrDDG::Register nodeB)
Definition: VirtRegIndependenceGraph.cc:149
VirtRegIndependenceGraph::newFalseDepsFromAssign
int newFalseDepsFromAssign(llvm::LiveInterval *interval, MachineInstrDDG::Register physReg)
Definition: VirtRegIndependenceGraph.cc:114
MachineInstrDDG::Register
unsigned Register
Definition: MachineInstrDDG.hh:143
VirtRegIndependenceGraph::vertexMap_
std::map< MachineInstrDDG::Register, FDPG::vertex_descriptor > vertexMap_
Definition: VirtRegIndependenceGraph.hh:106
VirtRegIndependenceGraph::VirtRegIndependenceGraph
VirtRegIndependenceGraph(llvm::MachineFunction &mf, llvm::VirtRegMap &vrm)
Definition: VirtRegIndependenceGraph.cc:46
MachineInstrDDG::vregDefiner
MIDDGNode * vregDefiner(Register vreg) const
Definition: MachineInstrDDG.hh:156
VirtRegIndependenceGraph::fdpg_
FDPG fdpg_
Definition: VirtRegIndependenceGraph.hh:104