41#include "LLVMTCEIRBuilder.hh"
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"
86#define EXIT_IF_THROWS(__X__) \
89 } catch (const Exception& e) { \
90 Application::errorStream() \
91 << "Error: " << e.errorMessage() << std::endl; \
108 ddgBuilder_(ipd), AA_(AA), modifyMF_(modifyMF),
109 scheduler_(NULL), dsf_(NULL),
110 bypasser_(NULL), loopFinder_(NULL) {
118 for (
int i = 0; i < fuNav.
count(); i++) {
139 tm_ = &mf.getTarget();
152 mang_ =
new llvm::Mangler();
156 if (mf.begin() == mf.end())
return true;
160 SmallString<256> Buffer;
161 mang_->getNameWithPrefix(Buffer, &mf.getFunction(),
false);
202 AAResultsWrapperPass* AARWPass =
203 getAnalysisIfAvailable<AAResultsWrapperPass>();
205 AA = &AARWPass->getAAResults();
239 <<
"spill moves in " <<
240 (std::string)(mf.getFunction().getName()) <<
": "
263 if (funcs == NULL || funcs->size() == 0)
266 SmallString<256> Buffer;
267 mang_->getNameWithPrefix(Buffer, &mf.getFunction(),
false);
275 SmallString<256> Buffer;
276 mang_->getNameWithPrefix(Buffer, &mf.getFunction(),
false);
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;
294 std::map<const BasicBlockNode*, BasicBlockNode*> ftSuccsToInlineAsm;
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;
304 bool firstInsOfProc =
true;
310 for (MachineFunction::const_iterator i = mf.begin(); i != mf.end(); i++) {
311 const MachineBasicBlock& mbb = *i;
318 bool firstBBofTheProgram =
322 if (firstBBofTheProgram) {
336 InnerLoopFinder::InnerLoopInfoIndex::const_iterator loopInfoI =
337 loopInfos.find(mbb.getBasicBlock());
338 if (loopInfoI != loopInfos.end()) {
350 unsigned realInstructionCount = 0;
351 bool lastInstrWasInlineAsm =
false;
354 for (MachineBasicBlock::const_iterator j = mbb.begin();
355 j != mbb.end(); j++) {
367 if (realInstructionCount > 0 && !lastInstrWasInlineAsm) {
370 ftSuccsToInlineAsm[bbn] = succBBN;
374 lastInstrWasInlineAsm =
true;
378 realInstructionCount = 0;
381 if (firstInsOfProc) {
384 firstInsOfProc =
false;
390 for (std::set<const MachineBasicBlock*>::iterator k =
391 emptyMBBs.begin(); k != emptyMBBs.end(); k++) {
397 realInstructionCount++;
404 MachineBasicBlock::const_iterator afterInlineAsm = j;
409 inlineAsmSuccs[bbn] = succBBN;
413 endingInlineAsmBBs.insert(&mbb);
417 lastInstrWasInlineAsm =
false;
420 if (j->getDesc().isCall() && j->getOperand(0).isGlobal()) {
424 const Function* callee =
425 dyn_cast<Function>(j->getOperand(0).getGlobal());
427 if (callee->size() == 0) {
429 "error: call to undefined function '";
430 errorMsg << callee->getName().str() <<
"'.";
432 __FILE__, __LINE__,
__func__, errorMsg);
436 if (&(*j) == &(mbb.back())) {
437 endingCallBBs.insert(&(*i));
439 MachineBasicBlock::const_iterator afterCall = j;
442 endingCallBBs.insert(&(*i));
448 callSuccs[bbn] = succBBN;
457 if (j->getDesc().isBranch()) {
460 if (j->getDesc().isConditionalBranch()) {
461 if (opName ==
"?jump") pred =
true;
462 if (opName ==
"BNZ") pred =
true;
463 if (opName ==
"BNZ1") pred =
true;
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;
477 if (opName.find(
"+") != std::string::npos) pred =
true;
478 bbPredicates[bbn] = pred;
479 const MachineOperand& mo = j->getOperand(j->getNumOperands()-1);
481 condJumpSucc[bbn] = mo.getMBB();
483 if (&(*j) == &(mbb.back())) {
484 endingCondJumpBBs.insert(&(*i));
487 endingCondJumpBBs.insert(&(*i));
494 ftSuccs[bbn] = succBBN;
501 if (&(*j) != &(mbb.back())) {
503 if (j->getDesc().isBranch())
507 endingUncondJumpBBs.insert(&(*i));
514 emptyMBBs.insert(&mbb);
532 for (MachineFunction::const_iterator i = mf.begin(); i != mf.end(); i++) {
533 const MachineBasicBlock& mbb = *i;
536 std::map<const MachineBasicBlock*, BasicBlockNode*>::iterator
541 bbn = bbMapIter->second;
548 for (MachineBasicBlock::const_iterator j = mbb.begin();
549 j != mbb.end(); j++) {
561 nextLabel = j->getOperand(0).getMCSymbol()->getName().str();
567 bbn = ftSuccsToInlineAsm[bbn];
573 bbn = inlineAsmSuccs[bbn];
586 if (nextLabel !=
"") {
596 if (j->getDesc().isReturn()) {
597 returningBBs.insert(bbn);
606 &(*j) != &(mbb.back())) {
608 if (j->getNextNode() !=
nullptr &&
609 !j->getNextNode()->isBranch()) {
611 assert(
false &&
"HWLOOP is not terminator in BB");
620 bbn = callSuccs[bbn];
626 if (j->getDesc().isBranch() &&
627 &(*j) != &(mbb.back())) {
632 assert(mbb.succ_size() == 1 &&
633 "HWLoop pre-header should have one succ MBB");
636 auto loopBody = *mbb.succ_begin();
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");
643 hwloopMBBs.insert(*mbb.succ_begin());
652 for (MachineFunction::const_iterator i = mf.begin(); i != mf.end(); i++) {
653 const MachineBasicBlock& mbb = *i;
656 std::map<const MachineBasicBlock*,BasicBlockNode*>::iterator
661 bbn = bbMapIter->second;
670 const MachineBasicBlock* jumpSucc = condJumpSucc[bbn];
673 std::map<const BasicBlockNode*, BasicBlockNode*>::iterator j =
675 std::map<const BasicBlockNode*, BasicBlockNode*>::iterator k =
677 std::map<const BasicBlockNode*, BasicBlockNode*>::iterator l =
678 inlineAsmSuccs.find(bbn);
679 std::map<const BasicBlockNode*, BasicBlockNode*>::iterator m =
680 ftSuccsToInlineAsm.find(bbn);
683 assert(((j != callSuccs.end())
684 + (k != ftSuccs.end())
685 + (l != inlineAsmSuccs.end())
686 + (m != ftSuccsToInlineAsm.end())) < 2);
688 if (j != callSuccs.end()) {
696 jumpSucc = condJumpSucc[bbn];
701 if (k != ftSuccs.end()) {
705 bbPredicates[bbn] ==
true ?
718 bbPredicates[bbn] ==
true ?
727 if (l != inlineAsmSuccs.end()) {
735 jumpSucc = condJumpSucc[bbn];
739 if (m != ftSuccsToInlineAsm.end()) {
747 jumpSucc = condJumpSucc[bbn];
754 for (MachineBasicBlock::const_succ_iterator si = mbb.succ_begin();
755 si != mbb.succ_end(); si++) {
756 const MachineBasicBlock* succ = *si;
759 std::map<const MachineBasicBlock*,BasicBlockNode*>::iterator
764 succBBN = bbMapIter->second;
776 if (jumpSucc != NULL) {
780 if (succ == jumpSucc) {
782 bbPredicates[bbn] ==
true ?
788 bbPredicates[bbn] ==
true ?
798 if (succ == jumpSucc) {
805 if ((hwloopMBBs.find(&mbb) != hwloopMBBs.end()) &&
812 }
else if (hasUncondJump) {
857 if (!mi.isInlineAsm())
return false;
862 unsigned numOperands = mi.getNumOperands();
865 unsigned numDefs = 0;
866 for (; mi.getOperand(numDefs).isReg() &&
867 mi.getOperand(numDefs).isDef();
871 if (mi.isInlineAsm() && numDefs < numOperands &&
872 mi.getOperand(numDefs).isSymbol()) {
873 asmStr = mi.getOperand(numDefs).getSymbolName();
879 asmStr ==
".longjmp";
930 NULL,
true,
true, llvmAA);
995 if (mo.isBlockAddress()) {
997 const MachineBasicBlock* mbb = NULL;
999 std::map<const MachineBasicBlock*, BasicBlockNode*>::iterator i =
1002 const MachineBasicBlock* mbbt = i->first;
1004 if (mbbt->getBasicBlock() == mo.getBlockAddress()->getBasicBlock()) {
1008 <<
"LLVMTCEIRBuilder: found multiple potential BB references."
1011 <<
"first: " << bb->
toString() << std::endl;
1013 <<
"another: " << bbt.
toString() << std::endl;
1018 if (mbbt->isSuccessor(mbb)) {
1031 const MachineBasicBlock* mbbt = i->first;
1033 if (mbbt->getBasicBlock() == mo.getBlockAddress()->getBasicBlock()) {
1041 <<
"Could not find referred MBB matching the referred BB:"
1047 MachineBasicBlock* mbb = mo.getMBB();
1048 std::map<const MachineBasicBlock*,BasicBlockNode*>::iterator i =
1052 std::map<const MachineBasicBlock*, BasicBlockNode*>::iterator j =
1058 j->second->basicBlock());
1062 i->second->basicBlock());
1072 const llvm::MCInstrDesc* opDesc = &instr.getDesc();
1073 if (opDesc->isReturn()) {
1080 if (opDesc->getOpcode() == TargetOpcode::DBG_VALUE) {
1084 if (opDesc->getOpcode() == TargetOpcode::KILL) {
1091 if (opName ==
"PSEUDO" || opName ==
"DEBUG_LABEL") {
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()) {
1107 MachineBasicBlock::const_iterator i,
1108 const MachineBasicBlock& mbb) {
1109 for (; i != mbb.end(); i++) {
1140 if (m.getFunction(procedure.
name()) != NULL)
continue;
1150 if (mi.getDesc().isReturn())
return "RET";
1155 mi.getParent()->getParent()->getFunction())->getInstrInfo()->
1156 getName(mi.getOpcode()).str();
1173 for (
int i = 0; i < rfNav.
count(); i++) {
1179 TCEString(
"Unable to figure the RF for llvm reg num ") <<
1198 return llvmRegNum - 1;
1204 llvm::MachineFunction& mf,
1207 llvm::MachineJumpTableInfo* jtInfo = mf.getJumpTableInfo();
1208 if (jtInfo == NULL || jtInfo->isEmpty()) {
1212 std::vector<llvm::MachineJumpTableEntry> entries = jtInfo->getJumpTables();
1214 for (
unsigned int i = 0; i < entries.size(); i++) {
1215 std::vector<BasicBlockNode*> nodes;
1217 std::vector<MachineBasicBlock*> blocks =
1219 for (
unsigned j = 0; j < blocks.size(); j++) {
1220 MachineBasicBlock* mbb = blocks.at(j);
1222 std::map<const MachineBasicBlock*, BasicBlockNode*>::iterator
1225 "The Basic Block Node for Machine Basic Block is missing!");
1226 bbn = bbMapIter->second;
1235 llvm::MachineFunction& mf,
1238 llvm::MachineJumpTableInfo* jtInfo = mf.getJumpTableInfo();
1239 if (jtInfo == NULL) {
1244 std::vector<MachineBasicBlock*> oldTable =
1245 jtInfo->getJumpTables().at(i).MBBs;
1246 for (
unsigned int j = 0; j < nodes.size(); j++) {
1249 MachineBasicBlock* oldMBB = oldTable.at(j);
1250 jtInfo->ReplaceMBBInJumpTable(i, oldMBB, newMBB);
1254 newMBB->setIsEHPad();
1266 std::shared_ptr<TTAProgram::Move> m,
1267 bool isDestination) {
1270 if (isDestination) {
1271 po->addInputNode(*mn);
1277 po->addOutputNode(*mn);
#define abortWithError(message)
#define assert(condition)
#define IGNORE_COMPILER_WARNING(X)
#define POP_COMPILER_DIAGS
#define EXIT_IF_THROWS(__X__)
static MachInfoCmdLineOptions options
std::shared_ptr< ProgramOperation > ProgramOperationPtr
virtual void handleProcedure(TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetMachine) override
static CmdLineOptions * cmdLineOptions()
static int verboseLevel()
static std::ostream & logStream()
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...
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()
void convertBBRefsToInstRefs()
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
bool isTripCountKnown() const
bool disableDelaySlotFiller() const
virtual FunctionNameList * primaryFunctions() const
void setSourceOperationPtr(ProgramOperationPtr po)
void addDestinationOperationPtr(ProgramOperationPtr po)
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)
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
virtual FunctionUnitNavigator functionUnitNavigator() const
virtual ControlUnit * controlUnit() const
void setTripCount(unsigned count)
void setInInnerLoop(bool inner=true)
virtual Instruction & firstInstruction() const
virtual std::string toString() const
virtual int instructionCount() const
bool hasControlFlowMove() const
Terminal & destination() const
Procedure & procedure(int index) const
void addProcedure(Procedure *proc)
int procedureCount() const
InstructionReferenceManager & instructionReferenceManager() const
void convertSymbolRefsToInsRefs(bool ignoreUnfoundSymbols=false)
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 fixProgramOperationReferences()
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
void clearFunctionBookkeeping()
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_
virtual ~LLVMTCEIRBuilder()
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)
InnerLoopInfoIndex innerLoopInfo()
std::map< const llvm::BasicBlock *, InnerLoopInfo > InnerLoopInfoIndex