OpenASIP  2.0
Public Member Functions | List of all members
CallsToJumps Class Reference

#include <CallsToJumps.hh>

Inheritance diagram for CallsToJumps:
Inheritance graph
Collaboration diagram for CallsToJumps:
Collaboration graph

Public Member Functions

 CallsToJumps (InterPassData &data)
 
virtual ~CallsToJumps ()
 
virtual void handleControlFlowGraph (ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
 
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
 

Detailed Description

Pass that converts all CALL operation calls to a JUMP that succeeds a regular move to RA that stores the address of the instruction following the original CALL.

This pass should be called for an unscheduled CFG before DDG construction.

Definition at line 36 of file CallsToJumps.hh.

Constructor & Destructor Documentation

◆ CallsToJumps()

CallsToJumps::CallsToJumps ( InterPassData data)
inline

Definition at line 38 of file CallsToJumps.hh.

38 : ControlFlowGraphPass(data) {}

◆ ~CallsToJumps()

virtual CallsToJumps::~CallsToJumps ( )
inlinevirtual

Definition at line 39 of file CallsToJumps.hh.

39 {}

Member Function Documentation

◆ handleControlFlowGraph()

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

Handles a single control flow graph.

The pass should work with any kind of control flow graph, it should not assume the CFG represents a whole procedure, for example.

Parameters
cfgThe control flow graph to handle.
machineThe target machine if any. (NullMachine::instance() if target machine is irrelevant).
Exceptions
Incase handling is unsuccesful for any reason (cfg might still get modified).

Reimplemented from ControlFlowGraphPass.

Definition at line 49 of file CallsToJumps.cc.

50  {
53  int nodeCount = cfg.nodeCount();
54  for (int bbIndex = 0; bbIndex < nodeCount; ++bbIndex) {
55  BasicBlockNode& bbn = dynamic_cast<BasicBlockNode&>(cfg.node(bbIndex));
56  if (!bbn.isNormalBB())
57  continue;
58 
59  assert(!bbn.isScheduled());
60 
61  BasicBlock& bb = bbn.basicBlock();
62 
63  // scan through the instructions, looking for CALLs
64  // replace each call with
65  // 1) a move to RA with an instruction reference to the instruction
66  // following the call (the next BB), and
67  // 2) a JUMP to the original CALL destination
68  // 3) some kind of annotation that marks that this JUMP should
69  // be treated like a function call, e.g., in the DDG builder
70  for (int i = 0, count = bb.instructionCount(); i < count; ++i) {
71  Instruction& instr = bb.instructionAtIndex(i);
72  if (instr.hasCall()) {
73 
74  // If unscheduled it should have exactly one move, the call.
75  assert(instr.moveCount() == 1);
76 
77  // In the TCE's CFG, a call splits the basic block, so this
78  // should be the last instruction as there are no delay slots
79  // in the intermediate representation.
80  assert(i + 1 == count);
81 
82 
83  Move& originalCall = instr.move(0);
84 
85  BasicBlockNode* nextBB = cfg.fallThruSuccessor(bbn);
86  assert(nextBB != NULL);
87 
88 #ifdef DEBUG_CALLS_TO_JUMPS
90  << "### found call: " << originalCall.toString()
91  << std::endl;
93  << "### BB: " << bb.toString() << std::endl;
95  << "### FallThroughBB: " << nextBB->basicBlock().toString()
96  << std::endl;
97 #endif
98 
99  // E.g. call to exit does not return and there is no sensible
100  // place to return. Just do not add the RA write in that case.
101  Instruction* returnLocation =
102  (nextBB->basicBlock().instructionCount() > 0) ?
103  &nextBB->basicBlock().firstInstruction() : NULL;
104 
105  CodeGenerator codeGen(targetMachine);
106 
108 
109  std::shared_ptr<Move> returnAddressMove = NULL;
110  std::shared_ptr<Move> jumpToFunction;
111 
112  if (originalCall.isUnconditional()) {
113 
114  if (returnLocation != NULL) {
115  InstructionReference returnRef =
116  irm.createReference(*returnLocation);
117 
118  returnAddressMove = std::make_shared<Move>(
119  new TerminalInstructionReference(returnRef),
121  *uMach.controlUnit()->returnAddressPort()),
122  uMach.universalBus());
123  }
124 
125  jumpToFunction = std::make_shared<Move>(
126  originalCall.source().copy(),
127  codeGen.createTerminalFUPort("jump", 1),
128  uMach.universalBus());
129  } else {
130 
131  if (returnLocation != NULL) {
132  InstructionReference returnRef =
133  irm.createReference(*returnLocation);
134 
135  returnAddressMove = std::make_shared<Move>(
136  new TerminalInstructionReference(returnRef),
138  *uMach.controlUnit()->returnAddressPort()),
139  uMach.universalBus(),
140  originalCall.guard().copy());
141  }
142 
143  jumpToFunction = std::make_shared<Move>(
144  originalCall.source().copy(),
145  codeGen.createTerminalFUPort("jump", 1),
146  uMach.universalBus(),
147  originalCall.guard().copy());
148  }
149 
150  jumpToFunction->addAnnotation(
151  ProgramAnnotation(ProgramAnnotation::ANN_JUMP_FUNCTION_CALL));
152 
153  if (returnAddressMove != NULL) {
154  Instruction* raMoveInstr =
156  raMoveInstr->addMove(returnAddressMove);
157  bb.insertBefore(instr, raMoveInstr);
158 
159  if (irm.hasReference(instr))
160  irm.replace(instr, *raMoveInstr);
161  }
162 
163  Instruction* jumpInstr =
165  jumpInstr->addMove(jumpToFunction);
166 
167  bb.insertBefore(instr, jumpInstr);
168 
169  if (returnAddressMove == NULL && irm.hasReference(instr))
170  irm.replace(instr, *jumpInstr);
171 
172  // Keep the instruction references up to date as
173  // the old call can be a jump target (so should be the
174  // new RA-move) if it starts a basic block.
175 
176 #ifdef DEBUG_CALLS_TO_JUMPS
178  << "### removing " << instr.toString() << std::endl;
179 #endif
180  assert(!irm.hasReference(instr));
181  bb.remove(instr);
182  }
183  }
184  }
185 }

References TTAProgram::AnnotatedInstructionElement::addAnnotation(), TTAProgram::Instruction::addMove(), TTAProgram::ProgramAnnotation::ANN_JUMP_FUNCTION_CALL, assert, BasicBlockNode::basicBlock(), TTAMachine::Machine::controlUnit(), TTAProgram::MoveGuard::copy(), TTAProgram::Terminal::copy(), TTAProgram::InstructionReferenceManager::createReference(), TTAProgram::CodeGenerator::createTerminalFUPort(), ControlFlowGraph::fallThruSuccessor(), TTAProgram::CodeSnippet::firstInstruction(), TTAProgram::Move::guard(), TTAProgram::Instruction::hasCall(), TTAProgram::InstructionReferenceManager::hasReference(), TTAProgram::CodeSnippet::insertBefore(), TTAMachine::NullInstructionTemplate::instance(), UniversalMachine::instance(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), ControlFlowGraph::instructionReferenceManager(), BasicBlockNode::isNormalBB(), BasicBlockNode::isScheduled(), TTAProgram::Move::isUnconditional(), Application::logStream(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), TTAProgram::CodeSnippet::remove(), TTAProgram::InstructionReferenceManager::replace(), TTAMachine::ControlUnit::returnAddressPort(), TTAProgram::Move::source(), TTAProgram::Move::toString(), TTAProgram::CodeSnippet::toString(), TTAProgram::Instruction::toString(), and UniversalMachine::universalBus().

Referenced by llvm::LLVMTCEIRBuilder::writeMachineFunction().

Here is the call graph for this function:

◆ shortDescription()

std::string CallsToJumps::shortDescription ( ) const
inlinevirtual

A short description of the pass, usually the optimization name, such as "basic block scheduler".

Returns
The description as a string.

Implements SchedulerPass.

Definition at line 44 of file CallsToJumps.hh.

44  {
45  return "Converts CALL operations to JUMPs and explicit RA save moves.";
46  }

The documentation for this class was generated from the following files:
TTAProgram::Instruction::addMove
void addMove(std::shared_ptr< Move > move)
Definition: Instruction.cc:147
TTAProgram::CodeSnippet::firstInstruction
virtual Instruction & firstInstruction() const
Definition: CodeSnippet.cc:216
TTAProgram::Instruction::move
Move & move(int i) const
Definition: Instruction.cc:193
BoostGraph::node
Node & node(const int index) const
TTAProgram::CodeSnippet::insertBefore
virtual void insertBefore(const Instruction &pos, Instruction *ins)
Definition: CodeSnippet.cc:514
UniversalMachine::universalBus
TTAMachine::Bus & universalBus() const
Definition: UniversalMachine.cc:306
TTAProgram::Instruction
Definition: Instruction.hh:57
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
TTAProgram::CodeSnippet::remove
virtual void remove(Instruction &ins)
Definition: CodeSnippet.cc:558
TTAProgram::InstructionReferenceManager::createReference
InstructionReference createReference(Instruction &ins)
Definition: InstructionReferenceManager.cc:73
UniversalMachine::instance
static UniversalMachine & instance()
Definition: UniversalMachine.cc:73
TTAProgram::Instruction::toString
std::string toString() const
Definition: Instruction.cc:576
TTAProgram::Move::toString
std::string toString() const
Definition: Move.cc:436
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
BasicBlockNode::isScheduled
bool isScheduled() const
Definition: BasicBlockNode.hh:93
ControlFlowGraphPass::ControlFlowGraphPass
ControlFlowGraphPass(InterPassData &data)
Definition: ControlFlowGraphPass.cc:42
ControlFlowGraph::instructionReferenceManager
TTAProgram::InstructionReferenceManager & instructionReferenceManager()
Definition: ControlFlowGraph.cc:2401
TTAProgram::Instruction::hasCall
bool hasCall() const
Definition: Instruction.cc:438
BasicBlockNode::basicBlock
TTAProgram::BasicBlock & basicBlock()
Definition: BasicBlockNode.cc:126
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
UniversalMachine
Definition: UniversalMachine.hh:56
TTAProgram::InstructionReferenceManager::hasReference
bool hasReference(Instruction &ins) const
Definition: InstructionReferenceManager.cc:143
TTAProgram::InstructionReferenceManager::replace
void replace(Instruction &insA, Instruction &insB)
Definition: InstructionReferenceManager.cc:96
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
BasicBlockNode
Definition: BasicBlockNode.hh:64
TTAProgram::TerminalInstructionReference
Definition: TerminalInstructionReference.hh:48
BasicBlockNode::isNormalBB
bool isNormalBB() const
Definition: BasicBlockNode.cc:239
TTAProgram::Move
Definition: Move.hh:55
TTAProgram::TerminalFUPort
Definition: TerminalFUPort.hh:56
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
TTAProgram::AnnotatedInstructionElement::addAnnotation
void addAnnotation(const ProgramAnnotation &annotation)
Definition: AnnotatedInstructionElement.cc:63
TTAMachine::NullInstructionTemplate::instance
static NullInstructionTemplate & instance()
Definition: NullInstructionTemplate.cc:62
TTAProgram::InstructionReferenceManager
Definition: InstructionReferenceManager.hh:82
ControlFlowGraph::fallThruSuccessor
BasicBlockNode * fallThruSuccessor(const BasicBlockNode &bbn) const
Definition: ControlFlowGraph.cc:1358
TTAProgram::Terminal::copy
virtual Terminal * copy() const =0
TTAProgram::CodeGenerator
Definition: CodeGenerator.hh:53
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAProgram::MoveGuard::copy
MoveGuard * copy() const
Definition: MoveGuard.cc:96
TTAProgram::CodeSnippet::toString
virtual std::string toString() const
Definition: CodeSnippet.hh:117
TTAProgram::ProgramAnnotation
Definition: ProgramAnnotation.hh:49
TTAMachine::ControlUnit::returnAddressPort
SpecialRegisterPort * returnAddressPort() const
Definition: ControlUnit.cc:307
BoostGraph::nodeCount
int nodeCount() const
TTAProgram::InstructionReference
Definition: InstructionReference.hh:49
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176