OpenASIP 2.2
Loading...
Searching...
No Matches
ControlFlowGraph.hh
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2011 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 ControlFlowGraph.hh
26 *
27 * Declaration of prototype control flow graph of TTA program
28 * representation.
29 *
30 * @author Andrea Cilio 2005 (cilio-no.spam-cs.tut.fi)
31 * @author Vladimir Guzma 2006 (vladimir.guzma-no.spam-tut.fi)
32 * @note rating: red
33 */
34
35#ifndef TTA_CONTROL_FLOW_GRAPH_HH
36#define TTA_CONTROL_FLOW_GRAPH_HH
37
38
39#include <map>
40#include <vector>
41
42#include "CompilerWarnings.hh"
43IGNORE_CLANG_WARNING("-Wunused-local-typedef")
44IGNORE_COMPILER_WARNING("-Wunused-parameter")
45#include <boost/graph/reverse_graph.hpp>
46#include <boost/graph/depth_first_search.hpp>
49
50namespace llvm {
51 class MCSymbol;
52 class MachineInstr;
53}
54
55#include "Exception.hh"
56#include "BoostGraph.hh"
57#include "BasicBlockNode.hh"
58#include "ControlFlowEdge.hh"
59#include "Address.hh"
60#include "NullAddress.hh"
61#include "hash_map.hh"
62#include "ProgramOperation.hh"
63
64namespace TTAProgram {
65 class Program;
66 class Procedure;
67 class Instruction;
68 class Move;
69 class InstructionReferenceManager;
70 class POMRelocBookkeeper;
71 class Address;
72 class NullAddress;
73 class Immediate;
74 class Terminal;
75}
76
77namespace TTAMachine {
78 class Machine;
79}
80
81namespace llvm {
82 class MachineFunction;
83 class MachineBasicBlock;
84 class MCInstrDesc;
85 class MCInstrInfo;
86}
87
88using boost::reverse_graph;
89
90class InterPassData;
92class CFGStatistics;
93
94/**
95 * Control Flow Graph.
96 *
97 * The basic blocks are initially in the original program order when traversed
98 * with nodeCount()/node().
99 */
100class ControlFlowGraph : public BoostGraph<BasicBlockNode, ControlFlowEdge> {
101public:
103 const TCEString name,
106 const TTAProgram::Procedure& procedure,
107 InterPassData& passData);
108 ControlFlowGraph(const TTAProgram::Procedure& procedure);
109 virtual ~ControlFlowGraph();
110
111 TCEString procedureName() const;
112 int alignment() const;
114
115 BasicBlockNode& entryNode() const;
116 BasicBlockNode& exitNode() const;
118
120 const CFGStatistics& statistics();
123
124 void copyToProcedure(
127
129 llvm::MachineFunction& mf,
131
134
136 EdgeSet incomingJumpEdges(const BasicBlockNode& bbn) const;
137 bool hasIncomingExternalJumps(const BasicBlockNode& bbn) const;
138
140
146
150
152 void detectBackEdges();
153
154 void reverseGuardOnOutEdges(const BasicBlockNode& bbn);
156 bool removeDeadCode,
159 llvm::MachineBasicBlock& getMBB(
160 llvm::MachineFunction& mf,
161 const TTAProgram::BasicBlock& bb) const;
162
164
165 bool isSingleBBLoop(const BasicBlockNode& node) const;
167
168 void addExit(NodeSet& retSourceNodes);
169
170 void sanitize();
171
173 TTAProgram::Move& move, BasicBlockNode& bb, int moveIndex);
174
177
178 BasicBlockNode* splitBB(BasicBlockNode& n, int remainingSize);
179
180 bool hasFallThruPredecessor(const BasicBlockNode& bbn);
181
183 const BasicBlockNode &src,
184 const TTAProgram::Terminal& jumpAddr,
185 const TTAMachine::Machine& mach) const;
186
188 const BasicBlockNode& src, const BasicBlockNode& dst) const;
189
190private:
191 // For temporary storage
192 typedef hash_map<InstructionAddress, const TTAProgram::Instruction*>
194 typedef std::vector<InstructionAddress> InstructionAddressVector;
195 // Type of reversed underlying graph, needed for control dependence
196 // analysis
197 typedef reverse_graph<ControlFlowGraph::Graph> ReversedGraph;
200 typedef std::pair<InstructionAddress, ControlFlowEdge::CFGEdgePredicate>
202 typedef std::set<ReturnSource> ReturnSourceSet;
203 /// DFS visitor which when finding back edge marks such edge as
204 /// back edge
205 class DFSBackEdgeVisitor : public boost::default_dfs_visitor {
206 public:
208 template < typename EdgeDescriptor, typename Graph >
209 void back_edge(EdgeDescriptor e, const Graph & g)const {
210 g[e]->setBackEdge();
211 }
212 };
213
214 void buildFrom(const TTAProgram::Procedure& procedure);
215 void createBBEdges(
216 const TTAProgram::Procedure& procedure,
217 InstructionAddressMap& leaders,
218 InstructionAddressMap& dataCodeRellocations);
219
221
223 const TTAProgram::Instruction& ins,
224 int moveIndex);
226 InstructionAddressMap& leaders,
227 const TTAProgram::Procedure& procedure);
229 InstructionAddressMap& leaders,
230 const TTAProgram::Procedure& procedure);
232 InstructionAddressMap& leaderSet,
233 InstructionAddressMap& dataCodeRellocations,
234 const TTAProgram::Procedure& procedure);
235
236 void createAllBlocks(
237 InstructionAddressMap& leaders,
238 const TTAProgram::Procedure& procedure);
241 const TTAProgram::Instruction& endBlock);
243 const TTAProgram::Instruction& iTail,
244 const TTAProgram::Instruction& iHead,
249
250 void directJump(
251 InstructionAddressMap& leaders,
252 const InstructionAddress& leaderAddr,
253 int insIndex,
254 int moveIndex,
255 const TTAProgram::Instruction& instructionTarget,
256 const TTAProgram::Procedure& procedure);
257 void indirectJump(
258 InstructionAddressMap& leaders,
259 const InstructionAddress& leaderAddr,
260 InstructionAddressMap& dataCodeRellocations,
261 int insIndex,
262 int moveIndex,
263 const TTAProgram::Procedure& procedure);
264 void createJumps(
265 InstructionAddressMap& leaders,
266 const InstructionAddress& leaderAddr,
267 InstructionAddressMap& dataCodeRellocations,
268 const TTAProgram::Procedure& procedure,
269 int insIndex,
270 int moveIndex);
271 unsigned int findNextIndex(
272 const TTAProgram::Procedure& proc,
273 int jumpInsIndex, int jumpMoveIndex);
274
275 void addExit();
276 void addEntryExitEdge();
277 void removeEntryExitEdge();
278
280 NodeSet findUnreachableNodes(const NodeSet& reachableNodes);
281
283
285 const NodeSet& unreachableNodes, DataDependenceGraph* ddg);
286 void mergeNodes(
287 BasicBlockNode& node1,
288 BasicBlockNode& node2,
291
292 bool jumpToBBN(
293 const TTAProgram::Terminal& jumpAddr, const BasicBlockNode& bbn) const;
294
295
297 JUMP_NOT_REMOVED = 0, /// nothing removed
298 JUMP_REMOVED, /// jump removed, other things remain in BB
299 LAST_ELEMENT_REMOVED /// last jump removed, no immeds in BB.
300 };
301
304 const TTAProgram::Instruction& target,
305 int idx,
306 DataDependenceGraph* ddg = NULL);
307
308 const llvm::MCInstrDesc&
309 findLLVMTargetInstrDesc(TCEString name, const llvm::MCInstrInfo& tii)
310 const;
311
312 void buildMBBFromBB(
313 llvm::MachineBasicBlock& mbb,
314 const TTAProgram::BasicBlock& bb) const;
315
316 // Data saved from original procedure object
323
324 // Collection of all basic blocks of the control flow graph indexed by
325 // the address of their start instruction (leader).
326 hash_map<InstructionAddress, BasicBlockNode*> blocks_;
327
328 // Mapping between original instructions and those in the cfg.
329 typedef hash_map<TTAProgram::Instruction*,TTAProgram::Instruction*>
331
334
335 // all basic blocks which contain a return instruction.
337
338 // Optional interpass data to aid in the construction of the CFG.
340
341 // IRM needs to be set explicitly if CFG is built and used without a
342 // Program object.
344
345 // Maps BasicBlockNode onto it's MachineBasicBlock equivalent
346 mutable std::map<const TTAProgram::BasicBlock*, llvm::MachineBasicBlock*>
348
349 /// For LLVM conversion: the dummy label instructions for SPU should be
350 /// created for with the given MCSymbol as argument after building.
351 mutable std::set<std::pair<ProgramOperationPtr, llvm::MCSymbol*> > tpos_;
352 /// For LLVM conversion: mapping of created MachineInstructions to TCE
353 /// ProgramOperations.
354 mutable std::map<ProgramOperation*, llvm::MachineInstr*>
356};
357#endif
UInt32 InstructionAddress
Definition BaseType.hh:175
#define IGNORE_COMPILER_WARNING(X)
#define POP_CLANG_DIAGS
#define POP_COMPILER_DIAGS
#define IGNORE_CLANG_WARNING(X)
GraphTraits::vertex_descriptor NodeDescriptor
Type with which nodes of the graph are seen internally.
boost::adjacency_list< boost::listS, boost::vecS, boost::bidirectionalS, Node *, Edge * > Graph
Internal graph type, providing actual graph-like operations. This type definition relies on bundled p...
std::set< ControlFlowEdge *, typename GraphEdge::Comparator > EdgeSet
Definition BoostGraph.hh:87
Node & node(const int index) const
EdgeDescriptor connectingEdge(const Node &nTail, const Node &nHead) const
virtual const TCEString & name() const
GraphTraits::edge_descriptor EdgeDescriptor
Type with which edges of the graph are seen internally.
std::set< BasicBlockNode *, typename GraphNode::Comparator > NodeSet
Definition BoostGraph.hh:86
DFS visitor which when finding back edge marks such edge as back edge.
void back_edge(EdgeDescriptor e, const Graph &g) const
std::vector< InstructionAddress > InstructionAddressVector
std::set< ReturnSource > ReturnSourceSet
void copyToLLVMMachineFunction(llvm::MachineFunction &mf, TTAProgram::InstructionReferenceManager *irm=NULL)
void setInstructionReferenceManager(TTAProgram::InstructionReferenceManager &irm)
void splitBasicBlocksWithCallsAndRefs()
BasicBlockNode & entryNode() const
void deleteNodeAndRefs(BasicBlockNode &node)
BasicBlockNode * fallThruSuccessor(const BasicBlockNode &bbn) const
const CFGStatistics & statistics()
void createJumps(InstructionAddressMap &leaders, const InstructionAddress &leaderAddr, InstructionAddressMap &dataCodeRellocations, const TTAProgram::Procedure &procedure, int insIndex, int moveIndex)
ReturnSourceSet returnSources_
@ LAST_ELEMENT_REMOVED
jump removed, other things remain in BB
@ JUMP_REMOVED
nothing removed
void mergeNodes(BasicBlockNode &node1, BasicBlockNode &node2, DataDependenceGraph *ddg, const ControlFlowEdge &connectingEdge)
hash_map< TTAProgram::Instruction *, TTAProgram::Instruction * > InsMap
bool jumpToBBN(const TTAProgram::Terminal &jumpAddr, const BasicBlockNode &bbn) const
void addExitFromSinkNodes(BasicBlockNode *exitNode)
void createBBEdges(const TTAProgram::Procedure &procedure, InstructionAddressMap &leaders, InstructionAddressMap &dataCodeRellocations)
unsigned int findNextIndex(const TTAProgram::Procedure &proc, int jumpInsIndex, int jumpMoveIndex)
bool hasIncomingExternalJumps(const BasicBlockNode &bbn) const
void buildFrom(const TTAProgram::Procedure &procedure)
void indirectJump(InstructionAddressMap &leaders, const InstructionAddress &leaderAddr, InstructionAddressMap &dataCodeRellocations, int insIndex, int moveIndex, const TTAProgram::Procedure &procedure)
hash_map< InstructionAddress, BasicBlockNode * > blocks_
void buildMBBFromBB(llvm::MachineBasicBlock &mbb, const TTAProgram::BasicBlock &bb) const
ControlFlowEdge * incomingFTEdge(const BasicBlockNode &bbn) const
TTAProgram::InstructionReferenceManager & instructionReferenceManager()
std::map< ProgramOperation *, llvm::MachineInstr * > programOperationToMIMap_
For LLVM conversion: mapping of created MachineInstructions to TCE ProgramOperations.
bool computeLeadersFromJumpSuccessors(InstructionAddressMap &leaders, const TTAProgram::Procedure &procedure)
BasicBlockNode * fallThroughPredecessor(const BasicBlockNode &bbn) const
void copyToProcedure(TTAProgram::Procedure &proc, TTAProgram::InstructionReferenceManager *irm=NULL)
ReversedGraph & reversedGraph() const
std::pair< InstructionAddress, ControlFlowEdge::CFGEdgePredicate > ReturnSource
std::set< std::pair< ProgramOperationPtr, llvm::MCSymbol * > > tpos_
For LLVM conversion: the dummy label instructions for SPU should be created for with the given MCSymb...
reverse_graph< ControlFlowGraph::Graph > ReversedGraph
BasicBlockNode * jumpSuccessor(BasicBlockNode &bbn)
bool hasMultipleUnconditionalSuccessors(const BasicBlockNode &node) const
InterPassData * passData_
TTAProgram::Address startAddress_
BasicBlockNode * splitBB(BasicBlockNode &n, int remainingSize)
bool hasFallThruPredecessor(const BasicBlockNode &bbn)
EdgeSet incomingJumpEdges(const BasicBlockNode &bbn) const
BasicBlockNode & exitNode() const
void directJump(InstructionAddressMap &leaders, const InstructionAddress &leaderAddr, int insIndex, int moveIndex, const TTAProgram::Instruction &instructionTarget, const TTAProgram::Procedure &procedure)
void computeLeadersFromRelocations(InstructionAddressMap &leaderSet, InstructionAddressMap &dataCodeRellocations, const TTAProgram::Procedure &procedure)
TTAProgram::Program * program() const
ControlFlowEdge & createControlFlowEdge(const TTAProgram::Instruction &iTail, const TTAProgram::Instruction &iHead, ControlFlowEdge::CFGEdgePredicate edgePredicate=ControlFlowEdge::CFLOW_EDGE_NORMAL, ControlFlowEdge::CFGEdgeType edgeType=ControlFlowEdge::CFLOW_EDGE_JUMP)
int findRelJumpDistance(const BasicBlockNode &src, const TTAProgram::Terminal &jumpAddr, const TTAMachine::Machine &mach) const
std::map< const TTAProgram::BasicBlock *, llvm::MachineBasicBlock * > bbMap_
bool allScheduledInBetween(const BasicBlockNode &src, const BasicBlockNode &dst) const
TTAProgram::Terminal * findJumpAddress(BasicBlockNode &src, ControlFlowEdge &e)
TTAProgram::Immediate * findLimmWrite(TTAProgram::Move &move, BasicBlockNode &bb, int moveIndex)
NodeSet findUnreachableNodes(const NodeSet &reachableNodes)
void createAllBlocks(InstructionAddressMap &leaders, const TTAProgram::Procedure &procedure)
void reverseGuardOnOutEdges(const BasicBlockNode &bbn)
void removeUnreachableNodes(const NodeSet &unreachableNodes, DataDependenceGraph *ddg)
hash_map< InstructionAddress, const TTAProgram::Instruction * > InstructionAddressMap
const llvm::MCInstrDesc & findLLVMTargetInstrDesc(TCEString name, const llvm::MCInstrInfo &tii) const
BoostGraph< BasicBlockNode, ControlFlowEdge >::NodeDescriptor NodeDescriptor
BasicBlockNode & createBlock(TTAProgram::Instruction &leader, const TTAProgram::Instruction &endBlock)
void computeLeadersFromRefManager(InstructionAddressMap &leaders, const TTAProgram::Procedure &procedure)
TTAProgram::Program * program_
TCEString procedureName() const
bool isSingleBBLoop(const BasicBlockNode &node) const
bool hasInstructionAnotherJump(const TTAProgram::Instruction &ins, int moveIndex)
TCEString printStatistics()
TTAProgram::InstructionReferenceManager * irm_
llvm::MachineBasicBlock & getMBB(llvm::MachineFunction &mf, const TTAProgram::BasicBlock &bb) const
BasicBlockNode & firstNormalNode() const
RemovedJumpData removeJumpToTarget(TTAProgram::CodeSnippet &cs, const TTAProgram::Instruction &target, int idx, DataDependenceGraph *ddg=NULL)
void optimizeBBOrdering(bool removeDeadCode, TTAProgram::InstructionReferenceManager &irm, DataDependenceGraph *ddg)
TTAProgram::Address endAddress_
BasicBlockNode * splitBasicBlockAtIndex(BasicBlockNode &bbn, int index)
const TTAProgram::Procedure * procedure_