44#include <boost/format.hpp>
50#include "LLVMTCEBuilder.hh"
100#include <llvm/IR/Constants.h>
101#include <llvm/IR/DerivedTypes.h>
102#include <llvm/IR/Module.h>
103#include "llvm/IR/InlineAsm.h"
104#include <llvm/CodeGen/MachineInstr.h>
105#include <llvm/CodeGen/MachineMemOperand.h>
106#include <llvm/CodeGen/MachineConstantPool.h>
107#include <llvm/CodeGen/TargetInstrInfo.h>
108#include <llvm/CodeGen/TargetLowering.h>
109#include <llvm/Target/TargetMachine.h>
110#include <llvm/Support/Debug.h>
111#include <llvm/Support/raw_ostream.h>
113#include <llvm/IR/DebugInfo.h>
115#include <llvm/MC/MCContext.h>
116#include <llvm/MC/MCSymbol.h>
126#include "tce_config.h"
128#include "llvm/IR/DataLayout.h"
131#include <llvm/MC/MCInstrDesc.h>
133#include <llvm/ADT/SmallString.h>
135#define END_SYMBOL_NAME "_end"
155 const TargetMachine& tm,
158 bool functionAtATime) :
159 MachineFunctionPass(ID) {
164 dl_ =
new DataLayout(
tm_->createDataLayout());
232 for (
int i = 0;i < fuNav.
count(); i++) {
240 for (
int o = 0; o < cu.operationCount(); o++) {
246 std::cerr <<
"ERROR: No control unit in the target machine!"
254 std::cerr <<
"ERROR: Address space set for the control unit in the "
268 for (
int i = 0; i < nav.
count(); i++) {
278 std::cerr <<
"ERROR: Unable to determine the default data address space."
285 <<
"' as the default data address space"
291 mang_ =
new Mangler();
299 for (Module::const_global_iterator i =
mod_->global_begin();
300 i !=
mod_->global_end(); i++) {
302 SmallString<256> Buffer;
303 mang_->getNameWithPrefix(Buffer, &(*i),
false);
306 const llvm::GlobalObject& gv = *i;
307 MaybeAlign gvAlign = gv.getAlign();
309 if (gv.hasSection() &&
310 gv.getSection() == std::string(
"llvm.metadata")) {
320 if (name ==
"__dso_handle") {
325 if (!i->hasInitializer()) {
326 std::cerr <<
"Initializer missing for: " << name << std::endl;
327 assert(
false &&
"No initializer. External linkage?");
330 const Constant* initializer = i->getInitializer();
331 TYPE_CONST Type* type = initializer->getType();
337 cast<PointerType>(gv.getType())->getAddressSpace();
338 #ifdef LLVM_OLDER_THAN_16
339 def.
alignment = std::max(gvAlign.hasValue()? gvAlign->value():0, (
long unsigned int)(
dl_->getPrefTypeAlignment(type)));
341 def.
alignment = std::max(gvAlign.has_value()? gvAlign->value():0, (
long unsigned int)(
dl_->getPrefTypeAlignment(type)));
343 def.
size =
dl_->getTypeStoreSize(type);
353 data_.push_back(def);
361 for (
unsigned i = 0; i <
data_.size(); i++) {
366 unsigned& dataEndPos =
dataEnd(aSpace);
371 while ((dataEndPos + pad) %
data_[i].alignment != 0) pad++;
381 data_[i].address = dataEndPos;
390 dataEndPos +=
data_[i].size;
394 for (
unsigned i = 0; i <
udata_.size(); i++) {
399 unsigned& dataEndPos =
dataEnd(aSpace);
404 while ((dataEndPos + pad) %
udata_[i].alignment != 0) pad++;
414 udata_[i].address = dataEndPos;
423 dataEndPos +=
udata_[i].size;
456 std::cerr << def.
name <<
" misaligned!" << std::endl;
457 std::cerr <<
" address: " << def.
address
458 <<
" alignment: " << def.
alignment << std::endl;
471 const GlobalVariable* var = NULL;
472 for (Module::const_global_iterator i =
mod_->global_begin();
473 i !=
mod_->global_end(); i++) {
475 SmallString<256> Buffer;
476 mang_->getNameWithPrefix(Buffer, &(*i),
false);
477 if (def.
name == Buffer.c_str()) {
485 assert(var != NULL &&
"Variable not found!");
488 unsigned paddedAddr =
505 unsigned address = def.
address;
524 int addressSpaceId,
unsigned& addr,
const Constant* cv,
525 bool forceInitialize,
unsigned forceAlignment) {
527 unsigned sz =
dl_->getTypeStoreSize(cv->getType());
528 llvm::Align align = (forceAlignment == 0)?
529 dl_->getABITypeAlign(cv->getType()):llvm::Align(forceAlignment);
536 align = (forceAlignment == 0)?llvm::Align(sz):llvm::Align(forceAlignment);
547 unsigned paddedAddr = addr;
551 if (!forceInitialize &&
552 (cv->isNullValue() || dyn_cast<UndefValue>(cv) != NULL)) {
561 if (isa<ConstantArray>(cv) ||
562 isa<ConstantStruct>(cv) ||
563 isa<ConstantVector>(cv)) {
565 for (
unsigned i = 0, e = cv->getNumOperands(); i != e; ++i) {
569 }
else if (
const ConstantInt* ci = dyn_cast<ConstantInt>(cv)) {
571 }
else if (
const ConstantFP* cfp = dyn_cast<ConstantFP>(cv)) {
573 }
else if (
const GlobalValue* gv = dyn_cast<GlobalValue>(cv)) {
575 }
else if (
const ConstantExpr* ce = dyn_cast<ConstantExpr>(cv)) {
577 }
else if (
const ConstantDataArray* cda = dyn_cast<ConstantDataArray>(cv)){
578 if (cda->isNullValue()) {
592 bool allZeros =
true;
593 for (
unsigned i = 0, e = cda->getNumElements(); i != e; ++i) {
594 llvm::Constant *ace =
595 cast<Constant>(cda->getElementAsConstant(i));
596 if (ace->isNullValue() || isa<UndefValue>(ace))
602 for (
unsigned int i = 0; i < cda->getNumElements(); i++) {
608 }
else if (
const ConstantDataSequential* cds =
609 dyn_cast<ConstantDataSequential>(cv)) {
613 unsigned alignmentOverride = 0;
614 if (cv->getType()->isVectorTy()) {
615 alignmentOverride = sz/cds->getNumElements();
617 for (
unsigned int i = 0; i < cds->getNumElements(); i++) {
620 forceInitialize, alignmentOverride);
639 int addressSpaceId,
unsigned& addr,
const ConstantInt* ci,
642 assert(addr % (
dl_->getABITypeAlign(ci->getType()).value()) == 0 &&
643 "Invalid alignment for constant int!");
645 std::vector<MinimumAddressableUnit> maus;
653 if (!(sz == 1 || sz == 2 || sz == 4 || sz == 8)) {
670 u.d = ci->getZExtValue();
675 for (
unsigned i = 0; i < sz; i++) {
676 maus.push_back(u.bytes[sz - i - 1]);
679 for (
unsigned i = 0; i < sz; i++) {
680 maus.push_back(u.bytes[i]);
695 int addressSpaceId,
unsigned& addr,
const ConstantFP* cfp) {
697 assert(addr % (
dl_->getABITypeAlign(cfp->getType()).value()) == 0
698 &&
"Invalid alignment for constant fp!");
705 std::vector<MinimumAddressableUnit> maus;
708 unsigned sz =
dl_->getTypeStoreSize(type);
712 if (type->getTypeID() == Type::DoubleTyID) {
714 double val = cfp->getValueAPF().convertToDouble();
723 for (
unsigned i = 0; i < sz; i++) {
724 maus.push_back(u.bytes[sz - i - 1]);
727 for (
unsigned i = 0; i < sz; i++) {
728 maus.push_back(u.bytes[i]);
733 }
else if (type->getTypeID() == Type::FloatTyID) {
735 float val = cfp->getValueAPF().convertToFloat();
744 for (
unsigned i = 0; i < sz; i++) {
745 maus.push_back(u.bytes[sz - i - 1]);
748 for (
unsigned i = 0; i < sz; i++) {
749 maus.push_back(u.bytes[i]);
754 }
else if (type->getTypeID() == Type::HalfTyID) {
755 APInt bits = cfp->getValueAPF().bitcastToAPInt();
756 uint64_t bigval = bits.getLimitedValue(0xFFFF);
764 for (
unsigned i = 0; i < sz; i++) {
765 maus.push_back(u.bytes[sz - i - 1]);
768 for (
unsigned i = 0; i < sz; i++) {
769 maus.push_back(u.bytes[i]);
775 assert(
false &&
"Unknown floating point typeID!");
790 int addressSpaceId,
unsigned& addr,
const GlobalValue* gv,
int offset) {
794 unsigned sz =
dl_->getTypeStoreSize(type);
796 SmallString<256> Buffer;
797 mang_->getNameWithPrefix(Buffer, gv,
false);
810 "Instruction reference with an offset not supported yet.");
819 unsigned gvAS = type->getAddressSpace();
826 assert(
false &&
"Global value label not found!");
841 int addressSpaceId,
unsigned& addr,
const ConstantExpr* ce,
int offset) {
843 assert(addr % (
dl_->getABITypeAlign(ce->getType()).value()) == 0 &&
844 "Invalid alignment for constant expr!");
846 unsigned opcode = ce->getOpcode();
847 if (opcode == Instruction::GetElementPtr) {
848 const Constant* ptr = ce->getOperand(0);
849 SmallVector<Value*, 8> idxVec(ce->op_begin() + 1, ce->op_end());
851 APInt offsetAI(
dl_->getPointerTypeSizeInBits(ce->getType()), 0);
852 bool success = cast<GEPOperator>(ce)->accumulateConstantOffset(
855 int64_t ptrOffset = offset + offsetAI.getSExtValue();
857 if (
const GlobalValue* gv = dyn_cast<GlobalValue>(ptr)) {
860 }
else if (
const ConstantExpr* ce =
861 dyn_cast<ConstantExpr>(ptr)) {
865 assert(
false &&
"Unsuported getElementPtr target!");
867 }
else if (opcode == Instruction::BitCast) {
868 const Constant* ptr = ce->getOperand(0);
869 if (
const ConstantExpr* ce = dyn_cast<ConstantExpr>(ptr)) {
872 }
else if (
const GlobalValue* gv = dyn_cast<GlobalValue>(ptr)) {
887 }
else if (opcode == Instruction::IntToPtr) {
889 const ConstantInt* ci = dyn_cast<ConstantInt>(ce->getOperand(0));
892 }
else if (opcode == Instruction::PtrToInt) {
900 }
else if (opcode == Instruction::Add) {
901 assert(
false &&
"NOT IMPLEMENTED");
902 }
else if (opcode == Instruction::Sub) {
903 assert(
false &&
"NOT IMPLEMENTED");
905 assert(
false &&
"NOT IMPLEMENTED");
922 int addressSpaceId,
unsigned& addr,
unsigned align) {
928 while ((addr + pad) % align != 0) pad++;
932 std::vector<MinimumAddressableUnit> zeros(pad, 0);
979 if (mf.begin() == mf.end())
return true;
983 SmallString<256> Buffer;
984 mang_->getNameWithPrefix(Buffer, &mf.getFunction(),
false);
994 std::set<std::string> emptyMBBs;
996 bool firstInsOfProc =
true;
999 for (MachineFunction::const_iterator i = mf.begin();
1000 i != mf.end(); i++) {
1005 for (MachineBasicBlock::const_iterator j = i->begin();
1006 j != i->end(); j++) {
1009#ifdef DEBUG_LLVMTCEBUILDER
1010 std::cerr <<
"### converting: ";
1011 std::cerr << std::endl;
1016 if (instr == NULL)
continue;
1020 <<
"ERROR: The machine contains multiple data address spaces "
1021 <<
"and ambigious memory accessing moves '"
1022 << instr->
toString() <<
"' were found." << std::endl;
1029 while (!emptyMBBs.empty()) {
1030 mbbs_[*emptyMBBs.begin()] = instr;
1031 emptyMBBs.erase(emptyMBBs.begin());
1034 std::string mbb =
mbbName(*i);
1041 bbIndex_[(*i).getBasicBlock()] = instr;
1045 if (firstInsOfProc) {
1047 instructionReferenceManager().createReference(*instr);
1052 firstInsOfProc =
false;
1061 emptyMBBs.insert(
mbbName(*i));
1067 if (firstInsOfProc) {
1069 proc->
add(dummyIns);
1072 instructionReferenceManager().createReference(*dummyIns);
1080 <<
"spill moves in " <<
1081 (std::string)(mf.getFunction().getName()) <<
": "
1099 unsigned& dataEndPos =
dataEnd(aSpace);
1115 for (
unsigned i = 0; i <
data_.size(); i++) {
1118 for (
unsigned i = 0; i <
udata_.size(); i++) {
1121 for (
auto cpDataDef :
cpData_) {
1136 endLoc = dataEndPos;
1143 for (DataMemIndex::const_iterator i =
dmemIndex_.begin();
1150 std::string>::iterator mbbRefIter =
1156 std::string mbb = mbbRefIter->second;
1158 assert(
false &&
"MBB not found from book keeping.");
1168 std::string>::iterator codeRefIter =
1173 std::string label = codeRefIter->second;
1175 std::cerr << (boost::format(
1176 "Function '%s' not defined.\n") %
1191#ifdef DISASSEMBLE_LLVM_OUTPUT
1192 std::ofstream outfile(
"llvm_output.S");
1203 MachineDCE& MDCE = getAnalysis<MachineDCE>();
1205 for (MachineDCE::UnusedFunctionsList::iterator i =
1208 std::string name = *i;
1211 <<
"Deleting unused function: " << name << std::endl;
1217 for (
int dataDefIdx = 0; dataDefIdx < dmem.dataDefinitionCount();
1220 if (dataDef.isInstructionAddress()) {
1227 <<
"Deleting data definition pointing to "
1228 <<
"dead function: " << name << std::endl;
1230 dmem.deleteDataDefinition(dataDefIdx);
1236 delete ¬UsedProc;
1275 hwOperation()->name();
1276 int numberOfPotentialFUs = 0;
1279 for (
int i = 0; i < fuNav.
count(); i++) {
1284 if (numberOfPotentialFUs > 1) {
1298 hasOperation(opName)) {
1302 TCEString(
"ERROR: Operation '") + opName +
1303 "' not found in the machine.");
1308 std::cerr <<
"ERROR: Operation '" << opName
1309 <<
"' is required by the program but not found "
1310 <<
"in the machine." << std::endl;
1329 bool isSpill =
false;
1330 bool isRaSlot =
false;
1331 bool isFpSlot =
false;
1332 const llvm::MCInstrDesc* opDesc = &mi->getDesc();
1333 unsigned opc = mi->getDesc().getOpcode();
1339 if (opc == TargetOpcode::DBG_VALUE
1340 || opc == TargetOpcode::DBG_LABEL
1341 || opc == TargetOpcode::DBG_INSTR_REF
1342 || opc == TargetOpcode::DBG_VALUE_LIST
1343 || opc == TargetOpcode::DBG_PHI
1344 || opc == TargetOpcode::KILL) {
1348 std::string opName =
"";
1350 bool hasGuard =
false;
1351 bool trueGuard =
true;
1354 if (opDesc->isReturn()) {
1367 if (opName ==
"PSEUDO" || opName ==
"DEBUG_LABEL") {
1374 if (opName ==
"DEBUG_LABEL") {
1378 if (opName[0] ==
'?') {
1380 opName = opName.substr(1);
1383 if (opName[0] ==
'!') {
1386 opName = opName.substr(1);
1389 if (opName ==
"MOVE") {
1390 return emitMove(mi, proc, hasGuard, trueGuard);
1394 if (opName ==
"INLINEASM") {
1398 if (opName ==
"CMOV_SELECT") {
1406 size_t split = opName.find(
"+");
1407 if (split != std::string::npos) {
1408 TCEString firstOp = opName.substr(0, split);
1409 TCEString remainingName = opName.substr(split+1);
1420 const Operation& operation = pool.operation(opName.c_str());
1422 std::vector<TTAProgram::Instruction*> operandMoves;
1423 std::vector<TTAProgram::Instruction*> resultMoves;
1425 int inputOperand = 0;
1427#ifdef DEBUG_LLVMTCEBUILDER
1431 << mi->getNumOperands() << std::endl;
1434 int guardOperandIndex = -1;
1437 for (
unsigned o = 0; o < mi->getNumOperands(); o++) {
1438 const MachineOperand& mo = mi->getOperand(o);
1443 if (mo.isReg() && mo.isUse()) {
1444 guardOperandIndex = o;
1458 for (
unsigned o = 0; o < mi->getNumOperands(); o++) {
1459 if ((
int)o == guardOperandIndex) {
1463 const MachineOperand& mo = mi->getOperand(o);
1471 if (mo.isMetadata()) {
1472 const MDNode* mdNode = mo.getMetadata();
1473 for (
unsigned int i = 0; i < mdNode->getNumOperands(); i++) {
1474 const MDOperand & oper = mdNode->getOperand(i);
1475 if (llvm::MDString* mds = dyn_cast<llvm::MDString>(oper)) {
1477 if (s ==
"AA_CATEGORY_STACK_SLOT") {
1479 }
else if (s ==
"AA_CATEGORY_RA_SAVE_SLOT") {
1481 }
else if (s ==
"AA_CATEGORY_FP_SAVE_SLOT") {
1491 "Operand mismatch.");
1502 const MachineOperand& base = mo;
1506 guard == NULL ? NULL : guard->
copy();
1508 auto move =
createMove(src, dst, bus, guardCopy);
1512 operandMoves.push_back(instr);
1517 const MachineOperand& offset = mi->getOperand(o);
1522 assert(inputOperand == 2);
1528 guard == NULL ? NULL : guard->
copy();
1530 auto move =
createMove(src, dst, bus, guardCopy);
1533 operandMoves.push_back(instr);
1536 assert(offset.getImm() == 0);
1542 guard == NULL ? NULL : guard->
copy();
1544 auto move =
createMove(src, dst, bus, guardCopy);
1547#ifdef DEBUG_LLVMTCEBUILDER
1549 <<
"adding " << move->toString() << std::endl;
1551 operandMoves.push_back(instr);
1561 "Operand mismatch.");
1567 guard == NULL ? NULL : guard->
copy();
1569 auto move =
createMove(src, dst, bus, guardCopy);
1572#ifdef DEBUG_LLVMTCEBUILDER
1574 <<
"adding " << move->toString() << std::endl;
1576 resultMoves.push_back(instr);
1581 for (
unsigned int i = 0; i < resultMoves.size();i++) {
1583 for (
int j = 0; j < resultIns.
moveCount(); j++) {
1591 if (!operandMoves.empty()) {
1592 first = operandMoves[0];
1593 }
else if (!resultMoves.empty()) {
1594 first = resultMoves[0];
1595 }
else if (opDesc->isReturn() && mi->getNumOperands() == 0) {
1611 operandMoves.push_back(instr);
1615 assert(
false &&
"No moves?");
1620 std::vector<std::string> candidateFUs;
1621 for (
unsigned i = 0; i < mi->getNumOperands(); ++i) {
1623 const MachineOperand& op = mi->getOperand(i);
1624 if (!op.isMetadata())
continue;
1625 const MDNode* mdNode = op.getMetadata();
1626 if (mdNode->getNumOperands() > 0) {
1628 llvm::Metadata* op = mdNode->getOperand(0);
1629 MDString* str = dyn_cast<llvm::MDString>(op);
1631 if (str->getString().str() ==
"fu_candidates") {
1632 for (
unsigned j = 1; j < mdNode->getNumOperands(); ++j) {
1633 op = mdNode->getOperand(j);
1634 str = dyn_cast<MDString>(op);
1635 TCEString fuName = str->getString().str();
1641 hasOperation(operation.
name())) {
1642#ifdef DEBUG_LLVMTCEBUILDER
1644 <<
"FU candidate " << str->getString().str() <<
" set for ";
1647 candidateFUs.push_back(str->getString().str());
1654 for (
unsigned i = 0; i < operandMoves.size(); i++) {
1659 for (
unsigned j = 0; j < candidateFUs.size(); ++j) {
1660 if (m->hasAnnotations(
1677 }
else if (isRaSlot) {
1681 }
else if (isFpSlot) {
1690 for (
unsigned i = 0; i < resultMoves.size(); i++) {
1695 for (
unsigned j = 0; j < candidateFUs.size(); ++j) {
1696 if (m->hasAnnotations(
1712 }
else if (isRaSlot) {
1716 }
else if (isFpSlot) {
1726 delete guard; guard = NULL;
1737 const Operation& operation = pool.operation(opName.c_str());
1743 for (
int i = 0; i < 2; i++) {
1744 const MachineOperand& mo = mi->getOperand(i);
1772 bool inverted = (opName[0] ==
'!');
1773 opName = opName.substr(1);
1777 const Operation& operation = pool.operation(opName.c_str());
1781 const MachineOperand& mo = mi->getOperand(2);
1802 const std::vector<TTAProgram::Instruction*>& operandMoves,
1804 for (
unsigned int i = 0; i < operandMoves.size(); i++) {
1832 if (mi->memoperands_begin() == mi->memoperands_end()) {
1834 <<
" does not have mem operands!"
1841 if (nodeId != UINT_MAX) {
1849 int addrSpaceId = 0;
1852 for (MachineInstr::mmo_iterator i = mi->memoperands_begin();
1853 i != mi->memoperands_end(); i++) {
1855 const PseudoSourceValue* psv = (*i)->getPseudoValue();
1872 const llvm::Value* memOpValue = (*i)->getValue();
1874 if (memOpValue != NULL) {
1875 std::string pointerName =
"";
1879 if (memOpValue->hasName()) {
1880 pointerName = memOpValue->getName().str();
1881 }
else if (isa<GetElementPtrInst>(memOpValue)) {
1883 cast<GetElementPtrInst>(
1884 memOpValue)->getPointerOperand();
1885 if (memOpValue->hasName()) {
1886 pointerName = memOpValue->getName().str();
1893 if (pointerName.length() > 0 &&
1894 isa<Argument>(memOpValue)) {
1896 offset = (*i)->getOffset();
1905 const llvm::Value* originMemOpValue = memOpValue;
1906 while (originMemOpValue != NULL) {
1908 (std::string)originMemOpValue->getName();
1912 if (dyn_cast<Instruction>(originMemOpValue) &&
1913 dyn_cast<Instruction>(originMemOpValue)->getMetadata(
"wi")) {
1915 cast<Instruction>(originMemOpValue)->getMetadata(
"wi");
1916 const MDNode* XYZ = dyn_cast<MDNode>(md->getOperand(2));
1917 assert(XYZ->getNumOperands() == 4);
1918 ConstantInt *CX = dyn_cast<ConstantInt>(
1919 dyn_cast<llvm::ConstantAsMetadata>(XYZ->getOperand(1))->getValue());
1920 ConstantInt *CY = dyn_cast<ConstantInt>(
1921 dyn_cast<llvm::ConstantAsMetadata>(XYZ->getOperand(2))->getValue());
1922 ConstantInt *CZ = dyn_cast<ConstantInt>(
1923 dyn_cast<llvm::ConstantAsMetadata>(XYZ->getOperand(3))->getValue());
1925 int id = (CZ->getZExtValue() & 0x0FF)
1926 | ((CY->getZExtValue() & 0x0FF) << 8)
1927 | ((CX->getZExtValue() & 0x0FF) << 16);
1930 ANN_OPENCL_WORK_ITEM_ID, id);
1939 if (isa<BitCastInst>(originMemOpValue)) {
1941 dyn_cast<BitCastInst>(originMemOpValue)->getDestTy();
1942 if (type->isPointerTy()) {
1943 #ifdef LLVM_OLDER_THAN_15
1944 llvm::Type* typeElem =
1945 cast<PointerType>(type)->getElementType();
1949 assert((isa<LoadInst>(originMemOpValue)
1950 || isa<StoreInst>(originMemOpValue)) &&
1951 "Expected Load or Store instruction");
1952 llvm::Type* typeElem = NULL;
1953 if (
auto *LI = dyn_cast<LoadInst>(originMemOpValue))
1954 typeElem = LI->getType();
1956 typeElem = cast<StoreInst>(originMemOpValue)
1957 ->getValueOperand()->getType();
1959 if (typeElem->isVectorTy()) {
1960 int numElems = cast<VectorType>(typeElem)
1962 .getKnownMinValue();
1963 int idLast = (CZ->getZExtValue() & 0x0FF)
1964 | ((CY->getZExtValue() & 0x0FF) << 8)
1965 | (((CX->getZExtValue()
1966 + numElems) & 0x0FF) << 16);
1969 ANN_OPENCL_WORK_ITEM_ID_LAST, idLast);
1976 if (isa<Argument>(originMemOpValue) &&
1977 cast<Argument>(originMemOpValue)->hasNoAliasAttr()) {
1980 ANN_POINTER_NOALIAS, 1);
2003 pointerName = originMemOpValue->getName().str();
2005 }
else if (isa<GetElementPtrInst>(originMemOpValue)) {
2007 cast<GetElementPtrInst>(originMemOpValue)->
2008 getPointerOperand();
2009 }
else if (isa<BitCastInst>(originMemOpValue)) {
2011 cast<BitCastInst>(originMemOpValue)->
2013 }
else if (isa<PtrToIntInst>(originMemOpValue)) {
2015 cast<PtrToIntInst>(originMemOpValue)->
2022 if (pointerName !=
"") {
2030 cast<PointerType>(memOpValue->getType())->
2033 if (addrSpaceId != 0) {
2036 std::string addressSpace =
2037 (boost::format(
"%d") % addrSpaceId).str();
2065 if (mi->getFlag(MachineInstr::FrameSetup)) {
2071 DebugLoc dl = mi->getDebugLoc();
2078 if (dl.getLine() == 0xFFFFFFF0) {
2086 bool hasDebugInfo =
false;
2087 hasDebugInfo = dl.getScope() != NULL;
2090 int sourceLineNumber = -1;
2094 sourceLineNumber = dl.getLine();
2097 cast<DIScope>(dl.getScope())->getFilename().str());
2099 if (sourceFileName.size() >
2102 sourceFileName.substr(
2103 sourceFileName.size() -
2112 if (sourceFileName !=
"") {
2115 ANN_DEBUG_SOURCE_CODE_PATH,
2125 const std::string& rfName,
int idx) {
2132 assert(idx >= 0 && idx < rf->size());
2135 const RFPort* port = NULL;
2136 for (
int i = 0; i < rf->
portCount(); i++) {
2154 if (bitLimit == 0) {
2159 unsigned dRegNum = mo.getReg();
2165 returnAddressPort());
2177 }
else if (mo.isFPImm()) {
2178 const APFloat& apf = mo.getFPImm()->getValueAPF();
2179 if (&apf.getSemantics() == &APFloat::IEEEhalf()) {
2180 APInt api = apf.bitcastToAPInt();
2181 uint16_t binary = (uint16_t)api.getRawData()[0];
2186 float fval = apf.convertToFloat();
2191 }
else if (mo.isImm()) {
2192 int width = bitLimit;
2195 }
else if (mo.isMBB() || mo.isBlockAddress()) {
2197 }
else if (mo.isFI()) {
2198 std::cerr <<
" Frame index source operand NOT IMPLEMENTED!"
2201 }
else if (mo.isCPI()) {
2203 int width = bitLimit;
2204 unsigned idx = mo.getIndex();
2216 ref << mo.getIndex() <<
"_" << mo.getOffset();
2219 }
else if (mo.isJTI()) {
2221 ref << mo.getIndex();
2223 }
else if (mo.isGlobal()) {
2225 cast<PointerType>(mo.getGlobal()->getType())->getAddressSpace();
2230 SmallString<256> Buffer;
2231 mang_->getNameWithPrefix(Buffer, mo.getGlobal(),
false);
2244 }
else if (mo.isJTI()) {
2245 std::cerr <<
" Jump table index operand NOT IMPLEMENTED!\n";
2247 }
else if (mo.isSymbol()) {
2249 }
else if (mo.isMCSymbol()) {
2251 }
else if (mo.isMetadata()) {
2252 assert(
"Metadata MachineOperands should not get here" &&
false);
2254 std::cerr <<
"Unknown src operand type!" << std::endl;
2265 const MachineOperand& mo) {
2266 llvm::MCSymbol* symbol = mo.getMCSymbol();
2281 for (std::set<TTAProgram::TerminalProgramOperation*>::const_iterator i =
2286 assert(po.get() != NULL);
2354 const std::vector<MachineConstantPoolEntry>& cp = mcp.getConstants();
2356 const unsigned cpAddrSpaceId = 0;
2359 for (
unsigned i = 0, e = cp.size(); i != e; ++i) {
2361 assert(!(cpe.isMachineConstantPoolEntry()) &&
"NOT SUPPORTED");
2362 if (!
globalCP_.count(cpe.Val.ConstVal)) {
2364 assert(cpe.getAlign().value() > 0);
2365 unsigned alignment = cpe.getAlign().value();
2367 unsigned address = dataEndPos;
2369 unsigned size = cpe.getSizeInBytes(*
dl_);
2371 address, alignment, size, cpe.Val.ConstVal));
2372 globalCP_.insert(std::make_pair(cpe.Val.ConstVal, address));
2392std::shared_ptr<TTAProgram::Move>
2394 const MachineOperand& src,
const MachineOperand& dst,
2396 assert(!src.isReg() || src.isUse());
2400 if (dst.isReg() && src.isReg() && dst.getReg() == src.getReg()) {
2409 auto move =
createMove(srcTerm, dstTerm, bus, guard);
2424 bool conditional,
bool trueGuard) {
2426 unsigned int operandCount = conditional ? 3 : 2;
2427 if (mi->getNumOperands() > operandCount) {
2428 for (
unsigned int i = operandCount; i < mi->getNumOperands(); i++) {
2430 if (!(mi->getOperand(i).isMetadata()) &&
2431 (!mi->getOperand(i).isImplicit())) {
2435 assert(mi->getOperand(i).isMetadata() ||
2436 mi->getOperand(i).isImplicit());
2440 assert(mi->getNumOperands() >= operandCount);
2442 const MachineOperand& dst = mi->getOperand(0);
2443 const MachineOperand& src = mi->getOperand(operandCount - 1);
2446 const MachineOperand& gmo = mi->getOperand(1);
2447 assert (gmo.isReg() && gmo.isUse());
2481 if (copyOp == NULL || guard != NULL) {
2484 TCEString(
"Unable to create a reg to reg copy due to "
2485 "having only one port in '") +
2502 <<
" having only 1 port" << std::endl;
2513 auto move =
createMove(srcTerm, dstTerm, bus, guard);
2545 const Operation& operation = pool.operation(
"jump");
2570 const MachineOperand& guardMo = mi->getOperand(1);
2576 assert(guardTerminal != NULL);
2587 if (dstT->
equals(*srcT)) {
2588 if (dstT->
equals(*srcF)) {
2589 std::cerr <<
"Empty select!" << std::endl;
2596 assert(trueGuard != NULL);
2597 auto trueMove =
createMove(srcT, dstT, bus, trueGuard);
2605 if (dstF->
equals(*srcF)) {
2610 assert(falseGuard != NULL);
2611 auto falseMove =
createMove(srcF, dstF, bus, falseGuard);
2614 proc->
add(falseIns);
2615 if (firstIns == NULL) {
2616 firstIns = falseIns;
2621 delete guardTerminal;
2623 assert(firstIns != NULL);
2637 SmallString<256> Buffer;
2638 mang_->getNameWithPrefix(Buffer, &mbb.getParent()->getFunction(),
false);
2654 if ((dyn_cast<ConstantArray>(cv) != NULL) ||
2655 (dyn_cast<ConstantStruct>(cv) != NULL) ||
2656 (dyn_cast<ConstantVector>(cv) != NULL)) {
2658 for (
unsigned i = 0, e = cv->getNumOperands(); i != e; ++i) {
2690 assert(idx >= 0 && idx < rf->size());
2691 const RFPort* port = NULL;
2692 for (
int i = 0; i < rf->
portCount(); i++) {
2707 unsigned mask = 0xffffffff;
2709 while (stackAlignment > 1) {
2711 stackAlignment = stackAlignment >> 1;
2729 spInit->add(spInitInst);
2746 std::vector<MinimumAddressableUnit> spmaus;
2747 unsigned nMaus =
sizeof(unsigned);
2749 for (
unsigned i = 0; i < nMaus; i++) {
2750 spmaus.push_back(u.bytes[nMaus-i-1]);
2753 for (
unsigned i = 0; i < nMaus; i++) {
2754 spmaus.push_back(u.bytes[i]);
2776 first, spInit->firstInstruction());
2791 const MachineFunction& mf,
2792 const MachineInstr* mi,
2800 assert(tm &&
"Inline asm parser requires TCETargetMachine.");
2804 for (
auto& opds : asmOpds) {
2805 auto& asmOpdNodes = std::get<1>(opds.second);
2806 for (
auto mo : asmOpdNodes) {
2808 !mf.getRegInfo().isReserved(mo->getReg())) {
2813 <<
"Error: An use of reserved register '"
2815 <<
"' in inline assembly." << std::endl;
2818 "Encountered errors in inline assembly.");
2828 if (!std::get<0>(srcLoc).empty()) {
2829 std::cerr << std::get<0>(srcLoc) <<
":" << std::get<1>(srcLoc)
2830 <<
":" << std::endl;
2832 for (
auto syntaxError : diag.errors()) {
2833 std::cerr <<
"Error in line " << syntaxError.lineNumber <<
": "
2834 << syntaxError.message << std::endl;
2836 for (
auto internalError : diag.otherErrors()) {
2837 std::cerr <<
"Error: " << internalError.message << std::endl;
2840 CompileError,
"Encountered errors in inline assembly parsing.");
2846 std::cerr << warning.toString() << std::endl;
2870 unsigned numOperands =
2872 mi->getNumOperands();
2874 unsigned numDefs = 0;
2875 for (; mi->getOperand(numDefs).isReg() &&
2876 mi->getOperand(numDefs).isDef();
2880 std::string opName = mi->getOperand(numDefs).getSymbolName();
2887 if (opName[0] ==
'.') {
2893 std::vector<std::string> addressedFUs;
2898 if (opName.substr(0,3) ==
"_AS") {
2901 std::string addressedAS;
2902 std::istringstream iss(opName);
2903 std::getline(iss, foo,
'.');
2904 std::getline(iss, addressedAS,
'.');
2905 std::getline(iss, opName,
'.');
2910 if (addressedAS.size() && addressedAS[0] ==
'#') {
2912 if (end == addressedAS.c_str()+1) {
2913 std::cerr <<
"ERROR: Address space id following # not a number '" << addressedAS
2918 for (
int i = 0; i < nav.
count(); i++) {
2928 for (
int i = 0; i < nav.
count(); i++) {
2930 if (as->
name() == addressedAS) {
2937 if (targetAS == NULL) {
2938 std::cerr <<
"ERROR: Address space '" << addressedAS
2946 for (
int j = 0; j < fuNav.
count(); j++) {
2949 addressedFUs.push_back(fu->
name());
2954 std::string addressedFU;
2956 std::istringstream iss(opName);
2957 std::getline(iss, addressedFU,
'.');
2958 std::getline(iss, opName,
'.');
2960 std::cerr <<
"ERROR: Function Unit '" << addressedFU
2965 addressedFUs.push_back(addressedFU);
2969 assert(numDefs != numOperands-1 &&
"No asm string?");
2970 assert(mi->getOperand(numDefs).isSymbol() &&
"No asm string?");
2977 std::cerr <<
"ERROR: Inline assembly not supported!" << std::endl;
2984 <<
"ERROR: Explicitly executed operation '"
2985 << opName <<
"' does not match any operation definition in OSAL."
2993 std::vector<TTAProgram::Instruction*> operandMoves;
2994 std::vector<TTAProgram::Instruction*> resultMoves;
3000 const Operation& operation = pool.operation(opName.c_str());
3001 int inputOperand = 0;
3003 const MachineFunction& mf = *mi->getParent()->getParent();
3006 unsigned startOp = InlineAsm::MIOp_FirstOperand;
3007 unsigned asmDescOp = InlineAsm::MIOp_FirstOperand;
3008 unsigned clobberOp = InlineAsm::MIOp_FirstOperand-1;
3009 for (
unsigned o = startOp; o < mi->getNumOperands(); o++) {
3010 const MachineOperand& mo = mi->getOperand(o);
3011 if (mo.isMetadata()) {
3013 }
else if (o == asmDescOp && mo.isImm()) {
3015 unsigned flag = mo.getImm();
3016 if (InlineAsm::getKind(flag) == InlineAsm::Kind_Clobber) {
3020 asmDescOp += 1 + InlineAsm::getNumOperandRegisters(flag);
3022 }
else if (o == clobberOp) {
3023 if (mf.getRegInfo().isReserved(mo.getReg())) {
3024 std::cerr <<
"Warning: inline assembly clobbers"
3025 <<
" reserved register (regNum = " << mo.getReg()
3026 <<
"), which has undefined behavior."
3029 }
else if (!(mo.isReg() || mo.isImm() || mo.isGlobal())) {
3032 std::cerr <<
"Ignoring an operand of " << opName << std::endl;
3038 if (mo.isImm() || mo.isGlobal() || mo.isUse()) {
3040 if (useOps.empty()) {
3042 if (mo.isImplicit()) {
3045 std::cerr << std::endl;
3046 std::cerr <<
"ERROR: Too many input operands for custom "
3047 <<
"operation '" << opName <<
"'." << std::endl;
3052 useOps.erase(useOps.begin());
3055 if (defOps.empty()) {
3057 if (mo.isImplicit()) {
3060 std::cerr << std::endl;
3061 std::cerr <<
"ERROR: Too many output operands for custom "
3062 <<
"operation '" << opName <<
"'." << std::endl;
3066 if (mf.getRegInfo().isReserved(mo.getReg())) {
3067 std::cerr <<
"Warning: inline assembly overwriting"
3068 <<
" reserved register (regNum = " << mo.getReg()
3069 <<
") has undefined behavior."
3075 defOps.erase(defOps.begin());
3083 if (mo.isImm() || mo.isGlobal() || mo.isUse()) {
3084 operandMoves.push_back(instr);
3092 resultMoves.push_back(instr);
3096 if (!defOps.empty() || !useOps.empty()) {
3097 std::cerr <<
"ERROR: All operands not defined for custom operation '"
3098 << opName <<
"'." << std::endl;
3100 std::cerr <<
"Undefined: " << defOps.size() <<
" output operands, "
3101 << useOps.size() <<
" input operands." << std::endl;
3108 if (!operandMoves.empty()) {
3109 first = operandMoves[0];
3110 }
else if (!resultMoves.empty()) {
3111 first = resultMoves[0];
3113 assert(
false &&
"No moves?");
3116 for (
unsigned i = 0; i < operandMoves.size(); i++) {
3117 proc->
add(operandMoves[i]);
3120 operandMoves[i]->move(0).removeAnnotations(
3123 for (
unsigned int j = 0; j < addressedFUs.size(); j++) {
3127 operandMoves[i]->move(0).addAnnotation(dstCandidate);
3132 for (
unsigned i = 0; i < resultMoves.size(); i++) {
3133 proc->
add(resultMoves[i]);
3136 resultMoves[i]->move(0).removeAnnotations(
3139 for (
unsigned int j = 0; j < addressedFUs.size(); j++) {
3143 resultMoves[i]->move(0).addAnnotation(srcCandidate);
3161 const std::string op,
const MachineInstr* mi,
3166 TCEString subOp(std::string(op, 1, op.length() - 1));
3168 if (subOp ==
"setjmp")
3171 if (subOp ==
"longjmp")
3174 if (subOp ==
"call_global_ctors")
3177 if (subOp ==
"call_global_dtors")
3214 if (mi->getNumOperands() != 5) {
3216 "ERROR: wrong number of operands in \".read_sp\"");
3222 TCEString sp = (boost::format(
"%s.%d") %
3236 const MachineOperand& dest = mi->getOperand(3);
3251 if (mi->getNumOperands() != 5) {
3253 "ERROR: wrong number of operands in \".return_to\"");
3262 const MachineOperand& src = mi->getOperand(3);
3282 if (mi->getNumOperands() != 5) {
3284 <<
"got " << mi->getNumOperands() <<
" operands" << std::endl;
3286 "ERROR: wrong number of operands in \".write_sp\"");
3294 TCEString sp = (boost::format(
"%s.%d") %
3308 const MachineOperand& src = mi->getOperand(3);
3325 if (mi->getNumOperands() != 6) {
3327 <<
"got " << mi->getNumOperands() <<
" operands" << std::endl;
3329 "ERROR: wrong number of operands in \".pointer_category\"");
3382 if (mi->getNumOperands() != 7) {
3383 std::cerr <<
"ERROR: wrong number of operands in "".setjmp"""
3387 const MachineOperand& val = mi->getOperand(3);
3388 const MachineOperand& env = mi->getOperand(5);
3392 TCEString sp = (boost::format(
"%s.%d") %
3427 codeGenerator.
pushToStack(*proc, sp, immTerminal);
3433 int buffer_words = 0;
3435 for (
int i = 0; i < nav.
count(); i++) {
3439 (boost::format(
"%s.%d") % rf.
name() % j).str();
3454 *returnInstruction);
3460 proc->
add(returnInstruction);
3463 for (
int i = 0; i < buffer_words; i++)
3492 bool constructors) {
3494 std::string globalName =
3496 (
"llvm.global_ctors") : (
"llvm.global_dtors");
3502 for (Module::const_global_iterator i =
mod_->global_begin();
3503 i !=
mod_->global_end(); i++) {
3505 const GlobalVariable* gv = &(*i);
3506 if (gv->getName() == globalName && gv->use_empty()) {
3511 auto init = gv->getInitializer();
3512 if (!isa<ConstantArray>(init)) {
3515 const ConstantArray* initList = cast<const ConstantArray>(init);
3516 for (
unsigned i = 0, e = initList->getNumOperands(); i != e; ++i) {
3517 if (ConstantStruct* cs =
3518 dyn_cast<ConstantStruct>(initList->getOperand(i))) {
3522 if (cs->getNumOperands() != 3) {
3523 return firstInstruction;
3527 if (cs->getOperand(1)->isNullValue()) {
3528 return firstInstruction;
3532 GlobalValue* gv = dyn_cast<GlobalValue>(
3534 assert(gv != NULL&&
"global constructor name not constv");
3536 SmallString<256> Buffer;
3537 mang_->getNameWithPrefix(Buffer, gv,
false);
3550 std::make_shared<TTAProgram::Move>(
3567 proc->
add(newInstr);
3569 if (firstInstruction == NULL)
3573 return firstInstruction;
3591 if (mi->getNumOperands() != 7) {
3592 std::cerr <<
"ERROR: wrong number of operands in "".longjmp"""
3596 const MachineOperand& env = mi->getOperand(3);
3597 const MachineOperand& val = mi->getOperand(5);
3602 TCEString sp = (boost::format(
"%s.%d") %
3634 for (
int i = 0; i < nav.
count(); i++) {
3638 (boost::format(
"%s.%d") % rf.
name() % j).str();
3677std::shared_ptr<TTAProgram::Move>
3684 std::shared_ptr<TTAProgram::Move> move =
nullptr;
3686 bool endRef =
false;
3696 if (guard == NULL) {
3697 move = std::make_shared<TTAProgram::Move>(src, dst, bus);
3699 move = std::make_shared<TTAProgram::Move>(src, dst, bus, guard);
3728 if (guardReg == NULL) {
3732 bool hasPortGuard =
false;
3734 for (
int i = 0; i < busNav.
count(); i++) {
3736 for (
int i = 0; i < bus->
guardCount(); i++) {
3739 if (regGuard != NULL &&
3747 if (portGuard !=
nullptr &&
3749 hasPortGuard =
true;
3756 guardReg->
index(),
nullptr);
3760 std::cerr <<
"Warning: Could not find suitable guard from any bus in the "
3761 <<
"processor. Did you forget to add guards to the processor?"
3776 for (
int i = 0; i < asNav.
count(); i++) {
3782 <<
"Address space with numerical id " <<
id <<
" not found."
3843 move.
source()).hwOperation()->name();
3845 bool foundLSU =
false;
3848 for (
int i = 0; i < fuNav.
count(); i++) {
3855 ANN_ALLOWED_UNIT_DST, fu.
name());
3884#ifdef WARN_AS_FU_NOT_FOUND
3887 <<
"WARNING: no candidate FU found for "
3888 << move.
toString() <<
" with address space id "
3889 << asNum <<
" not adding any AS info."
3896 abortWithError((boost::format(
"ERROR: No candidate FU found for %s"
3897 " address space id %u") % move.
toString() % asNum).str());
#define abortWithError(message)
#define PRINT_VAR(VARIABLE__)
#define assert(condition)
#define IGNORE_COMPILER_WARNING(X)
#define POP_COMPILER_DIAGS
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
std::string getSourceLocationString(const llvm::MachineInstr &mi)
AsmOperandMap getInlineAsmOperands(const llvm::MachineInstr &mi)
POP_COMPILER_DIAGS std::tuple< std::string, size_t > getSourceLocationInfo(const llvm::MachineInstr &mi)
std::shared_ptr< ProgramOperation > ProgramOperationPtr
SimValue dummy(32)
a dummy simvalue which is given for operands that are not bound
static CmdLineOptions * cmdLineOptions()
static int verboseLevel()
static std::ostream & logStream()
const std::set< CompilerMessage > & warnings() const
static std::string toString(const T &source)
static bool isInlineAsm(const llvm::MachineInstr &mi)
const AssemblyParserDiagnostic & diagnostics() const
bool parse(const llvm::MachineInstr &inlineAsmMI, const std::map< std::string, unsigned > &symbolTable, TTAProgram::BasicBlock &bb, TTAProgram::InstructionReferenceManager &irm)
bool printInlineAsmWarnings() const
uint64_t dataStartAddress(TTAMachine::AddressSpace &aSpace) const
bool isDataStartAddressSet(TTAMachine::AddressSpace &aSpace) const
static int maxMemoryAlignment(const TTAMachine::Machine &mach)
static bool canEncodeImmediateInteger(const TTAMachine::Machine &mach, int64_t imm, unsigned destWidth=UINT_MAX)
virtual bool isAddress() const
virtual bool isInput() const
virtual bool isOutput() const
virtual bool isNull() const
Operation & operation(const char *name)
virtual TCEString name() const
virtual bool isBaseOffsetMemOperation() const
virtual int numberOfInputs() const
virtual int numberOfOutputs() const
virtual Operand & operand(int id) const
static std::string disassemble(const TTAProgram::Move &move)
bool markersFound() const
unsigned pregion(const llvm::MachineInstr &I) const
bool startsWith(const std::string &str) const
static const size_t MAX_ANNOTATION_BYTES
Maximum number of bytes that annotation may contain.
virtual bool hasNumericalId(unsigned id) const
virtual ULongWord end() const
virtual ULongWord start() const
virtual int numberOfRegisters() const
virtual RFPort * port(const std::string &name) const
Guard * guard(int index) const
virtual TCEString name() const
OperandSet writtenOperands(int cycle) const
OperandSet readOperands(int cycle) const
std::set< int > OperandSet
Set for operand indexes.
virtual AddressSpace * addressSpace() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual bool hasOperation(const std::string &name) const
virtual bool hasAddressSpace() const
virtual bool isInverted() const
ExecutionPipeline * pipeline() const
const std::string & name() const
ComponentType * item(int index) const
bool hasItem(const std::string &name) const
virtual RegisterFileNavigator registerFileNavigator() const
virtual FunctionUnitNavigator functionUnitNavigator() const
bool isLittleEndian() const
bool hasOperation(const TCEString &opName) const
virtual BusNavigator busNavigator() const
virtual AddressSpaceNavigator addressSpaceNavigator() const
virtual ControlUnit * controlUnit() const
static NullInstructionTemplate & instance()
virtual bool isOutput() const
virtual int width() const =0
int registerIndex() const
const RegisterFile * registerFile() const
virtual int portCount() const
int annotationCount(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
void setAnnotation(const ProgramAnnotation &annotation)
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
void addAnnotation(const ProgramAnnotation &annotation)
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
TTAProgram::TerminalFUPort * createTerminalFUPort(const TCEString &opName, int operand)
TTAProgram::Terminal * createTerminalRegister(const TTAMachine::RegisterFile &rf, int regNum, bool readPort) const
void pushToStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::Terminal *srcTerminal)
TTAProgram::Instruction * addMoveToProcedure(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal)
void decrementStackPointer(TTAProgram::CodeSnippet &dstProcedure, const TCEString &spReg)
void pushRegisterToStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, const TCEString &srcReg)
void registerJump(TTAProgram::CodeSnippet &dstProcedure, const TCEString &jumpAddrReg)
void loadFromRegisterAddress(TTAProgram::CodeSnippet &dstProcedure, const TCEString &srcReg, const TCEString &dstReg)
void incrementStackPointer(TTAProgram::CodeSnippet &dstProcedure, const TCEString &spReg)
void storeToAddress(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *dstTerminal, const TCEString &srcReg)
void popFromStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::Terminal *dstTerminal)
void loadTerminal(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal)
void pushInstructionReferenceToStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::InstructionReference &srcAddr)
void popRegisterFromStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, const TCEString &dstReg)
virtual Instruction & nextInstruction(const Instruction &ins) const
virtual Instruction & firstInstruction() const
virtual void append(const CodeSnippet &cs)
virtual void add(Instruction *ins)
virtual int instructionCount() const
virtual Address startAddress() const
virtual void insertBefore(const Instruction &pos, Instruction *ins)
virtual Instruction & lastInstruction() const
virtual Instruction & instructionAtIndex(int index) const
virtual Address destinationAddress() const
void addDataDefinition(DataDefinition *dataDef)
DataDefinition & dataDefinition(Address address) const
void replace(Instruction &insA, Instruction &insB)
bool hasReference(Instruction &ins) const
InstructionReference createReference(Instruction &ins)
std::string toString() const
std::shared_ptr< Move > movePtr(int i) const
void addMove(std::shared_ptr< Move > move)
CodeSnippet & parent() const
std::string toString() const
Terminal & source() const
Terminal & destination() const
void add(Instruction *ins)
const std::vector< Byte > & payload() const
ProgramAnnotation::Id id() const
@ ANN_POINTER_NAME
information retrieved (from LLVM) about a pointer access
@ ANN_ALLOWED_UNIT_DST
Dst. unit candidate.
@ ANN_CONN_CANDIDATE_UNIT_DST
Dst. unit candidate.
@ ANN_CONN_CANDIDATE_UNIT_SRC
Src. unit candidate.
@ ANN_PARALLEL_REGION_ID
The ID from the _TCEPREGION_START(N) markers.
@ ANN_ALLOWED_UNIT_SRC
Candidate units can be passed for resource manager for choosing the source/destination unit of the mo...
@ ANN_STACKUSE_SPILL
spilled variable
@ ANN_DEBUG_SOURCE_CODE_LINE
The line number in the source code file the annotated move originates from.
@ ANN_STACKUSE_FP_SAVE
frame ptr save/load
@ ANN_STACKUSE_RA_SAVE
ra, new frontend
@ ANN_CONSTANT_MEM
Constant memory access.
GlobalScope & globalScope()
Procedure & procedure(int index) const
Instruction & firstInstruction() const
DataMemory & dataMemory(int index) const
void removeProcedure(Procedure &proc)
void addDataMemory(DataMemory *dataMem)
void addProcedure(Procedure *proc)
InstructionReferenceManager & instructionReferenceManager() const
int dataMemoryCount() const
virtual void addDataLabel(const DataLabel *dataLabel)
virtual void addCodeLabel(const CodeLabel *codeLabel)
void setProgramOperation(ProgramOperationPtr po)
bool isProgramOperationKnown() const
virtual int index() const
virtual const TTAMachine::RegisterFile & registerFile() const
virtual bool isRA() const
virtual Operation & hintOperation() const
virtual int index() const
virtual bool equals(const Terminal &other) const =0
virtual void setInstructionReference(InstructionReference ref)
virtual bool isGPR() const
virtual int operationIndex() const
virtual const TTAMachine::Port & port() const
virtual const TTAMachine::RegisterFile & registerFile() const
virtual bool isFUPort() const
virtual TTAMachine::HWOperation * operation(const std::string &name) const
virtual bool hasOperation(const std::string &name) const
static UniversalMachine & instance()
UniversalFunctionUnit & universalFunctionUnit() const
UnboundedRegisterFile & integerRegisterFile() const
TTAMachine::Bus & universalBus() const
MachineFrameInfo * curFrameInfo_
static unsigned POINTER_SIZE_64
std::map< TTAMachine::AddressSpace *, unsigned > dataEnds_
The first position after the last data in the given address space.
bool hasAmbiguousASpaceRefs(const TTAProgram::Instruction &instr) const
unsigned createDataDefinition(int addressSpaceId, unsigned &addr, const Constant *cv, bool forceInitialize=false, unsigned forceAlignment=0)
std::set< std::string > opset_
The operations supported by the current target machine.
virtual TTAProgram::Terminal * createMBBReference(const MachineOperand &mo)
void copyFUAnnotations(const std::vector< TTAProgram::Instruction * > &operandMoves, TTAProgram::Move &move) const
TTAProgram::Program * result()
TTAProgram::Instruction * emitSelect(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
unsigned initialStackPointerValue_
std::vector< DataDef > data_
Data definitions.
TTAMachine::Machine * mach_
Machine for building the program.
TTAProgram::Instruction * emitSpecialInlineAsm(const std::string op, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
static unsigned MAU_BITS
Target architechture MAU size in bits.
TTAProgram::DataMemory & dataMemoryForAddressSpace(TTAMachine::AddressSpace &aSpace)
TTAMachine::AddressSpace & addressSpaceById(unsigned id)
TTAProgram::TerminalRegister * createTerminalRegister(const std::string &rfName, int index)
virtual unsigned raPortDRegNum() const =0
std::map< TCEString, ProgramOperationPtr > labeledPOs_
std::vector< DataDef > udata_
std::set< TTAProgram::TerminalProgramOperation * > symbolicPORefs_
TTAProgram::Instruction * emitComparisonForBranch(TCEString firstOp, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
void createExprDataDefinition(int addressSpaceId, unsigned &addr, const ConstantExpr *gv, int offset=0)
TTAMachine::AddressSpace * defaultDataAddressSpace_
The default data memory address space (address space 0).
unsigned & dataEnd(TTAMachine::AddressSpace &aSpace)
unsigned addressSpaceId(TTAMachine::AddressSpace &aSpace) const
TTAProgram::Instruction * emitOperationMacro(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
std::shared_ptr< TTAProgram::Move > createMove(const MachineOperand &src, const MachineOperand &dst, TTAProgram::MoveGuard *guard)
TTAProgram::Instruction * handleMemoryCategoryInfo(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
static unsigned POINTER_SIZE_32
Target architecture pointer size in maus.
TTAProgram::Instruction * emitReturnTo(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
const llvm::TargetMachine * tm_
Target machine description.
TTAProgram::Instruction * emitRemaingingBrach(TCEString opName, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAProgram::Terminal * createTerminal(const MachineOperand &mo, int bitLimit=0)
LLVMTCECmdLineOptions * options_
The compiler options.
void createFPDataDefinition(int addressSpaceId, unsigned &addr, const llvm::ConstantFP *cfp)
void createSPInitLoad(TTAProgram::CodeSnippet &target, TTAProgram::Terminal &src, TTAProgram::Terminal &dst)
TTAProgram::Instruction * emitSetjmp(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
virtual unsigned spDRegNum() const =0
std::string mbbName(const MachineBasicBlock &mbb)
TTAProgram::Instruction * emitGlobalXXtructorCalls(const MachineInstr *mi, TTAProgram::CodeSnippet *proc, bool constructors)
void addCandidateLSUAnnotations(unsigned asNum, TTAProgram::Move &move)
std::map< const llvm::BasicBlock *, TTAProgram::Instruction * > bbIndex_
Basic Block -> first instruction in the BB map.
static bool isInlineAsm(const MachineInstr &instr)
llvm::Mangler * mang_
Mangler for mangling label strings.
std::map< std::string, unsigned > dataLabels_
Data labels.
std::map< const llvm::Constant *, unsigned > globalCP_
Global constant pool for all constants gathered from machine functions. Map key is unique constant an...
TTAProgram::Instruction * emitWriteSP(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
std::vector< std::shared_ptr< TTAProgram::Move > > endReferences_
Dummy references to the _end symbol.
TTAProgram::Instruction * emitLongjmp(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
std::map< std::string, TTAProgram::Instruction * > mbbs_
Machine basic block -> first instruction in the BB map.
virtual ~LLVMTCEBuilder()
void createGlobalValueDataDefinition(int addressSpaceId, unsigned &addr, const GlobalValue *gv, int offset=0)
std::map< TTAProgram::TerminalInstructionAddress *, std::string > codeLabelReferences_
Dummy code label references that have to be fixed after all instrutions have been built.
virtual void emitSPInitialization()
void deleteDeadProcedures()
void debugDataToAnnotations(const llvm::MachineInstr *mi, TTAProgram::Move &move)
TTAProgram::Program * prog_
Current program being built.
void fixProgramOperationReferences()
void emitDataDef(const DataDef &def)
TTAProgram::MoveGuard * createGuard(const TTAProgram::Terminal *guardReg, bool trueOrFalse)
std::vector< ConstantDataDef > cpData_
void emitConstantPool(const llvm::MachineConstantPool &cp)
const TTAMachine::HWOperation & getHWOperation(std::string opName)
bool multiDataMemMachine_
Set to true in case this machine has more than one data address spaces.
TTAProgram::Instruction * emitInstruction(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
bool isInitialized(const Constant *cv)
bool noAliasFound_
set to true in case at least one 'noalias' attribute (from the use of 'restricted' pointers) has been...
PRegionMarkerAnalyzer * pregions_
std::map< unsigned, unsigned > currentFnCP_
Constant pool for the current machine function. Map key is constant pool index and the value is addre...
const TargetMachine & targetMachine() const
std::map< TTAProgram::TerminalInstructionAddress *, std::string > mbbReferences_
Dummy basic block references that have to be fixed after all basic blocks have been built.
virtual TTAProgram::Terminal * createFUTerminal(const MachineOperand &) const
virtual TCEString operationName(const MachineInstr &mi) const =0
void setInitialStackPointerValue(unsigned value)
void createIntDataDefinition(int addressSpaceId, unsigned &addr, const llvm::ConstantInt *ci, bool isPointer=false)
void addPointerAnnotations(const llvm::MachineInstr *mi, TTAProgram::Move &move)
std::map< std::string, TTAProgram::Instruction * > codeLabels_
Code labels.
bool doFinalization(Module &M)
const llvm::DataLayout * dl_
The data layout for the machine.
TTAProgram::Instruction * emitInlineAsm(const MachineFunction &mf, const MachineInstr *mi, TTAProgram::BasicBlock *bb, TTAProgram::InstructionReferenceManager &irm)
virtual int registerIndex(unsigned llvmRegNum) const =0
virtual TTAProgram::Terminal * createSymbolReference(const MachineOperand &mo)
bool multiAddrSpacesFound_
set to true in case at least one non-default address space memory access has been found in the genera...
virtual TCEString registerFileName(unsigned llvmRegNum) const =0
TTAProgram::Instruction * emitReadSP(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
virtual TTAProgram::Terminal * createProgramOperationReference(const MachineOperand &mo)
bool runOnMachineFunction(MachineFunction &MF)
virtual TTAProgram::Instruction * emitMove(const MachineInstr *mi, TTAProgram::CodeSnippet *proc, bool conditional=false, bool trueGuard=true)
virtual bool isTTATarget() const
virtual bool writeMachineFunction(MachineFunction &MF)
TTAProgram::Instruction * emitReturn(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAMachine::AddressSpace * instrAddressSpace_
virtual void createMoveNode(ProgramOperationPtr &, std::shared_ptr< TTAProgram::Move > m, bool)
bool doInitialization(Module &M)
void padToAlignment(int addressSpaceId, unsigned &addr, unsigned align)
unsigned spDRegNum() const
std::string registerName(unsigned dwarfRegNum) const
std::string rfName(unsigned dwarfRegNum) const
unsigned registerIndex(unsigned dwarfRegNum) const
unsigned stackAlignment() const
Data definition structure for constant pool values.
const llvm::Constant * value
Data definition structure for global values.
UnusedFunctionsList removeableFunctions