22 #ifndef __EXEGRAPH_H__
23 #define __EXEGRAPH_H__
25 #include <elm/assert.h>
26 #include <elm/genstruct/Vector.h>
30 #include <elm/genstruct/DLList.h>
38 extern Identifier<bool>
START;
215 _buffer[
BODY] <<
"BODY";
279 inline N *
item(
void)
const {
return iter->source(); }
290 inline N *
item(
void)
const {
return iter->target(); }
309 _sequence = sequence;
310 _microprocessor = microprocessor;
314 int reg_bank_count = pf->
banks().count();
315 for(
int i = 0; i <reg_bank_count ; i++) {
317 rename_tables[i].table =
319 for (
int j=0 ; j<rename_tables[i].reg_bank->count() ; j++)
320 rename_tables[i].
table->set(j,NULL);
325 stage->deleteNodes();
326 if (stage->usesFunctionalUnits()) {
329 fu_stage->deleteNodes();
347 if (
inst->codePart() == BEFORE_PROLOGUE) {
348 N * node =
new N(
this, stage,
inst);
349 node->setLatency(MIN,0);
350 node->setLatency(
MAX,0);
352 stage->addNode(node);
354 for (
int b=0 ; b<reg_bank_count ; b++) {
355 for (
int r=0 ; r < rename_tables[b].reg_bank ->count() ; r++) {
356 rename_tables[b].table->set(r,node);
360 setFirstNode(BEFORE_PROLOGUE,
inst->firstNode());
361 setLastNode(BEFORE_PROLOGUE,
inst->lastNode());
364 if (!stage->usesFunctionalUnits()) {
365 N * node =
new N(
this, stage,
inst);
367 stage->addNode(node);
369 node->setNeedsOperands(
true);
371 node->setProducesOperands(
true);
375 bool first_fu_node =
true;
378 node =
new N(
this, fu_stage,
inst);
380 fu_stage->addNode(node);
382 stage->addNode(node);
384 node->setNeedsOperands(
true);
385 first_fu_node =
false;
389 node->setProducesOperands(
true);
391 if (
inst->codePart() != current_code_part) {
392 current_code_part =
inst->codePart();
393 setFirstNode(current_code_part,
inst->firstNode());
395 setLastNode(current_code_part,
inst->lastNode());
400 setEntryNode(sequence->
first()->firstNode());
407 if (previous != NULL) {
409 new ExeEdge(previous, node, ExeEdge::SOLID);
411 elm::cout <<
"SOLID edge between " << previous->name() <<
" and " << node->name() <<
" (pipeline order)\n";
414 if (node->needsOperands()) {
417 for(
int i = 0; i < reads.count(); i++) {
418 for (
int b=0 ; b<reg_bank_count ; b++) {
419 if (rename_tables[b].reg_bank == reads[i]->bank()) {
420 N *producing_node = rename_tables[b].table->get(reads[i]->number());
421 if (producing_node != NULL) {
425 if (pred == producing_node) {
433 elm::cout <<
"SOLID edge between " << producing_node->name() <<
" and " << node->name() <<
" (data dependency)\n";
434 new ExeEdge(producing_node, node, ExeEdge::SOLID);
442 if (node->producesOperands()) {
444 node->inst()->inst()->writtenRegs();
445 for(
int i = 0; i < writes.count(); i++) {
446 for (
int b=0 ; b<reg_bank_count ; b++) {
447 if (rename_tables[b].reg_bank == writes[i]->bank()) {
448 rename_tables[b].table->set(writes[i]->number(),node);
457 bool in_order =
false;
462 if (stage->width() == 1) {
466 if (previous != NULL) {
468 new ExeEdge(previous, node, ExeEdge::SOLID);
470 elm::cout <<
"SOLID edge between " << previous->name() <<
" and " << node->name() <<
" (program order)\n";
481 if (previous->inst()->codePart() == BEFORE_PROLOGUE) {
482 new ExeEdge(previous, node, ExeEdge::SOLID);
485 if (node->inst()->inst()->address().offset() != previous->inst()->inst()->address().offset() + 4)
486 new ExeEdge(previous, node, ExeEdge::SOLID);
488 if (node->inst()->inst()->address().offset() % (stage->width()*4) == 0)
489 new ExeEdge(previous, node, ExeEdge::SOLID);
491 new ExeEdge(previous, node, ExeEdge::SLASHED);
499 if (!stage->usesFunctionalUnits()) {
505 new ExeEdge(previous, node, ExeEdge::SLASHED);
507 elm::cout <<
"SLASHED edge between " << previous->name() <<
" and " << node->name() <<
" (stage width)\n";
510 if (previous_nodes.
count() == stage->width()) {
511 new ExeEdge(previous_nodes.
first(), node, ExeEdge::SOLID);
513 elm::cout <<
"SOLID edge between " << previous_nodes.
first()->name() <<
" and " << node->name() <<
" (stage width)\n";
527 new ExeEdge(previous, node, ExeEdge::SLASHED);
529 elm::cout <<
"SLASHED edge between " << previous->name() <<
" and " << node->name() <<
" (stage width)\n";
532 if (previous_nodes.
count() == fu_stage->
width()) {
533 new ExeEdge(previous_nodes.
first(), node, ExeEdge::SOLID);
535 elm::cout <<
"SOLID edge between " << previous_nodes.
first()->name() <<
" and " << node->name() <<
" (stage width)\n";
547 if (stage->usesFunctionalUnits()) {
550 N * previous_load = NULL;
551 N * previous_store = NULL;
553 if (node->inst()->inst()->isMem()) {
554 if (node->inst()->inst()->isLoad()) {
555 if (previous_store) {
556 new ExeEdge(previous_store, node, ExeEdge::SLASHED);
558 elm::cout <<
"SLASHED edge between " << previous_store->name() <<
" and " << node->name() <<
" (load after store)\n";
560 previous_load = node;
562 if (node->inst()->inst()->isStore()) {
563 if (previous_store) {
564 new ExeEdge(previous_store, node, ExeEdge::SLASHED);
566 elm::cout <<
"SLASHED edge between " << previous_store->name() <<
" and " << node->name() <<
" (store after store)\n";
569 new ExeEdge(previous_load, node, ExeEdge::SLASHED);
571 elm::cout <<
"SLASHED edge between " << previous_load->name() <<
" and " << node->name() <<
" (store after load)\n";
573 previous_store = node;
584 if (node->needsOperands()) {
586 new ExeEdge(previous, node, ExeEdge::SLASHED);
588 elm::cout <<
"SLASHED edge between " << previous->name() <<
" and " << node->name() <<
" (program order)\n";
597 if (stage->sourceQueue() != NULL) {
598 Queue<N> *queue = stage->sourceQueue();
601 if (st->destinationQueue() == queue) {
609 int index = node->inst()->
index() + stage->sourceQueue()->size();
610 for (
StageNodeIterator waiting_node(prod_stage) ; waiting_node ; waiting_node++) {
611 if (waiting_node->inst()->index() == index) {
612 new ExeEdge(node, waiting_node, ExeEdge::SLASHED);
623 if (!stage->usesFunctionalUnits()) {
626 if ((N*)node1 != (N*)node2)
627 node1->addContender(node2);
636 if ((N*)node1 != (N*)node2)
637 node1->addContender(node2);
646 for(
int i = 0; i <reg_bank_count ; i++)
647 delete rename_tables[i].
table;
void deleteNodes()
Clears the list of nodes related to this instruction.
Definition: ExeGraph.h:70
Definition: ExeGraph.h:248
N * _entry_node
Definition: ExeGraph.h:199
struct otawa::sem::inst inst
Definition: GenGraph.h:38
bool ended(void) const
Definition: ExeGraph.h:289
ExeNodeIterator(const PipelineStage< N > *stage)
Definition: Microprocessor.h:235
dtd::RefAttr< BasicBlock * > source("source", dtd::STRICT|dtd::REQUIRED)
ExeEdge * edge(void) const
Definition: ExeGraph.h:281
N * source(void) const
Definition: GenGraph.h:67
This class represents a bank of registers.
Definition: Register.h:68
void next(void)
Definition: ExeGraph.h:280
Definition: ExeGraph.h:243
Definition: ExeGraph.h:269
void setLatency(time_bound_t bound, int latency)
Definition: ExeGraph.h:175
Predecessor(const N *node)
Constructor.
Definition: ExeGraph.h:277
GenEdge(GenNode *source, GenNode *target)
Definition: GenGraph.h:66
struct otawa::ExeGraph::rename_table_t rename_table_t
PreorderIterator(ExeGraph< N > *graph, N *node)
Constructor.
Definition: ExeGraph.h:300
GenGraph< N, ExeEdge >::OutIterator iter
Definition: ExeGraph.h:294
ExeGraph()
Constructor.
Definition: ExeGraph.h:211
N * entryNode(void)
Definition: ExeGraph.h:229
elm::String _name
Definition: ExeGraph.h:152
bool _produces_operands
Definition: ExeGraph.h:151
Definition: features.h:47
edge_type_t _type
Definition: ExeGraph.h:129
Inst * _inst
Definition: ExeGraph.h:51
Iterator on the list of instructions of the sequence.
Definition: ExeGraph.h:93
GenGraph< N, ExeEdge > _graph
Definition: ExeGraph.h:209
FunctionalUnitPipelineIterator(const typename PipelineStage< N >::FunctionalUnit *fu)
Constructor.
Definition: ExeGraph.h:256
Definition: ExeGraph.h:121
Definition: ExeGraph.h:124
void setEntryNode(N *node)
Sets the entry node (used for topological graph exploration).
Definition: ExeGraph.h:227
int minLatency(void)
Definition: Microprocessor.h:200
GenGraph< N, typename ExeGraph< N >::ExeEdge > Graph
Definition: ExeGraph.h:297
Microprocessor< N > * _microprocessor
Definition: ExeGraph.h:203
N * _first_node[CODE_PARTS_NUMBER]
Definition: ExeGraph.h:200
hard::RegBank * reg_bank
Definition: ExeGraph.h:206
PipelineStage< N > * operandReadingStage(void)
Definition: Microprocessor.h:312
Definition: ExeGraph.h:205
Definition: ExeGraph.h:119
void trace(CString file, int line, CString fun)
void addNode(N *node)
Adds a node to the list of nodes related to this instruction.
Definition: ExeGraph.h:68
PipelineIterator(const Microprocessor< N > *processor)
Constructor.
Definition: ExeGraph.h:245
ContenderIterator(const ExeGraph< N >::ExeNode *node)
Constructor.
Definition: ExeGraph.h:193
int index()
Definition: ExeGraph.h:64
InstNodeIterator(const ExeInst< N > *inst)
Definition: ExeGraph.h:266
elm::genstruct::AllocatedTable< N * > * table
Definition: ExeGraph.h:207
int maxLatency(void)
Definition: Microprocessor.h:202
Definition: ExeGraph.h:118
ExeInst< N > * _inst
Definition: ExeGraph.h:147
int index(void)
Definition: Microprocessor.h:198
ExeInst(Inst *inst, BasicBlock *bb, typename ExeGraph< N >::code_part_t part, int index)
Constructor.
Definition: ExeGraph.h:58
void setIndex(int index)
Sets the instruction index.
Definition: ExeGraph.h:66
ExeEdge * edge(void) const
Definition: ExeGraph.h:292
Definition: ExeGraph.h:118
Definition: ExeGraph.h:145
Definition: ExeGraph.h:259
Inst * inst()
Definition: ExeGraph.h:60
ExeSequence< N > * _sequence
Definition: ExeGraph.h:202
A sequence of instructions (ExeInst)
Definition: ExeGraph.h:91
bool producesOperands(void)
Definition: ExeGraph.h:181
dtd::Element bb(dtd::make("bb", _BB).attr(id).attr(address).attr(size))
elm::genstruct::Vector< N * > _contenders
Definition: ExeGraph.h:154
elm::genstruct::Vector< N * > * contenders()
Definition: ExeGraph.h:187
ExeEdge(N *source, N *target, edge_type_t type)
Constructor.
Definition: ExeGraph.h:132
void next(void)
Definition: ExeGraph.h:291
void setLastNode(code_part_t part, N *node)
Definition: ExeGraph.h:236
void addLast(const T &value)
elm::String partName(code_part_t part)
Definition: ExeGraph.h:232
elm::genstruct::DLList< N * > _nodes
Definition: ExeGraph.h:55
ExeGraph< N >::code_part_t codePart()
Definition: ExeGraph.h:62
Definition: ExeGraph.h:275
Definition: Microprocessor.h:40
Definition: ExeGraph.h:116
N * firstNode()
Definition: ExeGraph.h:72
GenNode(graph::Graph *graph=0)
Definition: GenGraph.h:47
bool ended(void) const
Definition: ExeGraph.h:278
NodeIterator(const ExeInst *inst)
Constructor.
Definition: ExeGraph.h:80
Iterator(const DLList &_list)
Definition: ExeGraph.h:113
Definition: ExeGraph.h:191
edge_type_t
Definition: ExeGraph.h:123
elm::String name()
Returns the name of the node, composed of the name of the pipeline stage and the name of the instruct...
Definition: ExeGraph.h:189
Iterator on the list of nodes related to the instruction.
Definition: ExeGraph.h:78
N * item(void) const
Definition: ExeGraph.h:279
inst cont(void)
Definition: inst.h:151
virtual hard::Platform * platform(void)
Definition: WorkSpace.h:75
An iterator allowing to traverse the graph using preorder, that is, a node is only traversed when its...
Definition: PreorderIterator.h:31
PipelineStage< N > * pipelineStage(void)
Definition: ExeGraph.h:167
bool _needs_operands
Definition: ExeGraph.h:150
Graph * graph(void) const
Get the container graph if any.
Definition: Graph.h:75
void addContender(N *cont)
Adds a contender to the lists of contenders for the node.
Definition: ExeGraph.h:185
ExeNode(ExeGraph< N > *graph, PipelineStage< N > *stage, ExeInst< N > *inst)
Constructor.
Definition: ExeGraph.h:156
const T & last(void) const
InstIterator(const ExeSequence *seq)
Constructor.
Definition: ExeGraph.h:95
A workspace represents a program, its run-time and all information about WCET computation or any othe...
Definition: WorkSpace.h:67
Definition: Microprocessor.h:38
void setNeedsOperands(bool val)
Sets whether the node depends on input operands.
Definition: ExeGraph.h:179
const T & first(void) const
elm::String name()
Returns the name of the edge composed of the names of the source and target nodes separated by an arr...
Definition: ExeGraph.h:141
PipelineStage< N > * operandProducingStage(void)
Definition: Microprocessor.h:314
time_bound_t
Definition: ExeGraph.h:118
N * firstNode(code_part_t part)
Definition: ExeGraph.h:238
time_step_t
Definition: ExeGraph.h:119
enum otawa::ExeGraph::ExeEdge::edge_type_t edge_type_t_t
InstIterator(const ExeSequence< N > *sequence)
Constructor.
Definition: ExeGraph.h:261
Definition: ExeGraph.h:126
ExeGraph< N >::code_part_t _part
Definition: ExeGraph.h:54
BasicBlock * basicBlock()
Definition: ExeGraph.h:76
edge_type_t type(void)
Definition: ExeGraph.h:139
inst(void)
Definition: inst.h:118
Definition: ExeGraph.h:119
GenGraph< N, ExeEdge >::InIterator iter
Definition: ExeGraph.h:283
dtd::RefAttr< BasicBlock * > target("target", dtd::STRICT|dtd::REQUIRED)
An instruction represented in an ExeGraph.
Definition: ExeGraph.h:49
An execution graph that expresses precedence constraints on the execution of a sequence of instructio...
Definition: ExeGraph.h:40
Definition: Microprocessor.h:116
elm::String _name
Definition: ExeGraph.h:130
Definition: ExeGraph.h:119
bool needsOperands(void)
Definition: ExeGraph.h:177
Definition: ExeGraph.h:254
This is the minimal definition of a basic block.
Definition: BasicBlock.h:43
Definition: Microprocessor.h:65
Definition: ExeGraph.h:298
virtual void build(WorkSpace *fw, Microprocessor< N > *microprocessor, ExeSequence< N > *sequence)
Definition: ExeGraph.h:308
Successor(const N *node)
Constructor.
Definition: ExeGraph.h:288
N * _last_node[CODE_PARTS_NUMBER]
Definition: ExeGraph.h:201
PipelineStage< N > * _pipeline_stage
Definition: ExeGraph.h:148
int _latency[BOUNDS]
Definition: ExeGraph.h:149
ExeInst< N > * inst(void)
Definition: ExeGraph.h:169
elm::String shortName(void)
Definition: Microprocessor.h:186
This class represents assembly instruction of a piece of code.
Definition: Inst.h:62
Definition: ExeGraph.h:264
Definition: GenGraph.h:104
BasicBlock * _bb
Definition: ExeGraph.h:52
Definition: ExeGraph.h:115
Definition: ExeGraph.h:112
int latency()
Definition: ExeGraph.h:171
FunctionalUnitIterator(PipelineStage< N > *stage)
Constructor.
Definition: ExeGraph.h:251
N * target(void) const
Definition: GenGraph.h:68
Definition: GenGraph.h:121
N * item(void) const
Definition: ExeGraph.h:290
int latency(time_bound_t bound)
Definition: ExeGraph.h:173
void setFirstNode(code_part_t part, N *node)
Definition: ExeGraph.h:234
Definition: ExeGraph.h:119
code_part_t
Definition: ExeGraph.h:111
StageNodeIterator(const PipelineStage< N > *stage)
Definition: ExeGraph.h:271
Definition: ExeGraph.h:118
Definition: ExeGraph.h:125
N * lastNode(code_part_t part)
Definition: ExeGraph.h:240
Definition: ExeGraph.h:286
Iterator(const Vector &vec)
int _index
Definition: ExeGraph.h:53
GenGraph< N, typename ExeGraph< N >::ExeEdge > * graph()
Definition: ExeGraph.h:225
N * lastNode()
Definition: ExeGraph.h:74
elm::String _part_name[CODE_PARTS_NUMBER]
Definition: ExeGraph.h:204
Definition: ExeGraph.h:114
void setProducesOperands(bool val)
Sets whether the node produces output operands.
Definition: ExeGraph.h:183
int width(void) const
Definition: Microprocessor.h:182
int length()
Definition: ExeGraph.h:98