OpenASIP 2.2
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | List of all members
LoopPrologAndEpilogBuilder Class Reference

#include <LoopPrologAndEpilogBuilder.hh>

Collaboration diagram for LoopPrologAndEpilogBuilder:
Collaboration graph

Public Member Functions

 LoopPrologAndEpilogBuilder ()
 
virtual ~LoopPrologAndEpilogBuilder ()
 
virtual int build (DataDependenceGraph &ddg, SimpleResourceManager &rm, ControlFlowGraph &cfg, BasicBlockNode &loopBBN, int endCycle=-1, bool createEpilog=true)
 
BasicBlockNodeaddPrologFromRM (SimpleResourceManager &prologRM, SimpleResourceManager &loopRM, ControlFlowGraph &cfg, BasicBlockNode &loopBBN)
 
BasicBlockNodeaddEpilogFromRM (SimpleResourceManager &prologEpilogRM, int ii, ControlFlowGraph &cfg, BasicBlockNode &loopBBN)
 

Private Member Functions

void moveJumpDestination (TTAProgram::InstructionReferenceManager &irm, BasicBlockNode &tail, BasicBlockNode &dst, ControlFlowEdge &jumpEdge)
 
void addPrologIntoCfg (ControlFlowGraph &cfg, BasicBlockNode &prologBBN, BasicBlockNode &loopBBN)
 
void addEpilogIntoCfg (ControlFlowGraph &cfg, BasicBlockNode &epilogBBN, BasicBlockNode &loopBBN)
 
bool optimizeProlog (TTAProgram::BasicBlock &prolog)
 
bool optimizeEpilog (TTAProgram::BasicBlock &epilog)
 

Detailed Description

Classes that implement this interface are able to software bypass moves.

Definition at line 54 of file LoopPrologAndEpilogBuilder.hh.

Constructor & Destructor Documentation

◆ LoopPrologAndEpilogBuilder()

LoopPrologAndEpilogBuilder::LoopPrologAndEpilogBuilder ( )

Definition at line 56 of file LoopPrologAndEpilogBuilder.cc.

56 {
57}

◆ ~LoopPrologAndEpilogBuilder()

LoopPrologAndEpilogBuilder::~LoopPrologAndEpilogBuilder ( )
virtual

Definition at line 59 of file LoopPrologAndEpilogBuilder.cc.

59 {
60}

Member Function Documentation

◆ addEpilogFromRM()

BasicBlockNode * LoopPrologAndEpilogBuilder::addEpilogFromRM ( SimpleResourceManager prologEpilogRM,
int  ii,
ControlFlowGraph cfg,
BasicBlockNode loopBBN 
)

Definition at line 448 of file LoopPrologAndEpilogBuilder.cc.

450 {
451
453 BasicBlockNode* epilogNode = new BasicBlockNode(*epilogBB);
454
455 if (Application::verboseLevel() > 1) {
457 << "Copying epilog rm to bb" << epilogNode->toString()
458 << std::endl;
459 }
460
461 for (int i = BF2Scheduler::PROLOG_CYCLE_BIAS + ii;
462 i <= prologEpilogRM.largestCycle(); i++) {
463 TTAProgram::Instruction* newInstruction =
464 prologEpilogRM.instruction(i);
465 prologEpilogRM.loseInstructionOwnership(i);
466 epilogBB->add(newInstruction);
467 }
468 if (optimizeEpilog(*epilogBB)) {
469 addEpilogIntoCfg(cfg, *epilogNode, loopBBN);
470 epilogNode->setScheduled();
471 if (Application::verboseLevel() > 1) {
473 << "epilog added to cfg" << epilogNode->toString() << std::endl;
474
476 << "Disassembly of epilog" << std::endl <<
477 epilogBB->disassembly() << std::endl;
478 }
479 } else {
480 if (Application::verboseLevel() > 1) {
482 << "epilog empty, not added to cfg." << std::endl;
483 }
484 delete epilogNode;
485 }
486
487 return epilogNode;
488
489}
static int verboseLevel()
static std::ostream & logStream()
static const int PROLOG_CYCLE_BIAS
void setScheduled(bool state=true)
std::string toString() const
bool optimizeEpilog(TTAProgram::BasicBlock &epilog)
void addEpilogIntoCfg(ControlFlowGraph &cfg, BasicBlockNode &epilogBBN, BasicBlockNode &loopBBN)
virtual TTAProgram::Instruction * instruction(int cycle) const override
virtual void loseInstructionOwnership(int cycle)
virtual int largestCycle() const override
virtual void add(Instruction *ins)
virtual std::string disassembly() const

References TTAProgram::CodeSnippet::add(), addEpilogIntoCfg(), TTAProgram::CodeSnippet::disassembly(), SimpleResourceManager::instruction(), SimpleResourceManager::largestCycle(), Application::logStream(), SimpleResourceManager::loseInstructionOwnership(), optimizeEpilog(), BF2Scheduler::PROLOG_CYCLE_BIAS, BasicBlockNode::setScheduled(), BasicBlockNode::toString(), and Application::verboseLevel().

Here is the call graph for this function:

◆ addEpilogIntoCfg()

void LoopPrologAndEpilogBuilder::addEpilogIntoCfg ( ControlFlowGraph cfg,
BasicBlockNode epilogBBN,
BasicBlockNode loopBBN 
)
private

Adds an epilog into control flow graph.

Creates the node and fixed edges.

Parameters
cfgcfg where to add the epilog
prologBBbb which contains the epilog
loopBBNnode of cfg which contains the loop

Definition at line 166 of file LoopPrologAndEpilogBuilder.cc.

168 {
169
170 cfg.addNode(epilogBBN);
171 assert(cfg.outDegree(loopBBN) == 2);
172
173 for (int i = 0; i < cfg.outDegree(loopBBN); i++) {
174 ControlFlowEdge& loopExitEdge = cfg.outEdge(loopBBN,i);
175 if (!loopExitEdge.isFallThroughEdge()) {
176 continue;
177 }
178 BasicBlockNode& succNode = cfg.headNode(loopExitEdge);
179 cfg.moveInEdge(succNode, epilogBBN, loopExitEdge);
180 cfg.connectNodes(
181 epilogBBN, succNode, *(new ControlFlowEdge(
184 )));
185
186 return;
187 }
188 assert(false&&"Loop exit fall-thru not in ddg!");
189}
#define assert(condition)
virtual Node & headNode(const Edge &edge) const
virtual Edge & outEdge(const Node &node, const int index) const
virtual void addNode(Node &node)
virtual void moveInEdge(const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
virtual int outDegree(const Node &node) const
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
bool isFallThroughEdge() const

References BoostGraph< GraphNode, GraphEdge >::addNode(), assert, ControlFlowEdge::CFLOW_EDGE_FALLTHROUGH, ControlFlowEdge::CFLOW_EDGE_NORMAL, BoostGraph< GraphNode, GraphEdge >::connectNodes(), BoostGraph< GraphNode, GraphEdge >::headNode(), ControlFlowEdge::isFallThroughEdge(), BoostGraph< GraphNode, GraphEdge >::moveInEdge(), BoostGraph< GraphNode, GraphEdge >::outDegree(), and BoostGraph< GraphNode, GraphEdge >::outEdge().

Referenced by addEpilogFromRM(), and build().

Here is the call graph for this function:

◆ addPrologFromRM()

BasicBlockNode * LoopPrologAndEpilogBuilder::addPrologFromRM ( SimpleResourceManager prologRM,
SimpleResourceManager loopRM,
ControlFlowGraph cfg,
BasicBlockNode loopBBN 
)

Stupid immediates still have to be copied from the main loop :(

Definition at line 408 of file LoopPrologAndEpilogBuilder.cc.

411 {
412
413 int startCycle = prologRM.smallestCycle();
414
416 BasicBlockNode* prologNode = new BasicBlockNode(*prologBB);
417
418 if (Application::verboseLevel() > 1) {
420 << "Copying prolog rm to bb" << prologNode->toString()
421 << " Start cycle: " << startCycle << std::endl;
422 }
423 BasicBlockPass::copyRMToBB(prologRM, *prologBB, prologRM.machine(),
425 loopRM.initiationInterval()-1
427
428 if (optimizeProlog(*prologBB)) {
429 addPrologIntoCfg(cfg, *prologNode, loopBBN);
430 prologNode->setScheduled();
431
432 if (Application::verboseLevel() > 1) {
434 << "Prolog added to cfg" << prologNode->toString() << std::endl
435 << "Disassembly of prolog" << std::endl <<
436 prologBB->disassembly() << std::endl;
437 }
438 } else {
439 if (Application::verboseLevel() > 1) {
441 << "Empty prolog, not added to cfg" << std::endl;
442 }
443 delete prologNode;
444 }
445 return prologNode;
446}
static void copyRMToBB(SimpleResourceManager &rm, TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, int lastCycle=-1)
TTAProgram::InstructionReferenceManager & instructionReferenceManager()
void addPrologIntoCfg(ControlFlowGraph &cfg, BasicBlockNode &prologBBN, BasicBlockNode &loopBBN)
bool optimizeProlog(TTAProgram::BasicBlock &prolog)
const TTAMachine::Machine & machine() const
virtual int smallestCycle() const override
virtual unsigned initiationInterval() const

References addPrologIntoCfg(), BasicBlockPass::copyRMToBB(), TTAProgram::CodeSnippet::disassembly(), SimpleResourceManager::initiationInterval(), ControlFlowGraph::instructionReferenceManager(), Application::logStream(), ResourceManager::machine(), optimizeProlog(), BF2Scheduler::PROLOG_CYCLE_BIAS, BasicBlockNode::setScheduled(), SimpleResourceManager::smallestCycle(), BasicBlockNode::toString(), and Application::verboseLevel().

Here is the call graph for this function:

◆ addPrologIntoCfg()

void LoopPrologAndEpilogBuilder::addPrologIntoCfg ( ControlFlowGraph cfg,
BasicBlockNode prologBBN,
BasicBlockNode loopBBN 
)
private

Adds a prolog into control flow graph.

Creates the node and fixed edges and instruction references.

Parameters
cfgcfg where to add the prolog
prologBBbb which contains the prolog
loopBBNnode of cfg which contains the loop

Definition at line 120 of file LoopPrologAndEpilogBuilder.cc.

122 {
123
124 if (Application::verboseLevel() > 1) {
125 std::cerr << "adding prolog into cfg" << std::endl;
126 }
127 cfg.addNode(prologBBN);
128
129 // update incoming cfg edges to point into prolog
130 for (int i = 0; i < cfg.inDegree(loopBBN); i++) {
131 ControlFlowEdge&e = cfg.inEdge(loopBBN,i);
132 BasicBlockNode& tail = cfg.tailNode(e);
133 if (&tail != &loopBBN) {
134 cfg.moveInEdge(loopBBN, prologBBN,e);
135 i--;
136 if (e.isJumpEdge()) {
137 if (Application::verboseLevel() > 1) {
138 std::cerr << "\tmoving jump into loop into prolog"
139 << std::endl;
140 }
142 tail, prologBBN, e);
143 }
144 }
145 }
146
147 // connect prolog and loop
148 cfg.connectNodes(
149 prologBBN, loopBBN, *(new ControlFlowEdge(
152
153}
virtual Edge & inEdge(const Node &node, const int index) const
virtual int inDegree(const Node &node) const
virtual Node & tailNode(const Edge &edge) const
bool isJumpEdge() const
void moveJumpDestination(TTAProgram::InstructionReferenceManager &irm, BasicBlockNode &tail, BasicBlockNode &dst, ControlFlowEdge &jumpEdge)

References BoostGraph< GraphNode, GraphEdge >::addNode(), ControlFlowEdge::CFLOW_EDGE_FALLTHROUGH, ControlFlowEdge::CFLOW_EDGE_NORMAL, BoostGraph< GraphNode, GraphEdge >::connectNodes(), BoostGraph< GraphNode, GraphEdge >::inDegree(), BoostGraph< GraphNode, GraphEdge >::inEdge(), ControlFlowGraph::instructionReferenceManager(), ControlFlowEdge::isJumpEdge(), BoostGraph< GraphNode, GraphEdge >::moveInEdge(), moveJumpDestination(), BoostGraph< GraphNode, GraphEdge >::tailNode(), and Application::verboseLevel().

Referenced by addPrologFromRM(), and build().

Here is the call graph for this function:

◆ build()

int LoopPrologAndEpilogBuilder::build ( DataDependenceGraph ddg,
SimpleResourceManager rm,
ControlFlowGraph cfg,
BasicBlockNode loopBBN,
int  endCycle = -1,
bool  createEpilog = true 
)
virtual

Definition at line 192 of file LoopPrologAndEpilogBuilder.cc.

195 {
196
197 if (Application::verboseLevel() > 1) {
198 Application::logStream() << "Building epilog and prolog for the loop."
199 << std::endl;
200 std::cerr << "rm.smallestCycle: " << rm.smallestCycle() << std::endl;
201 std::cerr << "end cycle: " << endCycle << std::endl;
202 }
203
204 int ii = rm.initiationInterval();
205 if (Application::verboseLevel() > 1) {
206 Application::logStream() << "Investigate nodes. ii: " << ii
207 << std::endl;
208 }
209
210 // resolve how many times loop overlaps
211 int overlap_count;
212 if (endCycle != -1) {
213 overlap_count = ((endCycle - rm.smallestCycle()) / ii);
214 } else {
215 overlap_count = ddg.largestCycle() / ii;
216 }
217
218 TTAProgram::Move* jumpMove = NULL;
219 if (overlap_count > 0) {
220 if (Application::verboseLevel() > 1) {
222 << "Building prolog and epilog..... "
223 << " Overlapcount: " << overlap_count << std::endl;
224 }
225
226 DataDependenceGraph* rootDDG = static_cast<DataDependenceGraph*>(
227 ddg.rootGraph());
228
229 // make room for moves of prolog and epilog
230 TTAProgram::BasicBlock *prolog =
232 BasicBlockNode *prologNode = new BasicBlockNode(*prolog, true, true,
233 loopBBN.originalStartAddress(), false);
234
235 TTAProgram::BasicBlock *epilog = NULL;
236 BasicBlockNode* epilogNode = NULL;
237 if (createEpilog) {
238 epilog =
240 epilogNode = new BasicBlockNode(
241 *epilog, true, true, loopBBN.originalStartAddress(), false);
242 }
243 for (int i = 0; i < overlap_count * ii; i++) {
244 prolog->add(new TTAProgram::Instruction());
245 if (createEpilog) {
246 epilog->add(new TTAProgram::Instruction());
247 }
248 }
249
250 // scan for long immediates. these can be copied to both
251 // prolog and epilog.
252 for (int j = 0; j < overlap_count; j++) {
253 for (int i = 0; i < ii; i++) {
255 for (int k = 0; k < ins->immediateCount(); k++) {
256 auto newImm = ins->immediate(k).copy();
257 auto newImm2 = ins->immediate(k).copy();
258 prolog->instructionAtIndex(i+j*ii).addImmediate(newImm);
259 if (createEpilog) {
260 epilog->instructionAtIndex(i+j*ii).addImmediate(newImm2);
261 }
262 }
263 }
264 }
265 int newZero = endCycle + 1 - (ii * (1 + overlap_count));
266 for (int i = 0 ; i < overlap_count; i++) {
267 for (int j = 0; j < ddg.nodeCount(); j++) {
268 MoveNode& n = ddg.node(j);
269
270 // ignore jump
271 if (n.move().isControlFlowMove()) {
272 jumpMove = &n.move();
273 continue;
274 }
275
276 int cycle;
277 if (endCycle != -1) {
278 cycle = n.cycle() - newZero;
279 } else {
280 cycle = n.cycle();
281 }
282 int round = cycle / ii;
283 int place = cycle % ii;
284
285 MoveNode* nodeCopy;
286 if (createEpilog || round == 0) {
287 nodeCopy = n.copy();
288 nodeCopy->move().setGuard(NULL);
289
290 if (endCycle != -1) {
291 nodeCopy->setCycle(place + newZero);
292 } else {
293 nodeCopy->setCycle(place);
294 }
295
296 if (Application::verboseLevel() > 1) {
298 << "Node cycle: " << cycle
299 << " round: " << round
300 << " place: " << place << " "
301 << n.toString()<< "\t" ;
302 }
303 } else {
304 continue;
305 }
306/*
307 if (createEpilog) {
308 if (n.move().isControlFlowMove()) {
309 assert(!n.move().isUnconditional());
310 if (Application::verboseLevel() > 1) {
311 std::cerr << "jumpmove reversing guard at address: "
312 << &nodeCopy->move()<< std::endl;
313 }
314 nodeCopy->move().setGuard(
315 TTAProgram::CodeGenerator::createInverseGuard(
316 n.move().guard(), &n.move().bus()));
317 // TODO: set jump target to first of epilog
318 nodeCopy->move().setSource(
319 new TTAProgram::TerminalInstructionReference(
320 cfg.instructionReferenceManager().createReference(
321 epilog->instructionAtIndex(0))));
322 }
323 }
324*/
325 // select if node should go to prolog or epilog
326 if (round <= i) {
327 prolog->instructionAtIndex(
328 (i*ii)+place).addMove(nodeCopy->movePtr());
329 if (Application::verboseLevel() > 1) {
330 Application::logStream() << " to prolog" << std::endl;
331 }
332 rootDDG->addNode(*nodeCopy, *prologNode);
333 rootDDG->copyExternalInEdges(*nodeCopy, n);
334 rootDDG->copyExternalOutEdges(*nodeCopy, n);
335
336 } else {
337 if (createEpilog) {
338 epilog->instructionAtIndex(
339 (i*ii)+place).addMove(nodeCopy->movePtr());
340 if (Application::verboseLevel() > 1) {
341 Application::logStream() << " to epilog" << std::endl;
342 }
343 rootDDG->addNode(*nodeCopy, *epilogNode);
344 rootDDG->copyExternalInEdges(*nodeCopy, n);
345 rootDDG->copyExternalOutEdges(*nodeCopy, n);
346 }
347 }
348 }
349 }
350 assert(jumpMove != NULL);
351
352 if (Application::verboseLevel() > 1) {
354 << "Disassembly of prolog" << std::endl <<
355 prolog->disassembly() << std::endl;
356 if (createEpilog) {
358 << "Disassembly of epilog" << std::endl <<
359 epilog->disassembly() << std::endl;
360 }
361 }
362
363 if (optimizeProlog(*prolog)) {
364 if (Application::verboseLevel() > 1) {
366 << "Disassembly of optimized prolog" << std::endl <<
367 prolog->disassembly() << std::endl;
368 }
369 addPrologIntoCfg(cfg, *prologNode, loopBBN);
370 } else {
371 delete prologNode;
372 }
373 if (Application::verboseLevel() > 1) {
375 << "Prolog optimized."
376 << std::endl;
377 }
378 if (createEpilog) {
379 if (optimizeEpilog(*epilog)) {
380 if (Application::verboseLevel() > 1) {
382 << "Disassembly of optimized epilog" << std::endl <<
383 epilog->disassembly() << std::endl;
384 }
385 addEpilogIntoCfg(cfg, *epilogNode, loopBBN);
386 } else {
387 delete epilogNode; // TODO: what about the BB?
388 }
389 if (Application::verboseLevel() > 1) {
391 << "Epilog optimized."
392 << std::endl;
393 }
394 }
395 } else {
396 if (Application::verboseLevel() > 1) {
398 << "No overlapping instructions.No need for prolog or epilog."
399 << "Should have used normal scheduler."
400 << std::endl;
401 }
402 }
403
404 return overlap_count;
405}
InstructionAddress originalStartAddress() const
BoostGraph * rootGraph()
int nodeCount() const
Node & node(const int index) const
void copyExternalInEdges(MoveNode &nodeCopy, const MoveNode &source)
void copyExternalOutEdges(MoveNode &nodeCopy, const MoveNode &source)
void addNode(MoveNode &moveNode)
int cycle() const
Definition MoveNode.cc:421
std::shared_ptr< TTAProgram::Move > movePtr()
std::string toString() const
Definition MoveNode.cc:576
TTAProgram::Move & move()
void setCycle(const int newcycle)
Definition MoveNode.cc:503
MoveNode * copy()
Definition MoveNode.cc:135
virtual Instruction & instructionAtIndex(int index) const
std::shared_ptr< Immediate > copy() const
Definition Immediate.cc:131
void addImmediate(std::shared_ptr< Immediate > imm)
Immediate & immediate(int i) const
void addMove(std::shared_ptr< Move > move)
bool isControlFlowMove() const
Definition Move.cc:233
void setGuard(MoveGuard *guard)
Definition Move.cc:360

References TTAProgram::CodeSnippet::add(), addEpilogIntoCfg(), TTAProgram::Instruction::addImmediate(), TTAProgram::Instruction::addMove(), DataDependenceGraph::addNode(), addPrologIntoCfg(), assert, MoveNode::copy(), TTAProgram::Immediate::copy(), DataDependenceGraph::copyExternalInEdges(), DataDependenceGraph::copyExternalOutEdges(), MoveNode::cycle(), TTAProgram::CodeSnippet::disassembly(), TTAProgram::Instruction::immediate(), TTAProgram::Instruction::immediateCount(), SimpleResourceManager::initiationInterval(), SimpleResourceManager::instruction(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::Move::isControlFlowMove(), DataDependenceGraph::largestCycle(), Application::logStream(), MoveNode::move(), MoveNode::movePtr(), BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), optimizeEpilog(), optimizeProlog(), BasicBlockNode::originalStartAddress(), BoostGraph< GraphNode, GraphEdge >::rootGraph(), MoveNode::setCycle(), TTAProgram::Move::setGuard(), SimpleResourceManager::smallestCycle(), MoveNode::toString(), and Application::verboseLevel().

Here is the call graph for this function:

◆ moveJumpDestination()

void LoopPrologAndEpilogBuilder::moveJumpDestination ( TTAProgram::InstructionReferenceManager irm,
BasicBlockNode tail,
BasicBlockNode dst,
ControlFlowEdge jumpEdge 
)
private

Definition at line 63 of file LoopPrologAndEpilogBuilder.cc.

66 {
67 TTAProgram::BasicBlock& tailBB = tail.basicBlock();
68
69 auto predicate = jumpEdge.edgePredicate();
70 std::pair<int, TTAProgram::Move*> jumpData =
71 CopyingDelaySlotFiller::findJump(tailBB, &predicate);
72
73 std::pair<TTAProgram::Move*, std::shared_ptr<TTAProgram::Immediate> >
74 jumpAddressData;
75
76 // should be the same
77 int jumpIndex = jumpData.first;
78 TTAProgram::Move* jumpMove = jumpData.second;
79 if (jumpMove == NULL) {
80 abortWithError("incoming jump not found");
81 }
82
86
87 if (!jumpMove->source().isInstructionAddress()) {
88 // address comes from LIMM, search the write to limm reg.
89 jumpAddressData =
91 jumpIndex, *jumpMove, irm);
92 if (jumpAddressData.first == NULL &&
93 jumpAddressData.second == NULL) {
94 //Imm source not found, aborting
95 abortWithError("Unknown immediate contains jump address");
96 return;
97 }
98 if (jumpAddressData.first != NULL) {
99 jumpAddressData.first->setSource(
101 } else {
102 jumpAddressData.second->setValue(
104 }
105 } else {
106 jumpMove->source().setInstructionReference(ir);
107 }
108}
#define abortWithError(message)
TTAProgram::BasicBlock & basicBlock()
CFGEdgePredicate edgePredicate() const
static std::pair< TTAProgram::Move *, std::shared_ptr< TTAProgram::Immediate > > findJumpImmediate(int jumpIndex, TTAProgram::Move &jumpMove, TTAProgram::InstructionReferenceManager &irm)
static std::pair< int, TTAProgram::Move * > findJump(TTAProgram::BasicBlock &bb, ControlFlowEdge::CFGEdgePredicate *pred=nullptr)
int skippedFirstInstructions() const
Definition BasicBlock.cc:88
InstructionReference createReference(Instruction &ins)
Terminal & source() const
Definition Move.cc:302
virtual void setInstructionReference(InstructionReference ref)
Definition Terminal.cc:404
virtual bool isInstructionAddress() const
Definition Terminal.cc:87

References abortWithError, BasicBlockNode::basicBlock(), TTAProgram::InstructionReferenceManager::createReference(), ControlFlowEdge::edgePredicate(), CopyingDelaySlotFiller::findJump(), CopyingDelaySlotFiller::findJumpImmediate(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::Terminal::isInstructionAddress(), TTAProgram::Terminal::setInstructionReference(), TTAProgram::BasicBlock::skippedFirstInstructions(), and TTAProgram::Move::source().

Referenced by addPrologIntoCfg().

Here is the call graph for this function:

◆ optimizeEpilog()

bool LoopPrologAndEpilogBuilder::optimizeEpilog ( TTAProgram::BasicBlock epilog)
private

Definition at line 575 of file LoopPrologAndEpilogBuilder.cc.

575 {
576
577 if (epilog.instructionCount() == 0) {
578 return false;
579 }
580
581 for (int i = epilog.instructionCount() -1 ; i >= 0 ; i--) {
583 // check for moves is enough. no imms after moves.
584 if (ins.moveCount() > 0) {
585 break;
586 } else {
587 // empty? leave one ins behind just for
588 if (i == 0) {
589 return false;
590 }
591 assert(i!= 0);
592 epilog.remove(ins);
593 delete &ins;
594 }
595 }
596 return true;
597}
virtual int instructionCount() const
virtual void remove(Instruction &ins)

References assert, TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Instruction::moveCount(), and TTAProgram::CodeSnippet::remove().

Referenced by addEpilogFromRM(), and build().

Here is the call graph for this function:

◆ optimizeProlog()

bool LoopPrologAndEpilogBuilder::optimizeProlog ( TTAProgram::BasicBlock prolog)
private

Definition at line 492 of file LoopPrologAndEpilogBuilder.cc.

492 {
493
494 if (prolog.instructionCount() == 0) {
495 return false;
496 }
497 // optimize away immediate values not used
498 for (int i = 0; i < prolog.instructionCount() ;i++) {
500 for (int j = 0; j < ins.immediateCount(); j++) {
501 bool used = false;
502 bool overwritten = false;
503 TTAProgram::Immediate& imm = ins.immediate(j);
504 const TTAProgram::Terminal& t = imm.destination();
505 const TTAProgram::Terminal& dst = imm.destination();
506 const TTAMachine::ImmediateUnit& immu = dst.immediateUnit();
507 for (int k = i + immu.latency() ;
508 k < prolog.instructionCount() &&
509 !used && !overwritten; k++) {
510
512 // if immu has latency 0, check immediate before moves.
513 if (immu.latency() == 0 && k > i) {
514 for (int l = 0; l < ins2.immediateCount(); l++) {
515 const TTAProgram::Immediate& imm2 = ins2.immediate(l);
516 const TTAProgram::Terminal& t2 = imm2.destination();
517 if (&t2.immediateUnit() == & t.immediateUnit() &&
518 t2.index() == t.index()) {
519 overwritten = true;
520 break;
521 }
522 }
523 }
524
525 for (int l = 0; l < ins2.moveCount(); l++) {
526 const TTAProgram::Move& m = ins2.move(l);
527 const TTAProgram::Terminal& t2 = m.source();
528 if (t2.isImmediateRegister() &&
529 &t2.immediateUnit() == &dst.immediateUnit() &&
530 t2.index() == dst.index()) {
531 used = true;
532 break;
533 }
534 }
535 // if immu has latency 1, check moves before imms
536 if (immu.latency() == 1) {
537 for (int l = 0; l < ins2.immediateCount(); l++) {
538 const TTAProgram::Immediate& imm2 = ins2.immediate(l);
539 const TTAProgram::Terminal& t2 = imm2.destination();
540 if (&t2.immediateUnit() == & t.immediateUnit() &&
541 t2.index() == t.index()) {
542 overwritten = true;
543 break;
544 }
545 }
546 }
547 }
548 if (!used && overwritten) {
549 ins.removeImmediate(imm);
550 }
551 }
552 }
553 for (int i = 0; i <= prolog.instructionCount() -1 ;i++) {
555 // check for moves is enough. no imms after moves.
556 if (ins.moveCount() > 0 || ins.immediateCount() > 0) {
557 break;
558 } else {
559 // empty? leave one ins behind just for
560 if (i == prolog.instructionCount() - 1) {
561 return false;
562 }
563 prolog.remove(ins);
564 delete &ins;
565 // We removed current instruction, there shell be new current
566 // instruction once we increse i at beginning of the loop.
567 i--;
568 }
569 }
570 return true;
571}
virtual int latency() const
const Terminal & destination() const
Definition Immediate.cc:92
void removeImmediate(Immediate &imm)
Move & move(int i) const
virtual int index() const
Definition Terminal.cc:274
virtual bool isImmediateRegister() const
Definition Terminal.cc:97
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
Definition Terminal.cc:240

References TTAProgram::Immediate::destination(), TTAProgram::Instruction::immediate(), TTAProgram::Instruction::immediateCount(), TTAProgram::Terminal::immediateUnit(), TTAProgram::Terminal::index(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Terminal::isImmediateRegister(), TTAMachine::ImmediateUnit::latency(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), TTAProgram::CodeSnippet::remove(), TTAProgram::Instruction::removeImmediate(), and TTAProgram::Move::source().

Referenced by addPrologFromRM(), and build().

Here is the call graph for this function:

The documentation for this class was generated from the following files: