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

#include <Peel2BBLoops.hh>

Inheritance diagram for Peel2BBLoops:
Inheritance graph
Collaboration diagram for Peel2BBLoops:
Collaboration graph

Classes

struct  BBNodes
 

Public Member Functions

 Peel2BBLoops (InterPassData &data, const TTAMachine::Machine &targetMachine)
 
void handleControlFlowGraph (ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine) override
 
virtual std::string shortDescription () const override
 
- 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
 

Private Member Functions

bool negateOp (ProgramOperationPtr po)
 
BBNodes testIf2BBLoop (ControlFlowGraph &cfg, BasicBlockNode &bbn)
 
void peel2BBLoop (ControlFlowGraph &cfg, BBNodes &bbns)
 
void updateCFG (ControlFlowGraph &cfg, BBNodes &bbns)
 
void performCodeMotion (BBNodes &bbns)
 
void appendBB (const TTAProgram::BasicBlock &src, TTAProgram::BasicBlock &dest, BasicBlockNode *newJumpDest)
 

Private Attributes

TTAProgram::CodeGeneratorcodeGenerator_
 
TTAProgram::InstructionReferenceManagerirm_
 
const TTAMachine::Machinemach_
 

Detailed Description

Definition at line 22 of file Peel2BBLoops.hh.

Constructor & Destructor Documentation

◆ Peel2BBLoops()

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

Definition at line 31 of file Peel2BBLoops.cc.

32 :
34 codeGenerator_(new TTAProgram::CodeGenerator(targetMachine)),
35 irm_(NULL), mach_(targetMachine) {}
TTAProgram::CodeGenerator * codeGenerator_
TTAProgram::InstructionReferenceManager * irm_
const TTAMachine::Machine & mach_

Member Function Documentation

◆ appendBB()

void Peel2BBLoops::appendBB ( const TTAProgram::BasicBlock src,
TTAProgram::BasicBlock dest,
BasicBlockNode newJumpDest 
)
private

Definition at line 172 of file Peel2BBLoops.cc.

173 {
174
175 std::map<ProgramOperationPtr,ProgramOperationPtr> poMapping;
176
177 ProgramOperationPtr prevPO = nullptr;
178 for (int j = 0; j < src.instructionCount(); j++) {
181 dest.add(newIns);
182 for (int i = 0; i < ins.moveCount(); i++) {
183 const TTAProgram::Move& move = ins.move(i);
184 auto moveCopy = move.copy();
185 MoveNode* newMN = nullptr;
186
187 if (moveCopy->source().isFUPort()) {
188 ProgramOperationPtr newPO =
190 static_cast<TTAProgram::TerminalFUPort&>(
191 moveCopy->source()),
192 poMapping);
193 if (newPO != NULL) {
194 prevPO = newPO;
195 newMN = new MoveNode(moveCopy);
196 newPO->addOutputNode(*newMN);
197 newMN->setSourceOperationPtr(newPO);
198 }
199 }
200 if (moveCopy->destination().isFUPort()) {
202 static_cast<TTAProgram::TerminalFUPort&>(
203 moveCopy->destination()),
204 poMapping);
205 if (newPO != NULL) {
206 prevPO = newPO;
207 if (newMN == nullptr)
208 newMN = new MoveNode(moveCopy);
209 newPO->addInputNode(*newMN);
210 newMN->addDestinationOperationPtr(newPO);
211 }
212 }
213
214 // for jumps, need to update target and inverse guard.
215 if (moveCopy->isJump() && newJumpDest != nullptr) {
216 if (!moveCopy->isUnconditional()) {
217
218 // if fake guard, first try to inverse the op that
219 // generated it, but if it fails negate the guard.
220 if (!(moveCopy->guard().guard().parentBus() == nullptr
221 && negateOp(prevPO))) {
222
223 moveCopy->setGuard(
225 moveCopy->guard()));
226 }
227
228 } else { // bz / bnz
229 // TODO: put these into a map?
230 std::map<std::string, std::string> branchNegations =
231 {{"BZ", "BNZ"}, {"BNZ", "BZ"},
232 {"BZ1", "BNZ1"}, {"BNZ1", "BZ1"},
233 {"BEQ", "BNE"}, {"BNE", "BEQ"},
234 {"BGT", "BLE"}, {"BLE", "BGT"},
235 {"BGTU", "BLEU"}, {"BLEU", "BGTU"},
236 {"BLT", "BGE"}, {"BGE", "BLT"},
237 {"BLTU", "BGEU"}, {"BGEU", "BLTU"}
238 };
239 auto *dest = dynamic_cast<TTAProgram::TerminalFUPort*>(
240 &moveCopy->destination());
241 assert(dest);
242 TCEString jumpName = dest->hintOperation().name();
243 if (branchNegations.count(jumpName) > 0) {
245 std::string negatedOpName = branchNegations[jumpName];
246 const Operation& negatedOp =
247 pool.operation(negatedOpName.c_str());
248 newMN->destinationOperation().setOperation(negatedOp);
249 } else {
250 assert (false &&
251 "Cannot neg unknown conditional jump instr");
252 }
253 }
254 moveCopy->setSource(
256 newJumpDest->basicBlock()));
257 }
258 newIns->addMove(moveCopy);
259 }
260 }
261}
#define assert(condition)
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition MoveNode.hh:53
TTAProgram::BasicBlock & basicBlock()
void setSourceOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:541
void addDestinationOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:533
ProgramOperation & destinationOperation(unsigned int index=0) const
bool negateOp(ProgramOperationPtr po)
void setOperation(const Operation &op)
static ProgramOperationPtr fixTerminalPO(TTAProgram::TerminalFUPort &terminal, std::map< ProgramOperationPtr, ProgramOperationPtr > &poMapping)
static TTAProgram::MoveGuard * createInverseGuard(const TTAProgram::MoveGuard &mg, const TTAMachine::Bus *bus=NULL)
virtual void add(Instruction *ins)
virtual int instructionCount() const
virtual Instruction & instructionAtIndex(int index) const
Move & move(int i) const
void addMove(std::shared_ptr< Move > move)
std::shared_ptr< Move > copy() const
Definition Move.cc:413
std::unique_ptr< OperationPool > pool

References TTAProgram::CodeSnippet::add(), MoveNode::addDestinationOperationPtr(), TTAProgram::Instruction::addMove(), assert, BasicBlockNode::basicBlock(), codeGenerator_, TTAProgram::Move::copy(), TTAProgram::CodeGenerator::createInverseGuard(), MoveNode::destinationOperation(), SimpleIfConverter::fixTerminalPO(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), negateOp(), ProgramOperation::setOperation(), and MoveNode::setSourceOperationPtr().

Referenced by performCodeMotion().

Here is the call graph for this function:

◆ handleControlFlowGraph()

void Peel2BBLoops::handleControlFlowGraph ( ControlFlowGraph cfg,
const TTAMachine::Machine targetMachine 
)
overridevirtual

Handles a cfg.

Parameters
cfgcfg to be optimized.

Reimplemented from ControlFlowGraphPass.

Definition at line 101 of file Peel2BBLoops.cc.

102 {
103 if (codeGenerator_ == NULL) {
104 codeGenerator_ = new TTAProgram::CodeGenerator(targetMachine);
105 }
106
108
109 for (int i = 0; i < cfg.nodeCount(); i++) {
110
111 // first find the block containing the main body(end) of the loop
112 BasicBlockNode& bbn = cfg.node(i);
113
114 if (auto loopBlocks = testIf2BBLoop(cfg, bbn)) {
115 peel2BBLoop(cfg, loopBlocks);
116
117 // performing this may change other basic blocks so lets start
118 // from beginning(may it?)
119 i = 0;
120 }
121 }
122}
int nodeCount() const
Node & node(const int index) const
TTAProgram::InstructionReferenceManager & instructionReferenceManager()
BBNodes testIf2BBLoop(ControlFlowGraph &cfg, BasicBlockNode &bbn)
void peel2BBLoop(ControlFlowGraph &cfg, BBNodes &bbns)

References codeGenerator_, ControlFlowGraph::instructionReferenceManager(), irm_, BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), peel2BBLoop(), and testIf2BBLoop().

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

Here is the call graph for this function:

◆ negateOp()

bool Peel2BBLoops::negateOp ( ProgramOperationPtr  po)
private

Negates operation into operation which generates opposite predicate value.

Definition at line 267 of file Peel2BBLoops.cc.

267 {
268
269 // TODO: Shouldn't these be CAPSed? does this really work?
270 std::map<TCEString, TCEString> negateOps;
271 negateOps["eq"] = "ne";
272 negateOps["ne"] = "eq";
273 negateOps["le"] = "gt";
274 negateOps["gt"] = "le";
275 negateOps["lt"] = "ge";
276 negateOps["ge"] = "lt";
277 negateOps["leu"] = "gtu";
278 negateOps["gtu"] = "leu";
279 negateOps["ltu"] = "geu";
280 negateOps["geu"] = "ltu";
281
282 const Operation& op = po->operation();
283 std::cerr << "negating op: " << op.name() << std::endl;
284 auto i = negateOps.find(op.name());
285 if (i == negateOps.end()) {
286 std::cerr << "negated op for: " << op.name() << " not found!" << std::endl;
287 return false;
288 }
289 std::cerr << "negated opname: " << i->second << std::endl;
290
291 if (!MachineInfo::supportsOperation(mach_, i->second)) {
292 return false;
293 }
295 const Operation& negatedOp = pool.operation(i->second.c_str());
296 po->setOperation(negatedOp);
297 return true;
298}
static bool supportsOperation(const TTAMachine::Machine &mach, TCEString operation)
virtual TCEString name() const
Definition Operation.cc:93

References mach_, Operation::name(), and MachineInfo::supportsOperation().

Referenced by appendBB().

Here is the call graph for this function:

◆ peel2BBLoop()

void Peel2BBLoops::peel2BBLoop ( ControlFlowGraph cfg,
BBNodes bbns 
)
private

Definition at line 124 of file Peel2BBLoops.cc.

124 {
125 performCodeMotion(bbns);
126 updateCFG(cfg, bbns);
127}
void performCodeMotion(BBNodes &bbns)
void updateCFG(ControlFlowGraph &cfg, BBNodes &bbns)

References performCodeMotion(), and updateCFG().

Referenced by handleControlFlowGraph().

Here is the call graph for this function:

◆ performCodeMotion()

void Peel2BBLoops::performCodeMotion ( BBNodes bbns)
private

Definition at line 156 of file Peel2BBLoops.cc.

156 {
157 // the nasty jump to middle of bb, removed because copying the code
158 assert(SimpleIfConverter::removeJump(bbns.preLoop->basicBlock()));
159
160 // then append the end of the loop into the pre-loop BB,
161 // and inverse the guard and update the jump destination the post-loop
162 appendBB(bbns.endLoop->basicBlock(),
163 bbns.preLoop->basicBlock(),
164 bbns.postLoop);
165
166 // append end of loop to begin of the loop. no need to update jump.
167 appendBB(bbns.endLoop->basicBlock(),
168 bbns.beginLoop->basicBlock(),
169 nullptr);
170}
void appendBB(const TTAProgram::BasicBlock &src, TTAProgram::BasicBlock &dest, BasicBlockNode *newJumpDest)
static bool removeJump(TTAProgram::BasicBlock &bb)

References appendBB(), assert, BasicBlockNode::basicBlock(), Peel2BBLoops::BBNodes::beginLoop, Peel2BBLoops::BBNodes::endLoop, Peel2BBLoops::BBNodes::postLoop, Peel2BBLoops::BBNodes::preLoop, and SimpleIfConverter::removeJump().

Referenced by peel2BBLoop().

Here is the call graph for this function:

◆ shortDescription()

virtual std::string Peel2BBLoops::shortDescription ( ) const
inlineoverridevirtual

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 32 of file Peel2BBLoops.hh.

32 {
33 return "optimizes two-BB inner loops into single-bb inner loops";
34 }

◆ testIf2BBLoop()

Peel2BBLoops::BBNodes Peel2BBLoops::testIf2BBLoop ( ControlFlowGraph cfg,
BasicBlockNode bbn 
)
private

Definition at line 37 of file Peel2BBLoops.cc.

37 {
38
39 // entry/exit node or wrong number of succs/preds
40 if (!bbn.isNormalBB() || cfg.outDegree(bbn) != 2 ||
41 cfg.inDegree(bbn) != 2) {
42 return false;
43 }
44
45 // find possible loop begin node and pre-loop node.
46 auto iEdges = cfg.inEdges(bbn);
47 BasicBlockNode *loopBegin = NULL;
48 BasicBlockNode* preLoop = NULL;
49 for (auto e: iEdges) {
50 if (e->isFallThroughEdge()) {
51 loopBegin = &cfg.tailNode(*e);
52 } else {
53 preLoop = &cfg.tailNode(*e);
54 }
55 }
56 if (loopBegin == NULL || preLoop == NULL) {
57 return false;
58 }
59
60 auto oEdges = cfg.outEdges(bbn);
61 BasicBlockNode *afterLoop = NULL;
62 for (auto e: oEdges) {
63 if (e->isFallThroughEdge()) {
64 afterLoop = &cfg.headNode(*e);
65 } else { // jump to loop begin
66 if (&cfg.headNode(*e) != loopBegin) {
67 return false;
68 }
69 }
70 }
71
72 if (afterLoop == NULL) {
73 return false;
74 }
75
76 if (cfg.inDegree(*loopBegin) != 1 || cfg.outDegree(*loopBegin) != 1) {
77 return false;
78 }
79
80 if (!cfg.outEdge(*loopBegin, 0).isFallThroughEdge() ||
81 cfg.inEdge(*loopBegin, 0).isFallThroughEdge()) {
82 return false;
83 }
84
85 // incoming must not be fall-through.
86 if (cfg.outDegree(*preLoop) != 1) {
87 return false;
88 }
89
90 return BBNodes(preLoop, loopBegin, &bbn, afterLoop);
91}
bool isNormalBB() const
virtual Node & headNode(const Edge &edge) const
virtual Edge & outEdge(const Node &node, const int index) const
virtual Edge & inEdge(const Node &node, const int index) const
virtual int inDegree(const Node &node) const
virtual int outDegree(const Node &node) const
virtual EdgeSet outEdges(const Node &node) const
virtual Node & tailNode(const Edge &edge) const
virtual EdgeSet inEdges(const Node &node) const
bool isFallThroughEdge() const

References BoostGraph< GraphNode, GraphEdge >::headNode(), BoostGraph< GraphNode, GraphEdge >::inDegree(), BoostGraph< GraphNode, GraphEdge >::inEdge(), BoostGraph< GraphNode, GraphEdge >::inEdges(), ControlFlowEdge::isFallThroughEdge(), BasicBlockNode::isNormalBB(), BoostGraph< GraphNode, GraphEdge >::outDegree(), BoostGraph< GraphNode, GraphEdge >::outEdge(), BoostGraph< GraphNode, GraphEdge >::outEdges(), and BoostGraph< GraphNode, GraphEdge >::tailNode().

Referenced by handleControlFlowGraph().

Here is the call graph for this function:

◆ updateCFG()

void Peel2BBLoops::updateCFG ( ControlFlowGraph cfg,
BBNodes bbns 
)
private

Definition at line 130 of file Peel2BBLoops.cc.

130 {
131 // pre to loop-end needs to be converted from jump to fall-through,
132 // with correct predicate(which is got from the loop node, reversing it
133 cfg.disconnectNodes(*bbns.preLoop, *bbns.endLoop);
134 auto exitEdge = *cfg.connectingEdges(*bbns.endLoop, *bbns.postLoop).begin();
135 auto loopEdge = *cfg.connectingEdges(*bbns.endLoop, *bbns.beginLoop).begin();
136
137 ControlFlowEdge* intoLoop = new ControlFlowEdge(
138 loopEdge->edgePredicate(),
140
141 ControlFlowEdge* overLoop = new ControlFlowEdge(
142 exitEdge->edgePredicate(),
144
145 cfg.moveOutEdge(*bbns.endLoop, *bbns.beginLoop, *loopEdge);
146 loopEdge->setBackEdge();
147 cfg.moveOutEdge(*bbns.endLoop, *bbns.beginLoop, *exitEdge);
148 cfg.connectNodes(*bbns.preLoop, *bbns.beginLoop, *intoLoop);
149 cfg.connectNodes(*bbns.preLoop, *bbns.postLoop, *overLoop);
150
151 // old loop end bb
152 cfg.deleteNodeAndRefs(*bbns.endLoop);
153}
virtual void disconnectNodes(const Node &nTail, const Node &nHead)
virtual void moveOutEdge(const Node &source, const Node &destination, Edge &edge, const Node *head=NULL, bool childs=false)
EdgeSet connectingEdges(const Node &nTail, const Node &nHead) const
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
void deleteNodeAndRefs(BasicBlockNode &node)

References Peel2BBLoops::BBNodes::beginLoop, ControlFlowEdge::CFLOW_EDGE_FALLTHROUGH, ControlFlowEdge::CFLOW_EDGE_JUMP, BoostGraph< GraphNode, GraphEdge >::connectingEdges(), BoostGraph< GraphNode, GraphEdge >::connectNodes(), ControlFlowGraph::deleteNodeAndRefs(), BoostGraph< GraphNode, GraphEdge >::disconnectNodes(), Peel2BBLoops::BBNodes::endLoop, BoostGraph< GraphNode, GraphEdge >::moveOutEdge(), Peel2BBLoops::BBNodes::postLoop, and Peel2BBLoops::BBNodes::preLoop.

Referenced by peel2BBLoop().

Here is the call graph for this function:

Member Data Documentation

◆ codeGenerator_

TTAProgram::CodeGenerator* Peel2BBLoops::codeGenerator_
private

Definition at line 62 of file Peel2BBLoops.hh.

Referenced by appendBB(), and handleControlFlowGraph().

◆ irm_

TTAProgram::InstructionReferenceManager* Peel2BBLoops::irm_
private

Definition at line 63 of file Peel2BBLoops.hh.

Referenced by handleControlFlowGraph().

◆ mach_

const TTAMachine::Machine& Peel2BBLoops::mach_
private

Definition at line 64 of file Peel2BBLoops.hh.

Referenced by negateOp().


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