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"
141 using namespace llvm;
144 unsigned LLVMTCEBuilder::MAU_BITS = 8;
146 unsigned LLVMTCEBuilder::POINTER_SIZE_32 = 4;
147 unsigned LLVMTCEBuilder::POINTER_SIZE_64 = 8;
149 char LLVMTCEBuilder::ID = 0;
154 LLVMTCEBuilder::LLVMTCEBuilder(
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 def.
alignment = std::max(gvAlign.hasValue()? gvAlign->value():0, (
long unsigned int)(
dl_->getPrefTypeAlignment(type)));
339 def.
size =
dl_->getTypeStoreSize(type);
349 data_.push_back(def);
357 for (
unsigned i = 0; i <
data_.size(); i++) {
362 unsigned& dataEndPos =
dataEnd(aSpace);
367 while ((dataEndPos + pad) %
data_[i].alignment != 0) pad++;
377 data_[i].address = dataEndPos;
386 dataEndPos +=
data_[i].size;
390 for (
unsigned i = 0; i <
udata_.size(); i++) {
395 unsigned& dataEndPos =
dataEnd(aSpace);
400 while ((dataEndPos + pad) %
udata_[i].alignment != 0) pad++;
410 udata_[i].address = dataEndPos;
419 dataEndPos +=
udata_[i].size;
452 std::cerr << def.
name <<
" misaligned!" << std::endl;
453 std::cerr <<
" address: " << def.
address
454 <<
" alignment: " << def.
alignment << std::endl;
467 const GlobalVariable* var = NULL;
468 for (Module::const_global_iterator i =
mod_->global_begin();
469 i !=
mod_->global_end(); i++) {
471 SmallString<256> Buffer;
472 mang_->getNameWithPrefix(Buffer, &(*i),
false);
473 if (def.
name == Buffer.c_str()) {
481 assert(var != NULL &&
"Variable not found!");
484 unsigned paddedAddr =
501 unsigned address = def.
address;
520 int addressSpaceId,
unsigned& addr,
const Constant* cv,
521 bool forceInitialize,
unsigned forceAlignment) {
523 unsigned sz =
dl_->getTypeStoreSize(cv->getType());
524 unsigned align = (forceAlignment == 0)?
525 dl_->getABITypeAlignment(cv->getType()):forceAlignment;
532 align = (forceAlignment == 0)?sz:forceAlignment;
543 unsigned paddedAddr = addr;
547 if (!forceInitialize &&
548 (cv->isNullValue() || dyn_cast<UndefValue>(cv) != NULL)) {
557 if (isa<ConstantArray>(cv) ||
558 isa<ConstantStruct>(cv) ||
559 isa<ConstantVector>(cv)) {
561 for (
unsigned i = 0, e = cv->getNumOperands(); i != e; ++i) {
565 }
else if (
const ConstantInt* ci = dyn_cast<ConstantInt>(cv)) {
567 }
else if (
const ConstantFP* cfp = dyn_cast<ConstantFP>(cv)) {
569 }
else if (
const GlobalValue* gv = dyn_cast<GlobalValue>(cv)) {
571 }
else if (
const ConstantExpr* ce = dyn_cast<ConstantExpr>(cv)) {
573 }
else if (
const ConstantDataArray* cda = dyn_cast<ConstantDataArray>(cv)){
574 if (cda->isNullValue()) {
588 bool allZeros =
true;
589 for (
unsigned i = 0, e = cda->getNumElements(); i != e; ++i) {
590 llvm::Constant *ace =
591 cast<Constant>(cda->getElementAsConstant(i));
592 if (ace->isNullValue() || isa<UndefValue>(ace))
598 for (
unsigned int i = 0; i < cda->getNumElements(); i++) {
604 }
else if (
const ConstantDataSequential* cds =
605 dyn_cast<ConstantDataSequential>(cv)) {
609 unsigned alignmentOverride = 0;
610 if (cv->getType()->isVectorTy()) {
611 alignmentOverride = sz/cds->getNumElements();
613 for (
unsigned int i = 0; i < cds->getNumElements(); i++) {
616 forceInitialize, alignmentOverride);
635 int addressSpaceId,
unsigned& addr,
const ConstantInt* ci,
638 assert(addr % (
dl_->getABITypeAlignment(ci->getType())) == 0 &&
639 "Invalid alignment for constant int!");
641 std::vector<MinimumAddressableUnit> maus;
649 if (!(sz == 1 || sz == 2 || sz == 4 || sz == 8)) {
666 u.d = ci->getZExtValue();
671 for (
unsigned i = 0; i < sz; i++) {
672 maus.push_back(u.bytes[sz - i - 1]);
675 for (
unsigned i = 0; i < sz; i++) {
676 maus.push_back(u.bytes[i]);
691 int addressSpaceId,
unsigned& addr,
const ConstantFP* cfp) {
693 assert(addr % (
dl_->getABITypeAlignment(cfp->getType())) == 0
694 &&
"Invalid alignment for constant fp!");
701 std::vector<MinimumAddressableUnit> maus;
704 unsigned sz =
dl_->getTypeStoreSize(type);
708 if (type->getTypeID() == Type::DoubleTyID) {
710 double val = cfp->getValueAPF().convertToDouble();
719 for (
unsigned i = 0; i < sz; i++) {
720 maus.push_back(u.bytes[sz - i - 1]);
723 for (
unsigned i = 0; i < sz; i++) {
724 maus.push_back(u.bytes[i]);
729 }
else if (type->getTypeID() == Type::FloatTyID) {
731 float val = cfp->getValueAPF().convertToFloat();
740 for (
unsigned i = 0; i < sz; i++) {
741 maus.push_back(u.bytes[sz - i - 1]);
744 for (
unsigned i = 0; i < sz; i++) {
745 maus.push_back(u.bytes[i]);
750 }
else if (type->getTypeID() == Type::HalfTyID) {
751 APInt bits = cfp->getValueAPF().bitcastToAPInt();
752 uint64_t bigval = bits.getLimitedValue(0xFFFF);
760 for (
unsigned i = 0; i < sz; i++) {
761 maus.push_back(u.bytes[sz - i - 1]);
764 for (
unsigned i = 0; i < sz; i++) {
765 maus.push_back(u.bytes[i]);
771 assert(
false &&
"Unknown floating point typeID!");
786 int addressSpaceId,
unsigned& addr,
const GlobalValue* gv,
int offset) {
790 unsigned sz =
dl_->getTypeStoreSize(type);
792 SmallString<256> Buffer;
793 mang_->getNameWithPrefix(Buffer, gv,
false);
806 "Instruction reference with an offset not supported yet.");
815 unsigned gvAS = type->getAddressSpace();
822 assert(
false &&
"Global value label not found!");
837 int addressSpaceId,
unsigned& addr,
const ConstantExpr* ce,
int offset) {
839 assert(addr % (
dl_->getABITypeAlignment(ce->getType())) == 0 &&
840 "Invalid alignment for constant expr!");
842 unsigned opcode = ce->getOpcode();
843 if (opcode == Instruction::GetElementPtr) {
844 const Constant* ptr = ce->getOperand(0);
845 SmallVector<Value*, 8> idxVec(ce->op_begin() + 1, ce->op_end());
847 APInt offsetAI(
dl_->getPointerTypeSizeInBits(ce->getType()), 0);
848 bool success = cast<GEPOperator>(ce)->accumulateConstantOffset(
851 int64_t ptrOffset = offset + offsetAI.getSExtValue();
853 if (
const GlobalValue* gv = dyn_cast<GlobalValue>(ptr)) {
856 }
else if (
const ConstantExpr* ce =
857 dyn_cast<ConstantExpr>(ptr)) {
861 assert(
false &&
"Unsuported getElementPtr target!");
863 }
else if (opcode == Instruction::BitCast) {
864 const Constant* ptr = ce->getOperand(0);
865 if (
const ConstantExpr* ce = dyn_cast<ConstantExpr>(ptr)) {
868 }
else if (
const GlobalValue* gv = dyn_cast<GlobalValue>(ptr)) {
883 }
else if (opcode == Instruction::IntToPtr) {
885 const ConstantInt* ci = dyn_cast<ConstantInt>(ce->getOperand(0));
888 }
else if (opcode == Instruction::PtrToInt) {
896 }
else if (opcode == Instruction::Add) {
897 assert(
false &&
"NOT IMPLEMENTED");
898 }
else if (opcode == Instruction::Sub) {
899 assert(
false &&
"NOT IMPLEMENTED");
901 assert(
false &&
"NOT IMPLEMENTED");
918 int addressSpaceId,
unsigned& addr,
unsigned align) {
924 while ((addr + pad) % align != 0) pad++;
928 std::vector<MinimumAddressableUnit> zeros(pad, 0);
975 if (mf.begin() == mf.end())
return true;
979 SmallString<256> Buffer;
980 mang_->getNameWithPrefix(Buffer, &mf.getFunction(),
false);
990 std::set<std::string> emptyMBBs;
992 bool firstInsOfProc =
true;
995 for (MachineFunction::const_iterator i = mf.begin();
996 i != mf.end(); i++) {
1001 for (MachineBasicBlock::const_iterator j = i->begin();
1002 j != i->end(); j++) {
1005 #ifdef DEBUG_LLVMTCEBUILDER
1006 std::cerr <<
"### converting: ";
1007 std::cerr << std::endl;
1012 if (instr == NULL)
continue;
1016 <<
"ERROR: The machine contains multiple data address spaces "
1017 <<
"and ambigious memory accessing moves '"
1018 << instr->
toString() <<
"' were found." << std::endl;
1025 while (!emptyMBBs.empty()) {
1026 mbbs_[*emptyMBBs.begin()] = instr;
1027 emptyMBBs.erase(emptyMBBs.begin());
1030 std::string mbb =
mbbName(*i);
1037 bbIndex_[(*i).getBasicBlock()] = instr;
1041 if (firstInsOfProc) {
1043 instructionReferenceManager().createReference(*instr);
1048 firstInsOfProc =
false;
1057 emptyMBBs.insert(
mbbName(*i));
1063 if (firstInsOfProc) {
1065 proc->
add(dummyIns);
1068 instructionReferenceManager().createReference(*dummyIns);
1076 <<
"spill moves in " <<
1077 (std::string)(mf.getFunction().getName()) <<
": "
1095 unsigned& dataEndPos =
dataEnd(aSpace);
1111 for (
unsigned i = 0; i <
data_.size(); i++) {
1114 for (
unsigned i = 0; i <
udata_.size(); i++) {
1117 for (
auto cpDataDef :
cpData_) {
1132 endLoc = dataEndPos;
1139 for (DataMemIndex::const_iterator i =
dmemIndex_.begin();
1146 std::string>::iterator mbbRefIter =
1152 std::string mbb = mbbRefIter->second;
1154 assert(
false &&
"MBB not found from book keeping.");
1164 std::string>::iterator codeRefIter =
1169 std::string label = codeRefIter->second;
1171 std::cerr << (boost::format(
1172 "Function '%s' not defined.\n") %
1187 #ifdef DISASSEMBLE_LLVM_OUTPUT
1188 std::ofstream outfile(
"llvm_output.S");
1199 MachineDCE& MDCE = getAnalysis<MachineDCE>();
1201 for (MachineDCE::UnusedFunctionsList::iterator i =
1204 std::string name = *i;
1207 <<
"Deleting unused function: " << name << std::endl;
1213 for (
int dataDefIdx = 0; dataDefIdx < dmem.dataDefinitionCount();
1216 if (dataDef.isInstructionAddress()) {
1223 <<
"Deleting data definition pointing to "
1224 <<
"dead function: " << name << std::endl;
1226 dmem.deleteDataDefinition(dataDefIdx);
1232 delete ¬UsedProc;
1271 hwOperation()->name();
1272 int numberOfPotentialFUs = 0;
1275 for (
int i = 0; i < fuNav.
count(); i++) {
1280 if (numberOfPotentialFUs > 1) {
1294 hasOperation(opName)) {
1298 TCEString(
"ERROR: Operation '") + opName +
1299 "' not found in the machine.");
1304 std::cerr <<
"ERROR: Operation '" << opName
1305 <<
"' is required by the program but not found "
1306 <<
"in the machine." << std::endl;
1325 bool isSpill =
false;
1326 bool isRaSlot =
false;
1327 bool isFpSlot =
false;
1328 const llvm::MCInstrDesc* opDesc = &mi->getDesc();
1329 unsigned opc = mi->getDesc().getOpcode();
1335 if (opc == TargetOpcode::DBG_VALUE
1336 || opc == TargetOpcode::DBG_LABEL
1337 || opc == TargetOpcode::DBG_INSTR_REF
1338 || opc == TargetOpcode::DBG_VALUE_LIST
1339 || opc == TargetOpcode::DBG_PHI
1340 || opc == TargetOpcode::KILL) {
1344 std::string opName =
"";
1346 bool hasGuard =
false;
1347 bool trueGuard =
true;
1350 if (opDesc->isReturn()) {
1363 if (opName ==
"PSEUDO" || opName ==
"DEBUG_LABEL") {
1370 if (opName ==
"DEBUG_LABEL") {
1374 if (opName[0] ==
'?') {
1376 opName = opName.substr(1);
1379 if (opName[0] ==
'!') {
1382 opName = opName.substr(1);
1385 if (opName ==
"MOVE") {
1386 return emitMove(mi, proc, hasGuard, trueGuard);
1390 if (opName ==
"INLINEASM") {
1394 if (opName ==
"CMOV_SELECT") {
1402 size_t split = opName.find(
"+");
1403 if (split != std::string::npos) {
1404 TCEString firstOp = opName.substr(0, split);
1405 TCEString remainingName = opName.substr(split+1);
1418 std::vector<TTAProgram::Instruction*> operandMoves;
1419 std::vector<TTAProgram::Instruction*> resultMoves;
1421 int inputOperand = 0;
1423 #ifdef DEBUG_LLVMTCEBUILDER
1427 << mi->getNumOperands() << std::endl;
1430 int guardOperandIndex = -1;
1433 for (
unsigned o = 0; o < mi->getNumOperands(); o++) {
1434 const MachineOperand& mo = mi->getOperand(o);
1439 if (mo.isReg() && mo.isUse()) {
1440 guardOperandIndex = o;
1454 for (
unsigned o = 0; o < mi->getNumOperands(); o++) {
1455 if ((
int)o == guardOperandIndex) {
1459 const MachineOperand& mo = mi->getOperand(o);
1467 if (mo.isMetadata()) {
1468 const MDNode* mdNode = mo.getMetadata();
1469 for (
unsigned int i = 0; i < mdNode->getNumOperands(); i++) {
1470 const MDOperand & oper = mdNode->getOperand(i);
1471 if (llvm::MDString* mds = dyn_cast<llvm::MDString>(oper)) {
1473 if (s ==
"AA_CATEGORY_STACK_SLOT") {
1475 }
else if (s ==
"AA_CATEGORY_RA_SAVE_SLOT") {
1477 }
else if (s ==
"AA_CATEGORY_FP_SAVE_SLOT") {
1487 "Operand mismatch.");
1498 const MachineOperand& base = mo;
1502 guard == NULL ? NULL : guard->
copy();
1504 auto move =
createMove(src, dst, bus, guardCopy);
1508 operandMoves.push_back(instr);
1513 const MachineOperand& offset = mi->getOperand(o);
1518 assert(inputOperand == 2);
1524 guard == NULL ? NULL : guard->
copy();
1526 auto move =
createMove(src, dst, bus, guardCopy);
1529 operandMoves.push_back(instr);
1532 assert(offset.getImm() == 0);
1538 guard == NULL ? NULL : guard->
copy();
1540 auto move =
createMove(src, dst, bus, guardCopy);
1543 #ifdef DEBUG_LLVMTCEBUILDER
1545 <<
"adding " << move->toString() << std::endl;
1547 operandMoves.push_back(instr);
1557 "Operand mismatch.");
1563 guard == NULL ? NULL : guard->
copy();
1565 auto move =
createMove(src, dst, bus, guardCopy);
1568 #ifdef DEBUG_LLVMTCEBUILDER
1570 <<
"adding " << move->toString() << std::endl;
1572 resultMoves.push_back(instr);
1577 for (
unsigned int i = 0; i < resultMoves.size();i++) {
1579 for (
int j = 0; j < resultIns.
moveCount(); j++) {
1587 if (!operandMoves.empty()) {
1588 first = operandMoves[0];
1589 }
else if (!resultMoves.empty()) {
1590 first = resultMoves[0];
1591 }
else if (opDesc->isReturn() && mi->getNumOperands() == 0) {
1607 operandMoves.push_back(instr);
1611 assert(
false &&
"No moves?");
1616 std::vector<std::string> candidateFUs;
1617 for (
unsigned i = 0; i < mi->getNumOperands(); ++i) {
1619 const MachineOperand& op = mi->getOperand(i);
1620 if (!op.isMetadata())
continue;
1621 const MDNode* mdNode = op.getMetadata();
1622 if (mdNode->getNumOperands() > 0) {
1624 llvm::Metadata* op = mdNode->getOperand(0);
1625 MDString* str = dyn_cast<llvm::MDString>(op);
1627 if (str->getString().str() ==
"fu_candidates") {
1628 for (
unsigned j = 1; j < mdNode->getNumOperands(); ++j) {
1629 op = mdNode->getOperand(j);
1630 str = dyn_cast<MDString>(op);
1631 TCEString fuName = str->getString().str();
1637 hasOperation(operation.
name())) {
1638 #ifdef DEBUG_LLVMTCEBUILDER
1640 <<
"FU candidate " << str->getString().str() <<
" set for ";
1643 candidateFUs.push_back(str->getString().str());
1650 for (
unsigned i = 0; i < operandMoves.size(); i++) {
1655 for (
unsigned j = 0; j < candidateFUs.size(); ++j) {
1656 if (m->hasAnnotations(
1673 }
else if (isRaSlot) {
1677 }
else if (isFpSlot) {
1686 for (
unsigned i = 0; i < resultMoves.size(); i++) {
1691 for (
unsigned j = 0; j < candidateFUs.size(); ++j) {
1692 if (m->hasAnnotations(
1708 }
else if (isRaSlot) {
1712 }
else if (isFpSlot) {
1722 delete guard; guard = NULL;
1739 for (
int i = 0; i < 2; i++) {
1740 const MachineOperand& mo = mi->getOperand(i);
1768 bool inverted = (opName[0] ==
'!');
1769 opName = opName.substr(1);
1777 const MachineOperand& mo = mi->getOperand(2);
1798 const std::vector<TTAProgram::Instruction*>& operandMoves,
1800 for (
unsigned int i = 0; i < operandMoves.size(); i++) {
1828 if (mi->memoperands_begin() == mi->memoperands_end()) {
1830 <<
" does not have mem operands!"
1837 if (nodeId != UINT_MAX) {
1845 int addrSpaceId = 0;
1848 for (MachineInstr::mmo_iterator i = mi->memoperands_begin();
1849 i != mi->memoperands_end(); i++) {
1851 const PseudoSourceValue* psv = (*i)->getPseudoValue();
1868 const llvm::Value* memOpValue = (*i)->getValue();
1870 if (memOpValue != NULL) {
1871 std::string pointerName =
"";
1875 if (memOpValue->hasName()) {
1876 pointerName = memOpValue->getName().str();
1877 }
else if (isa<GetElementPtrInst>(memOpValue)) {
1879 cast<GetElementPtrInst>(
1880 memOpValue)->getPointerOperand();
1881 if (memOpValue->hasName()) {
1882 pointerName = memOpValue->getName().str();
1889 if (pointerName.length() > 0 &&
1890 isa<Argument>(memOpValue)) {
1892 offset = (*i)->getOffset();
1901 const llvm::Value* originMemOpValue = memOpValue;
1902 while (originMemOpValue != NULL) {
1904 (std::string)originMemOpValue->getName();
1908 if (dyn_cast<Instruction>(originMemOpValue) &&
1909 dyn_cast<Instruction>(originMemOpValue)->getMetadata(
"wi")) {
1911 cast<Instruction>(originMemOpValue)->getMetadata(
"wi");
1912 const MDNode* XYZ = dyn_cast<MDNode>(md->getOperand(2));
1913 assert(XYZ->getNumOperands() == 4);
1914 ConstantInt *CX = dyn_cast<ConstantInt>(
1915 dyn_cast<llvm::ConstantAsMetadata>(XYZ->getOperand(1))->getValue());
1916 ConstantInt *CY = dyn_cast<ConstantInt>(
1917 dyn_cast<llvm::ConstantAsMetadata>(XYZ->getOperand(2))->getValue());
1918 ConstantInt *CZ = dyn_cast<ConstantInt>(
1919 dyn_cast<llvm::ConstantAsMetadata>(XYZ->getOperand(3))->getValue());
1921 int id = (CZ->getZExtValue() & 0x0FF)
1922 | ((CY->getZExtValue() & 0x0FF) << 8)
1923 | ((CX->getZExtValue() & 0x0FF) << 16);
1926 ANN_OPENCL_WORK_ITEM_ID,
id);
1935 if (isa<BitCastInst>(originMemOpValue)) {
1937 dyn_cast<BitCastInst>(originMemOpValue)->getDestTy();
1938 if (type->isPointerTy()) {
1939 #ifdef LLVM_OLDER_THAN_15
1940 llvm::Type* typeElem =
1941 cast<PointerType>(type)->getElementType();
1945 assert((isa<LoadInst>(originMemOpValue)
1946 || isa<StoreInst>(originMemOpValue)) &&
1947 "Expected Load or Store instruction");
1948 llvm::Type* typeElem = NULL;
1949 if (
auto *LI = dyn_cast<LoadInst>(originMemOpValue))
1950 typeElem = LI->getType();
1952 typeElem = cast<StoreInst>(originMemOpValue)
1953 ->getValueOperand()->getType();
1955 if (typeElem->isVectorTy()) {
1956 int numElems = cast<VectorType>(typeElem)
1958 .getKnownMinValue();
1959 int idLast = (CZ->getZExtValue() & 0x0FF)
1960 | ((CY->getZExtValue() & 0x0FF) << 8)
1961 | (((CX->getZExtValue()
1962 + numElems) & 0x0FF) << 16);
1965 ANN_OPENCL_WORK_ITEM_ID_LAST, idLast);
1972 if (isa<Argument>(originMemOpValue) &&
1973 cast<Argument>(originMemOpValue)->hasNoAliasAttr()) {
1976 ANN_POINTER_NOALIAS, 1);
1999 pointerName = originMemOpValue->getName().str();
2001 }
else if (isa<GetElementPtrInst>(originMemOpValue)) {
2003 cast<GetElementPtrInst>(originMemOpValue)->
2004 getPointerOperand();
2005 }
else if (isa<BitCastInst>(originMemOpValue)) {
2007 cast<BitCastInst>(originMemOpValue)->
2009 }
else if (isa<PtrToIntInst>(originMemOpValue)) {
2011 cast<PtrToIntInst>(originMemOpValue)->
2018 if (pointerName !=
"") {
2026 cast<PointerType>(memOpValue->getType())->
2029 if (addrSpaceId != 0) {
2032 std::string addressSpace =
2033 (boost::format(
"%d") % addrSpaceId).str();
2061 if (mi->getFlag(MachineInstr::FrameSetup)) {
2067 DebugLoc dl = mi->getDebugLoc();
2074 if (dl.getLine() == 0xFFFFFFF0) {
2082 bool hasDebugInfo =
false;
2083 hasDebugInfo = dl.getScope() != NULL;
2086 int sourceLineNumber = -1;
2090 sourceLineNumber = dl.getLine();
2093 cast<DIScope>(dl.getScope())->getFilename().str());
2095 if (sourceFileName.size() >
2098 sourceFileName.substr(
2099 sourceFileName.size() -
2108 if (sourceFileName !=
"") {
2111 ANN_DEBUG_SOURCE_CODE_PATH,
2121 const std::string& rfName,
int idx) {
2128 assert(idx >= 0 && idx < rf->size());
2131 const RFPort* port = NULL;
2132 for (
int i = 0; i < rf->
portCount(); i++) {
2150 if (bitLimit == 0) {
2155 unsigned dRegNum = mo.getReg();
2161 returnAddressPort());
2173 }
else if (mo.isFPImm()) {
2174 const APFloat& apf = mo.getFPImm()->getValueAPF();
2175 if (&apf.getSemantics() == &APFloat::IEEEhalf()) {
2176 APInt api = apf.bitcastToAPInt();
2177 uint16_t binary = (uint16_t)api.getRawData()[0];
2182 float fval = apf.convertToFloat();
2187 }
else if (mo.isImm()) {
2188 int width = bitLimit;
2191 }
else if (mo.isMBB() || mo.isBlockAddress()) {
2193 }
else if (mo.isFI()) {
2194 std::cerr <<
" Frame index source operand NOT IMPLEMENTED!"
2197 }
else if (mo.isCPI()) {
2199 int width = bitLimit;
2200 unsigned idx = mo.getIndex();
2212 ref << mo.getIndex() <<
"_" << mo.getOffset();
2215 }
else if (mo.isJTI()) {
2217 ref << mo.getIndex();
2219 }
else if (mo.isGlobal()) {
2221 cast<PointerType>(mo.getGlobal()->getType())->getAddressSpace();
2226 SmallString<256> Buffer;
2227 mang_->getNameWithPrefix(Buffer, mo.getGlobal(),
false);
2240 }
else if (mo.isJTI()) {
2241 std::cerr <<
" Jump table index operand NOT IMPLEMENTED!\n";
2243 }
else if (mo.isSymbol()) {
2245 }
else if (mo.isMCSymbol()) {
2247 }
else if (mo.isMetadata()) {
2248 assert(
"Metadata MachineOperands should not get here" &&
false);
2250 std::cerr <<
"Unknown src operand type!" << std::endl;
2261 const MachineOperand& mo) {
2262 llvm::MCSymbol* symbol = mo.getMCSymbol();
2277 for (std::set<TTAProgram::TerminalProgramOperation*>::const_iterator i =
2282 assert(po.get() != NULL);
2350 const std::vector<MachineConstantPoolEntry>& cp = mcp.getConstants();
2352 const unsigned cpAddrSpaceId = 0;
2355 for (
unsigned i = 0, e = cp.size(); i != e; ++i) {
2357 assert(!(cpe.isMachineConstantPoolEntry()) &&
"NOT SUPPORTED");
2358 if (!
globalCP_.count(cpe.Val.ConstVal)) {
2360 assert(cpe.getAlign().value() > 0);
2361 unsigned alignment = cpe.getAlign().value();
2363 unsigned address = dataEndPos;
2365 unsigned size = cpe.getSizeInBytes(*
dl_);
2367 address, alignment, size, cpe.Val.ConstVal));
2368 globalCP_.insert(std::make_pair(cpe.Val.ConstVal, address));
2388 std::shared_ptr<TTAProgram::Move>
2390 const MachineOperand& src,
const MachineOperand& dst,
2392 assert(!src.isReg() || src.isUse());
2396 if (dst.isReg() && src.isReg() && dst.getReg() == src.getReg()) {
2405 auto move =
createMove(srcTerm, dstTerm, bus, guard);
2420 bool conditional,
bool trueGuard) {
2422 unsigned int operandCount = conditional ? 3 : 2;
2423 if (mi->getNumOperands() > operandCount) {
2424 for (
unsigned int i = operandCount; i < mi->getNumOperands(); i++) {
2426 if (!(mi->getOperand(i).isMetadata()) &&
2427 (!mi->getOperand(i).isImplicit())) {
2431 assert(mi->getOperand(i).isMetadata() ||
2432 mi->getOperand(i).isImplicit());
2436 assert(mi->getNumOperands() >= operandCount);
2438 const MachineOperand& dst = mi->getOperand(0);
2439 const MachineOperand& src = mi->getOperand(operandCount - 1);
2442 const MachineOperand& gmo = mi->getOperand(1);
2443 assert (gmo.isReg() && gmo.isUse());
2477 if (copyOp == NULL || guard != NULL) {
2480 TCEString(
"Unable to create a reg to reg copy due to "
2481 "having only one port in '") +
2498 <<
" having only 1 port" << std::endl;
2509 auto move =
createMove(srcTerm, dstTerm, bus, guard);
2566 const MachineOperand& guardMo = mi->getOperand(1);
2572 assert(guardTerminal != NULL);
2583 if (dstT->
equals(*srcT)) {
2584 if (dstT->
equals(*srcF)) {
2585 std::cerr <<
"Empty select!" << std::endl;
2592 assert(trueGuard != NULL);
2593 auto trueMove =
createMove(srcT, dstT, bus, trueGuard);
2601 if (dstF->
equals(*srcF)) {
2606 assert(falseGuard != NULL);
2607 auto falseMove =
createMove(srcF, dstF, bus, falseGuard);
2610 proc->
add(falseIns);
2611 if (firstIns == NULL) {
2612 firstIns = falseIns;
2617 delete guardTerminal;
2619 assert(firstIns != NULL);
2633 SmallString<256> Buffer;
2634 mang_->getNameWithPrefix(Buffer, &mbb.getParent()->getFunction(),
false);
2650 if ((dyn_cast<ConstantArray>(cv) != NULL) ||
2651 (dyn_cast<ConstantStruct>(cv) != NULL) ||
2652 (dyn_cast<ConstantVector>(cv) != NULL)) {
2654 for (
unsigned i = 0, e = cv->getNumOperands(); i != e; ++i) {
2686 assert(idx >= 0 && idx < rf->size());
2687 const RFPort* port = NULL;
2688 for (
int i = 0; i < rf->
portCount(); i++) {
2703 unsigned mask = 0xffffffff;
2705 while (stackAlignment > 1) {
2707 stackAlignment = stackAlignment >> 1;
2725 spInit->
add(spInitInst);
2742 std::vector<MinimumAddressableUnit> spmaus;
2743 unsigned nMaus =
sizeof(unsigned);
2745 for (
unsigned i = 0; i < nMaus; i++) {
2746 spmaus.push_back(u.bytes[nMaus-i-1]);
2749 for (
unsigned i = 0; i < nMaus; i++) {
2750 spmaus.push_back(u.bytes[i]);
2787 const MachineFunction& mf,
2788 const MachineInstr* mi,
2796 assert(tm &&
"Inline asm parser requires TCETargetMachine.");
2800 for (
auto& opds : asmOpds) {
2801 auto& asmOpdNodes = std::get<1>(opds.second);
2802 for (
auto mo : asmOpdNodes) {
2804 !mf.getRegInfo().isReserved(mo->getReg())) {
2809 <<
"Error: An use of reserved register '"
2811 <<
"' in inline assembly." << std::endl;
2814 "Encountered errors in inline assembly.");
2824 if (!std::get<0>(srcLoc).empty()) {
2825 std::cerr << std::get<0>(srcLoc) <<
":" << std::get<1>(srcLoc)
2826 <<
":" << std::endl;
2828 for (
auto syntaxError : diag.errors()) {
2829 std::cerr <<
"Error in line " << syntaxError.lineNumber <<
": "
2830 << syntaxError.message << std::endl;
2832 for (
auto internalError : diag.otherErrors()) {
2833 std::cerr <<
"Error: " << internalError.message << std::endl;
2836 CompileError,
"Encountered errors in inline assembly parsing.");
2842 std::cerr << warning.toString() << std::endl;
2866 unsigned numOperands =
2868 mi->getNumOperands();
2870 unsigned numDefs = 0;
2871 for (; mi->getOperand(numDefs).isReg() &&
2872 mi->getOperand(numDefs).isDef();
2876 std::string opName = mi->getOperand(numDefs).getSymbolName();
2883 if (opName[0] ==
'.') {
2889 std::vector<std::string> addressedFUs;
2894 if (opName.substr(0,3) ==
"_AS") {
2897 std::string addressedAS;
2898 std::istringstream iss(opName);
2899 std::getline(iss, foo,
'.');
2900 std::getline(iss, addressedAS,
'.');
2901 std::getline(iss, opName,
'.');
2906 if (addressedAS.size() && addressedAS[0] ==
'#') {
2908 if (end == addressedAS.c_str()+1) {
2909 std::cerr <<
"ERROR: Address space id following # not a number '" << addressedAS
2914 for (
int i = 0; i < nav.
count(); i++) {
2924 for (
int i = 0; i < nav.
count(); i++) {
2926 if (as->
name() == addressedAS) {
2933 if (targetAS == NULL) {
2934 std::cerr <<
"ERROR: Address space '" << addressedAS
2942 for (
int j = 0; j < fuNav.
count(); j++) {
2945 addressedFUs.push_back(fu->
name());
2950 std::string addressedFU;
2952 std::istringstream iss(opName);
2953 std::getline(iss, addressedFU,
'.');
2954 std::getline(iss, opName,
'.');
2956 std::cerr <<
"ERROR: Function Unit '" << addressedFU
2961 addressedFUs.push_back(addressedFU);
2965 assert(numDefs != numOperands-1 &&
"No asm string?");
2966 assert(mi->getOperand(numDefs).isSymbol() &&
"No asm string?");
2973 std::cerr <<
"ERROR: Inline assembly not supported!" << std::endl;
2980 <<
"ERROR: Explicitly executed operation '"
2981 << opName <<
"' does not match any operation definition in OSAL."
2989 std::vector<TTAProgram::Instruction*> operandMoves;
2990 std::vector<TTAProgram::Instruction*> resultMoves;
2997 int inputOperand = 0;
2999 const MachineFunction& mf = *mi->getParent()->getParent();
3002 unsigned startOp = InlineAsm::MIOp_FirstOperand;
3003 unsigned asmDescOp = InlineAsm::MIOp_FirstOperand;
3004 unsigned clobberOp = InlineAsm::MIOp_FirstOperand-1;
3005 for (
unsigned o = startOp; o < mi->getNumOperands(); o++) {
3006 const MachineOperand& mo = mi->getOperand(o);
3007 if (mo.isMetadata()) {
3009 }
else if (o == asmDescOp && mo.isImm()) {
3011 unsigned flag = mo.getImm();
3012 if (InlineAsm::getKind(flag) == InlineAsm::Kind_Clobber) {
3016 asmDescOp += 1 + InlineAsm::getNumOperandRegisters(flag);
3018 }
else if (o == clobberOp) {
3019 if (mf.getRegInfo().isReserved(mo.getReg())) {
3020 std::cerr <<
"Warning: inline assembly clobbers"
3021 <<
" reserved register (regNum = " << mo.getReg()
3022 <<
"), which has undefined behavior."
3025 }
else if (!(mo.isReg() || mo.isImm() || mo.isGlobal())) {
3028 std::cerr <<
"Ignoring an operand of " << opName << std::endl;
3034 if (mo.isImm() || mo.isGlobal() || mo.isUse()) {
3036 if (useOps.empty()) {
3038 if (mo.isImplicit()) {
3041 std::cerr << std::endl;
3042 std::cerr <<
"ERROR: Too many input operands for custom "
3043 <<
"operation '" << opName <<
"'." << std::endl;
3048 useOps.erase(useOps.begin());
3051 if (defOps.empty()) {
3053 if (mo.isImplicit()) {
3056 std::cerr << std::endl;
3057 std::cerr <<
"ERROR: Too many output operands for custom "
3058 <<
"operation '" << opName <<
"'." << std::endl;
3062 if (mf.getRegInfo().isReserved(mo.getReg())) {
3063 std::cerr <<
"Warning: inline assembly overwriting"
3064 <<
" reserved register (regNum = " << mo.getReg()
3065 <<
") has undefined behavior."
3071 defOps.erase(defOps.begin());
3079 if (mo.isImm() || mo.isGlobal() || mo.isUse()) {
3080 operandMoves.push_back(instr);
3088 resultMoves.push_back(instr);
3092 if (!defOps.empty() || !useOps.empty()) {
3093 std::cerr <<
"ERROR: All operands not defined for custom operation '"
3094 << opName <<
"'." << std::endl;
3096 std::cerr <<
"Undefined: " << defOps.size() <<
" output operands, "
3097 << useOps.size() <<
" input operands." << std::endl;
3104 if (!operandMoves.empty()) {
3105 first = operandMoves[0];
3106 }
else if (!resultMoves.empty()) {
3107 first = resultMoves[0];
3109 assert(
false &&
"No moves?");
3112 for (
unsigned i = 0; i < operandMoves.size(); i++) {
3113 proc->
add(operandMoves[i]);
3116 operandMoves[i]->move(0).removeAnnotations(
3119 for (
unsigned int j = 0; j < addressedFUs.size(); j++) {
3123 operandMoves[i]->move(0).addAnnotation(dstCandidate);
3128 for (
unsigned i = 0; i < resultMoves.size(); i++) {
3129 proc->
add(resultMoves[i]);
3132 resultMoves[i]->move(0).removeAnnotations(
3135 for (
unsigned int j = 0; j < addressedFUs.size(); j++) {
3139 resultMoves[i]->move(0).addAnnotation(srcCandidate);
3157 const std::string op,
const MachineInstr* mi,
3162 TCEString subOp(std::string(op, 1, op.length() - 1));
3164 if (subOp ==
"setjmp")
3167 if (subOp ==
"longjmp")
3170 if (subOp ==
"call_global_ctors")
3173 if (subOp ==
"call_global_dtors")
3210 if (mi->getNumOperands() != 5) {
3212 "ERROR: wrong number of operands in \".read_sp\"");
3218 TCEString sp = (boost::format(
"%s.%d") %
3232 const MachineOperand& dest = mi->getOperand(3);
3247 if (mi->getNumOperands() != 5) {
3249 "ERROR: wrong number of operands in \".return_to\"");
3258 const MachineOperand& src = mi->getOperand(3);
3278 if (mi->getNumOperands() != 5) {
3280 <<
"got " << mi->getNumOperands() <<
" operands" << std::endl;
3282 "ERROR: wrong number of operands in \".write_sp\"");
3290 TCEString sp = (boost::format(
"%s.%d") %
3304 const MachineOperand& src = mi->getOperand(3);
3321 if (mi->getNumOperands() != 6) {
3323 <<
"got " << mi->getNumOperands() <<
" operands" << std::endl;
3325 "ERROR: wrong number of operands in \".pointer_category\"");
3378 if (mi->getNumOperands() != 7) {
3379 std::cerr <<
"ERROR: wrong number of operands in "".setjmp"""
3383 const MachineOperand& val = mi->getOperand(3);
3384 const MachineOperand& env = mi->getOperand(5);
3388 TCEString sp = (boost::format(
"%s.%d") %
3423 codeGenerator.
pushToStack(*proc, sp, immTerminal);
3429 int buffer_words = 0;
3431 for (
int i = 0; i < nav.
count(); i++) {
3435 (boost::format(
"%s.%d") % rf.
name() % j).str();
3450 *returnInstruction);
3456 proc->
add(returnInstruction);
3459 for (
int i = 0; i < buffer_words; i++)
3488 bool constructors) {
3490 std::string globalName =
3492 (
"llvm.global_ctors") : (
"llvm.global_dtors");
3498 for (Module::const_global_iterator i =
mod_->global_begin();
3499 i !=
mod_->global_end(); i++) {
3501 const GlobalVariable* gv = &(*i);
3502 if (gv->getName() == globalName && gv->use_empty()) {
3507 auto init = gv->getInitializer();
3508 if (!isa<ConstantArray>(init)) {
3511 const ConstantArray* initList = cast<const ConstantArray>(init);
3512 for (
unsigned i = 0, e = initList->getNumOperands(); i != e; ++i) {
3513 if (ConstantStruct* cs =
3514 dyn_cast<ConstantStruct>(initList->getOperand(i))) {
3518 if (cs->getNumOperands() != 3) {
3519 return firstInstruction;
3523 if (cs->getOperand(1)->isNullValue()) {
3524 return firstInstruction;
3528 GlobalValue* gv = dyn_cast<GlobalValue>(
3530 assert(gv != NULL&&
"global constructor name not constv");
3532 SmallString<256> Buffer;
3533 mang_->getNameWithPrefix(Buffer, gv,
false);
3546 std::make_shared<TTAProgram::Move>(
3563 proc->
add(newInstr);
3565 if (firstInstruction == NULL)
3569 return firstInstruction;
3587 if (mi->getNumOperands() != 7) {
3588 std::cerr <<
"ERROR: wrong number of operands in "".longjmp"""
3592 const MachineOperand& env = mi->getOperand(3);
3593 const MachineOperand& val = mi->getOperand(5);
3598 TCEString sp = (boost::format(
"%s.%d") %
3630 for (
int i = 0; i < nav.
count(); i++) {
3634 (boost::format(
"%s.%d") % rf.
name() % j).str();
3673 std::shared_ptr<TTAProgram::Move>
3680 std::shared_ptr<TTAProgram::Move> move =
nullptr;
3682 bool endRef =
false;
3692 if (guard == NULL) {
3693 move = std::make_shared<TTAProgram::Move>(src, dst, bus);
3695 move = std::make_shared<TTAProgram::Move>(src, dst, bus, guard);
3724 if (guardReg == NULL) {
3728 bool hasPortGuard =
false;
3730 for (
int i = 0; i < busNav.
count(); i++) {
3732 for (
int i = 0; i < bus->
guardCount(); i++) {
3735 if (regGuard != NULL &&
3743 if (portGuard !=
nullptr &&
3745 hasPortGuard =
true;
3752 guardReg->
index(),
nullptr);
3756 std::cerr <<
"Warning: Could not find suitable guard from any bus in the "
3757 <<
"processor. Did you forget to add guards to the processor?"
3772 for (
int i = 0; i < asNav.
count(); i++) {
3778 <<
"Address space with numerical id " <<
id <<
" not found."
3839 move.
source()).hwOperation()->name();
3841 bool foundLSU =
false;
3844 for (
int i = 0; i < fuNav.
count(); i++) {
3851 ANN_ALLOWED_UNIT_DST, fu.
name());
3880 #ifdef WARN_AS_FU_NOT_FOUND
3883 <<
"WARNING: no candidate FU found for "
3884 << move.
toString() <<
" with address space id "
3885 << asNum <<
" not adding any AS info."
3892 abortWithError((boost::format(
"ERROR: No candidate FU found for %s"
3893 " address space id %u") % move.
toString() % asNum).str());