OpenASIP 2.2
Loading...
Searching...
No Matches
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"
39IGNORE_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"
49#include "TerminalFUPort.hh"
51#include "PreOptimizer.hh"
55#include "SimpleIfConverter.hh"
56#include "Peel2BBLoops.hh"
58#include "Machine.hh"
60#include "Program.hh"
61#include "RegisterCopyAdder.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"
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
99namespace llvm {
100
101char 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
130void
134
135bool
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
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 }
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
235 jumpConv.handleProcedure(*procedure, *mach_);
236
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 */
256bool
257LLVMTCEIRBuilder::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
273LLVMTCEIRBuilder::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 =
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) {
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 }
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);
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));
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);
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);
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 */
854bool
855LLVMTCEIRBuilder::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
882void
887
890 if (scheduler_ == NULL) {
892 // disabled for the LLVM->TCE->LLVM scheduling chain as
893 // it crashes
894 CopyingDelaySlotFiller* dsf = NULL;
896 dsf = &delaySlotFiller();
897 scheduler_ =
899 }
900 return *scheduler_;
901}
902
905 if (dsf_ == NULL)
907 return *dsf_;
908}
909
910void
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
937
938 PreOptimizer preOpt(*ipData_);
939 preOpt.handleCFGDDG(cfg, *ddg);
940
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
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
994LLVMTCEIRBuilder::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
1070bool
1071LLVMTCEIRBuilder::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
1105bool
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
1117bool
1120 return false;
1121}
1122
1123bool
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
1146TCEString
1147LLVMTCEIRBuilder::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
1161LLVMTCEIRBuilder::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
1185int
1186LLVMTCEIRBuilder::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
1202void
1204 llvm::MachineFunction& mf,
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
1233void
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 */
1263void
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}
#define verboseLog(text)
#define __func__
#define abortWithError(message)
#define assert(condition)
#define IGNORE_COMPILER_WARNING(X)
#define POP_COMPILER_DIAGS
#define EXIT_IF_THROWS(__X__)
static MachInfoCmdLineOptions options
Definition MachInfo.cc:46
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition MoveNode.hh:53
virtual void handleProcedure(TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetMachine) override
static CmdLineOptions * cmdLineOptions()
static int verboseLevel()
static std::ostream & logStream()
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
virtual void handleProcedure(TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetMachine) override
virtual void handleCFGDDG(ControlFlowGraph &cfg, DataDependenceGraph *ddg, const TTAMachine::Machine &targetMachine)
void setScheduled(bool state=true)
TTAProgram::BasicBlock & basicBlock()
void setBBOwnership(bool ownership=true)
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...
int nodeCount() const
virtual void addNode(Node &node)
virtual const TCEString & name() const
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
virtual void handleControlFlowGraph(ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
virtual bool isVerboseSwitchDefined() const
virtual void handleControlFlowGraph(ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
void copyToLLVMMachineFunction(llvm::MachineFunction &mf, TTAProgram::InstructionReferenceManager *irm=NULL)
void setInstructionReferenceManager(TTAProgram::InstructionReferenceManager &irm)
void splitBasicBlocksWithCallsAndRefs()
TTAProgram::InstructionReferenceManager & instructionReferenceManager()
void copyToProcedure(TTAProgram::Procedure &proc, TTAProgram::InstructionReferenceManager *irm=NULL)
llvm::MachineBasicBlock & getMBB(llvm::MachineFunction &mf, const TTAProgram::BasicBlock &bb) const
void optimizeBBOrdering(bool removeDeadCode, TTAProgram::InstructionReferenceManager &irm, DataDependenceGraph *ddg)
void addExit(NodeSet &retSourceNodes)
void initialize(ControlFlowGraph &cfg, DataDependenceGraph &ddg, const TTAMachine::Machine &machine)
void fillDelaySlots(ControlFlowGraph &cfg, DataDependenceGraph &ddg, const TTAMachine::Machine &machine)
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)
virtual void writeToDotFile(const TCEString &fileName) const
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
Definition Graph.hh:53
virtual FunctionNameList * primaryFunctions() const
static bool containsKey(const MapType &aMap, const KeyType &aKey)
void setSourceOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:541
void addDestinationOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:533
void handleControlFlowGraph(ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine) override
void handleCFGDDG(ControlFlowGraph &cfg, DataDependenceGraph &ddg)
static void findTempRegisters(const TTAMachine::Machine &machine, InterPassData &ipd)
virtual void handleControlFlowGraph(ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
static std::string stringToLower(const std::string &source)
bool startsWith(const std::string &str) const
virtual int width() const
virtual TCEString name() const
virtual AddressSpace * addressSpace() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual bool hasOperation(const std::string &name) const
const std::string & name() const
ComponentType * item(int index) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
void setTripCount(unsigned count)
void setInInnerLoop(bool inner=true)
virtual Instruction & firstInstruction() const
virtual std::string toString() const
virtual int instructionCount() const
Move & move(int i) const
bool hasControlFlowMove() const
Terminal & destination() const
Definition Move.cc:323
TCEString name() const
Definition Procedure.hh:66
Procedure & procedure(int index) const
Definition Program.cc:622
void addProcedure(Procedure *proc)
Definition Program.cc:524
int procedureCount() const
Definition Program.cc:610
InstructionReferenceManager & instructionReferenceManager() const
Definition Program.cc:688
void convertSymbolRefsToInsRefs(bool ignoreUnfoundSymbols=false)
Definition Program.cc:1264
void setProgramOperation(ProgramOperationPtr po)
ProgramOperationPtr programOperation() const
MachineFrameInfo * curFrameInfo_
std::set< std::string > opset_
The operations supported by the current target machine.
TTAMachine::Machine * mach_
Machine for building the program.
const llvm::TargetMachine * tm_
Target machine description.
LLVMTCECmdLineOptions * options_
The compiler options.
std::string mbbName(const MachineBasicBlock &mbb)
static bool isInlineAsm(const MachineInstr &instr)
llvm::Mangler * mang_
Mangler for mangling label strings.
virtual void emitSPInitialization()
TTAProgram::Program * prog_
Current program being built.
void addLabelForProgramOperation(TCEString label, ProgramOperationPtr po)
void emitConstantPool(const llvm::MachineConstantPool &cp)
TTAProgram::Instruction * emitInstruction(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
PRegionMarkerAnalyzer * pregions_
const TargetMachine & targetMachine() const
std::map< std::string, TTAProgram::Instruction * > codeLabels_
Code labels.
bool doFinalization(Module &M)
TTAProgram::Instruction * emitInlineAsm(const MachineFunction &mf, const MachineInstr *mi, TTAProgram::BasicBlock *bb, TTAProgram::InstructionReferenceManager &irm)
virtual bool isTTATarget() const
virtual void getAnalysisUsage(AnalysisUsage &AU) const
bool doInitialization(Module &M)
virtual TTAProgram::Terminal * createSymbolReference(const TCEString &symbolName)
void markJumpTableDestinations(llvm::MachineFunction &mf, ControlFlowGraph &cfg)
bool isRealInstruction(const MachineInstr &instr) const
BBSchedulerController * scheduler_
CopyingDelaySlotFiller & delaySlotFiller()
void compileFast(ControlFlowGraph &cfg)
DataDependenceGraphBuilder ddgBuilder_
bool hasRealInstructions(MachineBasicBlock::const_iterator i, const MachineBasicBlock &mbb)
std::vector< std::vector< BasicBlockNode * > > jumpTableRecord_
virtual TCEString registerFileName(unsigned llvmRegNum) const
bool isHotFunction(llvm::MachineFunction &mf) const
CopyingDelaySlotFiller * dsf_
bool writeMachineFunction(MachineFunction &mf)
std::map< const MachineBasicBlock *, BasicBlockNode * > skippedBBs_
virtual TCEString operationName(const MachineInstr &mi) const
void compileOptimized(ControlFlowGraph &cfg, llvm::AliasAnalysis *llvmAA)
CycleLookBackSoftwareBypasser * bypasser_
virtual bool doInitialization(Module &m)
virtual TTAProgram::Terminal * createMBBReference(const MachineOperand &mo)
void fixJumpTableDestinations(llvm::MachineFunction &mf, ControlFlowGraph &cfg)
std::map< const MachineBasicBlock *, BasicBlockNode * > bbMapping_
LLVMTCEIRBuilder(const TargetMachine &tm, TTAMachine::Machine *mach, InterPassData &ipd, AliasAnalysis *AA, bool functionAtATime=false, bool modifyMF=false)
void getAnalysisUsage(AnalysisUsage &AU) const
virtual int registerIndex(unsigned llvmRegNum) const
virtual bool doFinalization(Module &m)
virtual void createMoveNode(ProgramOperationPtr &po, std::shared_ptr< TTAProgram::Move > m, bool isDestination) override
BBSchedulerController & scheduler()
bool isExplicitReturn(const llvm::MachineInstr &mi) const
InnerLoopFinder * loopFinder_
ControlFlowGraph * buildTCECFG(llvm::MachineFunction &mf)
AAResults AliasAnalysis
InnerLoopInfoIndex innerLoopInfo()
std::map< const llvm::BasicBlock *, InnerLoopInfo > InnerLoopInfoIndex