OpenASIP  2.0
LLVMTCEIRBuilder.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2015 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file LLVMTCEIRBuilder.hh
26  *
27  * This builder builds a CFG and DDG from the new LLVM TTA backend format.
28  *
29  * @author Heikki Kultala 2011
30  * @author Henry Linjamäki 2017 (henry.linjamaki-no.spam-tut.fi)
31  * @note reting: red
32  */
33 
34 #ifdef NDEBUG
35 #undef NDEBUG
36 #endif
37 
38 #include "CompilerWarnings.hh"
39 IGNORE_COMPILER_WARNING("-Wunused-parameter")
40 
41 #include "LLVMTCEIRBuilder.hh"
42 #include "ControlFlowGraph.hh"
43 #include "Procedure.hh"
44 #include "AddressSpace.hh"
45 #include "ControlUnit.hh"
46 #include "DataDependenceGraph.hh"
49 #include "TerminalFUPort.hh"
50 #include "SequentialScheduler.hh"
51 #include "PreOptimizer.hh"
52 #include "BBSchedulerController.hh"
55 #include "SimpleIfConverter.hh"
56 #include "Peel2BBLoops.hh"
58 #include "Machine.hh"
60 #include "Program.hh"
61 #include "RegisterCopyAdder.hh"
62 #include "LLVMTCECmdLineOptions.hh"
63 #include "Instruction.hh"
64 #include "FunctionUnit.hh"
65 #include "HWOperation.hh"
66 #include "FUPort.hh"
67 #include "BasicBlock.hh"
68 #include "Move.hh"
69 #include "MapTools.hh"
70 #include "PRegionMarkerAnalyzer.hh"
71 #include "PostpassOperandSharer.hh"
72 #include "CallsToJumps.hh"
74 
75 #include <stdlib.h>
76 #include <llvm/ADT/SmallString.h>
77 #include <llvm/MC/MCContext.h>
78 #include <llvm/MC/MCSymbol.h>
79 #include <llvm/CodeGen/MachineJumpTableInfo.h>
80 #include <llvm/IR/Value.h>
81 #include <llvm/CodeGen/MachineMemOperand.h>
82 #include "llvm/Analysis/AliasAnalysis.h"
83 
85 
86 #define EXIT_IF_THROWS(__X__) \
87  try { \
88  __X__; \
89  } catch (const Exception& e) { \
90  Application::errorStream() \
91  << "Error: " << e.errorMessage() << std::endl; \
92  exit(1); \
93  }
94 
95 
96 //#define WRITE_DDG_DOTS
97 //#define WRITE_CFG_DOTS
98 
99 namespace llvm {
100 
101 char LLVMTCEIRBuilder::ID = -1;
102 
104  const llvm::TargetMachine& tm, TTAMachine::Machine* mach,
105  InterPassData& ipd, AliasAnalysis* AA, bool functionAtATime,
106  bool modifyMF) :
107  LLVMTCEBuilder(tm, mach, ID, functionAtATime), ipData_(&ipd),
108  ddgBuilder_(ipd), AA_(AA), modifyMF_(modifyMF),
109  scheduler_(NULL), dsf_(NULL),
110  bypasser_(NULL), loopFinder_(NULL) {
112 
113  if (functionAtATime_) {
115  mach->functionUnitNavigator();
116 
117  // the supported operation set
118  for (int i = 0; i < fuNav.count(); i++) {
119  const TTAMachine::FunctionUnit& fu = *fuNav.item(i);
120  for (int o = 0; o < fu.operationCount(); o++) {
121  opset_.insert(
123  }
124  }
125 
126  }
128 }
129 
130 void
131 LLVMTCEIRBuilder::getAnalysisUsage(AnalysisUsage &AU) const {
133 }
134 
135 bool
137 
138  if (tm_ == NULL)
139  tm_ = &mf.getTarget();
140 
142 
143  curFrameInfo_ = &mf.getFrameInfo();
144  assert(curFrameInfo_ != NULL);
145 
146  if (!functionAtATime_) {
147  // ensure data sections have been initialized when compiling
148  // the whole program at a time
150  emitConstantPool(*mf.getConstantPool());
151  } else {
152  mang_ = new llvm::Mangler();
153  }
154 
155  // omit empty functions..
156  if (mf.begin() == mf.end()) return true;
157 
159 
160  SmallString<256> Buffer;
161  mang_->getNameWithPrefix(Buffer, &mf.getFunction(), false);
162  TCEString fnName(Buffer.c_str());
163 
164  TTAProgram::Procedure* procedure =
165  new TTAProgram::Procedure(fnName, *as);
166 
167  if (!functionAtATime_) {
168  prog_->addProcedure(procedure);
169  }
170 
172  if (functionAtATime_) {
174  } else {
176  }
177 
178  ControlFlowGraph* cfg = buildTCECFG(mf);
180 #ifdef WRITE_CFG_DOTS
181  cfg->writeToDotFile(fnName + "_cfg1.dot");
182 #endif
183 
184  bool fastCompilation = options_ != NULL && options_->optLevel() == 0;
185 
186  markJumpTableDestinations(mf, *cfg);
187 
188  if (!mach_->controlUnit()->hasOperation("call")) {
189  CallsToJumps ctj(*ipData_);
190  ctj.handleControlFlowGraph(*cfg, *mach_);
191  }
192 
193  if (fastCompilation || !isHotFunction(mf)) {
194  verboseLog(TCEString("### compiling (fast): ") + fnName);
196  } else {
197  verboseLog(TCEString("### compiling (optimized): ") + fnName);
198  AliasAnalysis* AA = NULL;
199  if (!AA_) {
200  // Called through LLVMBackend. We are actual module and
201  // can get previous pass analysis!
202  AAResultsWrapperPass* AARWPass =
203  getAnalysisIfAvailable<AAResultsWrapperPass>();
204  if (AARWPass)
205  AA = &AARWPass->getAAResults();
206  } else {
207  // Called through LLVMTCEScheduler. We are not registered
208  // module in pass manager, so we do not have previous
209  // pass analysis data, but LLVMTCEScheduler kindly
210  // got them for us and passed through.
211  AA = AA_;
212  }
213  EXIT_IF_THROWS(compileOptimized(*cfg, AA));
214  }
215 
216  if (!modifyMF_) {
218  }
219  cfg->copyToProcedure(*procedure, irm);
220 #ifdef WRITE_CFG_DOTS
221  cfg->writeToDotFile(fnName + "_cfg4.dot");
222 #endif
223  if (procedure->instructionCount() > 0) {
224  codeLabels_[fnName] = &procedure->firstInstruction();
225  }
226 
227  if (modifyMF_) {
228  cfg->copyToLLVMMachineFunction(mf, irm);
229  fixJumpTableDestinations(mf, *cfg);
230  delete cfg;
231  return true;
232  }
233 
234  AbsoluteToRelativeJumps jumpConv(*ipData_);
235  jumpConv.handleProcedure(*procedure, *mach_);
236 
237  if (Application::verboseLevel() > 0 && spillMoveCount_ > 0) {
239  << "spill moves in " <<
240  (std::string)(mf.getFunction().getName()) << ": "
241  << spillMoveCount_ << std::endl;
242  }
243 
244  delete cfg;
245  if (functionAtATime_) delete irm;
246  return false;
247 }
248 
249 /**
250  * Returns false in case the given function should be compiled with
251  * fast settings without optimizations.
252  *
253  * This looks into the tcecc --primary-functions function list if it's
254  * set. If not set, assumes all functions are "hot".
255  */
256 bool
257 LLVMTCEIRBuilder::isHotFunction(llvm::MachineFunction& mf) const {
258 
259  if (options_ == NULL) return true;
260 
262 
263  if (funcs == NULL || funcs->size() == 0)
264  return true;
265 
266  SmallString<256> Buffer;
267  mang_->getNameWithPrefix(Buffer, &mf.getFunction(), false);
268  TCEString fnName(Buffer.c_str());
269  return AssocTools::containsKey(*funcs, fnName);
270 }
271 
273 LLVMTCEIRBuilder::buildTCECFG(llvm::MachineFunction& mf) {
274 
275  SmallString<256> Buffer;
276  mang_->getNameWithPrefix(Buffer, &mf.getFunction(), false);
277  TCEString fnName(Buffer.c_str());
278 
279  ControlFlowGraph* cfg = new ControlFlowGraph(fnName, prog_);
280 
281  bbMapping_.clear();
282  skippedBBs_.clear();
283 
284  // TODO: these maps/sets with pointer keys are possible source of
285  // indeterminism.
286  std::set<const MachineBasicBlock*> endingCallBBs;
287  std::set<const MachineBasicBlock*> endingCondJumpBBs;
288  std::set<const MachineBasicBlock*> endingUncondJumpBBs;
289  std::set<const MachineBasicBlock*> endingInlineAsmBBs;
290  std::map<const BasicBlockNode*, BasicBlockNode*> callSuccs;
291  std::map<const BasicBlockNode*, const MachineBasicBlock*> condJumpSucc;
292  std::map<const BasicBlockNode*, BasicBlockNode*> ftSuccs;
293  // This holds BB -> inlineAsmBB mapping.
294  std::map<const BasicBlockNode*, BasicBlockNode*> ftSuccsToInlineAsm;
295  // This holds inlineAsmBB -> BB and inlineAsmBB -> inlineAsmBB mapping.
296  std::map<const BasicBlockNode*, BasicBlockNode*> inlineAsmSuccs;
297  std::set<const MachineBasicBlock*> emptyMBBs;
298  std::set<const MachineBasicBlock*> hwloopMBBs;
299  std::map<const BasicBlockNode*, bool> bbPredicates;
300  ControlFlowGraph::NodeSet returningBBs;
301 
302  BasicBlockNode* entry = new BasicBlockNode(0, 0, true);
303  cfg->addNode(*entry);
304  bool firstInsOfProc = true;
305 
307  hwloopMBBs.clear();
308 
309  // 1st loop create all BB's. do not fill them yet.
310  for (MachineFunction::const_iterator i = mf.begin(); i != mf.end(); i++) {
311  const MachineBasicBlock& mbb = *i;
312  //TODO: what does the parameter do? start address?
314 
315  // this doesn't seem robust: it assumes _start is added to
316  // the program first and the BBs added in their program
317  // order
318  bool firstBBofTheProgram =
319  !functionAtATime_ && prog_->procedureCount() == 1 &&
320  cfg->nodeCount() == 1;
321  // first BB of the program
322  if (firstBBofTheProgram) {
324  }
325 
326  TCEString bbName = mbbName(mbb);
327  BasicBlockNode* bbn = new BasicBlockNode(*bb);
328  bbn->setBBOwnership(true);
329 
330  // if the basic block is detected as an inner loop basic block,
331  // transform the info to the built TCE CFG
332  if (loopFinder_ != NULL) {
335 
336  InnerLoopFinder::InnerLoopInfoIndex::const_iterator loopInfoI =
337  loopInfos.find(mbb.getBasicBlock());
338  if (loopInfoI != loopInfos.end()) {
340  (*loopInfoI).second;
341  bb->setInInnerLoop();
342  if (loopInfo.isTripCountKnown()) {
343  bb->setTripCount(loopInfo.tripCount());
344  }
345  }
346  }
347 
348  bool newMBB = true;
349  bool newBB = true;
350  unsigned realInstructionCount = 0;
351  bool lastInstrWasInlineAsm = false;
352 
353  // 1st loop: create all BB's. Do not fill them with instructions.
354  for (MachineBasicBlock::const_iterator j = mbb.begin();
355  j != mbb.end(); j++) {
356 
357  if (!isRealInstruction(*j)) {
358  continue;
359  }
360 
361  // Put all instances of inline asm blocks to own BB.
362  // Split BB if there is instructions already added to BB.
363  if (isInlineAsm(*j)) {
364  // TODO check if inline asm does not have any instructions?
365  // Split BB before the inline asm unless first instruction in
366  // BB.
367  if (realInstructionCount > 0 && !lastInstrWasInlineAsm) {
368  bb = new TTAProgram::BasicBlock(0);
369  BasicBlockNode* succBBN = new BasicBlockNode(*bb);
370  ftSuccsToInlineAsm[bbn] = succBBN;
371  bbn = succBBN;
372  newBB = true;
373  }
374  lastInstrWasInlineAsm = true;
375  }
376 
377  if (newBB) {
378  realInstructionCount = 0;
379  newBB = false;
380  cfg->addNode(*bbn);
381  if (firstInsOfProc) {
382  ControlFlowEdge* edge = new ControlFlowEdge;
383  cfg->connectNodes(*entry, *bbn, *edge);
384  firstInsOfProc = false;
385  }
386 
387  if (newMBB) {
388  newMBB = false;
389  bbMapping_[&(mbb)] = bbn;
390  for (std::set<const MachineBasicBlock*>::iterator k =
391  emptyMBBs.begin(); k != emptyMBBs.end(); k++) {
392  skippedBBs_[*k] = bbn;
393  }
394  emptyMBBs.clear();
395  }
396  }
397  realInstructionCount++;
398 
399  // Put all instances of INLINEASM nodes to own BB.
400  // This one "closes" inline asm BB and creates new BB for rest
401  // of the instructions or next inline asm block.
402  if (isInlineAsm(*j)) {
403  // New BB after inline asm.
404  MachineBasicBlock::const_iterator afterInlineAsm = j;
405  ++afterInlineAsm;
406  if (hasRealInstructions(afterInlineAsm, mbb)) {
407  bb = new TTAProgram::BasicBlock(0);
408  BasicBlockNode* succBBN = new BasicBlockNode(*bb);
409  inlineAsmSuccs[bbn] = succBBN;
410  bbn = succBBN;
411  newBB = true;
412  } else {
413  endingInlineAsmBBs.insert(&mbb);
414  }
415  continue;
416  }
417  lastInstrWasInlineAsm = false;
418 
419  if (j->getDesc().isCall() || isExplicitReturn(*j)) {
420  if (j->getDesc().isCall() && j->getOperand(0).isGlobal()) {
421  // If it's a direct call (not via function pointer),
422  // check that the called function is defined. At this
423  // point we should have a fully linked program.
424  const Function* callee =
425  dyn_cast<Function>(j->getOperand(0).getGlobal());
426  assert(callee != NULL);
427  if (callee->size() == 0) {
428  TCEString errorMsg =
429  "error: call to undefined function '";
430  errorMsg << callee->getName().str() << "'.";
431  throw CompileError(
432  __FILE__, __LINE__, __func__, errorMsg);
433  }
434  }
435  // if last ins of bb is call, no need to create new bb.
436  if (&(*j) == &(mbb.back())) {
437  endingCallBBs.insert(&(*i));
438  } else {
439  MachineBasicBlock::const_iterator afterCall = j;
440  ++afterCall;
441  if (!hasRealInstructions(afterCall, mbb)) {
442  endingCallBBs.insert(&(*i));
443  } else {
444  // create a new BB for code after the call
445  bb = new TTAProgram::BasicBlock(0);
446  BasicBlockNode* succBBN = new BasicBlockNode(*bb);
447  succBBN->setBBOwnership(true);
448  callSuccs[bbn] = succBBN;
449  bbn = succBBN;
450  newBB = true;
451  }
452  }
453  continue;
454  }
455  // also need to split BB on cond branch.
456  // LLVM BB may contain 2 branches.
457  if (j->getDesc().isBranch()) {
458  TCEString opName = operationName(*j);
459  bool pred = false;
460  if (j->getDesc().isConditionalBranch()) {
461  if (opName == "?jump") pred = true;
462  if (opName == "BNZ") pred = true;
463  if (opName == "BNZ1") pred = true;
464  // TODO: Should this not have BZ/BZ1?
465  if (opName == "BEQ") pred = true;
466  if (opName == "BNE") pred = true;
467  if (opName == "BGT") pred = true;
468  if (opName == "BGTU") pred = true;
469  if (opName == "BLT") pred = true;
470  if (opName == "BLTU") pred = true;
471  if (opName == "BLE") pred = true;
472  if (opName == "BLEU") pred = true;
473  if (opName == "BGE") pred = true;
474  if (opName == "BGEU") pred = true;
475 
476  // TODO: what is the meaning of this?
477  if (opName.find("+") != std::string::npos) pred = true;
478  bbPredicates[bbn] = pred;
479  const MachineOperand& mo = j->getOperand(j->getNumOperands()-1);
480  assert(mo.isMBB());
481  condJumpSucc[bbn] = mo.getMBB();
482 
483  if (&(*j) == &(mbb.back())) {
484  endingCondJumpBBs.insert(&(*i));
485  } else {
486  if (!hasRealInstructions(j, mbb)) {
487  endingCondJumpBBs.insert(&(*i));
488  } else {
489  // create a new BB for the code after the conditional branch.
490  // this should only contain one uncond jump.
491  bb = new TTAProgram::BasicBlock(0);
492  BasicBlockNode* succBBN = new BasicBlockNode(*bb);
493  succBBN->setBBOwnership(true);
494  ftSuccs[bbn] = succBBN;
495  bbn = succBBN;
496  newBB = true;
497  }
498  }
499  } else {
500  // has to be uncond jump, and last ins of bb.
501  if (&(*j) != &(mbb.back())) {
502  Application::logStream() << " not at the end of ";
503  if (j->getDesc().isBranch())
504  Application::logStream() << " is branch";
505  abortWithError("Jump was not last ins of BB.");
506  }
507  endingUncondJumpBBs.insert(&(*i));
508  }
509  continue;
510  }
511  } // for loop
512  if (newMBB) {
513  assert(newBB);
514  emptyMBBs.insert(&mbb);
515  }
516  if (newBB) {
517  assert(firstBBofTheProgram || bb->instructionCount() == 0);
518  delete bbn;
519  }
520  }
521 
523  if (functionAtATime_) {
525  } else {
527  }
528 
529  // 2nd loop: create all instructions inside BB's.
530  // this can only come after the first loop so that BB's have
531  // already been generated.
532  for (MachineFunction::const_iterator i = mf.begin(); i != mf.end(); i++) {
533  const MachineBasicBlock& mbb = *i;
534 
535  BasicBlockNode* bbn = NULL;
536  std::map<const MachineBasicBlock*, BasicBlockNode*>::iterator
537  bbMapIter = bbMapping_.find(&mbb);
538  if (bbMapIter == bbMapping_.end()) {
539  continue;
540  } else {
541  bbn = bbMapIter->second;
542  }
543  TTAProgram::BasicBlock* bb = &bbn->basicBlock();
544 
545  /* If this is non-empty, the ProgramOperation of the next
546  instruction should be indexed with the given label. */
547  TCEString nextLabel = "";
548  for (MachineBasicBlock::const_iterator j = mbb.begin();
549  j != mbb.end(); j++) {
550 
551  if (!isTTATarget() &&
552  (operationName(*j) == "HBR_LABEL" ||
553  operationName(*j) == "PROLOG_LABEL")) {
554 
555  /*
556  FIXME: this code fails when there are multiple labels
557  pointing to the same instruction. Only the last label
558  will be indexed. */
559  assert(nextLabel == "");
560 
561  nextLabel = j->getOperand(0).getMCSymbol()->getName().str();
562  continue;
563  }
564 
565  if (isInlineAsm(*j)) {
566  if (AssocTools::containsKey(ftSuccsToInlineAsm, bbn)) {
567  bbn = ftSuccsToInlineAsm[bbn];
568  bb = &bbn->basicBlock();
569  }
570  emitInlineAsm(mf, &*j, bb, *irm);
571  bbn->setScheduled(true);
572  if (AssocTools::containsKey(inlineAsmSuccs, bbn)) {
573  bbn = inlineAsmSuccs[bbn];
574  bb = &bbn->basicBlock();
575  }
576  continue;
577  }
578 
579  TTAProgram::Instruction* instr = NULL;
580  instr = emitInstruction(&*j, bb);
581 
582  if (instr == NULL) {
583  continue;
584  }
585 
586  if (nextLabel != "") {
588  dynamic_cast<TTAProgram::TerminalFUPort&>(
589  instr->move(0).destination());
591  nextLabel = "";
592  }
593 
594  // basic blocks that contain return instruction will have jump
595  // edge to exit node in cfg, not callpass edge.
596  if (j->getDesc().isReturn()) {
597  returningBBs.insert(bbn);
598  }
599 
600  // if a call or an explicit return instruction,
601  // or an unconditional jump from inline asm, switch to the
602  // next TCE bb (in callsucc chain) that was created in the
603  // previous loop
604  if ((j->getDesc().isCall() || isExplicitReturn(*j) ||
605  (!j->getDesc().isBranch() && instr->hasControlFlowMove())) &&
606  &(*j) != &(mbb.back())) {
607  if (operationName(*j) == "hwloop") {
608  if (j->getNextNode() != nullptr &&
609  !j->getNextNode()->isBranch()) {
610  mbb.dump();
611  assert(false && "HWLOOP is not terminator in BB");
612  }
613  }
614  if (!AssocTools::containsKey(callSuccs, bbn)) {
615  // the call ends the basic block, after this only at most
616  // "non real" instructions (such as debug metadata), which
617  // we can simply ignore
618  break;
619  }
620  bbn = callSuccs[bbn];
621  bb = &bbn->basicBlock();
622  }
623 
624  // conditional jump or indirect jump that is not last ins splits
625  // a bb.
626  if (j->getDesc().isBranch() &&
627  &(*j) != &(mbb.back())) {
628  bbn = ftSuccs[bbn];
629  bb = &bbn->basicBlock();
630  }
631  if (operationName(*j) == "hwloop") {
632  assert(mbb.succ_size() == 1 &&
633  "HWLoop pre-header should have one succ MBB");
634 
635  // Validate loop pattern (one fall-through and one jump back).
636  auto loopBody = *mbb.succ_begin();
637  auto it = find(
638  loopBody->succ_begin(), loopBody->succ_end(), loopBody);
639  assert((loopBody->succ_size() == 2 &&
640  it != loopBody->succ_end()) &&
641  "HWLoop body should have one loop-back and exit edge");
642 
643  hwloopMBBs.insert(*mbb.succ_begin());
644  continue;
645  }
646  }
647 
648  assert(bb->instructionCount() != 0);
649  }
650 
651  // 3rd loop: create edges?
652  for (MachineFunction::const_iterator i = mf.begin(); i != mf.end(); i++) {
653  const MachineBasicBlock& mbb = *i;
654 
655  const BasicBlockNode* bbn = NULL;
656  std::map<const MachineBasicBlock*,BasicBlockNode*>::iterator
657  bbMapIter = bbMapping_.find(&mbb);
658  if (bbMapIter == bbMapping_.end()) {
659  continue;
660  } else {
661  bbn = bbMapIter->second;
662  }
663 
664  // is last ins a call?
665  bool callPass = AssocTools::containsKey(endingCallBBs, &mbb);
666  bool ftPass = AssocTools::containsKey(endingCondJumpBBs, &mbb);
667  bool hasUncondJump =
668  AssocTools::containsKey(endingUncondJumpBBs, &mbb);
669 
670  const MachineBasicBlock* jumpSucc = condJumpSucc[bbn];
671 
672  while (true) {
673  std::map<const BasicBlockNode*, BasicBlockNode*>::iterator j =
674  callSuccs.find(bbn);
675  std::map<const BasicBlockNode*, BasicBlockNode*>::iterator k =
676  ftSuccs.find(bbn);
677  std::map<const BasicBlockNode*, BasicBlockNode*>::iterator l =
678  inlineAsmSuccs.find(bbn);
679  std::map<const BasicBlockNode*, BasicBlockNode*>::iterator m =
680  ftSuccsToInlineAsm.find(bbn);
681 
682  // BB should not have 2+ fallthrough successors.
683  assert(((j != callSuccs.end())
684  + (k != ftSuccs.end())
685  + (l != inlineAsmSuccs.end())
686  + (m != ftSuccsToInlineAsm.end())) < 2);
687 
688  if (j != callSuccs.end()) {
689  const BasicBlockNode* callSucc = j->second;
690  assert(callSucc != NULL);
691  ControlFlowEdge* cfe = new ControlFlowEdge(
694  cfg->connectNodes(*bbn, *callSucc, *cfe);
695  bbn = callSucc;
696  jumpSucc = condJumpSucc[bbn];
697  continue;
698  }
699 
700  // BB has conditional jump which is not last ins.
701  if (k != ftSuccs.end()) {
702  assert(jumpSucc != NULL);
703  assert(MapTools::containsKey(bbPredicates,bbn));
704  ControlFlowEdge* cfe = new ControlFlowEdge(
705  bbPredicates[bbn] == true ?
709  if (MapTools::containsKey(bbMapping_, jumpSucc)) {
710  cfg->connectNodes(*bbn, *bbMapping_[jumpSucc], *cfe);
711  } else {
712  cfg->connectNodes(*bbn, *skippedBBs_[jumpSucc], *cfe);
713  }
714 
715  const BasicBlockNode* ftSucc = k->second;
716  assert(ftSucc != NULL);
717  cfe = new ControlFlowEdge(
718  bbPredicates[bbn] == true ?
722  cfg->connectNodes(*bbn, *ftSucc, *cfe);
723  bbn = ftSucc;
724  continue;
725  }
726 
727  if (l != inlineAsmSuccs.end()) {
728  const BasicBlockNode* inlineAsmSucc = l->second;
729  assert(inlineAsmSucc);
730  ControlFlowEdge* cfe = new ControlFlowEdge(
733  cfg->connectNodes(*bbn, *inlineAsmSucc, *cfe);
734  bbn = inlineAsmSucc;
735  jumpSucc = condJumpSucc[bbn];
736  continue;
737  }
738 
739  if (m != ftSuccsToInlineAsm.end()) {
740  const BasicBlockNode* inlineAsmPred = m->second;
741  assert(inlineAsmPred);
742  ControlFlowEdge* cfe = new ControlFlowEdge(
745  cfg->connectNodes(*bbn, *inlineAsmPred, *cfe);
746  bbn = inlineAsmPred;
747  jumpSucc = condJumpSucc[bbn];
748  continue;
749  }
750 
751  break;
752  }
753 
754  for (MachineBasicBlock::const_succ_iterator si = mbb.succ_begin();
755  si != mbb.succ_end(); si++) {
756  const MachineBasicBlock* succ = *si;
757 
758  BasicBlockNode* succBBN = NULL;
759  std::map<const MachineBasicBlock*,BasicBlockNode*>::iterator
760  bbMapIter = bbMapping_.find(succ);
761  if (bbMapIter == bbMapping_.end()) {
762  succBBN = skippedBBs_[succ];
763  } else {
764  succBBN = bbMapIter->second;
765  }
766 
767  // TODO: type of the edge
768  ControlFlowEdge* cfe = NULL;
769  // if last ins of bb was call, cheyte call-pass edge.
770  if (callPass) {
771  cfe = new ControlFlowEdge(
774  } else {
775  // do we have conditional jump?
776  if (jumpSucc != NULL) {
777  // fall-through is a pass to next mbb.
778  if (ftPass) {
779  assert(MapTools::containsKey(bbPredicates,bbn));
780  if (succ == jumpSucc) {
781  cfe = new ControlFlowEdge(
782  bbPredicates[bbn] == true ?
786  } else {
787  cfe = new ControlFlowEdge(
788  bbPredicates[bbn] == true ?
792  }
793  } else {
794  // split a bb. ft edges created earlier.
795  // cond.jump edge also created earlier.
796  // just needs to add the uncond jump edge.
797 
798  if (succ == jumpSucc) {
799  continue;
800  }
801  cfe = new ControlFlowEdge;
802  }
803  } else { // no conditional jump. ft to next bb.
804  // Insert hwloop jumps
805  if ((hwloopMBBs.find(&mbb) != hwloopMBBs.end()) &&
806  (&mbb == succ)) {
807  // Loop jump to same BB
808  cfe = new ControlFlowEdge(
811  succBBN->setHWLoop();
812  } else if (hasUncondJump) {
813  cfe = new ControlFlowEdge;
814  } else {
815  // no unconditional jump to next bb. limits bb
816  // reordering
817  cfe = new ControlFlowEdge(
820  }
821  }
822  }
823  cfg->connectNodes(*bbn, *succBBN, *cfe);
824  }
825  }
826 
828  // add back edge properties.
829  cfg->detectBackEdges();
830 
831  /* Split BBs with calls inside. These can be produced
832  from expanding the pseudo asm blocks. Currently at least
833  the call_global_[cd]tors expands to multiple calls to the
834  global object constructors and destructors. */
837 
838  // create jumps to exit node
839  cfg->addExit(returningBBs);
840 
841  delete pregions_;
842  pregions_ = NULL;
843 
844  // add back edge properties.
845  cfg->detectBackEdges();
846  //cfg->writeToDotFile(fnName + ".cfg.dot");
847  return cfg;
848 }
849 
850 /**
851  * Returns true in case the given MI is an explict return instruction generated
852  * from the pseudo assembly string ".return_to".
853  */
854 bool
855 LLVMTCEIRBuilder::isExplicitReturn(const llvm::MachineInstr& mi) const {
856 
857  if (!mi.isInlineAsm()) return false;
858 
859  // Copied from LLVM's AsmPrinterInlineAsm.cpp. There doesn't
860  // seem to be a cleaner way to get the inline assembly text
861  // but this hack.
862  unsigned numOperands = mi.getNumOperands();
863 
864  // Count the number of register definitions to find the asm string.
865  unsigned numDefs = 0;
866  for (; mi.getOperand(numDefs).isReg() &&
867  mi.getOperand(numDefs).isDef();
868  ++numDefs);
869 
870  TCEString asmStr = "";
871  if (mi.isInlineAsm() && numDefs < numOperands &&
872  mi.getOperand(numDefs).isSymbol()) {
873  asmStr = mi.getOperand(numDefs).getSymbolName();
874  }
875  // The .return_to pseudo assembly is used in threading code
876  // to switch execution to another thread when returning from
877  // the current function. A very special case.
878  return asmStr.startsWith(".return_to ") ||
879  asmStr == ".longjmp";
880 }
881 
882 void
885  sched.handleControlFlowGraph(cfg, *mach_);
886 }
887 
890  if (scheduler_ == NULL) {
892  // disabled for the LLVM->TCE->LLVM scheduling chain as
893  // it crashes
894  CopyingDelaySlotFiller* dsf = NULL;
895  if (!modifyMF_ && delaySlotFilling_)
896  dsf = &delaySlotFiller();
897  scheduler_ =
899  }
900  return *scheduler_;
901 }
902 
905  if (dsf_ == NULL)
907  return *dsf_;
908 }
909 
910 void
912  ControlFlowGraph& cfg,
913  llvm::AliasAnalysis* llvmAA) {
914 
915  SimpleIfConverter ifConverter(*ipData_, *mach_);
916  ifConverter.handleControlFlowGraph(cfg, *mach_);
917  Peel2BBLoops peel2bbLoops(*ipData_, *mach_);
918  peel2bbLoops.handleControlFlowGraph(cfg, *mach_);
919 
920 #if 0
922  dynamic_cast<SchedulerCmdLineOptions*>(
924 #endif
925 
926  // TODO: on trunk single bb loop(swp), last param true(rr, threading)
928  cfg,
930  NULL, true, true, llvmAA);
931 
932  TCEString fnName = cfg.name();
933 #ifdef WRITE_DDG_DOTS
934  ddg->writeToDotFile(cfg.name() + "_ddg1.dot");
935 #endif
936  cfg.optimizeBBOrdering(true, cfg.instructionReferenceManager(), ddg);
937 
938  PreOptimizer preOpt(*ipData_);
939  preOpt.handleCFGDDG(cfg, *ddg);
940 
941  cfg.optimizeBBOrdering(true, cfg.instructionReferenceManager(), ddg);
942 
943 #ifdef WRITE_DDG_DOTS
944  ddg->writeToDotFile(cfg.name() + "_ddg2.dot");
945 #endif
946 
947  if (!modifyMF_) {
948  // BBReferences converted to Inst references
949  // break LLVM->POM ->LLVM chain because we
950  // need the BB refs to rebuild the LLVM CFG
952  }
953 
954  if (delaySlotFilling_)
955  delaySlotFiller().initialize(cfg, *ddg, *mach_);
956  scheduler().handleCFGDDG(cfg, ddg, *mach_ );
957 
958 #ifdef WRITE_CFG_DOTS
959  fnName = cfg.name();
960  cfg.writeToDotFile(fnName + "_cfg2.dot");
961 #endif
962 #ifdef WRITE_DDG_DOTS
963  ddg->writeToDotFile(fnName + "_ddg3.dot");
964 #endif
965 
966  if (!functionAtATime_) {
967  // TODO: make DS filler work with FAAT
968  // sched yield emitter does not work with the delay slot filler
969 
970  if (delaySlotFilling_) {
971  delaySlotFiller().fillDelaySlots(cfg, *ddg, *mach_);
972  }
973  }
974 
975 #ifdef WRITE_CFG_DOTS
976  cfg.writeToDotFile(fnName + "_cfg3.dot");
977 #endif
978 
980  ppos.handleControlFlowGraph(cfg, *mach_);
981 
982 #ifdef WRITE_DDG_DOTS
983  ddg->writeToDotFile(fnName + "_ddg4.dot");
984 #endif
985 
986 #ifdef WRITE_CFG_DOTS
987  cfg.writeToDotFile(fnName + "_cfg4.dot");
988 #endif
989  delete ddg;
990 }
991 
992 
994 LLVMTCEIRBuilder::createMBBReference(const MachineOperand& mo) {
995  if (mo.isBlockAddress()) {
996  TTAProgram::BasicBlock* bb = NULL;
997  const MachineBasicBlock* mbb = NULL;
998 
999  std::map<const MachineBasicBlock*, BasicBlockNode*>::iterator i =
1000  bbMapping_.begin();
1001  for (; i != bbMapping_.end(); ++i) {
1002  const MachineBasicBlock* mbbt = i->first;
1003  TTAProgram::BasicBlock& bbt = i->second->basicBlock();
1004  if (mbbt->getBasicBlock() == mo.getBlockAddress()->getBasicBlock()) {
1005  if (bb != NULL) {
1006 #if 0
1008  << "LLVMTCEIRBuilder: found multiple potential BB references."
1009  << std::endl;
1011  << "first: " << bb->toString() << std::endl;
1013  << "another: " << bbt.toString() << std::endl;
1014 #endif
1015  // in case the original BB is split to multiple machine BBs,
1016  // refer to the first one in the chain because the original
1017  // BB reference could not have referred to middle of an BB
1018  if (mbbt->isSuccessor(mbb)) {
1019  bb = &bbt;
1020  mbb = mbbt;
1021  }
1022  } else {
1023  bb = &bbt;
1024  mbb = mbbt;
1025  }
1026  }
1027  }
1028 
1029  i = skippedBBs_.begin();
1030  for (; i != skippedBBs_.end(); ++i) {
1031  const MachineBasicBlock* mbbt = i->first;
1032  TTAProgram::BasicBlock& bbt = i->second->basicBlock();
1033  if (mbbt->getBasicBlock() == mo.getBlockAddress()->getBasicBlock()) {
1034  assert (bb == NULL);
1035  bb = &bbt;
1036  }
1037  }
1038 
1039  if (bb == NULL) {
1041  << "Could not find referred MBB matching the referred BB:"
1042  << std::endl;
1043  assert (bb != NULL);
1044  }
1046  }
1047  MachineBasicBlock* mbb = mo.getMBB();
1048  std::map<const MachineBasicBlock*,BasicBlockNode*>::iterator i =
1049  bbMapping_.find(mbb);
1050 
1051  if (i == bbMapping_.end()) {
1052  std::map<const MachineBasicBlock*, BasicBlockNode*>::iterator j =
1053  skippedBBs_.find(mbb);
1054  if (j == skippedBBs_.end()) {
1055  assert(j != skippedBBs_.end());
1056  }
1058  j->second->basicBlock());
1059  }
1060 
1062  i->second->basicBlock());
1063 }
1064 
1067  return new TTAProgram::TerminalSymbolReference(symbolName);
1068 }
1069 
1070 bool
1071 LLVMTCEIRBuilder::isRealInstruction(const MachineInstr& instr) const {
1072  const llvm::MCInstrDesc* opDesc = &instr.getDesc();
1073  if (opDesc->isReturn()) {
1074  return true;
1075  }
1076 
1077  // when the -g option turn on, this will come up opc with this, therefore
1078  // add this to ignore however, it is uncertain whether the debug "-g" will
1079  // generate more opc, need to verify
1080  if (opDesc->getOpcode() == TargetOpcode::DBG_VALUE) {
1081  return false;
1082  }
1083 
1084  if (opDesc->getOpcode() == TargetOpcode::KILL) {
1085  return false;
1086  }
1087 
1088  std::string opName = operationName(instr);
1089 
1090  // Pseudo instrs or debug labels don't require any actual instructions.
1091  if (opName == "PSEUDO" || opName == "DEBUG_LABEL") {
1092  return false;
1093  }
1094 
1095  if (opName == "MOVE") {
1096  const MachineOperand& dst = instr.getOperand(0);
1097  const MachineOperand& src = instr.getOperand(1);
1098  if (dst.isReg() && src.isReg() && dst.getReg() == src.getReg()) {
1099  return false;
1100  }
1101  }
1102  return true;
1103 }
1104 
1105 bool
1107  MachineBasicBlock::const_iterator i,
1108  const MachineBasicBlock& mbb) {
1109  for (; i != mbb.end(); i++) {
1110  if (isRealInstruction(*i)) {
1111  return true;
1112  }
1113  }
1114  return false;
1115 }
1116 
1117 bool
1120  return false;
1121 }
1122 
1123 bool
1125 
1126  // Catch the exception here as throwing exceptions
1127  // through library boundaries is flaky. It crashes
1128  // on x86-32 Linux at least. See:
1129  // https://bugs.launchpad.net/tce/+bug/894816
1132 
1133  // The Program can now have a bunch of unscheduled Procedures
1134  // created by the SchedYieldEmitter. Schedule them now.
1135  for (int p = 0; p < prog_->procedureCount(); ++p) {
1136  TTAProgram::Procedure& procedure = prog_->procedure(p);
1137  // assume all functions that were not in the original LLVM
1138  // module are new ones that need to be scheduled
1139 
1140  if (m.getFunction(procedure.name()) != NULL) continue;
1141  scheduler().handleProcedure(procedure, *mach_);
1142  }
1143  return false;
1144 }
1145 
1146 TCEString
1147 LLVMTCEIRBuilder::operationName(const MachineInstr& mi) const {
1148  if (dynamic_cast<const TCETargetMachine*>(&targetMachine())
1149  != NULL) {
1150  if (mi.getDesc().isReturn()) return "RET";
1151  return dynamic_cast<const TCETargetMachine&>(targetMachine())
1152  .operationName(mi.getDesc().getOpcode());
1153  } else {
1154  return targetMachine().getSubtargetImpl(
1155  mi.getParent()->getParent()->getFunction())->getInstrInfo()->
1156  getName(mi.getOpcode()).str();
1157  }
1158 }
1159 
1160 TCEString
1161 LLVMTCEIRBuilder::registerFileName(unsigned llvmRegNum) const {
1162  if (isTTATarget()) {
1163  return dynamic_cast<const TCETargetMachine&>(
1164  targetMachine()).rfName(llvmRegNum);
1165  } else {
1166  // LLVM does not support explicit register file info
1167  // at the moment, so we assume there's only one reg file
1168  // in the machine. Pick the first one that is not
1169  // a 1-bit reg file.
1172 
1173  for (int i = 0; i < rfNav.count(); i++) {
1174  const TTAMachine::RegisterFile& rf = *rfNav.item(i);
1175  if (rf.width() > 1)
1176  return rf.name();
1177  }
1179  TCEString("Unable to figure the RF for llvm reg num ") <<
1180  llvmRegNum);
1181 
1182  }
1183 }
1184 
1185 int
1186 LLVMTCEIRBuilder::registerIndex(unsigned llvmRegNum) const {
1187  if (isTTATarget()) {
1188  return dynamic_cast<const TCETargetMachine&>(
1189  targetMachine()).registerIndex(llvmRegNum);
1190  } else {
1191  /* Assume for non-TTA targets the register index
1192  is the final and correct one and that there's only
1193  one register file. With TTA we have to do conversion
1194  due to the multiple register files option which LLVM
1195  does not support. */
1196  // LLVM index registers starting from 1, we start ours from 0
1197  // decrease index to avoid out of range error.
1198  return llvmRegNum - 1;
1199  }
1200 }
1201 
1202 void
1204  llvm::MachineFunction& mf,
1205  ControlFlowGraph&) {
1206 
1207  llvm::MachineJumpTableInfo* jtInfo = mf.getJumpTableInfo();
1208  if (jtInfo == NULL || jtInfo->isEmpty()) {
1209  return;
1210  }
1211 
1212  std::vector<llvm::MachineJumpTableEntry> entries = jtInfo->getJumpTables();
1213  jumpTableRecord_.clear();
1214  for (unsigned int i = 0; i < entries.size(); i++) {
1215  std::vector<BasicBlockNode*> nodes;
1216  jumpTableRecord_.push_back(nodes);
1217  std::vector<MachineBasicBlock*> blocks =
1218  entries.at(i).MBBs;
1219  for (unsigned j = 0; j < blocks.size(); j++) {
1220  MachineBasicBlock* mbb = blocks.at(j);
1221  BasicBlockNode* bbn = NULL;
1222  std::map<const MachineBasicBlock*, BasicBlockNode*>::iterator
1223  bbMapIter = bbMapping_.find(mbb);
1224  assert(bbMapIter != bbMapping_.end() &&
1225  "The Basic Block Node for Machine Basic Block is missing!");
1226  bbn = bbMapIter->second;
1227  jumpTableRecord_.at(i).push_back(bbn);
1228  }
1229  }
1230 
1231 }
1232 
1233 void
1235  llvm::MachineFunction& mf,
1236  ControlFlowGraph& cfg) {
1237 
1238  llvm::MachineJumpTableInfo* jtInfo = mf.getJumpTableInfo();
1239  if (jtInfo == NULL) {
1240  return;
1241  }
1242  for (unsigned int i = 0; i < jumpTableRecord_.size(); i++) {
1243  std::vector<BasicBlockNode*> nodes = jumpTableRecord_.at(i);
1244  std::vector<MachineBasicBlock*> oldTable =
1245  jtInfo->getJumpTables().at(i).MBBs;
1246  for (unsigned int j = 0; j < nodes.size(); j++) {
1247  const BasicBlockNode* bbn = nodes.at(j);
1248  MachineBasicBlock* newMBB = &cfg.getMBB(mf, bbn->basicBlock());
1249  MachineBasicBlock* oldMBB = oldTable.at(j);
1250  jtInfo->ReplaceMBBInJumpTable(i, oldMBB, newMBB);
1251  // Slight cheating to force LLVM to emit machine basic block label
1252  // to avoid missing references from Jump Table Records to basic
1253  // blocks. TODO: Proper fix is needed.
1254  newMBB->setIsEHPad();
1255  }
1256  }
1257 }
1258 
1259 /**
1260  * Create MoveNode and attach it to TerminalFUs.
1261  * The MoveNode will be owned by DDG.
1262  */
1263 void
1265  ProgramOperationPtr& po,
1266  std::shared_ptr<TTAProgram::Move> m,
1267  bool isDestination) {
1268  MoveNode* mn = new MoveNode(m);
1269 
1270  if (isDestination) {
1271  po->addInputNode(*mn);
1274  dynamic_cast<TTAProgram::TerminalFUPort&>(m->destination());
1275  term.setProgramOperation(po);
1276  } else {
1277  po->addOutputNode(*mn);
1278  mn->setSourceOperationPtr(po);
1280  dynamic_cast<TTAProgram::TerminalFUPort&>(m->source());
1281  term.setProgramOperation(po);
1282  }
1283 }
1284 
1286 
1288  if (Application::cmdLineOptions() != NULL) {
1289  options =
1290  dynamic_cast<LLVMTCECmdLineOptions*>(
1293 // PostpassOperandSharer::printStats();
1294 // CycleLookBackSoftwareBypasser::printStats();
1295  }
1296  }
1297 
1298  delete scheduler_;
1299  delete bypasser_;
1300  delete dsf_;
1301 }
1302 }
llvm::LLVMTCEBuilder::spillMoveCount_
int spillMoveCount_
Definition: LLVMTCEBuilder.hh:261
llvm::LLVMTCEIRBuilder::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const
Definition: LLVMTCEIRBuilder.cc:131
SimpleInterPassDatum
Definition: InterPassDatum.hh:64
PRegionMarkerAnalyzer
Definition: PRegionMarkerAnalyzer.hh:42
llvm
Definition: InlineAsmParser.hh:49
BoostGraph::connectNodes
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
llvm::LLVMTCEIRBuilder::registerIndex
virtual int registerIndex(unsigned llvmRegNum) const
Definition: LLVMTCEIRBuilder.cc:1186
TTAProgram::Program::addProcedure
void addProcedure(Procedure *proc)
Definition: Program.cc:524
llvm::LLVMTCEBuilder::doFinalization
bool doFinalization(Module &M)
Definition: LLVMTCEBuilder.cc:1090
SimpleIfConverter.hh
TTAProgram::TerminalFUPort::setProgramOperation
void setProgramOperation(ProgramOperationPtr po)
Definition: TerminalFUPort.hh:94
llvm::LLVMTCEBuilder::emitInstruction
TTAProgram::Instruction * emitInstruction(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:1322
TTAProgram::CodeSnippet::firstInstruction
virtual Instruction & firstInstruction() const
Definition: CodeSnippet.cc:216
llvm::LLVMTCEBuilder::prog_
TTAProgram::Program * prog_
Current program being built.
Definition: LLVMTCEBuilder.hh:250
ControlFlowGraph::splitBasicBlocksWithCallsAndRefs
void splitBasicBlocksWithCallsAndRefs()
Definition: ControlFlowGraph.cc:2850
llvm::LLVMTCEIRBuilder::doFinalization
virtual bool doFinalization(Module &m)
Definition: LLVMTCEIRBuilder.cc:1124
llvm::LLVMTCEIRBuilder::createMBBReference
virtual TTAProgram::Terminal * createMBBReference(const MachineOperand &mo)
Definition: LLVMTCEIRBuilder.cc:994
AbsoluteToRelativeJumps.hh
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
CopyingDelaySlotFiller.hh
BBSchedulerController::handleCFGDDG
virtual void handleCFGDDG(ControlFlowGraph &cfg, DataDependenceGraph *ddg, const TTAMachine::Machine &targetMachine)
Definition: BBSchedulerController.cc:603
TTAProgram::Instruction::move
Move & move(int i) const
Definition: Instruction.cc:193
TTAProgram::Program::procedureCount
int procedureCount() const
Definition: Program.cc:610
TCEString::startsWith
bool startsWith(const std::string &str) const
InnerLoopFinder::InnerLoopInfo::isTripCountKnown
bool isTripCountKnown() const
Definition: InnerLoopFinder.hh:37
ControlFlowGraph::copyToProcedure
void copyToProcedure(TTAProgram::Procedure &proc, TTAProgram::InstructionReferenceManager *irm=NULL)
Definition: ControlFlowGraph.cc:1448
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
CycleLookBackSoftwareBypasser
Definition: CycleLookBackSoftwareBypasser.hh:52
TerminalSymbolReference.hh
LLVMTCECmdLineOptions::disableDelaySlotFiller
bool disableDelaySlotFiller() const
Definition: LLVMTCECmdLineOptions.cc:324
SequentialScheduler.hh
llvm::LLVMTCEBuilder::opset_
std::set< std::string > opset_
The operations supported by the current target machine.
Definition: LLVMTCEBuilder.hh:253
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
BoostGraph< BasicBlockNode, ControlFlowEdge >::NodeSet
std::set< BasicBlockNode *, typename BasicBlockNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
llvm::LLVMTCEBuilder::options_
LLVMTCECmdLineOptions * options_
The compiler options.
Definition: LLVMTCEBuilder.hh:268
TTAProgram::Instruction
Definition: Instruction.hh:57
llvm::LLVMTCEIRBuilder::bbMapping_
std::map< const MachineBasicBlock *, BasicBlockNode * > bbMapping_
Definition: LLVMTCEIRBuilder.hh:168
CallsToJumps.hh
MapTools.hh
Procedure.hh
llvm::LLVMTCEIRBuilder::isHotFunction
bool isHotFunction(llvm::MachineFunction &mf) const
Definition: LLVMTCEIRBuilder.cc:257
llvm::LLVMTCEIRBuilder::hasRealInstructions
bool hasRealInstructions(MachineBasicBlock::const_iterator i, const MachineBasicBlock &mbb)
Definition: LLVMTCEIRBuilder.cc:1106
llvm::LLVMTCEIRBuilder::AA_
AliasAnalysis * AA_
Definition: LLVMTCEIRBuilder.hh:172
PRegionMarkerAnalyzer.hh
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
AbsoluteToRelativeJumps::handleProcedure
virtual void handleProcedure(TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetMachine) override
Definition: AbsoluteToRelativeJumps.cc:52
llvm::LLVMTCEBuilder::tm_
const llvm::TargetMachine * tm_
Target machine description.
Definition: LLVMTCEBuilder.hh:245
llvm::LLVMTCEIRBuilder::ipData_
InterPassData * ipData_
Definition: LLVMTCEIRBuilder.hh:161
PreOptimizer
Definition: PreOptimizer.hh:66
AddressSpace.hh
DataDependenceGraph.hh
MoveNode
Definition: MoveNode.hh:65
InnerLoopFinder::innerLoopInfo
InnerLoopInfoIndex innerLoopInfo()
Definition: InnerLoopFinder.hh:58
PreOptimizer::handleCFGDDG
void handleCFGDDG(ControlFlowGraph &cfg, DataDependenceGraph &ddg)
Definition: PreOptimizer.cc:511
llvm::LLVMTCEBuilder::curFrameInfo_
MachineFrameInfo * curFrameInfo_
Definition: LLVMTCEBuilder.hh:265
CompileError
Definition: Exception.hh:1019
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
TTAMachine::FunctionUnit::addressSpace
virtual AddressSpace * addressSpace() const
Definition: FunctionUnit.cc:580
llvm::LLVMTCEIRBuilder::delaySlotFiller
CopyingDelaySlotFiller & delaySlotFiller()
Definition: LLVMTCEIRBuilder.cc:904
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
PostpassOperandSharer.hh
BoostGraph::addNode
virtual void addNode(Node &node)
llvm::LLVMTCEBuilder::functionAtATime_
bool functionAtATime_
Definition: LLVMTCEBuilder.hh:257
llvm::LLVMTCEBuilder::mach_
TTAMachine::Machine * mach_
Machine for building the program.
Definition: LLVMTCEBuilder.hh:242
llvm::LLVMTCEIRBuilder::fixJumpTableDestinations
void fixJumpTableDestinations(llvm::MachineFunction &mf, ControlFlowGraph &cfg)
Definition: LLVMTCEIRBuilder.cc:1234
TTAMachine::Machine::Navigator::count
int count() const
llvm::LLVMTCEBuilder::fixProgramOperationReferences
void fixProgramOperationReferences()
Definition: LLVMTCEBuilder.cc:2276
LLVMTCECmdLineOptions::optLevel
int optLevel() const
Definition: LLVMTCECmdLineOptions.cc:292
CopyingDelaySlotFiller::initialize
void initialize(ControlFlowGraph &cfg, DataDependenceGraph &ddg, const TTAMachine::Machine &machine)
Definition: CopyingDelaySlotFiller.cc:1937
Peel2BBLoops.hh
ControlFlowGraph::instructionReferenceManager
TTAProgram::InstructionReferenceManager & instructionReferenceManager()
Definition: ControlFlowGraph.cc:2401
llvm::LLVMTCEBuilder::mang_
llvm::Mangler * mang_
Mangler for mangling label strings.
Definition: LLVMTCEBuilder.hh:247
SchedulerCmdLineOptions
Definition: SchedulerCmdLineOptions.hh:45
TerminalBasicBlockReference.hh
llvm::LLVMTCEBuilder::emitConstantPool
void emitConstantPool(const llvm::MachineConstantPool &cp)
Definition: LLVMTCEBuilder.cc:2346
verboseLog
#define verboseLog(text)
Definition: Application.hh:115
ControlFlowEdge
Definition: ControlFlowEdge.hh:50
ProgramOperationPtr
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition: MoveNode.hh:52
ControlFlowEdge::CFLOW_EDGE_NORMAL
@ CFLOW_EDGE_NORMAL
Definition: ControlFlowEdge.hh:53
llvm::LLVMTCEBuilder::emitSPInitialization
virtual void emitSPInitialization()
Definition: LLVMTCEBuilder.cc:2669
MoveNode::setSourceOperationPtr
void setSourceOperationPtr(ProgramOperationPtr po)
Definition: MoveNode.cc:541
BasicBlockNode::basicBlock
TTAProgram::BasicBlock & basicBlock()
Definition: BasicBlockNode.cc:126
assert
#define assert(condition)
Definition: Application.hh:86
llvm::LLVMTCEIRBuilder::LLVMTCEIRBuilder
LLVMTCEIRBuilder(const TargetMachine &tm, TTAMachine::Machine *mach, InterPassData &ipd, AliasAnalysis *AA, bool functionAtATime=false, bool modifyMF=false)
Definition: LLVMTCEIRBuilder.cc:103
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
SimpleIfConverter
Definition: SimpleIfConverter.hh:40
llvm::LLVMTCEIRBuilder::createSymbolReference
virtual TTAProgram::Terminal * createSymbolReference(const TCEString &symbolName)
Definition: LLVMTCEIRBuilder.cc:1066
InnerLoopFinder.hh
llvm::LLVMTCEIRBuilder::scheduler
BBSchedulerController & scheduler()
Definition: LLVMTCEIRBuilder.cc:889
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
CopyingDelaySlotFiller::fillDelaySlots
void fillDelaySlots(ControlFlowGraph &cfg, DataDependenceGraph &ddg, const TTAMachine::Machine &machine)
Definition: CopyingDelaySlotFiller.cc:405
CycleLookBackSoftwareBypasser.hh
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
HWOperation.hh
TTAProgram::BasicBlock::setTripCount
void setTripCount(unsigned count)
Definition: BasicBlock.hh:109
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
llvm::LLVMTCEBuilder::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &AU) const
Definition: LLVMTCEBuilder.hh:125
Instruction.hh
llvm::LLVMTCEIRBuilder::compileOptimized
void compileOptimized(ControlFlowGraph &cfg, llvm::AliasAnalysis *llvmAA)
Definition: LLVMTCEIRBuilder.cc:911
llvm::LLVMTCEIRBuilder::ddgBuilder_
DataDependenceGraphBuilder ddgBuilder_
Definition: LLVMTCEIRBuilder.hh:166
MoveNode::addDestinationOperationPtr
void addDestinationOperationPtr(ProgramOperationPtr po)
Definition: MoveNode.cc:533
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
ControlFlowGraph.hh
DataDependenceGraph::INTRA_BB_ANTIDEPS
@ INTRA_BB_ANTIDEPS
Definition: DataDependenceGraph.hh:80
RegisterCopyAdder::findTempRegisters
static void findTempRegisters(const TTAMachine::Machine &machine, InterPassData &ipd)
Definition: RegisterCopyAdder.cc:2136
LLVMTCECmdLineOptions.hh
InnerLoopFinder::InnerLoopInfo
Definition: InnerLoopFinder.hh:32
Application::cmdLineOptions
static CmdLineOptions * cmdLineOptions()
Definition: Application.cc:397
llvm::LLVMTCEIRBuilder::modifyMF_
bool modifyMF_
Definition: LLVMTCEIRBuilder.hh:175
__func__
#define __func__
Definition: Application.hh:67
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
CopyingDelaySlotFiller
Definition: CopyingDelaySlotFiller.hh:71
BasicBlockNode
Definition: BasicBlockNode.hh:64
ControlFlowGraph::addExit
void addExit(NodeSet &retSourceNodes)
llvm::LLVMTCEIRBuilder::isRealInstruction
bool isRealInstruction(const MachineInstr &instr) const
Definition: LLVMTCEIRBuilder.cc:1071
InterPassData
Definition: InterPassData.hh:48
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
llvm::LLVMTCEBuilder::isInlineAsm
static bool isInlineAsm(const MachineInstr &instr)
Definition: LLVMTCEBuilder.cc:3908
ControlFlowGraphPass::handleControlFlowGraph
virtual void handleControlFlowGraph(ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
Definition: ControlFlowGraphPass.cc:65
llvm::LLVMTCEIRBuilder::jumpTableRecord_
std::vector< std::vector< BasicBlockNode * > > jumpTableRecord_
Definition: LLVMTCEIRBuilder.hh:170
TerminalFUPort.hh
BasicBlockNode::setBBOwnership
void setBBOwnership(bool ownership=true)
Definition: BasicBlockNode.hh:103
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
Machine.hh
llvm::LLVMTCEIRBuilder::markJumpTableDestinations
void markJumpTableDestinations(llvm::MachineFunction &mf, ControlFlowGraph &cfg)
Definition: LLVMTCEIRBuilder.cc:1203
CmdLineOptions::isVerboseSwitchDefined
virtual bool isVerboseSwitchDefined() const
Definition: CmdLineOptions.cc:300
InnerLoopFinder::InnerLoopInfoIndex
std::map< const llvm::BasicBlock *, InnerLoopInfo > InnerLoopInfoIndex
Definition: InnerLoopFinder.hh:42
llvm::LLVMTCEIRBuilder::createMoveNode
virtual void createMoveNode(ProgramOperationPtr &po, std::shared_ptr< TTAProgram::Move > m, bool isDestination) override
Definition: LLVMTCEIRBuilder.cc:1264
LLVMTCECmdLineOptions::primaryFunctions
virtual FunctionNameList * primaryFunctions() const
Definition: LLVMTCECmdLineOptions.cc:254
LLVMTCECmdLineOptions
Definition: LLVMTCECmdLineOptions.hh:48
ControlFlowGraph::convertBBRefsToInstRefs
void convertBBRefsToInstRefs()
Definition: ControlFlowGraph.cc:2436
SequentialScheduler
Definition: SequentialScheduler.hh:56
TTAProgram::TerminalBasicBlockReference
Definition: TerminalBasicBlockReference.hh:42
GraphBase::writeToDotFile
virtual void writeToDotFile(const TCEString &fileName) const
TTAProgram::TerminalFUPort
Definition: TerminalFUPort.hh:56
llvm::LLVMTCEIRBuilder::compileFast
void compileFast(ControlFlowGraph &cfg)
Definition: LLVMTCEIRBuilder.cc:883
options
static MachInfoCmdLineOptions options
Definition: MachInfo.cc:46
Peel2BBLoops
Definition: Peel2BBLoops.hh:22
llvm::LLVMTCEIRBuilder::bypasser_
CycleLookBackSoftwareBypasser * bypasser_
Definition: LLVMTCEIRBuilder.hh:183
llvm::LLVMTCEIRBuilder::writeMachineFunction
bool writeMachineFunction(MachineFunction &mf)
Definition: LLVMTCEIRBuilder.cc:136
llvm::LLVMTCEIRBuilder::dsf_
CopyingDelaySlotFiller * dsf_
Definition: LLVMTCEIRBuilder.hh:182
llvm::LLVMTCEIRBuilder::delaySlotFilling_
bool delaySlotFilling_
Definition: LLVMTCEIRBuilder.hh:179
ControlFlowGraph::getMBB
llvm::MachineBasicBlock & getMBB(llvm::MachineFunction &mf, const TTAProgram::BasicBlock &bb) const
Definition: ControlFlowGraph.cc:2829
TTAProgram::TerminalFUPort::programOperation
ProgramOperationPtr programOperation() const
Definition: TerminalFUPort.hh:97
BasicBlockNode::setScheduled
void setScheduled(bool state=true)
Definition: BasicBlockNode.hh:94
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
llvm::LLVMTCEIRBuilder::isExplicitReturn
bool isExplicitReturn(const llvm::MachineInstr &mi) const
Definition: LLVMTCEIRBuilder.cc:855
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
IGNORE_COMPILER_WARNING
#define IGNORE_COMPILER_WARNING(X)
Definition: CompilerWarnings.hh:51
PostpassOperandSharer
Definition: PostpassOperandSharer.hh:47
llvm::LLVMTCEBuilder::doInitialization
bool doInitialization(Module &M)
Definition: LLVMTCEBuilder.cc:429
ControlFlowGraph::setInstructionReferenceManager
void setInstructionReferenceManager(TTAProgram::InstructionReferenceManager &irm)
Definition: ControlFlowGraph.hh:142
TTAProgram::InstructionReferenceManager
Definition: InstructionReferenceManager.hh:82
TTAProgram::Program::instructionReferenceManager
InstructionReferenceManager & instructionReferenceManager() const
Definition: Program.cc:688
ControlFlowGraph::detectBackEdges
void detectBackEdges()
Definition: ControlFlowGraph.cc:2426
Program.hh
ControlFlowGraph::copyToLLVMMachineFunction
void copyToLLVMMachineFunction(llvm::MachineFunction &mf, TTAProgram::InstructionReferenceManager *irm=NULL)
Definition: ControlFlowGraph.cc:1679
TCEString
Definition: TCEString.hh:53
FUPort.hh
llvm::LLVMTCEBuilder::codeLabels_
std::map< std::string, TTAProgram::Instruction * > codeLabels_
Code labels.
Definition: LLVMTCEBuilder.hh:239
BasicBlock.hh
CallsToJumps
Definition: CallsToJumps.hh:36
ControlUnit.hh
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
POP_COMPILER_DIAGS
#define POP_COMPILER_DIAGS
Definition: CompilerWarnings.hh:68
ControlFlowEdge::CFLOW_EDGE_FALSE
@ CFLOW_EDGE_FALSE
Definition: ControlFlowEdge.hh:55
DataDependenceGraphBuilder::build
virtual DataDependenceGraph * build(ControlFlowGraph &cGraph, DataDependenceGraph::AntidependenceLevel antidependenceLevel, const TTAMachine::Machine &mach, const UniversalMachine *um=NULL, bool createMemAndFUDeps=true, bool createDeathInformation=true, llvm::AliasAnalysis *AA=NULL)
Definition: DataDependenceGraphBuilder.cc:2120
llvm::LLVMTCEIRBuilder::ID
static char ID
Definition: LLVMTCEIRBuilder.hh:62
InstructionReferenceManager.hh
llvm::LLVMTCEBuilder::pregions_
PRegionMarkerAnalyzer * pregions_
Definition: LLVMTCEBuilder.hh:259
Peel2BBLoops::handleControlFlowGraph
void handleControlFlowGraph(ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine) override
Definition: Peel2BBLoops.cc:101
SimpleIfConverter::handleControlFlowGraph
virtual void handleControlFlowGraph(ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
Definition: SimpleIfConverter.cc:135
TTAProgram::Procedure::name
TCEString name() const
Definition: Procedure.hh:66
ControlFlowGraph::optimizeBBOrdering
void optimizeBBOrdering(bool removeDeadCode, TTAProgram::InstructionReferenceManager &irm, DataDependenceGraph *ddg)
Definition: ControlFlowGraph.cc:2522
RegisterCopyAdder.hh
llvm::LLVMTCEIRBuilder::skippedBBs_
std::map< const MachineBasicBlock *, BasicBlockNode * > skippedBBs_
Definition: LLVMTCEIRBuilder.hh:177
llvm::TCETargetMachine
Definition: TCETargetMachine.hh:106
TTAProgram::Terminal
Definition: Terminal.hh:60
llvm::LLVMTCEIRBuilder::scheduler_
BBSchedulerController * scheduler_
Definition: LLVMTCEIRBuilder.hh:181
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
PreOptimizer.hh
BBSchedulerController.hh
TTAProgram::Instruction::hasControlFlowMove
bool hasControlFlowMove() const
Definition: Instruction.cc:471
TTAProgram::CodeSnippet::toString
virtual std::string toString() const
Definition: CodeSnippet.hh:117
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
llvm::LLVMTCEIRBuilder::doInitialization
virtual bool doInitialization(Module &m)
Definition: LLVMTCEIRBuilder.cc:1118
AbsoluteToRelativeJumps
Definition: AbsoluteToRelativeJumps.hh:39
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
EXIT_IF_THROWS
#define EXIT_IF_THROWS(__X__)
Definition: LLVMTCEIRBuilder.cc:86
Move.hh
InnerLoopFinder::InnerLoopInfo::tripCount
int tripCount() const
Definition: InnerLoopFinder.hh:36
TTAProgram::BasicBlock::setInInnerLoop
void setInInnerLoop(bool inner=true)
Definition: BasicBlock.hh:104
llvm::LLVMTCEIRBuilder::loopFinder_
InnerLoopFinder * loopFinder_
Definition: LLVMTCEIRBuilder.hh:185
BasicBlockNode::setHWLoop
void setHWLoop(bool hwloop=true)
Set true if the bbn is known to be a loop body of a hwloop with loop pattern- preheader BB -> loop bo...
Definition: BasicBlockNode.hh:110
llvm::LLVMTCEIRBuilder::operationName
virtual TCEString operationName(const MachineInstr &mi) const
Definition: LLVMTCEIRBuilder.cc:1147
BoostGraph::name
virtual const TCEString & name() const
TTAMachine::BaseRegisterFile::width
virtual int width() const
BBSchedulerController::handleProcedure
virtual void handleProcedure(TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetMachine) override
Definition: BBSchedulerController.cc:284
ControlFlowEdge::CFLOW_EDGE_FALLTHROUGH
@ CFLOW_EDGE_FALLTHROUGH
Definition: ControlFlowEdge.hh:62
BoostGraph::nodeCount
int nodeCount() const
llvm::LLVMTCEBuilder::clearFunctionBookkeeping
void clearFunctionBookkeeping()
Definition: LLVMTCEBuilder.hh:231
ControlFlowEdge::CFLOW_EDGE_TRUE
@ CFLOW_EDGE_TRUE
Definition: ControlFlowEdge.hh:54
TTAProgram::TerminalSymbolReference
Definition: TerminalSymbolReference.hh:42
llvm::LLVMTCEIRBuilder::registerFileName
virtual TCEString registerFileName(unsigned llvmRegNum) const
Definition: LLVMTCEIRBuilder.cc:1161
TTAProgram::Program::procedure
Procedure & procedure(int index) const
Definition: Program.cc:622
ControlFlowEdge::CFLOW_EDGE_CALL
@ CFLOW_EDGE_CALL
Definition: ControlFlowEdge.hh:61
TTAProgram::Procedure
Definition: Procedure.hh:55
llvm::LLVMTCEBuilder
Definition: LLVMTCEBuilder.hh:102
llvm::LLVMTCEBuilder::targetMachine
const TargetMachine & targetMachine() const
Definition: LLVMTCEBuilder.hh:157
llvm::LLVMTCEBuilder::addLabelForProgramOperation
void addLabelForProgramOperation(TCEString label, ProgramOperationPtr po)
Definition: LLVMTCEBuilder.hh:222
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
llvm::AliasAnalysis
AAResults AliasAnalysis
Definition: DataDependenceGraphBuilder.hh:45
ControlFlowEdge::CFLOW_EDGE_JUMP
@ CFLOW_EDGE_JUMP
Definition: ControlFlowEdge.hh:60
CallsToJumps::handleControlFlowGraph
virtual void handleControlFlowGraph(ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
Definition: CallsToJumps.cc:49
llvm::LLVMTCEBuilder::initDataSections
void initDataSections()
Definition: LLVMTCEBuilder.cc:210
StringTools::stringToLower
static std::string stringToLower(const std::string &source)
Definition: StringTools.cc:160
TTAProgram::Program::convertSymbolRefsToInsRefs
void convertSymbolRefsToInsRefs(bool ignoreUnfoundSymbols=false)
Definition: Program.cc:1264
llvm::LLVMTCEIRBuilder::~LLVMTCEIRBuilder
virtual ~LLVMTCEIRBuilder()
Definition: LLVMTCEIRBuilder.cc:1285
llvm::LLVMTCEIRBuilder::buildTCECFG
ControlFlowGraph * buildTCECFG(llvm::MachineFunction &mf)
Definition: LLVMTCEIRBuilder.cc:273
CompilerWarnings.hh
ControlFlowGraph
Definition: ControlFlowGraph.hh:100
llvm::LLVMTCEBuilder::emitInlineAsm
TTAProgram::Instruction * emitInlineAsm(const MachineFunction &mf, const MachineInstr *mi, TTAProgram::BasicBlock *bb, TTAProgram::InstructionReferenceManager &irm)
Definition: LLVMTCEBuilder.cc:2786
BBSchedulerController
Definition: BBSchedulerController.hh:62
TTAMachine::Machine
Definition: Machine.hh:73
FunctionUnit.hh
llvm::LLVMTCEBuilder::isTTATarget
virtual bool isTTATarget() const
Definition: LLVMTCEBuilder.hh:132
llvm::LLVMTCEBuilder::mbbName
std::string mbbName(const MachineBasicBlock &mbb)
Definition: LLVMTCEBuilder.cc:2632