OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
SimpleIfConverter Class Reference

#include <SimpleIfConverter.hh>

Inheritance diagram for SimpleIfConverter:
Inheritance graph
Collaboration diagram for SimpleIfConverter:
Collaboration graph

Classes

struct  CandidateBlocks
 

Public Member Functions

 SimpleIfConverter (InterPassData &data, const TTAMachine::Machine &targetMachine)
 
virtual void handleControlFlowGraph (ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
 
virtual void handleProcedure (TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetMachine)
 
virtual void handleProgram (TTAProgram::Program &program, const TTAMachine::Machine &targetMachine)
 
virtual std::string shortDescription () const
 
- Public Member Functions inherited from ControlFlowGraphPass
 ControlFlowGraphPass (InterPassData &data)
 
virtual ~ControlFlowGraphPass ()
 
void executeBasicBlockPass (ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine, BasicBlockPass &bbPass)
 
- Public Member Functions inherited from SchedulerPass
 SchedulerPass (InterPassData &data)
 
virtual ~SchedulerPass ()
 
InterPassDatainterPassData ()
 
virtual std::string longDescription () const
 

Static Public Member Functions

static bool removeJump (TTAProgram::BasicBlock &bb)
 
static ProgramOperationPtr fixTerminalPO (TTAProgram::TerminalFUPort &terminal, std::map< ProgramOperationPtr, ProgramOperationPtr > &poMapping)
 

Private Member Functions

CandidateBlocksdetectDiamond (BasicBlockNode &bbn, BasicBlockNode &fallThruNode, BasicBlockNode &jumpDestNode, ControlFlowGraph &cfg)
 
CandidateBlocksdetectTriangleViaJump (BasicBlockNode &bbn, BasicBlockNode &fallThruNode, BasicBlockNode &jumpDestNode, ControlFlowGraph &cfg)
 
CandidateBlocksdetectTriangleViaFt (BasicBlockNode &bbn, BasicBlockNode &fallThruNode, BasicBlockNode &jumpDestNode, ControlFlowGraph &cfg)
 
std::pair< BasicBlockNode *, BasicBlockNode * > successors (BasicBlockNode &node, ControlFlowGraph &cfg)
 
CandidateBlockssearchCandidate (ControlFlowGraph &cfg)
 
void addJump (TTAProgram::BasicBlock &bb, BasicBlockNode &bbn)
 
void appendBB (const TTAProgram::BasicBlock &src, TTAProgram::BasicBlock &dest, TTAProgram::MoveGuard *mg, bool removeJumps)
 
bool writesRegister (const TTAProgram::BasicBlock &bb, int index, const TTAMachine::RegisterFile &rf, bool ignoreLastInstruction)
 
bool hasConditionals (TTAProgram::BasicBlock &bb)
 
bool canConvert (CandidateBlocks *candidates, ControlFlowGraph &cfg)
 
void combineBlocks (CandidateBlocks &bblocks)
 
void convert (CandidateBlocks &bblocks, ControlFlowGraph &cfg)
 
void updateCfg (CandidateBlocks &bblocks, ControlFlowGraph &cfg)
 
- Private Member Functions inherited from ProcedurePass
 ProcedurePass (InterPassData &data)
 
virtual ~ProcedurePass ()
 
- Private Member Functions inherited from SchedulerPass
 SchedulerPass (InterPassData &data)
 
virtual ~SchedulerPass ()
 
InterPassDatainterPassData ()
 
virtual std::string longDescription () const
 
- Private Member Functions inherited from ProgramPass
 ProgramPass (InterPassData &data)
 
virtual ~ProgramPass ()
 

Private Attributes

TTAProgram::CodeGeneratorcodeGenerator_
 
TTAProgram::InstructionReferenceManagerirm_
 
int diamonds_
 
int diamonds2_
 
int triangles1_
 
int triangles2_
 
int grAborts_
 
int grDefAborts_
 
int grUseAborts_
 
int loopAborts_
 
int uncondAborts_
 
int sizeAborts_
 
int succAborts_
 
int diamondSizeLimit_
 
int triangleSizeLimit1_
 
int triangleSizeLimit2_
 

Additional Inherited Members

- Static Private Member Functions inherited from ProcedurePass
static void copyCfgToProcedure (TTAProgram::Procedure &procedure, ControlFlowGraph &cfg)
 
static void executeControlFlowGraphPass (TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetmachine, ControlFlowGraphPass &cfgp)
 
- Static Private Member Functions inherited from ProgramPass
static void executeProcedurePass (TTAProgram::Program &program, const TTAMachine::Machine &targetMachine, ProcedurePass &procedurePass)
 

Detailed Description

Definition at line 40 of file SimpleIfConverter.hh.

Constructor & Destructor Documentation

◆ SimpleIfConverter()

SimpleIfConverter::SimpleIfConverter ( InterPassData data,
const TTAMachine::Machine targetMachine 
)

Constructor

Parameters
InterPassDataInterPassData. Not used.
dsLimitdiamond-shape size limit
tsLimit1triangle-shape size limit(convert fall-thru)
tsLimit2triangle-shape size limit(convert jump)

Definition at line 60 of file SimpleIfConverter.cc.

61 :
63 ProgramPass(data), codeGenerator_(NULL), irm_(NULL),
69
70 // allow overriding the thresholds using a scheduler command line switch
73 if (opts != NULL && opts->ifConversionThreshold() > -1) {
77 } else if (diamondSizeLimit_ == -1 ||
78 triangleSizeLimit1_ == -1 ||
79 triangleSizeLimit2_ == -1) {
80
81 // fall back to an heuristics to determine proper limits for
82 // if-conversion according to the available ILP in the target
83 // machine
84
85 MachineAnalysis ma(targetMachine);
86
87 // rf ports can be shared by ops with neg guards, so
88 // rfilp * 2 on this heuristic.
89 float diamondOperations =
90 pow(pow(ma.busILP(), -2) +
91 pow((ma.fuILP()*2), -2) +
92 pow((ma.bypassedRfILP()*2), -2), -0.5)
93 * (1+targetMachine.controlUnit()->delaySlots());
94
95 // on triangle structures there is no moves with opposite guards,
96 // use the default averageilp
97 float triangleOperations = ma.averageILP()
98 * (1+targetMachine.controlUnit()->delaySlots());
99
100 if (diamondSizeLimit_ == -1) {
101 diamondSizeLimit_ = int(diamondOperations*2.25);
102 }
103 if (triangleSizeLimit1_ == -1) {
104 triangleSizeLimit1_ = int(triangleOperations*1.5);
105 }
106 if (triangleSizeLimit2_ == -1) {
107 triangleSizeLimit2_ = int(triangleOperations*1.5);
108 }
109 }
110
111 if (Application::verboseLevel() > 2) {
113 << "if-conversion thresholds:" << std::endl
114 << " diamond: " << diamondSizeLimit_ << std::endl
115 << "triangle1: " << triangleSizeLimit1_ << std::endl
116 << "triangle2: " << triangleSizeLimit2_ << std::endl;
117 }
118
119}
static CmdLineOptions * cmdLineOptions()
static int verboseLevel()
static std::ostream & logStream()
virtual int ifConversionThreshold() const
TTAProgram::InstructionReferenceManager * irm_
TTAProgram::CodeGenerator * codeGenerator_
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345

References MachineAnalysis::averageILP(), MachineAnalysis::busILP(), MachineAnalysis::bypassedRfILP(), Application::cmdLineOptions(), TTAMachine::Machine::controlUnit(), TTAMachine::ControlUnit::delaySlots(), diamondSizeLimit_, MachineAnalysis::fuILP(), SchedulerCmdLineOptions::ifConversionThreshold(), Application::logStream(), triangleSizeLimit1_, triangleSizeLimit2_, and Application::verboseLevel().

Here is the call graph for this function:

Member Function Documentation

◆ addJump()

void SimpleIfConverter::addJump ( TTAProgram::BasicBlock bb,
BasicBlockNode dest 
)
private

Adds a jump at the end of a basic block.

This may create an dangling instr reference?

Parameters
bbbasicBlock add the jump at end of this basic block.
destdestination of the jump.

Definition at line 704 of file SimpleIfConverter.cc.

705 {
706 Instruction* ins = new Instruction;
709
710 ins->addMove(
712
713 bb.add(ins);
714}
TTAProgram::BasicBlock & basicBlock()
std::shared_ptr< TTAProgram::Move > createJump(TTAProgram::InstructionReference &dst)
virtual Instruction & firstInstruction() const
virtual void add(Instruction *ins)
InstructionReference createReference(Instruction &ins)
void addMove(std::shared_ptr< Move > move)

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), BasicBlockNode::basicBlock(), codeGenerator_, TTAProgram::CodeGenerator::createJump(), TTAProgram::InstructionReferenceManager::createReference(), TTAProgram::CodeSnippet::firstInstruction(), and irm_.

Referenced by combineBlocks().

Here is the call graph for this function:

◆ appendBB()

void SimpleIfConverter::appendBB ( const TTAProgram::BasicBlock src,
TTAProgram::BasicBlock dest,
TTAProgram::MoveGuard mg,
bool  removeJumps 
)
private

Definition at line 587 of file SimpleIfConverter.cc.

589 {
590
591 std::map<ProgramOperationPtr,ProgramOperationPtr> poMapping;
592
593 for (int j = 0; j < src.instructionCount(); j++) {
594 const Instruction& ins = src.instructionAtIndex(j);
595 Instruction* newIns = new Instruction();
596 dest.add(newIns);
597 for (int i = 0; i < ins.moveCount(); i++) {
598 const TTAProgram::Move& move = ins.move(i);
599 if (!(move.isJump() && removeJumps)) {
600 auto moveCopy = move.copy();
601 if (moveCopy->source().isFUPort()) {
602 ProgramOperationPtr newPO =
604 static_cast<TTAProgram::TerminalFUPort&>(
605 moveCopy->source()),
606 poMapping);
607 if (newPO != NULL) {
608 MoveNode* mn = new MoveNode(moveCopy);
609 newPO->addOutputNode(*mn);
610 mn->setSourceOperationPtr(newPO);
611 }
612 }
613 if (moveCopy->destination().isFUPort()) {
615 static_cast<TTAProgram::TerminalFUPort&>(
616 moveCopy->destination()),
617 poMapping);
618 if (newPO != NULL) {
619 MoveNode* mn = new MoveNode(moveCopy);
620 newPO->addInputNode(*mn);
622 }
623 }
624
625 if (!moveCopy->isReturn() && mg != NULL) {
626 moveCopy->setGuard(mg->copy());
627 }
628 newIns->addMove(moveCopy);
629 }
630 }
631 }
632}
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition MoveNode.hh:53
void setSourceOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:541
void addDestinationOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:533
static ProgramOperationPtr fixTerminalPO(TTAProgram::TerminalFUPort &terminal, std::map< ProgramOperationPtr, ProgramOperationPtr > &poMapping)
virtual int instructionCount() const
virtual Instruction & instructionAtIndex(int index) const
Move & move(int i) const
MoveGuard * copy() const
Definition MoveGuard.cc:96
std::shared_ptr< Move > copy() const
Definition Move.cc:413
bool isJump() const
Definition Move.cc:164

References TTAProgram::CodeSnippet::add(), MoveNode::addDestinationOperationPtr(), TTAProgram::Instruction::addMove(), TTAProgram::Move::copy(), TTAProgram::MoveGuard::copy(), fixTerminalPO(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Move::isJump(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), and MoveNode::setSourceOperationPtr().

Referenced by combineBlocks().

Here is the call graph for this function:

◆ canConvert()

bool SimpleIfConverter::canConvert ( CandidateBlocks candidates,
ControlFlowGraph cfg 
)
private

Checks whether if conversion is possible for given basic blocks.

Parameters
candidatesData about area being converted.

Definition at line 289 of file SimpleIfConverter.cc.

290 {
291 if (candidates == NULL) {
292 return false;
293 }
294 assert(candidates->firstBB_.instructionCount() > 0);
295 TTAProgram::Instruction* jumpIns =
296 &candidates->firstBB_.lastInstruction();
297 assert(jumpIns->moveCount()==1);
298 TTAProgram::Move* jumpMove = &jumpIns->move(0);
299 assert(jumpMove->source().isInstructionAddress() ||
300 jumpMove->source().isBasicBlockReference());
301 if (jumpMove->isUnconditional()) {
302 jumpIns = &candidates->firstBB_.previousInstruction(*jumpIns);
303 jumpMove = &jumpIns->move(0);
304 assert(jumpMove->source().isInstructionAddress() ||
305 jumpMove->source().isBasicBlockReference());
306 }
307
308 // check that the jump is conditional.
309 // broken cfg may lead it to be unconditional
310 if(jumpMove->isUnconditional()) {
312 return false;
313 }
314
315 // Cannot convert if there are not register guards.
316 if (!jumpMove->guard().guard().parentBus()) {
317 return false;
318 }
319 candidates->guard_ = jumpMove->guard().copy();
320
321 // find the guard reg
322 const Guard &g = candidates->guard_->guard();
323 const RegisterGuard* rg = dynamic_cast<const RegisterGuard*>(&g);
324
325 candidates->invg_ =
326 codeGenerator_->createInverseGuard(*candidates->guard_);
327
328 // if something fails on guad generation or extraction
329 // caused for example by port guards or missing inverse guard.
330 if (rg == NULL || candidates->invg_ == NULL) {
331 grAborts_++;
332 return false;
333 }
334 candidates->grIndex_ = rg->registerIndex();
335 candidates->grFile_ = rg->registerFile();
336
337 // if converting fall-thru-node
338 if (candidates->joinNode_ != &candidates->fallThruNode_ &&
339 candidates->succNode1_ != &candidates->fallThruNode_) {
340 bool lastToConvert = &candidates->fallThruBB_ == candidates->joinBB_;
341 if (writesRegister(
342 candidates->fallThruBB_, candidates->grIndex_,
343 *candidates->grFile_, lastToConvert)) {
344 grDefAborts_++;
345#if 0
346 PRINT_VAR(candidates->fallThruNode_.nodeID());
347 PRINT_VAR(candidates->grIndex_);
348 PRINT_VAR(candidates->grFile_);
349
351 << candidates->fallThruBB_.disassembly()
352 << std::endl;
353#endif
354 return false;
355 }
356 // cannot have double guards
357 if (hasConditionals(candidates->fallThruBB_)) {
358 grUseAborts_++;
359 return false;
360 }
361 }
362
363 // if converting jump node
364 if (candidates->joinNode_ != &candidates->jumpDestNode_ &&
365 candidates->succNode1_ != &candidates->jumpDestNode_) {
366
367 bool lastToConvert = &candidates->fallThruBB_ != candidates->joinBB_;
368 if (writesRegister(
369 candidates->jumpDestBB_, candidates->grIndex_,
370 *candidates->grFile_, lastToConvert)) {
371 grDefAborts_++;
372 return false;
373 }
374 // cannot have double guards
375 if (hasConditionals(candidates->jumpDestBB_)) {
376 grUseAborts_++;
377 return false;
378 }
379 }
380
381 // Do not allow backwards fall throughs from the last BB to the first!
382 // TODO: some day convert these to jumps. For now, just give up when
383 // encountering these.
384 ControlFlowGraph::EdgeSet outEdges = cfg.outEdges(candidates->lastNode_);
385 for (auto o: outEdges) {
386 if (!o->isJumpEdge() &&
387 &cfg.headNode(*o) == &candidates->firstNode_) {
388 return false;
389 }
390 }
391
392 // no reason why not
393 return true;
394
395}
#define PRINT_VAR(VARIABLE__)
#define assert(condition)
virtual Node & headNode(const Edge &edge) const
virtual EdgeSet outEdges(const Node &node) const
std::set< GraphEdge *, typename GraphEdge::Comparator > EdgeSet
Definition Graph.hh:54
bool writesRegister(const TTAProgram::BasicBlock &bb, int index, const TTAMachine::RegisterFile &rf, bool ignoreLastInstruction)
bool hasConditionals(TTAProgram::BasicBlock &bb)
virtual Bus * parentBus() const
const RegisterFile * registerFile() const
static TTAProgram::MoveGuard * createInverseGuard(const TTAProgram::MoveGuard &mg, const TTAMachine::Bus *bus=NULL)
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345
bool isUnconditional() const
Definition Move.cc:154
Terminal & source() const
Definition Move.cc:302
virtual bool isBasicBlockReference() const
Definition Terminal.cc:139
virtual bool isInstructionAddress() const
Definition Terminal.cc:87

References assert, codeGenerator_, TTAProgram::MoveGuard::copy(), TTAProgram::CodeGenerator::createInverseGuard(), TTAProgram::CodeSnippet::disassembly(), SimpleIfConverter::CandidateBlocks::fallThruBB_, SimpleIfConverter::CandidateBlocks::fallThruNode_, SimpleIfConverter::CandidateBlocks::firstBB_, SimpleIfConverter::CandidateBlocks::firstNode_, grAborts_, grDefAborts_, SimpleIfConverter::CandidateBlocks::grFile_, SimpleIfConverter::CandidateBlocks::grIndex_, grUseAborts_, TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), SimpleIfConverter::CandidateBlocks::guard_, hasConditionals(), BoostGraph< GraphNode, GraphEdge >::headNode(), TTAProgram::CodeSnippet::instructionCount(), SimpleIfConverter::CandidateBlocks::invg_, TTAProgram::Terminal::isBasicBlockReference(), TTAProgram::Terminal::isInstructionAddress(), TTAProgram::Move::isUnconditional(), SimpleIfConverter::CandidateBlocks::joinBB_, SimpleIfConverter::CandidateBlocks::joinNode_, SimpleIfConverter::CandidateBlocks::jumpDestBB_, SimpleIfConverter::CandidateBlocks::jumpDestNode_, TTAProgram::CodeSnippet::lastInstruction(), SimpleIfConverter::CandidateBlocks::lastNode_, Application::logStream(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), GraphNode::nodeID(), BoostGraph< GraphNode, GraphEdge >::outEdges(), TTAMachine::Guard::parentBus(), TTAProgram::CodeSnippet::previousInstruction(), PRINT_VAR, TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), TTAProgram::Move::source(), SimpleIfConverter::CandidateBlocks::succNode1_, uncondAborts_, and writesRegister().

Referenced by searchCandidate().

Here is the call graph for this function:

◆ combineBlocks()

void SimpleIfConverter::combineBlocks ( CandidateBlocks bblocks)
private

Combines many basic blocks into one and sets the guards accordingly.

Parameters
bblocksAll the data needed for the operation

Definition at line 492 of file SimpleIfConverter.cc.

492 {
493
494 // TODO: should not set guard of jump of lastbb.
495
496 // remove the branch jump.
497 assert(removeJump(bblocks.firstBB_));
498
499 // fall thru node handling.
500 if (&bblocks.fallThruNode_ != bblocks.succNode1_) {
501
502 if (&bblocks.fallThruBB_ != bblocks.joinBB_) {
503 appendBB(
504 bblocks.fallThruBB_, bblocks.firstBB_, bblocks.invg_,
505 &bblocks.fallThruBB_ != &bblocks.lastBB_);
506 }
507 }
508
509 // jump dest node handling
510 if (&bblocks.jumpDestNode_ != bblocks.succNode1_) {
511
512 if (&bblocks.jumpDestBB_ != bblocks.joinBB_) {
513 appendBB(bblocks.jumpDestBB_, bblocks.firstBB_, bblocks.guard_,
514 &bblocks.jumpDestBB_ != &bblocks.lastBB_ ||
515 (bblocks.succNode2_ == NULL &&
516 bblocks.succNode1_->isNormalBB()));
517 }
518 }
519
520 if (bblocks.joinBB_ != NULL) {
521 appendBB(*bblocks.joinBB_, bblocks.firstBB_, NULL, false);
522 }
523
524 bool isLastUncondJump = false;
525 if (bblocks.firstBB_.instructionCount() != 0) {
526 TTAProgram::Instruction& last = bblocks.firstBB_.lastInstruction();
527 for (int i = 0; i < last.moveCount(); i++) {
528 TTAProgram::Move& move = last.move(i);
529 if (move.isUnconditional() && move.isJump()) {
530 isLastUncondJump = true;
531 }
532 }
533 }
534
535 // handle the last jump which may need to be added.
536 if (bblocks.succNode1_->isNormalBB() &&
537 !isLastUncondJump && !bblocks.removeJoin_) {
538 bblocks.createJump_ = true;
539 addJump(bblocks.firstBB_, *bblocks.succNode1_);
540 }
541}
void appendBB(const TTAProgram::BasicBlock &src, TTAProgram::BasicBlock &dest, TTAProgram::MoveGuard *mg, bool removeJumps)
void addJump(TTAProgram::BasicBlock &bb, BasicBlockNode &bbn)
static bool removeJump(TTAProgram::BasicBlock &bb)

References addJump(), appendBB(), assert, SimpleIfConverter::CandidateBlocks::createJump_, SimpleIfConverter::CandidateBlocks::fallThruBB_, SimpleIfConverter::CandidateBlocks::fallThruNode_, SimpleIfConverter::CandidateBlocks::firstBB_, SimpleIfConverter::CandidateBlocks::guard_, TTAProgram::CodeSnippet::instructionCount(), SimpleIfConverter::CandidateBlocks::invg_, TTAProgram::Move::isJump(), BasicBlockNode::isNormalBB(), TTAProgram::Move::isUnconditional(), SimpleIfConverter::CandidateBlocks::joinBB_, SimpleIfConverter::CandidateBlocks::jumpDestBB_, SimpleIfConverter::CandidateBlocks::jumpDestNode_, SimpleIfConverter::CandidateBlocks::lastBB_, TTAProgram::CodeSnippet::lastInstruction(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), SimpleIfConverter::CandidateBlocks::removeJoin_, removeJump(), SimpleIfConverter::CandidateBlocks::succNode1_, and SimpleIfConverter::CandidateBlocks::succNode2_.

Referenced by convert().

Here is the call graph for this function:

◆ convert()

void SimpleIfConverter::convert ( CandidateBlocks bblocks,
ControlFlowGraph cfg 
)
private

Do the if conversion for given area. All checks are already done, this must not fail.

Parameters
bblocksThe data about blocks being merged
cfgControlFlowGraph.

Definition at line 405 of file SimpleIfConverter.cc.

405 {
406
407 // combines blocks
408 combineBlocks(bblocks);
409
410 // update cfg about the changes
411 updateCfg(bblocks, cfg);
412}
void updateCfg(CandidateBlocks &bblocks, ControlFlowGraph &cfg)
void combineBlocks(CandidateBlocks &bblocks)

References combineBlocks(), and updateCfg().

Referenced by handleControlFlowGraph().

Here is the call graph for this function:

◆ detectDiamond()

SimpleIfConverter::CandidateBlocks * SimpleIfConverter::detectDiamond ( BasicBlockNode bbn,
BasicBlockNode fallThruNode,
BasicBlockNode jumpDestNode,
ControlFlowGraph cfg 
)
private

Definition at line 781 of file SimpleIfConverter.cc.

784 {
785
786 if (cfg.outDegree(fallThruNode) != 1 ||
787 cfg.outDegree(jumpDestNode) != 1) {
788 return NULL;
789 }
790
791 ControlFlowEdge& jdse = cfg.outEdge(jumpDestNode,0);
792 ControlFlowEdge& ftse = cfg.outEdge(fallThruNode,0);
793
794 BasicBlockNode& jdSucc = cfg.headNode(jdse);
795 BasicBlockNode& ftSucc = cfg.headNode(ftse);
796
797 if (jdse.isCallPassEdge() ||
798 ftse.isCallPassEdge() ||
799 &jdSucc != &ftSucc ||
800 jdse.isBackEdge() ||
801 ftse.isBackEdge()) {
802 return NULL;
803 }
804
805 if (&jdSucc == &bbn) {
806 loopAborts_++;
807 return NULL;
808 }
809 //not desirable if nodes are too big.
810 if (fallThruNode.basicBlock().instructionCount() >
812 jumpDestNode.basicBlock().instructionCount() >
814 sizeAborts_++;
815 return NULL;
816 }
817
818 bool keepFt = (cfg.inDegree(fallThruNode) != 1);
819 bool keepJd = (cfg.inDegree(jumpDestNode) != 1);
820
821 // temporary fix as these are hard for cfg updates
822 if (keepFt || keepJd) {
823 return NULL;
824 }
825
826 if (!jdSucc.isNormalBB()) {
827 // last BB of diamond is exit node?
828 return new CandidateBlocks(
829 bbn, fallThruNode, jumpDestNode,
830 jumpDestNode, NULL, &jdSucc, NULL,
831 false, !keepFt, !keepJd);
832 }
833
834 // find successors.
835 std::pair<BasicBlockNode*,BasicBlockNode*> succ =
836 successors(jdSucc, cfg);
837
838 if (succ.first == NULL) {
839 succAborts_++;
840 return NULL;
841 }
842
843 bool keepJoin = (keepJd | keepFt) || cfg.inDegree(jdSucc) > 2 ||
844 !jdSucc.isNormalBB();
845
846 // Cannot if-convert code where possibility of fall-through loop.
847 if (jdSucc.nodeID() < bbn.nodeID()) {
848 keepJoin = true;
849 }
850
851 if (keepJoin) {
852 ControlFlowGraph::EdgeSet joinOutEdges = cfg.outEdges(jdSucc);
853 for (ControlFlowGraph::EdgeSet::iterator i = joinOutEdges.begin();
854 i != joinOutEdges.end(); i++) {
855 ControlFlowEdge& e = **i;
858 // then do not contain last BB in the diamond
859 return new CandidateBlocks(
860 bbn, fallThruNode, jumpDestNode, jumpDestNode,
861 NULL, &jdSucc, NULL, false, !keepFt, !keepJd);
862 }
863 }
864 }
865
866 return new CandidateBlocks(
867 bbn, fallThruNode, jumpDestNode, jdSucc, &jdSucc,
868 succ.first, succ.second, !keepJoin, !keepFt, !keepJd);
869}
bool isNormalBB() const
virtual Edge & outEdge(const Node &node, const int index) const
virtual int inDegree(const Node &node) const
virtual int outDegree(const Node &node) const
bool isBackEdge() const
CFGEdgeType edgeType()
bool isCallPassEdge() const
CFGEdgePredicate edgePredicate() const
int nodeID() const
std::pair< BasicBlockNode *, BasicBlockNode * > successors(BasicBlockNode &node, ControlFlowGraph &cfg)

References BasicBlockNode::basicBlock(), ControlFlowEdge::CFLOW_EDGE_JUMP, ControlFlowEdge::CFLOW_EDGE_NORMAL, diamondSizeLimit_, ControlFlowEdge::edgePredicate(), ControlFlowEdge::edgeType(), BoostGraph< GraphNode, GraphEdge >::headNode(), BoostGraph< GraphNode, GraphEdge >::inDegree(), TTAProgram::CodeSnippet::instructionCount(), ControlFlowEdge::isBackEdge(), ControlFlowEdge::isCallPassEdge(), BasicBlockNode::isNormalBB(), loopAborts_, GraphNode::nodeID(), BoostGraph< GraphNode, GraphEdge >::outDegree(), BoostGraph< GraphNode, GraphEdge >::outEdge(), BoostGraph< GraphNode, GraphEdge >::outEdges(), sizeAborts_, succAborts_, and successors().

Referenced by searchCandidate().

Here is the call graph for this function:

◆ detectTriangleViaFt()

SimpleIfConverter::CandidateBlocks * SimpleIfConverter::detectTriangleViaFt ( BasicBlockNode bbn,
BasicBlockNode fallThruNode,
BasicBlockNode jumpDestNode,
ControlFlowGraph cfg 
)
private

Definition at line 932 of file SimpleIfConverter.cc.

936 {
937
938 if (cfg.outDegree(fallThruNode) != 1) {
939 return NULL;
940 }
941 ControlFlowEdge& e = cfg.outEdge(fallThruNode,0);
942 if (e.isCallPassEdge() || e.isBackEdge() ||
943 &cfg.headNode(e) != &jumpDestNode) {
944 return NULL;
945 }
946
947 // find successors.
948 std::pair<BasicBlockNode*,BasicBlockNode*> succ =
949 successors(jumpDestNode, cfg);
950
951 bool keepFt = (cfg.inDegree(fallThruNode) != 1);
952 bool keepJd = keepFt|(cfg.inDegree(jumpDestNode) > 2);
953 //assert(cfg.inDegree(jumpDestNode) > 1);
954
955 // temporary fix as these are hard for cfg updates
956 if (keepFt) {
957 return NULL;
958 }
959
960 //not desirable if fallThruNnode is big.
961 if (fallThruNode.basicBlock().instructionCount() >
963 sizeAborts_++;
964 return NULL;
965 }
966
967 if (keepJd) {
968 if (cfg.jumpSuccessor(fallThruNode) != NULL) {
969 return NULL;
970 }
971 return new CandidateBlocks(
972 bbn, fallThruNode, jumpDestNode, fallThruNode, NULL,
973 &jumpDestNode, NULL, false, true, false);
974 }
975 // Cannot if-convert code where possibility of fall-through loop.
976 if ((succ.first != NULL && succ.first->nodeID() < bbn.nodeID()) ||
977 (succ.second != NULL && succ.second->nodeID() < bbn.nodeID())) {
978 return NULL;
979 }
980
981 if (succ.first == NULL) {
982 // we have a triangle first->jump->ft(branch)
983 return new CandidateBlocks(
984 bbn, fallThruNode, jumpDestNode, jumpDestNode,
985 NULL, succ.first, succ.second, !keepJd,
986 !keepFt, !keepJd);
987 } else {
988 // we have a triangle first->jump->ft(branch)
989 return new CandidateBlocks(
990 bbn, fallThruNode, jumpDestNode, jumpDestNode,
991 &jumpDestNode, succ.first, succ.second, !keepJd,
992 !keepFt, !keepJd);
993 }
994 return NULL;
995}
BasicBlockNode * jumpSuccessor(BasicBlockNode &bbn)

References BasicBlockNode::basicBlock(), BoostGraph< GraphNode, GraphEdge >::headNode(), BoostGraph< GraphNode, GraphEdge >::inDegree(), TTAProgram::CodeSnippet::instructionCount(), ControlFlowEdge::isBackEdge(), ControlFlowEdge::isCallPassEdge(), ControlFlowGraph::jumpSuccessor(), GraphNode::nodeID(), BoostGraph< GraphNode, GraphEdge >::outDegree(), BoostGraph< GraphNode, GraphEdge >::outEdge(), sizeAborts_, successors(), and triangleSizeLimit1_.

Referenced by searchCandidate().

Here is the call graph for this function:

◆ detectTriangleViaJump()

SimpleIfConverter::CandidateBlocks * SimpleIfConverter::detectTriangleViaJump ( BasicBlockNode bbn,
BasicBlockNode fallThruNode,
BasicBlockNode jumpDestNode,
ControlFlowGraph cfg 
)
private

Definition at line 873 of file SimpleIfConverter.cc.

877 {
878
879 if (cfg.outDegree(jumpDestNode) != 1) {
880 return NULL;
881 }
882 ControlFlowEdge& jdse = cfg.outEdge(jumpDestNode,0);
883 BasicBlockNode& jdSucc = cfg.headNode(jdse);
884 if (&jdSucc != &fallThruNode || jdse.isBackEdge()) {
885 return NULL;
886 }
887
888 // find successors.
889 std::pair<BasicBlockNode*,BasicBlockNode*> succ =
890 successors(fallThruNode, cfg);
891
892 bool keepJd = (cfg.inDegree(jumpDestNode) != 1);
893 bool keepFt = keepJd|(cfg.inDegree(fallThruNode) > 2);
894 //assert(cfg.inDegree(fallThruNode) > 1);
895
896 // temporary fix as these are hard for cfg updates
897 if (keepFt || keepJd) {
898 return NULL;
899 }
900
901 // Cannot if-convert code where possibility of fall-through loop.
902 if ((succ.first != NULL && succ.first->nodeID() < bbn.nodeID()) ||
903 (succ.second != NULL && succ.second->nodeID() < bbn.nodeID())) {
904 return NULL;
905 }
906
907 // we have a triangle first->jump->ft(branch)
908
909 //not desirable if jump dest node is big.
910 if (jumpDestNode.basicBlock().instructionCount() >
912 sizeAborts_++;
913 return NULL;
914 }
915
916 if (succ.first == NULL) {
917 return new CandidateBlocks(
918 bbn, fallThruNode, jumpDestNode, fallThruNode,
919 NULL, succ.first, succ.second, !keepFt,
920 !keepFt, !keepJd);
921 } else {
922 return new CandidateBlocks(
923 bbn, fallThruNode, jumpDestNode, fallThruNode,
924 &fallThruNode, succ.first, succ.second, !keepFt,
925 !keepFt, !keepJd);
926 }
927 return NULL;
928}

References BasicBlockNode::basicBlock(), BoostGraph< GraphNode, GraphEdge >::headNode(), BoostGraph< GraphNode, GraphEdge >::inDegree(), TTAProgram::CodeSnippet::instructionCount(), ControlFlowEdge::isBackEdge(), GraphNode::nodeID(), BoostGraph< GraphNode, GraphEdge >::outDegree(), BoostGraph< GraphNode, GraphEdge >::outEdge(), sizeAborts_, successors(), and triangleSizeLimit2_.

Referenced by searchCandidate().

Here is the call graph for this function:

◆ fixTerminalPO()

ProgramOperationPtr SimpleIfConverter::fixTerminalPO ( TTAProgram::TerminalFUPort terminal,
std::map< ProgramOperationPtr, ProgramOperationPtr > &  poMapping 
)
static

Definition at line 563 of file SimpleIfConverter.cc.

564 {
565
567 if (po == NULL) {
568 return ProgramOperationPtr();
569 }
570 std::map<ProgramOperationPtr,ProgramOperationPtr>::iterator i =
571 poMapping.find(po);
572
573 if (i == poMapping.end()) {
574 // create new programOperation
576 new ProgramOperation(terminal.hintOperation(), po->machineInstr()));
577 poMapping[po] = newPO;
578 terminal.setProgramOperation(newPO);
579 return newPO;
580 } else {
581 terminal.setProgramOperation(i->second);
582 return i->second;
583 }
584}
virtual Operation & hintOperation() const
void setProgramOperation(ProgramOperationPtr po)
ProgramOperationPtr programOperation() const

References TTAProgram::TerminalFUPort::hintOperation(), TTAProgram::TerminalFUPort::programOperation(), and TTAProgram::TerminalFUPort::setProgramOperation().

Referenced by Peel2BBLoops::appendBB(), and appendBB().

Here is the call graph for this function:

◆ handleControlFlowGraph()

void SimpleIfConverter::handleControlFlowGraph ( ControlFlowGraph cfg,
const TTAMachine::Machine targetMachine 
)
virtual

Handles a cfg. Does if conversion for the cfg.

Parameters
cfgcfg to be if-converted.

Reimplemented from ControlFlowGraphPass.

Definition at line 135 of file SimpleIfConverter.cc.

136 {
139 const bool printCFGs = opts != NULL && opts->dumpIfConversionCFGs();
140
141 if (printCFGs)
142 cfg.writeToDotFile(cfg.name() + ".cfg.before_ifc.dot");
143
144 if (codeGenerator_ == NULL) {
146 new CodeGenerator(targetMachine);
147 }
148
150
151 while (true) {
152 // do thru cfg..
153 CandidateBlocks* bblocks = searchCandidate(cfg);
154 if (bblocks == NULL) {
155 break;
156 } else {
157 convert(*bblocks, cfg);
158 delete bblocks;
159 }
160 }
161
162 if (Application::verboseLevel() > 2) {
164 "Converted: " << std::endl <<
165 "\tDiamonds: " << diamonds_ << std::endl <<
166 "\tDiamonds(2): " << diamonds2_ << std::endl <<
167 "\tTriangles(1): " << triangles1_ << std::endl <<
168 "\tTriangles(2): " << triangles2_ << std::endl <<
169
170 "Aborts: " << std::endl <<
171 "\tGrDef: " << grDefAborts_ << std::endl <<
172 "\tAlready guarded: " << grUseAborts_ << std::endl <<
173 "\tLoop Aborts: " << loopAborts_ << std::endl <<
174 "\tUncond jump: " << uncondAborts_ << std::endl <<
175 "\tSize: " << sizeAborts_ << std::endl <<
176 "\tSucc unknown aborts: " << succAborts_ << std::endl;
177 }
178
179 if (printCFGs)
180 cfg.writeToDotFile(cfg.name() + ".cfg.after_ifc.dot");
181}
virtual const TCEString & name() const
TTAProgram::InstructionReferenceManager & instructionReferenceManager()
virtual void writeToDotFile(const TCEString &fileName) const
virtual bool dumpIfConversionCFGs() const
void convert(CandidateBlocks &bblocks, ControlFlowGraph &cfg)
CandidateBlocks * searchCandidate(ControlFlowGraph &cfg)

References Application::cmdLineOptions(), codeGenerator_, convert(), diamonds2_, diamonds_, SchedulerCmdLineOptions::dumpIfConversionCFGs(), grDefAborts_, grUseAborts_, ControlFlowGraph::instructionReferenceManager(), irm_, Application::logStream(), loopAborts_, BoostGraph< GraphNode, GraphEdge >::name(), searchCandidate(), sizeAborts_, succAborts_, triangles1_, triangles2_, uncondAborts_, Application::verboseLevel(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by llvm::LLVMTCEIRBuilder::compileOptimized(), and handleProcedure().

Here is the call graph for this function:

◆ handleProcedure()

void SimpleIfConverter::handleProcedure ( TTAProgram::Procedure procedure,
const TTAMachine::Machine targetMachine 
)
virtual

Handles a procedure. Does if conversion for the procedure.

Parameters
procedureprocedure to be if-converted.
targetMachinemachine for which to be compiled.

Reimplemented from ProcedurePass.

Definition at line 190 of file SimpleIfConverter.cc.

192 {
193 irm_ = &procedure.parent().instructionReferenceManager();
194 ControlFlowGraph cfg(procedure);
195
196 cfg.updateReferencesFromProcToCfg();
197
198 handleControlFlowGraph(cfg, targetMachine);
199
200 cfg.copyToProcedure(procedure);
201}
virtual void handleControlFlowGraph(ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
virtual Program & parent() const
InstructionReferenceManager & instructionReferenceManager() const
Definition Program.cc:688

References ControlFlowGraph::copyToProcedure(), handleControlFlowGraph(), TTAProgram::Program::instructionReferenceManager(), irm_, TTAProgram::CodeSnippet::parent(), and ControlFlowGraph::updateReferencesFromProcToCfg().

Here is the call graph for this function:

◆ handleProgram()

void SimpleIfConverter::handleProgram ( TTAProgram::Program program,
const TTAMachine::Machine targetMachine 
)
virtual

Handles a program. Does if conversion for the whole program.

Parameters
programprogram to be if-converted.
targetMachinemachine for which to be compiled.

Reimplemented from ProgramPass.

Definition at line 210 of file SimpleIfConverter.cc.

211 {
212 if (codeGenerator_ == NULL) {
213 codeGenerator_ = new CodeGenerator(targetMachine);
214 }
215
216 ProgramPass::executeProcedurePass(program, targetMachine, *this);
217
218 delete codeGenerator_; codeGenerator_ = NULL;
219}
find Finds info of the inner loops in the program
static void executeProcedurePass(TTAProgram::Program &program, const TTAMachine::Machine &targetMachine, ProcedurePass &procedurePass)

References codeGenerator_, ProgramPass::executeProcedurePass(), and program.

Here is the call graph for this function:

◆ hasConditionals()

bool SimpleIfConverter::hasConditionals ( TTAProgram::BasicBlock bb)
private

Checks whether there exists any conditional moves in given BB.

Parameters
bbBasicBlock where to check for conditional moves.
Returns
true if some move is conditional

Definition at line 550 of file SimpleIfConverter.cc.

550 {
551 for (int j = 0; j < bb.instructionCount(); j++) {
552 Instruction& ins = bb.instructionAtIndex(j);
553 for (int i = 0; i < ins.moveCount(); i++) {
554 if (!ins.move(i).isUnconditional()) {
555 return true;
556 }
557 }
558 }
559 return false;
560}

References TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Move::isUnconditional(), TTAProgram::Instruction::move(), and TTAProgram::Instruction::moveCount().

Referenced by canConvert().

Here is the call graph for this function:

◆ removeJump()

bool SimpleIfConverter::removeJump ( TTAProgram::BasicBlock bb)
static

Tries to remove a jump from the end of a basic block.

Parameters
bbbasic block where to remove the jump from
Returns
true if removed, false if not removed

Definition at line 679 of file SimpleIfConverter.cc.

679 {
680
681 for (int i = bb.instructionCount() -1 ; i >= 0; i--) {
682 Instruction* jumpIns = &bb.lastInstruction();
683 if (jumpIns->moveCount() != 0) {
684 if (jumpIns->hasJump()) {
685 Move *move = &jumpIns->move(0);
686 jumpIns->removeMove(*move);
687 return true;
688 } else {
689 return false;
690 }
691 }
692 }
693 return false;
694}
virtual Instruction & lastInstruction() const
void removeMove(Move &move)

References TTAProgram::Instruction::hasJump(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::CodeSnippet::lastInstruction(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), and TTAProgram::Instruction::removeMove().

Referenced by combineBlocks(), and Peel2BBLoops::performCodeMotion().

Here is the call graph for this function:

◆ searchCandidate()

SimpleIfConverter::CandidateBlocks * SimpleIfConverter::searchCandidate ( ControlFlowGraph cfg)
private

Searches a single area of basic blocs to be converted at once.

Conversion should always be possible for blocks this returns, All checks are done here.

This always returnsa the first area of blocks that can be converted. If actual conversion is not done/cfg is not changed, returns the same are again and again.

Parameters
cfgControlFlowGraph.

Definition at line 234 of file SimpleIfConverter.cc.

234 {
235 for (int i = 0; i < cfg.nodeCount(); i++) {
236
237 BasicBlockNode& bbn = cfg.node(i);
238
239 // entry/exit node or too many successors
240 if (!bbn.isNormalBB() || cfg.outDegree(bbn) != 2) {
241 continue;
242 }
243
244 std::pair<BasicBlockNode*,BasicBlockNode*> nodes =
245 successors(bbn, cfg);
246
247 BasicBlockNode* fallThruNode = nodes.first;
248 BasicBlockNode* jumpDestNode = nodes.second;
249
250 if (fallThruNode == NULL || jumpDestNode == NULL ||
251 !fallThruNode->isNormalBB() || !jumpDestNode->isNormalBB()) {
252 continue;
253 }
254
255 CandidateBlocks* cb =
256 detectDiamond(bbn, *fallThruNode, *jumpDestNode, cfg);
257 if (canConvert(cb, cfg)) {
258 diamonds_++;
259 return cb;
260 }
261 if (cb == NULL) {
262 cb = detectTriangleViaJump(bbn, *fallThruNode, *jumpDestNode, cfg);
263 if (canConvert(cb, cfg)) {
264 triangles2_++;
265 return cb;
266 }
267 }
268 if (cb == NULL) {
269 cb = detectTriangleViaFt(bbn, *fallThruNode, *jumpDestNode, cfg);
270 if (canConvert(cb, cfg)) {
271 triangles1_++;
272 return cb;
273 }
274 }
275 // some canconvert failed.
276 if (cb != NULL) {
277 delete cb;
278 }
279 }
280 return NULL;
281}
int nodeCount() const
Node & node(const int index) const
CandidateBlocks * detectTriangleViaFt(BasicBlockNode &bbn, BasicBlockNode &fallThruNode, BasicBlockNode &jumpDestNode, ControlFlowGraph &cfg)
bool canConvert(CandidateBlocks *candidates, ControlFlowGraph &cfg)
CandidateBlocks * detectDiamond(BasicBlockNode &bbn, BasicBlockNode &fallThruNode, BasicBlockNode &jumpDestNode, ControlFlowGraph &cfg)
CandidateBlocks * detectTriangleViaJump(BasicBlockNode &bbn, BasicBlockNode &fallThruNode, BasicBlockNode &jumpDestNode, ControlFlowGraph &cfg)

References canConvert(), detectDiamond(), detectTriangleViaFt(), detectTriangleViaJump(), diamonds_, BasicBlockNode::isNormalBB(), BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), BoostGraph< GraphNode, GraphEdge >::outDegree(), successors(), triangles1_, and triangles2_.

Referenced by handleControlFlowGraph().

Here is the call graph for this function:

◆ shortDescription()

std::string SimpleIfConverter::shortDescription ( ) const
virtual

Tells what this scheduler pass does

Implements SchedulerPass.

Definition at line 125 of file SimpleIfConverter.cc.

125 {
126 return std::string("Simple if converter");
127}

◆ successors()

std::pair< BasicBlockNode *, BasicBlockNode * > SimpleIfConverter::successors ( BasicBlockNode node,
ControlFlowGraph cfg 
)
private

Returns 2 successors blocks of given block in specified order.

First contains the unconditional successor. Second contains the jumo target of conditional jump if exists, or null. If cannot analyze, returns both nulls.

Parameters
nodeNode whose successors to check
cfgcfg where the successors are searched.

Definition at line 728 of file SimpleIfConverter.cc.

729 {
730 ControlFlowGraph::NodeSet succs = cfg.successors(node);
731 if (succs.size() == 1) {
732 return std::pair<BasicBlockNode*,BasicBlockNode*>(*succs.begin(),NULL);
733 }
734 if (succs.size() != 2) {
736 << "Warning: Successor cound of node: " << node.toString()
737 << " is: " << succs.size() << std::endl;
738 cfg.writeToDotFile("IfConverterInvalidNumberOfSuccessors_cfg.dot");
739 }
740
741 if (node.basicBlock().instructionCount() == 0) {
742 return std::pair<BasicBlockNode*,BasicBlockNode*>(NULL,NULL);
743 }
744
745 assert(succs.size() == 2);
746 ControlFlowEdge& edge = cfg.outEdge(node,0);
747
748 TTAProgram::Instruction* jumpIns =
749 &node.basicBlock().lastInstruction();
750 TTAProgram::Move* jumpMove = &jumpIns->move(0);
751 if (!jumpMove->isJump()) {
752 return std::pair<BasicBlockNode*,BasicBlockNode*>(NULL,NULL);
753 }
754
755 if (jumpMove->isUnconditional()) {
756 jumpIns = &node.basicBlock().previousInstruction(*jumpIns);
757 if (jumpIns == NULL ||
760 return std::pair<BasicBlockNode*,BasicBlockNode*>(NULL,NULL);
761 }
762 jumpMove = &jumpIns->move(0);
763 if (jumpMove->isUnconditional() || !jumpMove->isJump()) {
765 return std::pair<BasicBlockNode*,BasicBlockNode*>(NULL,NULL);
766 }
767 }
768
769 if (edge.isTrueEdge() == jumpMove->guard().guard().isInverted()) {
770 return std::pair<BasicBlockNode*,BasicBlockNode*>(
771 &cfg.headNode(edge),
772 &cfg.headNode(cfg.outEdge(node,1)));
773 } else {
774 return std::pair<BasicBlockNode*,BasicBlockNode*>(
775 &cfg.headNode(cfg.outEdge(node,1)),
776 &cfg.headNode(edge));
777 }
778}
std::string toString() const
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
bool isTrueEdge() const
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
Definition Graph.hh:53
virtual bool isInverted() const
virtual Instruction & previousInstruction(const Instruction &ins) const
static NullInstruction & instance()

References assert, BasicBlockNode::basicBlock(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), BoostGraph< GraphNode, GraphEdge >::headNode(), TTAProgram::NullInstruction::instance(), TTAProgram::CodeSnippet::instructionCount(), TTAMachine::Guard::isInverted(), TTAProgram::Move::isJump(), ControlFlowEdge::isTrueEdge(), TTAProgram::Move::isUnconditional(), TTAProgram::CodeSnippet::lastInstruction(), Application::logStream(), TTAProgram::Instruction::move(), BoostGraph< GraphNode, GraphEdge >::outEdge(), TTAProgram::CodeSnippet::previousInstruction(), BoostGraph< GraphNode, GraphEdge >::successors(), BasicBlockNode::toString(), uncondAborts_, and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by detectDiamond(), detectTriangleViaFt(), detectTriangleViaJump(), and searchCandidate().

Here is the call graph for this function:

◆ updateCfg()

void SimpleIfConverter::updateCfg ( CandidateBlocks bblocks,
ControlFlowGraph cfg 
)
private

Updates CFG after if conversion

Parameters
bblocksThe data about blocks being merged
cfgThe cfg to update

Definition at line 421 of file SimpleIfConverter.cc.

421 {
422
423 // these should not be needed but just for sure.
424 cfg.disconnectNodes(bblocks.firstNode_, bblocks.jumpDestNode_);
425 cfg.disconnectNodes(bblocks.firstNode_, bblocks.fallThruNode_);
426
427// assert(cfg.outDegree(bblocks.firstNode_) == 0);
428 if (bblocks.joinNode_ != NULL) {
429 if (bblocks.joinNode_ != &bblocks.jumpDestNode_ && bblocks.removeJd_) {
430 cfg.disconnectNodes(bblocks.jumpDestNode_, *bblocks.joinNode_);
431 }
432 if (bblocks.joinNode_ != &bblocks.fallThruNode_ && bblocks.removeFt_) {
433 cfg.disconnectNodes(bblocks.fallThruNode_, *bblocks.joinNode_);
434 }
435 }
436
437 // copy out edges
438 ControlFlowGraph::EdgeSet outEdges = cfg.outEdges(bblocks.lastNode_);
439 for (ControlFlowGraph::EdgeSet::iterator i = outEdges.begin();
440 i != outEdges.end(); i++) {
441 BasicBlockNode& bbn = cfg.headNode(**i);
442 ControlFlowEdge oldEdge = **i;
443
444 // some fall-thru's may become jumps.
445 ControlFlowEdge::CFGEdgeType eType = bblocks.createJump_ ?
447
449 (*i)->edgePredicate(), eType);
450
451 if (oldEdge.isBackEdge()) {
452 cfe->setBackEdge();
453 }
454
455 cfg.connectNodes(bblocks.firstNode_, bbn, *cfe);
456
457 // if the original join node is being deleted, remove edges
458 if (bblocks.removeJoin_) {
459 cfg.removeEdge(oldEdge);
460 }
461 }
462
463 if (bblocks.joinNode_ != &bblocks.fallThruNode_ &&
464 bblocks.succNode1_ != &bblocks.fallThruNode_ && bblocks.removeFt_) {
465 //assert(cfg.inDegree(bblocks.fallThruNode_) == 0);
466 // remove nodes from CFG.
467 cfg.deleteNodeAndRefs(bblocks.fallThruNode_);
468 }
469
470 if (bblocks.joinNode_ != &bblocks.jumpDestNode_ &&
471 bblocks.succNode1_ != &bblocks.jumpDestNode_ && bblocks.removeJd_) {
472 //assert(cfg.inDegree(bblocks.jumpDestNode_) == 0);
473 cfg.deleteNodeAndRefs(bblocks.jumpDestNode_);
474 }
475
476 if (bblocks.joinNode_ != NULL) {
477 if (bblocks.removeJoin_) {
478 //assert(cfg.inDegree(*bblocks.joinNode_) == 0);
479 cfg.deleteNodeAndRefs(*bblocks.joinNode_);
480 }
481 }
482}
virtual void removeEdge(Edge &e)
virtual void disconnectNodes(const Node &nTail, const Node &nHead)
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
void setBackEdge()
Add property to edge to mark is as back edge - loop edge DO NOT USE unless you know what you are doin...
void deleteNodeAndRefs(BasicBlockNode &node)

References ControlFlowEdge::CFLOW_EDGE_JUMP, BoostGraph< GraphNode, GraphEdge >::connectNodes(), SimpleIfConverter::CandidateBlocks::createJump_, ControlFlowGraph::deleteNodeAndRefs(), BoostGraph< GraphNode, GraphEdge >::disconnectNodes(), SimpleIfConverter::CandidateBlocks::fallThruNode_, SimpleIfConverter::CandidateBlocks::firstNode_, BoostGraph< GraphNode, GraphEdge >::headNode(), ControlFlowEdge::isBackEdge(), SimpleIfConverter::CandidateBlocks::joinNode_, SimpleIfConverter::CandidateBlocks::jumpDestNode_, SimpleIfConverter::CandidateBlocks::lastNode_, BoostGraph< GraphNode, GraphEdge >::outEdges(), BoostGraph< GraphNode, GraphEdge >::removeEdge(), SimpleIfConverter::CandidateBlocks::removeFt_, SimpleIfConverter::CandidateBlocks::removeJd_, SimpleIfConverter::CandidateBlocks::removeJoin_, ControlFlowEdge::setBackEdge(), and SimpleIfConverter::CandidateBlocks::succNode1_.

Referenced by convert().

Here is the call graph for this function:

◆ writesRegister()

bool SimpleIfConverter::writesRegister ( const TTAProgram::BasicBlock bb,
int  index,
const TTAMachine::RegisterFile rf,
bool  ignoreLastInstruction 
)
private

Checks whether a given register is written in given BB.

Parameters
bbBasicBlock where to check for register writes
indexindex of the register in a registerfile
rfregister file of the register
Returns
true if there exists a write to given register

Definition at line 644 of file SimpleIfConverter.cc.

646 {
647 // check that jump does not mess the guard reg.
648 // TODO: if could do register renaming to counter this?
649 int iCount = ignoreLastInstruction ?
650 bb.instructionCount() -1 :
651 bb.instructionCount();
652 for (int i = 0; i < iCount; i++) {
654 // should be only 1 move / ins. but loop to be sure.
655 for (int j = 0; j < ins.moveCount(); j++) {
656 TTAProgram::Move& move = ins.move(j);
657 Terminal& dest = move.destination();
658 // if writes to the guard reg?
659 if (dest.isGPR()) {
660 TerminalRegister& tr = dynamic_cast<TerminalRegister&>(dest);
661 if (tr.index() == index && &tr.registerFile() == &rf) {
662 // simple solution is to disallow this.
663 // moderate solution is o allow only for last
664 // best solution is to allow this for one that can be last
665 return true;
666 }
667 }
668 }
669 }
670 return false;
671}
Terminal & destination() const
Definition Move.cc:323
virtual int index() const
virtual const TTAMachine::RegisterFile & registerFile() const
virtual bool isGPR() const
Definition Terminal.cc:107

References TTAProgram::Move::destination(), TTAProgram::TerminalRegister::index(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Terminal::isGPR(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), and TTAProgram::TerminalRegister::registerFile().

Referenced by canConvert().

Here is the call graph for this function:

Member Data Documentation

◆ codeGenerator_

TTAProgram::CodeGenerator* SimpleIfConverter::codeGenerator_
private

Definition at line 146 of file SimpleIfConverter.hh.

Referenced by addJump(), canConvert(), handleControlFlowGraph(), and handleProgram().

◆ diamonds2_

int SimpleIfConverter::diamonds2_
private

Definition at line 150 of file SimpleIfConverter.hh.

Referenced by handleControlFlowGraph().

◆ diamonds_

int SimpleIfConverter::diamonds_
private

Definition at line 149 of file SimpleIfConverter.hh.

Referenced by handleControlFlowGraph(), and searchCandidate().

◆ diamondSizeLimit_

int SimpleIfConverter::diamondSizeLimit_
private

Definition at line 162 of file SimpleIfConverter.hh.

Referenced by detectDiamond(), and SimpleIfConverter().

◆ grAborts_

int SimpleIfConverter::grAborts_
private

Definition at line 154 of file SimpleIfConverter.hh.

Referenced by canConvert().

◆ grDefAborts_

int SimpleIfConverter::grDefAborts_
private

Definition at line 155 of file SimpleIfConverter.hh.

Referenced by canConvert(), and handleControlFlowGraph().

◆ grUseAborts_

int SimpleIfConverter::grUseAborts_
private

Definition at line 156 of file SimpleIfConverter.hh.

Referenced by canConvert(), and handleControlFlowGraph().

◆ irm_

TTAProgram::InstructionReferenceManager* SimpleIfConverter::irm_
private

Definition at line 147 of file SimpleIfConverter.hh.

Referenced by addJump(), handleControlFlowGraph(), and handleProcedure().

◆ loopAborts_

int SimpleIfConverter::loopAborts_
private

Definition at line 157 of file SimpleIfConverter.hh.

Referenced by detectDiamond(), and handleControlFlowGraph().

◆ sizeAborts_

int SimpleIfConverter::sizeAborts_
private

◆ succAborts_

int SimpleIfConverter::succAborts_
private

Definition at line 160 of file SimpleIfConverter.hh.

Referenced by detectDiamond(), and handleControlFlowGraph().

◆ triangles1_

int SimpleIfConverter::triangles1_
private

Definition at line 151 of file SimpleIfConverter.hh.

Referenced by handleControlFlowGraph(), and searchCandidate().

◆ triangles2_

int SimpleIfConverter::triangles2_
private

Definition at line 152 of file SimpleIfConverter.hh.

Referenced by handleControlFlowGraph(), and searchCandidate().

◆ triangleSizeLimit1_

int SimpleIfConverter::triangleSizeLimit1_
private

Definition at line 163 of file SimpleIfConverter.hh.

Referenced by detectTriangleViaFt(), and SimpleIfConverter().

◆ triangleSizeLimit2_

int SimpleIfConverter::triangleSizeLimit2_
private

Definition at line 164 of file SimpleIfConverter.hh.

Referenced by detectTriangleViaJump(), and SimpleIfConverter().

◆ uncondAborts_

int SimpleIfConverter::uncondAborts_
private

Definition at line 158 of file SimpleIfConverter.hh.

Referenced by canConvert(), handleControlFlowGraph(), and successors().


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