OpenASIP  2.0
LLVMTCEBuilder.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2020 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file LLVMTCEBuilder.cc
26  *
27  * Implementation of LLVMTCEBuilder class.
28  *
29  * @author Veli-Pekka Jääskeläinen 2007-2009 (vjaaskel-no.spam-cs.tut.fi)
30  * @author Mikael Lepistö 2009 (mikael.lepisto-no.spam-tut.fi)
31  * @author Esa Määttä 2009 (esa.maatta-no.spam-tut.fi)
32  * @author Pekka Jääskeläinen 2007-2020
33  * @author Henry Linjamäki 2016-2017 (henry.linjamaki-no.spam-tut.fi)
34  * @note reting: red
35  */
36 #ifdef NDEBUG
37 #undef NDEBUG
38 #endif
39 
40 #include <list>
41 #include <fstream>
42 #include <sstream>
43 
44 #include <boost/format.hpp>
45 
46 #include "CompilerWarnings.hh"
47 
48 IGNORE_COMPILER_WARNING("-Wunused-parameter")
49 
50 #include "LLVMTCEBuilder.hh"
51 #include "Program.hh"
52 #include "BasicBlock.hh"
53 #include "Machine.hh"
54 #include "Procedure.hh"
55 #include "Instruction.hh"
56 #include "NullInstruction.hh"
57 #include "DataDefinition.hh"
58 #include "DataAddressDef.hh"
60 #include "InstructionReference.hh"
61 #include "Move.hh"
62 #include "MoveGuard.hh"
63 #include "Guard.hh"
64 #include "Terminal.hh"
67 #include "TerminalAddress.hh"
68 #include "TerminalRegister.hh"
69 #include "TerminalImmediate.hh"
70 #include "TerminalFUPort.hh"
72 #include "ControlUnit.hh"
73 #include "SpecialRegisterPort.hh"
74 #include "UniversalMachine.hh"
75 #include "UniversalFunctionUnit.hh"
76 #include "ExecutionPipeline.hh"
77 #include "POMDisassembler.hh"
78 #include "DataMemory.hh"
79 #include "CodeLabel.hh"
80 #include "DataLabel.hh"
81 #include "LLVMTCEBuilder.hh"
82 #include "Operand.hh"
83 #include "CodeGenerator.hh"
84 #include "ProgramAnnotation.hh"
85 #include "TCEString.hh"
86 #include "ProgramOperation.hh"
87 #include "LLVMTCECmdLineOptions.hh"
88 #include "GlobalScope.hh"
90 #include "HWOperation.hh"
91 #include "AssocTools.hh"
92 #include "PRegionMarkerAnalyzer.hh"
93 #include "Conversion.hh"
94 #include "UnboundedRegisterFile.hh"
95 #include "InstructionElement.hh"
96 #include "MachineInfo.hh"
97 #include "LiveRangeData.hh"
98 #include "LLVMUtilities.hh"
99 
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>
112 
113 #include <llvm/IR/DebugInfo.h>
114 
115 #include <llvm/MC/MCContext.h>
116 #include <llvm/MC/MCSymbol.h>
117 
118 #include "MapTools.hh"
119 #include "StringTools.hh"
120 #include "Operation.hh"
121 #include "OperationPool.hh"
122 #include "MoveNode.hh"
123 
124 #include "TCETargetMachine.hh"
125 
126 #include "tce_config.h"
127 
128 #include "llvm/IR/DataLayout.h"
129 
130 #define TYPE_CONST
131 #include <llvm/MC/MCInstrDesc.h>
132 
133 #include <llvm/ADT/SmallString.h>
134 
135 #define END_SYMBOL_NAME "_end"
136 
137 //#define DISASSEMBLE_LLVM_OUTPUT
139 
140 using namespace TTAMachine;
141 using namespace llvm;
143 
144 unsigned LLVMTCEBuilder::MAU_BITS = 8;
145 //pointer size in bytes
146 unsigned LLVMTCEBuilder::POINTER_SIZE_32 = 4; // Pointer size in maus.
147 unsigned LLVMTCEBuilder::POINTER_SIZE_64 = 8; // Pointer size in maus.
148 
149 char LLVMTCEBuilder::ID = 0;
150 
151 //#define DEBUG_LLVMTCEBUILDER
152 //#define WARN_AS_FU_NOT_FOUND
153 
154 LLVMTCEBuilder::LLVMTCEBuilder(
155  const TargetMachine& tm,
156  TTAMachine::Machine* mach,
157  char& ID,
158  bool functionAtATime) :
159  MachineFunctionPass(ID) {
160  initMembers();
161  tm_ = &tm;
162  mach_ = mach;
163  functionAtATime_ = functionAtATime;
164  dl_ = new DataLayout(tm_->createDataLayout());
165 }
166 
167 LLVMTCEBuilder::LLVMTCEBuilder(char& ID) : MachineFunctionPass(ID) {
168  initMembers();
169 }
170 
171 void
173  mod_ = NULL;
174  tm_ = NULL;
175  prog_ = NULL;
176  mach_ = NULL;
177  mang_ = NULL;
178  noAliasFound_ = false;
179  multiAddrSpacesFound_ = false;
180  multiDataMemMachine_ = false;
181  spillMoveCount_ = 0;
182  dataInitialized_ = false;
184 
185  if (Application::cmdLineOptions() != NULL) {
186  options_ =
187  dynamic_cast<LLVMTCECmdLineOptions*>(
189  }
190 }
191 
192 
193 /**
194  * The Destructor.
195  */
197  if (mang_ != NULL) {
198  delete mang_;
199  mang_ = NULL;
200  }
201 }
202 
203 /**
204  * Initializes the data sections of the POM.
205  *
206  * Can be called multiple times. Doesn't do anything after the first
207  * successful call.
208  */
209 void
211 
212  if (dataInitialized_)
213  return;
214 
215  dataInitialized_ = true;
216 
217  assert(mach_ != NULL);
218  assert(tm_ != NULL);
219  assert(mod_ != NULL);
220 
221  if (prog_ != NULL) {
222  delete prog_;
223  prog_ = NULL;
224  }
225 
226  // List of supported operations.
227  opset_.insert("jump");
228  opset_.insert("call");
231 
232  for (int i = 0;i < fuNav.count(); i++) {
233  const FunctionUnit& fu = *fuNav.item(i);
234  for (int o = 0; o < fu.operationCount(); o++) {
236  }
237  }
238 
239  const auto& cu = *mach_->controlUnit();
240  for (int o = 0; o < cu.operationCount(); o++) {
241  opset_.insert(StringTools::stringToLower(cu.operation(o)->name()));
242  }
243 
244  // Set GCU address space as the instruction address space.
245  if (mach_->controlUnit() == NULL) {
246  std::cerr << "ERROR: No control unit in the target machine!"
247  << std::endl;
248 
249  assert(false);
250  }
251 
253  if (instrAddressSpace_ == NULL) {
254  std::cerr << "ERROR: Address space set for the control unit in the "
255  << "target machine."
256  << std::endl;
257 
258  assert(false);
259  }
260 
261  // FIXME: data address space
264 
265  multiDataMemMachine_ = nav.count() > 2;
267 
268  for (int i = 0; i < nav.count(); i++) {
269  if (nav.item(i) != instrAddressSpace_) {
270  if (!multiDataMemMachine_ || nav.item(i)->hasNumericalId(0)) {
272  break;
273  }
274  }
275  }
276 
277  if (defaultDataAddressSpace_ == NULL) {
278  std::cerr << "ERROR: Unable to determine the default data address space."
279  << std::endl;
280  abort();
281  } else {
284  << "using '" << defaultDataAddressSpace_->name()
285  << "' as the default data address space"
286  << std::endl;
287  }
288  }
289 
291  mang_ = new Mangler();
292 
293  const TCETargetMachine* tm = dynamic_cast<const TCETargetMachine*>(tm_);
294  assert(tm != NULL);
295 
297 
298  // Global variables.
299  for (Module::const_global_iterator i = mod_->global_begin();
300  i != mod_->global_end(); i++) {
301 
302  SmallString<256> Buffer;
303  mang_->getNameWithPrefix(Buffer, &(*i), false);
304  TCEString name(Buffer.c_str());
305 
306  const llvm::GlobalObject& gv = *i;
307  MaybeAlign gvAlign = gv.getAlign();
308 
309  if (gv.hasSection() &&
310  gv.getSection() == std::string("llvm.metadata")) {
311  // do not write debug constants to the data section
312  continue;
313  }
314 
315  if (name == END_SYMBOL_NAME) {
316  // Skip original _end symbol.
317  continue;
318  }
319 
320  if (name == "__dso_handle") {
321  // Should not be needed without dynamic library support.
322  continue;
323  }
324 
325  if (!i->hasInitializer()) {
326  std::cerr << "Initializer missing for: " << name << std::endl;
327  assert(false && "No initializer. External linkage?");
328  }
329 
330  const Constant* initializer = i->getInitializer();
331  TYPE_CONST Type* type = initializer->getType();
332 
333  DataDef def;
334  def.name = name;
335  def.address = 0;
336  def.addressSpaceId =
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);
340  // memcpy seems to assume global values are aligned by 4
341  if (def.size > def.alignment) {
342  def.alignment = std::max(def.alignment, tm->stackAlignment());
343  }
344 
345  assert(def.alignment != 0);
346 
347  if (isInitialized(initializer)) {
348  def.initialize = true;
349  data_.push_back(def);
350  } else {
351  def.initialize = false;
352  udata_.push_back(def);
353  }
354  }
355 
356  // Map initialized data to memory.
357  for (unsigned i = 0; i < data_.size(); i++) {
358 
359  TTAMachine::AddressSpace& aSpace =
361 
362  unsigned& dataEndPos = dataEnd(aSpace);
364 
365  // padding
366  unsigned pad = 0;
367  while ((dataEndPos + pad) % data_[i].alignment != 0) pad++;
368  if (pad > 0) {
369  TTAProgram::Address address(dataEndPos, aSpace);
370  dmem.addDataDefinition(
372  address, pad, mach_->isLittleEndian(), NULL, true));
373  dataEndPos += pad;
374  }
375 
376  dataLabels_[data_[i].name] = dataEndPos;
377  data_[i].address = dataEndPos;
378 
379  // Add data label.
380  TTAProgram::Address addr(dataEndPos, aSpace);
381  TTAProgram::DataLabel* label =
382  new TTAProgram::DataLabel(data_[i].name, addr, gscope);
383 
384  gscope.addDataLabel(label);
385 
386  dataEndPos += data_[i].size;
387  }
388 
389  // Map uninitialized data to memory.
390  for (unsigned i = 0; i < udata_.size(); i++) {
391 
392  TTAMachine::AddressSpace& aSpace =
394 
395  unsigned& dataEndPos = dataEnd(aSpace);
397 
398  // padding
399  unsigned pad = 0;
400  while ((dataEndPos + pad) % udata_[i].alignment != 0) pad++;
401  if (pad > 0) {
402  TTAProgram::Address address(dataEndPos, aSpace);
403  dmem.addDataDefinition(
405  address, pad, mach_->isLittleEndian()));
406 
407  dataEndPos += pad;
408  }
409 
410  udata_[i].address = dataEndPos;
411  dataLabels_[udata_[i].name] = dataEndPos;
412 
413  // Add data label.
414  TTAProgram::Address addr(dataEndPos, aSpace);
415  TTAProgram::DataLabel* label =
416  new TTAProgram::DataLabel(udata_[i].name, addr, gscope);
417 
418  gscope.addDataLabel(label);
419  dataEndPos += udata_[i].size;
420  }
421 }
422 
423 /**
424  * Initializer creates a new POM and adds all global data initializations.
425  *
426  * @param m Module to initialize the writer for.
427  */
428 bool
430  mod_ = &m;
431  dataInitialized_ = false;
432  return false;
433 }
434 
435 /**
436  * Creates data definition from a Constant initializer and adds it to the
437  * machine data memory.
438  *
439  * @param addr Address where the data is to be defined in the data memory.
440  * @param cv Constant initializer for the data.
441  */
442 void
444 
445  TTAMachine::AddressSpace& aSpace =
448 
449  if (!def.initialize) {
450 
451  if (def.address % def.alignment != 0) {
452  std::cerr << def.name << " misaligned!" << std::endl;
453  std::cerr << " address: " << def.address
454  << " alignment: " << def.alignment << std::endl;
455 
456  assert(false);
457  }
458 
459  TTAProgram::Address addr(def.address, aSpace);
460  dmem.addDataDefinition(
462  addr, def.size, mach_->isLittleEndian()));
463 
464  return;
465  } else {
466 
467  const GlobalVariable* var = NULL;
468  for (Module::const_global_iterator i = mod_->global_begin();
469  i != mod_->global_end(); i++) {
470 
471  SmallString<256> Buffer;
472  mang_->getNameWithPrefix(Buffer, &(*i), false);
473  if (def.name == Buffer.c_str()) {
474  var = &(*i);
475  break;
476  }
477  }
478 
479  unsigned addr = def.address;
480 
481  assert(var != NULL && "Variable not found!");
482 
483 #ifndef NDEBUG
484  unsigned paddedAddr =
485 #endif
486  createDataDefinition(def.addressSpaceId, addr, var->getInitializer());
487  assert(paddedAddr == def.address);
488  }
489 }
490 
491 /**
492  * Creates data definition from a Constant pool entry definition.
493  *
494  * @param addr Address where the data is to be defined in the data memory.
495  * @param cv Constant initializer for the data.
496  */
497 void
499 
500 #ifndef NDEBUG
501  unsigned address = def.address;
502 #endif
503  createDataDefinition(0, address, def.value);
504  assert(address == def.address + def.size);
505 }
506 
507 /**
508  * Creates POM data definition from a llvm data initializer.
509  *
510  * @param addr Address for the POM data.
511  * @param cv Initializer for the data in llvm.
512  * @param forceInitialize In case wanting to use initialization data even
513  * for null values.
514  * @param forceAlignment Use the given alignment for the constant instead of
515  * the alignment defined in DataLayout.
516  * @return POM data address after padding data to correct alignment.
517  */
518 unsigned
520  int addressSpaceId, unsigned& addr, const Constant* cv,
521  bool forceInitialize, unsigned forceAlignment) {
522 
523  unsigned sz = dl_->getTypeStoreSize(cv->getType());
524  unsigned align = (forceAlignment == 0)?
525  dl_->getABITypeAlignment(cv->getType()):forceAlignment;
526 
527  // KLUDGE FIX: Currently, for little-endian machines, OSAL base simd
528  // module has only vector load and store operations that require full
529  // vector width alignment.
530  // Remove this when accesses can be done at ABI alignment.
531  if (mach_->isLittleEndian() && cv->getType()->isVectorTy()) {
532  align = (forceAlignment == 0)?sz:forceAlignment;
533  }
534 
535  TTAMachine::AddressSpace& aSpace =
538 
539  padToAlignment(addressSpaceId, addr, align);
540 
541  // paddedAddr is the actual address data was put to
542  // after alignment.
543  unsigned paddedAddr = addr;
544 
545  // Initialize with zeros if this is an uninitialized part of a partially
546  // initialized data structure.
547  if (!forceInitialize &&
548  (cv->isNullValue() || dyn_cast<UndefValue>(cv) != NULL)) {
549  TTAProgram::Address address(addr, aSpace);
550  dmem.addDataDefinition(
552  address, sz, mach_->isLittleEndian(), NULL, true));
553  addr += sz;
554  return paddedAddr;
555  }
556 
557  if (isa<ConstantArray>(cv) ||
558  isa<ConstantStruct>(cv) ||
559  isa<ConstantVector>(cv)) {
560 
561  for (unsigned i = 0, e = cv->getNumOperands(); i != e; ++i) {
563  addressSpaceId, addr, cast<Constant>(cv->getOperand(i)));
564  }
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()) {
575  TTAProgram::Address address(addr, aSpace);
576  dmem.addDataDefinition(
578  address, sz, mach_->isLittleEndian(), NULL, false) );
579  } else {
580  /* If the array has non-zero values, do not split the
581  definitions to initialized and uninitialized data sections, but
582  initialize them all. Otherwise we might end up having zillions
583  of UData and Data sections after each other in the TPEF for the
584  initialization data, because the sections have only one start
585  address. It soon exceeds the maximum number of
586  sections in case of large initialized arrays with some of the
587  values being zeros. */
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))
593  continue;
594  allZeros = false;
595  break;
596  }
597 
598  for (unsigned int i = 0; i < cda->getNumElements(); i++) {
600  addressSpaceId, addr, cda->getElementAsConstant(i),
601  !allZeros);
602  }
603  }
604  } else if (const ConstantDataSequential* cds =
605  dyn_cast<ConstantDataSequential>(cv)) {
606  // Force other alignment for vector types. If the element type is less
607  // than i32, it gets promoted based on DataLayout's ABI or Preferred
608  // alignment of integer type.
609  unsigned alignmentOverride = 0;
610  if (cv->getType()->isVectorTy()) {
611  alignmentOverride = sz/cds->getNumElements();
612  }
613  for (unsigned int i = 0; i < cds->getNumElements(); i++) {
615  addressSpaceId, addr, cds->getElementAsConstant(i),
616  forceInitialize, alignmentOverride);
617  }
618  } else {
619  // LLVM does not include dump() when built in non-debug mode.
620  // cv->dump();
621  abortWithError("Unknown cv type.");
622  }
623  return paddedAddr;
624 }
625 
626 
627 /**
628  * Creates data definition of a constant integer value.
629  *
630  * @param addr Address where the integer is to be defined.
631  * @param ci Constant initializer for the integer value.
632  */
633 void
635  int addressSpaceId, unsigned& addr, const ConstantInt* ci,
636  bool isPointer) {
637 
638  assert(addr % (dl_->getABITypeAlignment(ci->getType())) == 0 &&
639  "Invalid alignment for constant int!");
640 
641  std::vector<MinimumAddressableUnit> maus;
642 
643  unsigned sz = ((ci->getBitWidth() + MAU_BITS-1) / MAU_BITS);
644 
645  if (isPointer) {
647  }
648 
649  if (!(sz == 1 || sz == 2 || sz == 4 || sz == 8)) {
650 
651 // std::cerr << "## int with size " << sz << "!" << std::endl;
652  }
653 
654  TTAMachine::AddressSpace& aSpace =
657 
658  TTAProgram::Address start(addr, aSpace);
659 
660  // FIXME: Assuming 8bit MAU.
661  union {
662  int64_t d;
663  char bytes[8];
664  } u;
665 
666  u.d = ci->getZExtValue();
667 
669 
670  if (!mach_->isLittleEndian()) {
671  for (unsigned i = 0; i < sz; i++) {
672  maus.push_back(u.bytes[sz - i - 1]);
673  }
674  } else {
675  for (unsigned i = 0; i < sz; i++) {
676  maus.push_back(u.bytes[i]);
677  }
678  }
679 
680  def = new TTAProgram::DataDefinition(start, maus, mach_->isLittleEndian());
681  addr += def->size();
682  dmem.addDataDefinition(def);
683 }
684 
685 
686 /**
687  * Creates data definition of a floating point constant.
688  */
689 void
691  int addressSpaceId, unsigned& addr, const ConstantFP* cfp) {
692 
693  assert(addr % (dl_->getABITypeAlignment(cfp->getType())) == 0
694  && "Invalid alignment for constant fp!");
695 
696  TTAMachine::AddressSpace& aSpace =
699 
700  TTAProgram::Address start(addr, aSpace);
701  std::vector<MinimumAddressableUnit> maus;
702 
703  TYPE_CONST Type* type = cfp->getType();
704  unsigned sz = dl_->getTypeStoreSize(type);
705 
706  TTAProgram::DataDefinition* def = NULL;
707 
708  if (type->getTypeID() == Type::DoubleTyID) {
709 
710  double val = cfp->getValueAPF().convertToDouble();
711  assert(sz == 8);
712  union {
713  double d;
714  char bytes[8];
715  } u;
716 
717  u.d = val;
718  if (!mach_->isLittleEndian()) {
719  for (unsigned i = 0; i < sz; i++) {
720  maus.push_back(u.bytes[sz - i - 1]);
721  }
722  } else {
723  for (unsigned i = 0; i < sz; i++) {
724  maus.push_back(u.bytes[i]);
725  }
726  }
727  def = new TTAProgram::DataDefinition(
728  start, maus, mach_->isLittleEndian());
729  } else if (type->getTypeID() == Type::FloatTyID) {
730 
731  float val = cfp->getValueAPF().convertToFloat();
732  assert(sz == 4);
733  union {
734  float f;
735  char bytes[4];
736  } u;
737 
738  u.f = val;
739  if (!mach_->isLittleEndian()) {
740  for (unsigned i = 0; i < sz; i++) {
741  maus.push_back(u.bytes[sz - i - 1]);
742  }
743  } else {
744  for (unsigned i = 0; i < sz; i++) {
745  maus.push_back(u.bytes[i]);
746  }
747  }
748  def = new TTAProgram::DataDefinition(
749  start, maus, mach_->isLittleEndian());
750  } else if (type->getTypeID() == Type::HalfTyID) {
751  APInt bits = cfp->getValueAPF().bitcastToAPInt();
752  uint64_t bigval = bits.getLimitedValue(0xFFFF);
753  assert(sz == 2);
754  union {
755  short h;
756  char bytes[2];
757  } u;
758  u.h = bigval;
759  if (!mach_->isLittleEndian()) {
760  for (unsigned i = 0; i < sz; i++) {
761  maus.push_back(u.bytes[sz - i - 1]);
762  }
763  } else {
764  for (unsigned i = 0; i < sz; i++) {
765  maus.push_back(u.bytes[i]);
766  }
767  }
768  def = new TTAProgram::DataDefinition(
769  start, maus, mach_->isLittleEndian());
770  } else {
771  assert(false && "Unknown floating point typeID!");
772  }
773  addr += def->size();
774  dmem.addDataDefinition(def);
775 }
776 
777 
778 /**
779  * Creates data definition for a global value reference.
780  *
781  * @param addr Address where the reference is to be defined.
782  * @param gv Global value reference.
783  */
784 void
786  int addressSpaceId, unsigned& addr, const GlobalValue* gv, int offset) {
787 
788  TYPE_CONST PointerType* type = gv->getType();
789 
790  unsigned sz = dl_->getTypeStoreSize(type);
791 
792  SmallString<256> Buffer;
793  mang_->getNameWithPrefix(Buffer, gv, false);
794  TCEString label(Buffer.c_str());
795 
796  TTAMachine::AddressSpace& aSpace =
799 
800  TTAProgram::Address start(addr, aSpace);
801 
802  TTAProgram::DataDefinition* def = NULL;
803  if (codeLabels_.find(label) != codeLabels_.end()) {
804  assert(
805  offset == 0 &&
806  "Instruction reference with an offset not supported yet.");
807 
808  TTAProgram::Instruction* instr = codeLabels_[label];
811 
813  start, sz, ref, mach_->isLittleEndian());
814  } else if (dataLabels_.find(label) != dataLabels_.end()) {
815  unsigned gvAS = type->getAddressSpace();
817  TTAProgram::Address ref((dataLabels_[label] + offset), aSpace);
818 
819  def = new TTAProgram::DataAddressDef(
820  start, sz, ref, mach_->isLittleEndian());
821  } else {
822  assert(false && "Global value label not found!");
823  }
824  addr += def->size();
825  dmem.addDataDefinition(def);
826 }
827 
828 /**
829  * Creates POM data definition from a llvm constant expression initializer.
830  *
831  * @param addr Address of the POM data definition.
832  * @param ce Expression to create the data definition for.
833  * @param offset Offset for an address defined by the expression.
834  */
835 void
837  int addressSpaceId, unsigned& addr, const ConstantExpr* ce, int offset) {
838 
839  assert(addr % (dl_->getABITypeAlignment(ce->getType())) == 0 &&
840  "Invalid alignment for constant expr!");
841 
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());
846 
847  APInt offsetAI(dl_->getPointerTypeSizeInBits(ce->getType()), 0);
848  bool success = cast<GEPOperator>(ce)->accumulateConstantOffset(
849  *dl_, offsetAI);
850  assert(success); // Fails if GEP is not all-constant.
851  int64_t ptrOffset = offset + offsetAI.getSExtValue();
852 
853  if (const GlobalValue* gv = dyn_cast<GlobalValue>(ptr)) {
855  addressSpaceId, addr, gv, ptrOffset);
856  } else if (const ConstantExpr* ce =
857  dyn_cast<ConstantExpr>(ptr)) {
859  addressSpaceId, addr, ce, ptrOffset);
860  } else {
861  assert(false && "Unsuported getElementPtr target!");
862  }
863  } else if (opcode == Instruction::BitCast) {
864  const Constant* ptr = ce->getOperand(0);
865  if (const ConstantExpr* ce = dyn_cast<ConstantExpr>(ptr)) {
867  addressSpaceId, addr, ce, offset);
868  } else if (const GlobalValue* gv = dyn_cast<GlobalValue>(ptr)) {
870  addressSpaceId, addr, gv, offset);
871  } else {
872  assert(offset == 0);
873 #ifndef NDEBUG
874  unsigned dataAddr =
876  addressSpaceId, addr, ptr);
877  // Data should have been padded already:
878  assert(dataAddr == addr);
879 #else
881 #endif
882  }
883  } else if (opcode == Instruction::IntToPtr) {
884  assert(offset == 0);
885  const ConstantInt* ci = dyn_cast<ConstantInt>(ce->getOperand(0));
886  assert(ci != NULL);
887  createIntDataDefinition(addressSpaceId, addr, ci, true);
888  } else if (opcode == Instruction::PtrToInt) {
889  assert(offset == 0);
890  // Data should have been padded already:
891 #ifndef NDEBUG
892  unsigned dataAddr =
893 #endif
894  createDataDefinition(addressSpaceId, addr, ce->getOperand(0));
895  assert(dataAddr == addr);
896  } else if (opcode == Instruction::Add) {
897  assert(false && "NOT IMPLEMENTED");
898  } else if (opcode == Instruction::Sub) {
899  assert(false && "NOT IMPLEMENTED");
900  } else {
901  assert(false && "NOT IMPLEMENTED");
902  }
903 }
904 
905 /**
906  * Pads data memory with zeroes until desired alignment is reached.
907  *
908  * Zero padding is only added when necessary. That is the address is already
909  * aligned.
910  *
911  * @param addressSpaceId The address space id.
912  * @param addr The current address, which is updated to the desired alignment
913  * after the call.
914  * @param align The desired alignment.
915  */
916 void
918  int addressSpaceId, unsigned& addr, unsigned align) {
919 
922 
923  unsigned pad = 0;
924  while ((addr + pad) % align != 0) pad++;
925 
926  // Pad with zeros to correct alignment.
927  if (pad > 0) {
928  std::vector<MinimumAddressableUnit> zeros(pad, 0);
929  TTAProgram::Address address(addr, aSpace);
930  dmem.addDataDefinition(
932  address, zeros, mach_->isLittleEndian()));
933 
934  addr += pad;
935  }
936 }
937 
938 
939 /**
940  * Creates POM procedure of a MachineFunction object and adds it to the
941  * current program.
942  *
943  * @param mf MachineFunction to process.
944  * @return Always false.
945  */
946 bool
948  return writeMachineFunction(mf);
949 }
950 
951 /**
952  * Writes machine function to POM.
953  *
954  * Actually does things to MachineFunction which was supposed to be done
955  * in runOnMachineFunction, but which cannot be done during that, because
956  * MachineDCE is not ready yet at that time...
957  */
958 bool
960 
961  // the new TTA backend does not initialize TCETargetMachine
962  // in construction (at least not yet)
963  if (tm_ == NULL)
964  tm_ = dynamic_cast<const TCETargetMachine*>(&mf.getTarget());
965 
966  assert(tm_ != NULL);
967 
968  curFrameInfo_ = &mf.getFrameInfo();
969  assert(curFrameInfo_ != NULL);
970 
971  // ensure data sections have been initialized
973 
974  // omit empty functions..
975  if (mf.begin() == mf.end()) return true;
976 
977  // TODO: make list of mf's which for the pass will be ran afterwards..
978 
979  SmallString<256> Buffer;
980  mang_->getNameWithPrefix(Buffer, &mf.getFunction(), false);
981  TCEString fnName(Buffer.c_str());
982 
983  emitConstantPool(*mf.getConstantPool());
984 
985  TTAProgram::Procedure* proc =
987 
988  prog_->addProcedure(proc);
989 
990  std::set<std::string> emptyMBBs;
991 
992  bool firstInsOfProc = true;
993  spillMoveCount_ = 0;
994  // iterate basic blocks from MachineFunction
995  for (MachineFunction::const_iterator i = mf.begin();
996  i != mf.end(); i++) {
997 
998  bool newMBB = true;
999 
1000  // iterate MachineInstr from basic blocks
1001  for (MachineBasicBlock::const_iterator j = i->begin();
1002  j != i->end(); j++) {
1003 
1004  TTAProgram::Instruction* instr = NULL;
1005 #ifdef DEBUG_LLVMTCEBUILDER
1006  std::cerr << "### converting: ";
1007  std::cerr << std::endl;
1008 #endif
1009  instr = emitInstruction(&*j, proc);
1010 
1011  // Pseudo instructions:
1012  if (instr == NULL) continue;
1013 
1016  << "ERROR: The machine contains multiple data address spaces "
1017  << "and ambigious memory accessing moves '"
1018  << instr->toString() << "' were found." << std::endl;
1019  abort();
1020  }
1021 
1022  // If there was any empty basic blocks before this instruction,
1023  // set the basic blocks to point the next available (this)
1024  // instruction.
1025  while (!emptyMBBs.empty()) {
1026  mbbs_[*emptyMBBs.begin()] = instr;
1027  emptyMBBs.erase(emptyMBBs.begin());
1028  }
1029 
1030  std::string mbb = mbbName(*i);
1031 
1032  // Keep book of first instructions in basic blocks.
1033  if (newMBB) {
1034  newMBB = false;
1036  mbbs_[mbb] = instr;
1037  bbIndex_[(*i).getBasicBlock()] = instr;
1038  }
1039 
1040  // Keep book of first instructions in functions.
1041  if (firstInsOfProc) {
1043  instructionReferenceManager().createReference(*instr);
1045  new TTAProgram::CodeLabel(ref, fnName));
1046 
1047  codeLabels_[fnName] = instr;
1048  firstInsOfProc = false;
1049  }
1050  }
1051 
1052  // If the basic block didn't hold any instructions
1053  // (i.e. it probably contained only pseudo instructions),
1054  // add it to the set of empty BBs that will be set to point
1055  // the next instruction in the program.
1056  if (newMBB) {
1057  emptyMBBs.insert(mbbName(*i));
1058  }
1059  }
1060 
1061  // if the procedure would otherwise be empty, add a dummy instruction there,
1062  // and make the procedure cdelabel to point it.
1063  if (firstInsOfProc) {
1065  proc->add(dummyIns);
1066 
1068  instructionReferenceManager().createReference(*dummyIns);
1070  new TTAProgram::CodeLabel(ref, fnName));
1071 
1072  codeLabels_[fnName] = dummyIns;
1073  }
1074  if (Application::verboseLevel() > 0) {
1076  << "spill moves in " <<
1077  (std::string)(mf.getFunction().getName()) << ": "
1078  << spillMoveCount_ << std::endl;
1079  }
1080  return false;
1081 }
1082 
1083 /**
1084  * Finalizes the POM building.
1085  *
1086  * Creates data initializers.
1087  * Fixes dummy code references to point the actual instructions.
1088  */
1089 bool
1091 
1092  // errs() << "Finalize LLVMPOM builder\n";
1093 
1095  unsigned& dataEndPos = dataEnd(aSpace);
1096 
1097  // Create new _end symbol at the end of the data memory definitions of
1098  // the default address space. This is used by malloc() to determine the
1099  // beginning of the heap.
1100  DataDef def;
1101  def.name = END_SYMBOL_NAME;
1102  def.address = dataEndPos;
1103  def.addressSpaceId = 0;
1104  def.alignment = 1;
1105  def.size = 1;
1106  def.initialize = false;
1107  emitDataDef(def);
1108  dataLabels_[def.name] = def.address;
1109 
1110  // Create data initializers.
1111  for (unsigned i = 0; i < data_.size(); i++) {
1112  emitDataDef(data_[i]);
1113  }
1114  for (unsigned i = 0; i < udata_.size(); i++) {
1115  emitDataDef(udata_[i]);
1116  }
1117  for (auto cpDataDef : cpData_) {
1118  emitDataDef(cpDataDef);
1119  }
1120 
1121 
1122  TTAProgram::Address endAddr(dataEndPos, aSpace);
1124  END_SYMBOL_NAME, endAddr, prog_->globalScope());
1125 
1126  prog_->globalScope().addDataLabel(label);
1127 
1128  // Fix references to _end symbol.
1129  unsigned i = 0;
1130  for (; i < endReferences_.size(); i++) {
1131  SimValue endLoc(mach_->is64bit() ? 64 : 32);
1132  endLoc = dataEndPos;
1134  new TTAProgram::TerminalAddress(endLoc, aSpace);
1135 
1136  endReferences_[i]->setSource(ea);
1137  }
1138 
1139  for (DataMemIndex::const_iterator i = dmemIndex_.begin();
1140  i != dmemIndex_.end(); ++i) {
1141  prog_->addDataMemory((*i).second);
1142  }
1143 
1144  // Fix references to basic blocks.
1146  std::string>::iterator mbbRefIter =
1147  mbbReferences_.begin();
1148 
1149  for (; mbbRefIter != mbbReferences_.end(); mbbRefIter++) {
1150  TTAProgram::TerminalInstructionAddress* term = mbbRefIter->first;
1151 
1152  std::string mbb = mbbRefIter->second;
1153  if (mbbs_.find(mbb) == mbbs_.end()) {
1154  assert(false && "MBB not found from book keeping.");
1155  }
1156  TTAProgram::Instruction& instr = *mbbs_[mbb];
1159  term->setInstructionReference(newRef);
1160  }
1161 
1162  // Fix references to code labels.
1164  std::string>::iterator codeRefIter =
1165  codeLabelReferences_.begin();
1166 
1167  for (; codeRefIter != codeLabelReferences_.end(); codeRefIter++) {
1168  TTAProgram::TerminalInstructionAddress* term = codeRefIter->first;
1169  std::string label = codeRefIter->second;
1170  if (codeLabels_.find(label) == codeLabels_.end()) {
1171  std::cerr << (boost::format(
1172  "Function '%s' not defined.\n") %
1173  label).str();
1174  exit(EXIT_FAILURE);
1175  }
1176 
1177  TTAProgram::Instruction& instr = *codeLabels_[label];
1180 
1181  term->setInstructionReference(newRef);
1182  }
1183 
1184  // Add stackpointer initialization.
1186 
1187 #ifdef DISASSEMBLE_LLVM_OUTPUT
1188  std::ofstream outfile("llvm_output.S");
1189  outfile << POMDisassembler::disassemble(*prog_, true);
1190  outfile.close();
1191 #endif
1192 
1193  return false;
1194 }
1195 
1196 void
1198  // get machine dce analysis
1199  MachineDCE& MDCE = getAnalysis<MachineDCE>();
1200 
1201  for (MachineDCE::UnusedFunctionsList::iterator i =
1202  MDCE.removeableFunctions.begin();
1203  i != MDCE.removeableFunctions.end(); i++) {
1204  std::string name = *i;
1205  if (Application::verboseLevel() > 0) {
1207  << "Deleting unused function: " << name << std::endl;
1208  }
1209  TTAProgram::Procedure& notUsedProc = prog_->procedure(name);
1210  // Delete data definitions poining to the deleted procedure.
1211  for (int dmemIdx = 0; dmemIdx < prog_->dataMemoryCount(); dmemIdx++) {
1212  auto& dmem = prog_->dataMemory(dmemIdx);
1213  for (int dataDefIdx = 0; dataDefIdx < dmem.dataDefinitionCount();
1214  dataDefIdx++) {
1215  auto& dataDef = dmem.dataDefinition(dataDefIdx);
1216  if (dataDef.isInstructionAddress()) {
1217  auto instrAddr = dataDef.destinationAddress();
1218  if (instrAddr != notUsedProc.startAddress()) {
1219  continue;
1220  }
1221  if (Application::verboseLevel() > 0) {
1223  << "Deleting data definition pointing to "
1224  << "dead function: " << name << std::endl;
1225  }
1226  dmem.deleteDataDefinition(dataDefIdx);
1227  }
1228  }
1229  }
1230  prog_->removeProcedure(notUsedProc);
1231 
1232  delete &notUsedProc;
1233  }
1234 }
1235 
1236 /**
1237  * Sets the value the stack pointer should be initialized to.
1238  */
1239 void
1241  initialStackPointerValue_ = value;
1242 }
1243 
1244 
1245 // std::min(addressSpaceById(0).end() & 0xfffffff8, value);
1246 
1247 /**
1248  * Checks that the potential memory operations triggered in the
1249  * given unscheduled instruction (with exactly one move) have
1250  * unambiguous address space.
1251  *
1252  * This should be called as a sanity check for instructions in
1253  * a program (and a machine) with multiple address spaces. Returns
1254  * true in case the instruction has at least one move that refers
1255  * to memory without the address space information being unambiguous
1256  * in the currently targeted machine.
1257  */
1258 bool
1260  const TTAProgram::Instruction& instr) const {
1261 
1262  const TTAProgram::Move& m = instr.move(0);
1263  const TTAProgram::Terminal& t = m.destination();
1264  if (t.isFUPort() && !t.isRA() &&
1266  !m.hasAnnotations(
1268 
1269  TCEString opName =
1270  dynamic_cast<const TTAProgram::TerminalFUPort&>(t).
1271  hwOperation()->name();
1272  int numberOfPotentialFUs = 0;
1275  for (int i = 0; i < fuNav.count(); i++) {
1276  const TTAMachine::FunctionUnit& fu = *fuNav.item(i);
1277  if (fu.hasOperation(opName)) numberOfPotentialFUs++;
1278  }
1279 
1280  if (numberOfPotentialFUs > 1) {
1281  return true;
1282  }
1283  }
1284  return false;
1285 }
1286 
1288 LLVMTCEBuilder::getHWOperation(std::string opName) {
1289  const TTAMachine::FunctionUnit* fu = NULL;
1290 
1291  if (UniversalMachine::instance().controlUnit()->hasOperation(opName)) {
1293  } else if (UniversalMachine::instance().universalFunctionUnit().
1294  hasOperation(opName)) {
1296  } else {
1298  TCEString("ERROR: Operation '") + opName +
1299  "' not found in the machine.");
1300  }
1301 
1302  // Check that the target machine supports this instruction.
1303  if (opset_.find(StringTools::stringToLower(opName)) == opset_.end()) {
1304  std::cerr << "ERROR: Operation '" << opName
1305  << "' is required by the program but not found "
1306  << "in the machine." << std::endl;
1307  abortWithError("Cannot proceed.");
1308  }
1309  return *fu->operation(opName);
1310 }
1311 
1312 /**
1313  * Creates POM instructions from a LLVM MachineInstruction.
1314  *
1315  * One POM instruction per Move are created.
1316  *
1317  * @param mi Machine instruction to emit to the POM.
1318  * @param proc POM procedure to append the instruction to.
1319  * @return First of the POM instructions emitted.
1320  */
1323  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
1324 
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();
1330 
1331  // when the -g option turn on, this will come up opc with this, therefore
1332  // add this to ignore however, it is uncertain whether the debug "-g" will
1333  // generate more opc, need to verify
1334  // NOTE there is similar code in ConstantTransformer::runOnMachineFunction
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) {
1341  return NULL;
1342  }
1343 
1344  std::string opName = "";
1345 
1346  bool hasGuard = false;
1347  bool trueGuard = true;
1348  if (dynamic_cast<const TCETargetMachine*>(&targetMachine()) != NULL) {
1349 
1350  if (opDesc->isReturn()) {
1351  // in case of TTA targets, the return node needs to be
1352  // converted to ra -> jump here as it does not map 1:1
1353  // with the DAG names and we map LLVM DAG names to OSAL
1354  // operations
1355  // FIXME: this is the wrong way to do this:
1356  // should LowerReturn to RA -> JUMP.1 instead and process just
1357  // like any other operation here.
1358  return emitReturn(mi, proc);
1359  }
1360  opName = operationName(*mi);
1361 
1362  // Pseudo instructions don't require any actual instructions.
1363  if (opName == "PSEUDO" || opName == "DEBUG_LABEL") {
1364  return NULL;
1365  }
1366 
1367  // Debug labels don't require any actual instructions.
1368  // TODO: should store the data and apply to next? (or prev?) instr,
1369  // but just ignore it to not cause a crash.
1370  if (opName =="DEBUG_LABEL") {
1371  return nullptr;
1372  }
1373 
1374  if (opName[0] == '?') {
1375  hasGuard = true;
1376  opName = opName.substr(1);
1377  }
1378 
1379  if (opName[0] == '!') {
1380  hasGuard = true;
1381  trueGuard = false;
1382  opName = opName.substr(1);
1383  }
1384 
1385  if (opName == "MOVE") {
1386  return emitMove(mi, proc, hasGuard, trueGuard);
1387  }
1388 
1389  // TODO: guarded also for these
1390  if (opName == "INLINEASM") {
1391  return emitOperationMacro(mi, proc);
1392  }
1393 
1394  if (opName == "CMOV_SELECT") {
1395  return emitSelect(mi, proc);
1396  }
1397  } else {
1398  opName = operationName(*mi);
1399  }
1400 
1401  // split compare + jump combo op.
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);
1406  TTAProgram::Instruction* ins = emitComparisonForBranch(firstOp, mi, proc);
1407  emitRemaingingBrach(remainingName, mi, proc);
1408  return ins;
1409  }
1410 
1411  const HWOperation& op = getHWOperation(opName);
1412 
1414 
1415  OperationPool pool;
1416  const Operation& operation = pool.operation(opName.c_str());
1417 
1418  std::vector<TTAProgram::Instruction*> operandMoves;
1419  std::vector<TTAProgram::Instruction*> resultMoves;
1420 
1421  int inputOperand = 0;
1422  int outputOperand = operation.numberOfInputs();
1423 #ifdef DEBUG_LLVMTCEBUILDER
1424  PRINT_VAR(operation.numberOfInputs());
1425  PRINT_VAR(operation.numberOfOutputs());
1426  Application::logStream() << " mi->getNumOperands() = "
1427  << mi->getNumOperands() << std::endl;
1428 #endif
1429  TTAProgram::MoveGuard* guard = NULL;
1430  int guardOperandIndex = -1;
1431 
1432  if (hasGuard) {
1433  for (unsigned o = 0; o < mi->getNumOperands(); o++) {
1434  const MachineOperand& mo = mi->getOperand(o);
1435 
1436  // Guarded operations have the guarded element as the first
1437  // operand.
1438 
1439  if (mo.isReg() && mo.isUse()) {
1440  guardOperandIndex = o;
1441  // Create move from the condition operand register to bool
1442  // register which is used by the guard.
1444  // inv guards not yet supported
1445  guard = createGuard(t, trueGuard);
1446  delete t;
1447  assert(guard != NULL);
1448  break;
1449  }
1450  }
1451  }
1452 
1453 
1454  for (unsigned o = 0; o < mi->getNumOperands(); o++) {
1455  if ((int)o == guardOperandIndex) {
1456  continue;
1457  }
1458 
1459  const MachineOperand& mo = mi->getOperand(o);
1460  TTAProgram::Terminal* src = NULL;
1461  TTAProgram::Terminal* dst = NULL;
1462 
1463  if (!mo.isReg() || mo.isUse() || operation.numberOfOutputs() == 0) {
1464  ++inputOperand;
1465  if (inputOperand > operation.numberOfInputs()) {
1466 
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)) {
1472  TCEString s = mds->getString().str();
1473  if (s == "AA_CATEGORY_STACK_SLOT") {
1474  isSpill = true;
1475  } else if (s == "AA_CATEGORY_RA_SAVE_SLOT") {
1476  isRaSlot = true;
1477  } else if (s == "AA_CATEGORY_FP_SAVE_SLOT") {
1478  isFpSlot = true;
1479  }
1480  }
1481  }
1482  }
1483  continue;
1484  }
1485 
1486  assert(operation.operand(inputOperand).isInput() &&
1487  "Operand mismatch.");
1488 
1489  // currently the input operand of the base+offset mem operations
1490  // are not marked as addresses as alias analysis does not work
1491  // in that case correctly, thus we have to treat those operations
1492  // as special cases for the time being
1493  if (operation.operand(inputOperand).isAddress() ||
1494  (operation.isBaseOffsetMemOperation() && inputOperand == 1)) {
1495  // MachineInstructions have two operands for each Operation
1496  // address operand: base and offset immediate, split it to
1497  // two in case of an add+ld/st.
1498  const MachineOperand& base = mo;
1499  src = createTerminal(base);
1500  dst = new TTAProgram::TerminalFUPort(op, inputOperand);
1501  TTAProgram::MoveGuard* guardCopy =
1502  guard == NULL ? NULL : guard->copy();
1503 
1504  auto move = createMove(src, dst, bus, guardCopy);
1506  instr->addMove(move);
1507 
1508  operandMoves.push_back(instr);
1509 
1510  debugDataToAnnotations(mi, *move);
1511  addPointerAnnotations(mi, *move);
1512  o += 1;
1513  const MachineOperand& offset = mi->getOperand(o);
1514  if (operation.isBaseOffsetMemOperation()) {
1515  ++inputOperand;
1516  // the offset is always the 2nd operand for the standard
1517  // base+offset ops
1518  assert(inputOperand == 2);
1519 
1520  // create the offset operand move
1521  src = createTerminal(offset);
1522  dst = new TTAProgram::TerminalFUPort(op, inputOperand);
1523  TTAProgram::MoveGuard* guardCopy =
1524  guard == NULL ? NULL : guard->copy();
1525 
1526  auto move = createMove(src, dst, bus, guardCopy);
1527  instr = new TTAProgram::Instruction();
1528  instr->addMove(move);
1529  operandMoves.push_back(instr);
1530  debugDataToAnnotations(mi, *move);
1531  } else {
1532  assert(offset.getImm() == 0);
1533  }
1534  } else {
1535  src = createTerminal(mo);
1536  dst = new TTAProgram::TerminalFUPort(op, inputOperand);
1537  TTAProgram::MoveGuard* guardCopy =
1538  guard == NULL ? NULL : guard->copy();
1539 
1540  auto move = createMove(src, dst, bus, guardCopy);
1542  instr->addMove(move);
1543 #ifdef DEBUG_LLVMTCEBUILDER
1545  << "adding " << move->toString() << std::endl;
1546 #endif
1547  operandMoves.push_back(instr);
1548  debugDataToAnnotations(mi, *move);
1549  }
1550  } else {
1551  ++outputOperand;
1552  if (operation.operand(outputOperand).isNull())
1553  continue;
1554 
1555  assert(operation.operand(outputOperand).isOutput() &&
1556  !operation.operand(outputOperand).isAddress() &&
1557  "Operand mismatch.");
1558 
1559  src = new TTAProgram::TerminalFUPort(op, outputOperand);
1560  dst = createTerminal(mo);
1561 
1562  TTAProgram::MoveGuard* guardCopy =
1563  guard == NULL ? NULL : guard->copy();
1564 
1565  auto move = createMove(src, dst, bus, guardCopy);
1567  instr->addMove(move);
1568 #ifdef DEBUG_LLVMTCEBUILDER
1570  << "adding " << move->toString() << std::endl;
1571 #endif
1572  resultMoves.push_back(instr);
1573  debugDataToAnnotations(mi, *move);
1574  }
1575  } // End of for each MI Operand
1576 
1577  for (unsigned int i = 0; i < resultMoves.size();i++) {
1578  TTAProgram::Instruction& resultIns = *resultMoves[i];
1579  for (int j = 0; j < resultIns.moveCount(); j++) {
1580  TTAProgram::Move& resultMove = resultIns.move(j);
1581  // if some operand was mem operand, copy the addr space annotations from that operand
1582  copyFUAnnotations(operandMoves, resultMove);
1583  }
1584  }
1585  // Return the first instruction of the whole operation.
1586  TTAProgram::Instruction* first = NULL;
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) {
1592  // LLVM allows RET without any paramters and with defined return value.
1593  // RET with return value is converted above but not the other one.
1594  // To convert it to move, we just write 0 as source terminal.
1595  // LLVM already generated code to put return address on a top of the stack,
1596  // so no point explicitely writing ra -> ret.1.
1597  const TTAMachine::HWOperation* jump = &getHWOperation(opName);
1599  new TTAProgram::TerminalFUPort(*jump, 1);
1600  int width = mach_->is64bit() ? 64 : 32;
1601  SimValue val(0, width);
1602 
1603  auto move = createMove(
1604  new TTAProgram::TerminalImmediate(val), dst, bus);
1606  instr->addMove(move);
1607  operandMoves.push_back(instr);
1608  first = instr;
1609  debugDataToAnnotations(mi, *move);
1610  } else {
1611  assert(false && "No moves?");
1612  }
1613  ProgramOperationPtr po(new ProgramOperation(operation, mi));
1614 
1615  // Read candidate FUs from MachineInstr metadata.
1616  std::vector<std::string> candidateFUs;
1617  for (unsigned i = 0; i < mi->getNumOperands(); ++i) {
1618 
1619  const MachineOperand& op = mi->getOperand(i);
1620  if (!op.isMetadata()) continue;
1621  const MDNode* mdNode = op.getMetadata();
1622  if (mdNode->getNumOperands() > 0) {
1623 
1624  llvm::Metadata* op = mdNode->getOperand(0);
1625  MDString* str = dyn_cast<llvm::MDString>(op);
1626 
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();
1632  /* The metadata from MachineInstr might contain "illegal"
1633  FU candidates, pointing to FUs that do not contain the
1634  operation. Filter them out. */
1635  if (mach_->functionUnitNavigator().hasItem(fuName) &&
1636  mach_->functionUnitNavigator().item(fuName)->
1637  hasOperation(operation.name())) {
1638 #ifdef DEBUG_LLVMTCEBUILDER
1640  << "FU candidate " << str->getString().str() << " set for ";
1641  mi->dump();
1642 #endif
1643  candidateFUs.push_back(str->getString().str());
1644  }
1645  }
1646  }
1647  }
1648  }
1649 
1650  for (unsigned i = 0; i < operandMoves.size(); i++) {
1651  TTAProgram::Instruction* instr = operandMoves[i];
1652  auto m = instr->movePtr(0);
1653 
1654  // Add candidate FUs as DST candidates
1655  for (unsigned j = 0; j < candidateFUs.size(); ++j) {
1656  if (m->hasAnnotations(
1658  !m->hasAnnotation(
1660  candidateFUs[j]))
1661  continue; // do not add candidates that are not allowed
1662 
1663  m->addAnnotation(
1666  }
1667 
1668  // create the memory category annotations
1669  if (isSpill) {
1670  m->addAnnotation(
1673  } else if (isRaSlot) {
1674  m->addAnnotation(
1677  } else if (isFpSlot) {
1678  m->addAnnotation(
1681  }
1682 
1683  proc->add(instr);
1684  createMoveNode(po, m, true);
1685  }
1686  for (unsigned i = 0; i < resultMoves.size(); i++) {
1687  TTAProgram::Instruction* instr = resultMoves[i];
1688  auto m = instr->movePtr(0);
1689 
1690  // Add candidate FUs as SRC candidates
1691  for (unsigned j = 0; j < candidateFUs.size(); ++j) {
1692  if (m->hasAnnotations(
1694  !m->hasAnnotation(
1696  candidateFUs[j]))
1697  continue; // do not add candidates that are not allowed
1698 
1699  m->addAnnotation(TTAProgram::ProgramAnnotation(
1701  }
1702 
1703  // create the memory category annotations
1704  if (isSpill) {
1705  m->addAnnotation(
1708  } else if (isRaSlot) {
1709  m->addAnnotation(
1712  } else if (isFpSlot) {
1713  m->addAnnotation(
1716  }
1717 
1718  proc->add(instr);
1719  createMoveNode(po, m, false);
1720  }
1721 
1722  delete guard; guard = NULL;
1723  return first;
1724 }
1725 
1726 
1728  TCEString opName, const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
1729 
1730  const HWOperation& op = getHWOperation(opName);
1731 
1732  OperationPool pool;
1733  const Operation& operation = pool.operation(opName.c_str());
1734  const Bus& bus = UniversalMachine::instance().universalBus();
1735 
1736  ProgramOperationPtr po(new ProgramOperation(operation, mi));
1737 
1738  TTAProgram::Instruction* first = nullptr;
1739  for (int i = 0; i < 2; i++) {
1740  const MachineOperand& mo = mi->getOperand(i);
1743  auto move = createMove(src, dst, bus);
1745  if (i == 0) {
1746  first = instr;
1747  }
1748  instr->addMove(move);
1749  proc->add(instr);
1750  createMoveNode(po, move, true);
1751  }
1752 
1753  // dummy result value, to universal machine register
1756  *UniversalMachine::instance().booleanRegisterFile().port(0), 0);
1757  auto move = createMove(src, dst, bus);
1759  instr->addMove(move);
1760  proc->add(instr);
1761  createMoveNode(po, move, false);
1762  return first;
1763 }
1764 
1766  TCEString opName, const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
1767 
1768  bool inverted = (opName[0] == '!');
1769  opName = opName.substr(1); // drop the inversion char
1770  const HWOperation& op = getHWOperation(opName);
1771 
1772  OperationPool pool;
1773  const Operation& operation = pool.operation(opName.c_str());
1774  const Bus& bus = UniversalMachine::instance().universalBus();
1775 
1776  ProgramOperationPtr po(new ProgramOperation(operation, mi));
1777  const MachineOperand& mo = mi->getOperand(2);
1780 
1781  RegisterGuard* bypassRegGuard =
1782  new RegisterGuard(inverted,
1783  UniversalMachine::instance().booleanRegisterFile(),
1784  0, nullptr);
1785 
1786  auto move = createMove(src, dst, bus, (new TTAProgram::MoveGuard(*bypassRegGuard)));
1788  instr->addMove(move);
1789  proc->add(instr);
1790  createMoveNode(po, move, true);
1791  return instr;
1792 }
1793 
1794 
1795 
1796 void
1798  const std::vector<TTAProgram::Instruction*>& operandMoves,
1799  TTAProgram::Move& move) const {
1800  for (unsigned int i = 0; i < operandMoves.size(); i++) {
1801  TTAProgram::Move& operandMove = operandMoves[i]->move(0);
1802  for (int j = 0; j < operandMove.annotationCount(); j++) {
1803  TTAProgram::ProgramAnnotation anno = operandMove.annotation(j);
1804  if (anno.id() ==
1806  move.addAnnotation(
1809  anno.payload()));
1810  }
1811  }
1812  }
1813 }
1814 
1815 /**
1816  * Adds annotations to a pointer-register move to assist the
1817  * TCE-side alias analysis.
1818  *
1819  * Note: this function now assumes that mi has only one address
1820  * operand.
1821  */
1822 void
1824  const llvm::MachineInstr* mi, TTAProgram::Move& move) {
1825 
1826  // copy some pointer data to Move annotations
1827 #if 0
1828  if (mi->memoperands_begin() == mi->memoperands_end()) {
1829  Application::logStream() << "move " << move->toString()
1830  << " does not have mem operands!"
1831  << std::endl;
1832  }
1833 #endif
1834 
1835  if (pregions_->markersFound()) {
1836  unsigned nodeId = pregions_->pregion(*mi);
1837  if (nodeId != UINT_MAX) {
1838  TTAProgram::ProgramAnnotation progAnnotation(
1840  nodeId);
1841  move.addAnnotation(progAnnotation);
1842  }
1843  }
1844 
1845  int addrSpaceId = 0;
1846  // TODO: why this is a loop actually?? It only handles a single
1847  // Move anyways --Pekka
1848  for (MachineInstr::mmo_iterator i = mi->memoperands_begin();
1849  i != mi->memoperands_end(); i++) {
1850 
1851  const PseudoSourceValue* psv = (*i)->getPseudoValue();
1852  if (psv != NULL) {
1853  if (psv->isConstant(curFrameInfo_)) {
1854  TTAProgram::ProgramAnnotation progAnnotation(
1856  move.addAnnotation(progAnnotation);
1857  } else {
1858 // it seems this breaks something, so disabled.
1859 #if 0
1860  if (!psv->isAliased(curFrameInfo_)) {
1861  TTAProgram::ProgramAnnotation progAnnotation(
1863  move.addAnnotation(progAnnotation);
1864  }
1865 #endif
1866  }
1867  }
1868  const llvm::Value* memOpValue = (*i)->getValue();
1869 
1870  if (memOpValue != NULL) {
1871  std::string pointerName = "";
1872  // can we get the name right away or have to through
1873  // GetElemntPtrInst
1874 
1875  if (memOpValue->hasName()) {
1876  pointerName = memOpValue->getName().str();
1877  } else if (isa<GetElementPtrInst>(memOpValue)) {
1878  memOpValue =
1879  cast<GetElementPtrInst>(
1880  memOpValue)->getPointerOperand();
1881  if (memOpValue->hasName()) {
1882  pointerName = memOpValue->getName().str();
1883  }
1884  }
1885 
1886  /// TODO: this is not very optimal, it gets the offset
1887  /// info only for the memory accesses to function argument
1888  /// pointers?
1889  if (pointerName.length() > 0 &&
1890  isa<Argument>(memOpValue)) {
1891  unsigned offset;
1892  offset = (*i)->getOffset();
1893  TTAProgram::ProgramAnnotation progAnnotation(
1895  offset);
1896  move.addAnnotation(progAnnotation);
1897  }
1898 
1899  // try to find the origin for the pointer which can be
1900  // a function argument with 'noalias' attribute set
1901  const llvm::Value* originMemOpValue = memOpValue;
1902  while (originMemOpValue != NULL) {
1903  TCEString currentPointerName =
1904  (std::string)originMemOpValue->getName();
1905 
1906  // Query metadata of the memory operands to find work item
1907  // identifiers for OpenCL memory operands.
1908  if (dyn_cast<Instruction>(originMemOpValue) &&
1909  dyn_cast<Instruction>(originMemOpValue)->getMetadata("wi")) {
1910  const MDNode* md =
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());
1920 
1921  int id = (CZ->getZExtValue() & 0x0FF)
1922  | ((CY->getZExtValue() & 0x0FF) << 8)
1923  | ((CX->getZExtValue() & 0x0FF) << 16);
1924  TTAProgram::ProgramAnnotation progAnnotation(
1926  ANN_OPENCL_WORK_ITEM_ID, id);
1927  move.addAnnotation(progAnnotation);
1928  // In case the memory operand is BitCastInst, we may be
1929  // looking at the vector memory access.
1930  // Find the type of the accessed element and if it is
1931  // vector add second annotation marking the last work
1932  // it id the vector is accessing.
1933  // Without this information there DDGBuilder can not
1934  // correctly create edges.
1935  if (isa<BitCastInst>(originMemOpValue)) {
1936  llvm::Type* type =
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();
1942  #else
1943  //TODO: Replace this with getLoadStoreType but
1944  // it takes a non const argument?
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();
1951  else
1952  typeElem = cast<StoreInst>(originMemOpValue)
1953  ->getValueOperand()->getType();
1954  #endif
1955  if (typeElem->isVectorTy()) {
1956  int numElems = cast<VectorType>(typeElem)
1957  ->getElementCount()
1958  .getKnownMinValue();
1959  int idLast = (CZ->getZExtValue() & 0x0FF)
1960  | ((CY->getZExtValue() & 0x0FF) << 8)
1961  | (((CX->getZExtValue()
1962  + numElems) & 0x0FF) << 16);
1963  TTAProgram::ProgramAnnotation progAnnotation(
1965  ANN_OPENCL_WORK_ITEM_ID_LAST, idLast);
1966  move.addAnnotation(progAnnotation);
1967  }
1968  }
1969  }
1970  }
1971 
1972  if (isa<Argument>(originMemOpValue) &&
1973  cast<Argument>(originMemOpValue)->hasNoAliasAttr()) {
1974  TTAProgram::ProgramAnnotation progAnnotation(
1976  ANN_POINTER_NOALIAS, 1);
1977  move.addAnnotation(progAnnotation);
1978  noAliasFound_ = true;
1979 
1980 
1981  /// FIXME: this is not correct, especially
1982  /// when the above offset info is set!
1983 
1984  /*
1985  As the restrict keyword is assigned only to the pointer
1986  we found, we now pretend we are accessing through
1987  that pointer even though we might not be as the
1988  new pointer might be created through pointer
1989  arithmetic. In case
1990  we are not, the offset in the pointer arithmetic
1991  should be associated with the real pointer, not
1992  the origin pointer with the restrict keyword!
1993 
1994  Correct way is to add another annotation from
1995  which restrict pointer the current pointer is
1996  derived from and separate annotation for the
1997  real pointer name + offset.
1998  */
1999  pointerName = originMemOpValue->getName().str();
2000  break;
2001  } else if (isa<GetElementPtrInst>(originMemOpValue)) {
2002  originMemOpValue =
2003  cast<GetElementPtrInst>(originMemOpValue)->
2004  getPointerOperand();
2005  } else if (isa<BitCastInst>(originMemOpValue)) {
2006  originMemOpValue =
2007  cast<BitCastInst>(originMemOpValue)->
2008  getOperand(0);
2009  } else if (isa<PtrToIntInst>(originMemOpValue)) {
2010  originMemOpValue =
2011  cast<PtrToIntInst>(originMemOpValue)->
2012  getOperand(0);
2013  } else {
2014  break;
2015  }
2016  }
2017 
2018  if (pointerName != "") {
2019  TTAProgram::ProgramAnnotation pointerAnn(
2021  pointerName);
2022  move.addAnnotation(pointerAnn);
2023  }
2024 
2025  addrSpaceId =
2026  cast<PointerType>(memOpValue->getType())->
2027  getAddressSpace();
2028 
2029  if (addrSpaceId != 0) {
2030  // this annotation is used only for alias analysis as
2031  // the address spaces are assumed to be always disjoint
2032  std::string addressSpace =
2033  (boost::format("%d") % addrSpaceId).str();
2034  TTAProgram::ProgramAnnotation progAnnotation(
2036  addressSpace);
2037  move.addAnnotation(progAnnotation);
2038  multiAddrSpacesFound_ = true;
2039  }
2040  }
2041  }
2042  if (multiDataMemMachine_) {
2043  // annotate all memory moves with FU candidate sets
2044  // so the memory operations are assigned to the correct
2045  // load-store units in the multimemory machine
2046 
2047  // for stack accesses, there is no LLVM pointer info in which
2048  // case we add the default addr space id 0
2049  addCandidateLSUAnnotations(addrSpaceId, move);
2050  }
2051 }
2052 
2053 /**
2054  * Helper method that converts LLVM debug data markers to Move annotations.
2055  */
2056 void
2058  const llvm::MachineInstr* mi, TTAProgram::Move& move) {
2059 
2060  // annotate the moves generated from known ra saves.
2061  if (mi->getFlag(MachineInstr::FrameSetup)) {
2062  TTAProgram::ProgramAnnotation progAnnotation(
2064  move.setAnnotation(progAnnotation);
2065  }
2066 
2067  DebugLoc dl = mi->getDebugLoc();
2068  if (!dl)
2069  return;
2070 
2071  // TODO: nobody currently generates these
2072  // spill line number kludges, this is deprecated.
2073  // annotate the moves generated from known spill instructions
2074  if (dl.getLine() == 0xFFFFFFF0) {
2075  TTAProgram::ProgramAnnotation progAnnotation(
2077  move.setAnnotation(progAnnotation);
2078  ++spillMoveCount_;
2079  } else {
2080  // handle file+line number debug info
2081 
2082  bool hasDebugInfo = false;
2083  hasDebugInfo = dl.getScope() != NULL;
2084  if (hasDebugInfo) {
2085 
2086  int sourceLineNumber = -1;
2087  TCEString sourceFileName = "";
2088 
2089  // inspired from lib/codegen/MachineInstr.cpp
2090  sourceLineNumber = dl.getLine();
2091  sourceFileName =
2092  static_cast<TCEString>(
2093  cast<DIScope>(dl.getScope())->getFilename().str());
2094 
2095  if (sourceFileName.size() >
2097  sourceFileName =
2098  sourceFileName.substr(
2099  sourceFileName.size() -
2102  }
2103  TTAProgram::ProgramAnnotation progAnnotation(
2105  sourceLineNumber);
2106  move.addAnnotation(progAnnotation);
2107 
2108  if (sourceFileName != "") {
2109  TTAProgram::ProgramAnnotation progAnnotation(
2111  ANN_DEBUG_SOURCE_CODE_PATH,
2112  sourceFileName);
2113  move.addAnnotation(progAnnotation);
2114  }
2115  }
2116  }
2117 }
2118 
2121  const std::string& rfName, int idx) {
2122 
2123  const RegisterFile* rf;
2124  if (!mach_->registerFileNavigator().hasItem(rfName)) {
2126  } else {
2127  rf = mach_->registerFileNavigator().item(rfName);
2128  assert(idx >= 0 && idx < rf->size());
2129  }
2130 
2131  const RFPort* port = NULL;
2132  for (int i = 0; i < rf->portCount(); i++) {
2133  if (rf->port(i)->isOutput()) {
2134  port = rf->port(i);
2135  break;
2136  }
2137  }
2138  assert(port != NULL);
2139  return new TTAProgram::TerminalRegister(*port, idx);
2140 }
2141 
2142 /**
2143  * Creates a POM source terminal from an LLVM machine operand.
2144  *
2145  * @param mo LLVM machine operand.
2146  * @return POM terminal.
2147  */
2149 LLVMTCEBuilder::createTerminal(const MachineOperand& mo, int bitLimit) {
2150  if (bitLimit == 0) {
2151  bitLimit = mach_->is64bit() ? 64 : 32;
2152  }
2153 
2154  if (mo.isReg()) {
2155  unsigned dRegNum = mo.getReg();
2156 
2157  // is it the RA register?
2158  if (isTTATarget() && dRegNum == raPortDRegNum()) {
2159  return new TTAProgram::TerminalFUPort(
2160  *UniversalMachine::instance().controlUnit()->
2161  returnAddressPort());
2162  }
2163 
2164  // an FU port register?
2166  if (term != NULL)
2167  return term;
2168 
2169  // a general purpose register?
2170  std::string rfName = registerFileName(dRegNum);
2171  int idx = registerIndex(dRegNum);
2172  return createTerminalRegister(rfName, idx);
2173  } else if (mo.isFPImm()) {
2174  const APFloat& apf = mo.getFPImm()->getValueAPF();
2175  if (&apf.getSemantics() == &APFloat::IEEEhalf()) { //Half float
2176  APInt api = apf.bitcastToAPInt();
2177  uint16_t binary = (uint16_t)api.getRawData()[0];
2178  SimValue val(bitLimit);
2179  val = HalfFloatWord( binary );
2180  return new TTAProgram::TerminalImmediate(val);
2181  } else {
2182  float fval = apf.convertToFloat();
2183  SimValue val(bitLimit);
2184  val = fval;
2185  return new TTAProgram::TerminalImmediate(val);
2186  }
2187  } else if (mo.isImm()) {
2188  int width = bitLimit;
2189  SimValue val(mo.getImm(), width);
2190  return new TTAProgram::TerminalImmediate(val);
2191  } else if (mo.isMBB() || mo.isBlockAddress()) {
2192  return createMBBReference(mo);
2193  } else if (mo.isFI()) {
2194  std::cerr << " Frame index source operand NOT IMPLEMENTED!"
2195  << std::endl;
2196  assert(false);
2197  } else if (mo.isCPI()) {
2198  if (!functionAtATime_) {
2199  int width = bitLimit;
2200  unsigned idx = mo.getIndex();
2201  assert(currentFnCP_.find(idx) != currentFnCP_.end() &&
2202  "CPE not found!");
2203  unsigned addr = currentFnCP_[idx];
2204  SimValue cpeAddr(addr, width);
2205  return new TTAProgram::TerminalImmediate(cpeAddr);
2206  } else {
2207  // Constant Pool Index is converted to dummy
2208  // symbol reference. Will be converted back
2209  // when doing POM->LLVM transfer.
2210  // Format of reference is ".CP_INDEX_OFFSET".
2211  TCEString ref(".CP_");
2212  ref << mo.getIndex() << "_" << mo.getOffset();
2213  return createSymbolReference(ref);
2214  }
2215  } else if (mo.isJTI()) {
2216  TCEString ref(".JTI_");
2217  ref << mo.getIndex();
2218  return createSymbolReference(ref);
2219  } else if (mo.isGlobal()) {
2220  unsigned aSpaceId =
2221  cast<PointerType>(mo.getGlobal()->getType())->getAddressSpace();
2222 
2223  TTAMachine::AddressSpace& aSpace =
2224  addressSpaceById(aSpaceId);
2225 
2226  SmallString<256> Buffer;
2227  mang_->getNameWithPrefix(Buffer, mo.getGlobal(), false);
2228  TCEString name(Buffer.c_str());
2229 
2230  if (name == END_SYMBOL_NAME) {
2231  return createSymbolReference(name);
2232  } else if (dataLabels_.find(name) != dataLabels_.end()) {
2233  SimValue address(dataLabels_[name] + mo.getOffset(), bitLimit);
2234  return new TTAProgram::TerminalAddress(address, aSpace);
2235 
2236  } else {
2237  // TODO: this lacks offset??
2238  return createSymbolReference(name);
2239  }
2240  } else if (mo.isJTI()) {
2241  std::cerr << " Jump table index operand NOT IMPLEMENTED!\n";
2242  assert(false);
2243  } else if (mo.isSymbol()) {
2244  return createSymbolReference(mo);
2245  } else if (mo.isMCSymbol()) {
2247  } else if (mo.isMetadata()) {
2248  assert("Metadata MachineOperands should not get here" && false);
2249  } else {
2250  std::cerr << "Unknown src operand type!" << std::endl;
2251  // LLVM does not include dump() when built in non-debug mode.
2252  // mo.getParent()->dump();
2253  assert(false);
2254  }
2255  abortWithError("Should not get here!");
2256  return NULL;
2257 }
2258 
2261  const MachineOperand& mo) {
2262  llvm::MCSymbol* symbol = mo.getMCSymbol();
2264  new TTAProgram::TerminalProgramOperation(symbol->getName().str());
2265  symbolicPORefs_.insert(term);
2266  return term;
2267 }
2268 
2269 /**
2270  * Fixes the symbolic ProgramOperation references to point to the
2271  * now created real ProgramOperations.
2272  *
2273  * Assumes the POs are found in the label index.
2274  */
2275 void
2277  for (std::set<TTAProgram::TerminalProgramOperation*>::const_iterator i =
2278  symbolicPORefs_.begin(); i != symbolicPORefs_.end(); ++i) {
2280  if (term->isProgramOperationKnown()) continue;
2281  ProgramOperationPtr po = labeledPOs_[term->label()];
2282  assert(po.get() != NULL);
2283  term->setProgramOperation(po);
2284  }
2285 }
2286 
2288 LLVMTCEBuilder::createMBBReference(const MachineOperand& mo) {
2290 
2293  mbbReferences_[ref] = mbbName(*mo.getMBB());
2294  return ref;
2295 }
2296 
2298 LLVMTCEBuilder::createSymbolReference(const MachineOperand& mo) {
2299  //} else if (mo.isExternalSymbol()) {
2300 
2301  /**
2302  * NOTE: Hack to get code compiling even if llvm falsely makes libcalls to
2303  * external functions even if they are found from currently lowered program.
2304  *
2305  * http://llvm.org/bugs/show_bug.cgi?id=2673
2306  *
2307  * Should be removed after fix is applied to llvm.. (maybe never...)
2308  */
2309  return createSymbolReference(mo.getSymbolName());
2310 }
2311 
2314  if (name == END_SYMBOL_NAME) {
2315  return NULL;
2316  }
2317 
2320 
2321 
2324  *dummy);
2325 
2326  codeLabelReferences_[ref] = name;
2327  return ref;
2328  /**
2329  * END OF HACK
2330  */
2331 
2332 }
2333 
2334 /**
2335  * Reserves space and addresses for constant pool entries.
2336  *
2337  * Data defitions are not emitted until in doFinalization() because CP values
2338  * may refer to symbols not yet encountered such as functions and _end symbol.
2339  *
2340  * The constant pool is appended to the end of the default data memory.
2341  * FIXME: should be emitted before global data.
2342  *
2343  * @param mcp Constant pool to emit.
2344  */
2345 void
2346 LLVMTCEBuilder::emitConstantPool(const MachineConstantPool& mcp) {
2347 
2348  currentFnCP_.clear();
2349 
2350  const std::vector<MachineConstantPoolEntry>& cp = mcp.getConstants();
2351 
2352  const unsigned cpAddrSpaceId = 0;
2353  unsigned& dataEndPos = dataEnd(addressSpaceById(cpAddrSpaceId));
2354 
2355  for (unsigned i = 0, e = cp.size(); i != e; ++i) {
2356  auto& cpe = cp[i];
2357  assert(!(cpe.isMachineConstantPoolEntry()) && "NOT SUPPORTED");
2358  if (!globalCP_.count(cpe.Val.ConstVal)) {
2359  // New unique constant.
2360  assert(cpe.getAlign().value() > 0);
2361  unsigned alignment = cpe.getAlign().value();
2362  padToAlignment(cpAddrSpaceId, dataEndPos, alignment);
2363  unsigned address = dataEndPos;
2364 
2365  unsigned size = cpe.getSizeInBytes(*dl_);
2366  cpData_.emplace_back(ConstantDataDef(
2367  address, alignment, size, cpe.Val.ConstVal));
2368  globalCP_.insert(std::make_pair(cpe.Val.ConstVal, address));
2369  dataEndPos += size;
2370  // std::cerr << "Constant* = " << cpe.Val.ConstVal << ", "
2371  // << "value = ";
2372  // cpe.Val.ConstVal->dump();
2373  }
2374  // Map current machine function constant pool indexes to the
2375  // addresses of the global CP constants.
2376  currentFnCP_[i] = globalCP_.at(cpe.Val.ConstVal);
2377  }
2378 }
2379 
2380 
2381 /**
2382  * Creates POM instruction for a move.
2383  *
2384  * @param src The source operand.
2385  * @param dst The dst operand.
2386  * @return POM Move.
2387  */
2388 std::shared_ptr<TTAProgram::Move>
2390  const MachineOperand& src, const MachineOperand& dst,
2391  TTAProgram::MoveGuard* guard) {
2392  assert(!src.isReg() || src.isUse());
2393  assert(dst.isDef());
2394 
2395  // eliminate register-to-itself moves
2396  if (dst.isReg() && src.isReg() && dst.getReg() == src.getReg()) {
2397  return NULL;
2398  }
2399 
2401  TTAProgram::Terminal* dstTerm = createTerminal(dst);
2402  TTAProgram::Terminal* srcTerm =
2403  createTerminal(src, dstTerm->port().width());
2404 
2405  auto move = createMove(srcTerm, dstTerm, bus, guard);
2406 
2407  return move;
2408 }
2409 
2410 /**
2411  * Creates POM instruction for a move.
2412  *
2413  * @param mi Move machine instruction.
2414  * @param proc POM procedure to add the move to.
2415  * @return Emitted POM instruction.
2416  */
2419  const MachineInstr* mi, TTAProgram::CodeSnippet* proc,
2420  bool conditional, bool trueGuard) {
2421 
2422  unsigned int operandCount = conditional ? 3 : 2;
2423  if (mi->getNumOperands() > operandCount) {
2424  for (unsigned int i = operandCount; i < mi->getNumOperands(); i++) {
2425 #if 0
2426  if (!(mi->getOperand(i).isMetadata()) &&
2427  (!mi->getOperand(i).isImplicit())) {
2428  mi->dump();
2429  }
2430 #endif
2431  assert(mi->getOperand(i).isMetadata() ||
2432  mi->getOperand(i).isImplicit());
2433  }
2434  }
2435 
2436  assert(mi->getNumOperands() >= operandCount); // src, dst
2437 
2438  const MachineOperand& dst = mi->getOperand(0);
2439  const MachineOperand& src = mi->getOperand(operandCount - 1);
2440  TTAProgram::MoveGuard* guard = NULL;
2441  if (conditional) {
2442  const MachineOperand& gmo = mi->getOperand(1);
2443  assert (gmo.isReg() && gmo.isUse());
2444  // Create move from the condition operand register to bool register
2445  // which is used by the guard.
2447  // inv guards not yet supported
2448  guard = createGuard(t, trueGuard);
2449  }
2450 
2451  TTAProgram::Terminal* dstTerm = createTerminal(dst);
2452  TTAProgram::Terminal* srcTerm =
2453  createTerminal(src, dstTerm->port().width());
2454 
2455  if (srcTerm->isGPR() && dstTerm->isGPR() &&
2456  &srcTerm->registerFile() == &dstTerm->registerFile()) {
2457 
2458  // Omit no-op copies.
2459  if (srcTerm->index() == dstTerm->index())
2460  return NULL;
2461 
2462  if (srcTerm->registerFile().portCount() == 1) {
2463  // Cannot perform a reg2reg move with single ported register
2464  // files, need to find another way to perform the copy.
2465  const TTAMachine::HWOperation* copyOp = NULL;
2466 
2467  // Use only operations which get imm 0 as the other operand
2468  // for the lowest immediate requirements.
2469  if (mach_->hasOperation("XOR")) {
2470  copyOp = &getHWOperation("XOR");
2471  } else if (mach_->hasOperation("OR")) {
2472  copyOp = &getHWOperation("OR");
2473  } else if (mach_->hasOperation("ADD")) {
2474  copyOp = &getHWOperation("ADD");
2475  }
2476 
2477  if (copyOp == NULL || guard != NULL) {
2479  CompileError,
2480  TCEString("Unable to create a reg to reg copy due to "
2481  "having only one port in '") +
2482  srcTerm->registerFile().name() + "'.");
2483  }
2484 
2485  SimValue val(0, mach_->is64bit() ? 64 : 32);
2486 
2489  TTAProgram::TerminalFUPort* oprTerm =
2490  new TTAProgram::TerminalFUPort(*copyOp, 1);
2491  TTAProgram::TerminalFUPort* trigTerm =
2492  new TTAProgram::TerminalFUPort(*copyOp, 2);
2493  TTAProgram::TerminalFUPort* resTerm =
2494  new TTAProgram::TerminalFUPort(*copyOp, 3);
2495 
2496  Application::logStream() << "Created a reg to reg copy due to RF "
2497  << srcTerm->registerFile().name()
2498  << " having only 1 port" << std::endl;
2499  CodeGenerator codeGenerator(*mach_);
2500  // 0 -> OP.1
2501  codeGenerator.addMoveToProcedure(*proc, immTerm, oprTerm);
2502  // RF.X -> OP.2
2503  codeGenerator.addMoveToProcedure(*proc, srcTerm, trigTerm);
2504  // OP.3 -> RF.Y
2505  return codeGenerator.addMoveToProcedure(*proc, resTerm, dstTerm);
2506  }
2507  }
2509  auto move = createMove(srcTerm, dstTerm, bus, guard);
2510 
2511  if (move == NULL) {
2512  return NULL;
2513  }
2515 
2516  instr->addMove(move);
2517  proc->add(instr);
2518  return instr;
2519 }
2520 
2521 
2522 /**
2523  * Creates POM instructions for a return.
2524  *
2525  * @param mi Return machine instruction.
2526  * @param proc POM procedure to add the return to.
2527  * @return First of the emitted POM instructions.
2528  */
2531  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
2532 
2535  *UniversalMachine::instance().controlUnit()->returnAddressPort());
2536 
2537  TTAMachine::HWOperation& jump =
2539 
2540  OperationPool pool;
2541  const Operation& operation = pool.operation("jump");
2542 
2544  auto move = createMove(src, dst, bus);
2546  instr->addMove(move);
2547  proc->add(instr);
2548  ProgramOperationPtr po(new ProgramOperation(operation, mi));
2549  createMoveNode(po, move, true);
2550  return instr;
2551 }
2552 
2553 /**
2554  * Creates POM instructions for a select.
2555  *
2556  * @param mi select machine instruction.
2557  * @param proc POM procedure to add the select to.
2558  * @return First of the emitted POM instructions.
2559  */
2562  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
2563 
2564 // 0 = dest?
2565 
2566  const MachineOperand& guardMo = mi->getOperand(1);
2567 
2568  // Create move from the condition operand register to bool register
2569  // which is used by the guard.
2570  TTAProgram::Terminal *guardTerminal = createTerminal(guardMo);
2571 
2572  assert(guardTerminal != NULL);
2573 
2574  TTAProgram::Terminal* dstT = createTerminal(mi->getOperand(0));
2575  TTAProgram::Terminal* dstF = createTerminal(mi->getOperand(0));
2576  TTAProgram::Terminal* srcT = createTerminal(mi->getOperand(2));
2577  TTAProgram::Terminal* srcF = createTerminal(mi->getOperand(3));
2578 
2580  TTAProgram::Instruction *firstIns = NULL;
2581 
2582  // do no create X -> X moves.
2583  if (dstT->equals(*srcT)) {
2584  if (dstT->equals(*srcF)) {
2585  std::cerr << "Empty select!" << std::endl;
2586  return NULL;
2587  }
2588  delete srcT;
2589  delete dstT;
2590  } else {
2591  TTAProgram::MoveGuard* trueGuard = createGuard(guardTerminal, true);
2592  assert(trueGuard != NULL);
2593  auto trueMove = createMove(srcT, dstT, bus, trueGuard);
2595  trueIns->addMove(trueMove);
2596  proc->add(trueIns);
2597  firstIns = trueIns;
2598  }
2599 
2600  // do no create X -> X moves.
2601  if (dstF->equals(*srcF)) {
2602  delete srcF;
2603  delete dstF;
2604  } else {
2605  TTAProgram::MoveGuard* falseGuard = createGuard(guardTerminal, false);
2606  assert(falseGuard != NULL);
2607  auto falseMove = createMove(srcF, dstF, bus, falseGuard);
2609  falseIns->addMove(falseMove);
2610  proc->add(falseIns);
2611  if (firstIns == NULL) {
2612  firstIns = falseIns;
2613  }
2614  }
2615 
2616  // guardTerminal was just temporary used as helper when creating guards.
2617  delete guardTerminal;
2618 
2619  assert(firstIns != NULL);
2620  return firstIns;
2621 }
2622 
2623 /**
2624  * Returns string identifier for a basic block.
2625  *
2626  * These identifiers are used for the BB -> POM instruction book keeping.
2627  *
2628  * @param mbb Basic block object.
2629  * @return String identifier for the basic block.
2630  */
2631 std::string
2632 LLVMTCEBuilder::mbbName(const MachineBasicBlock& mbb) {
2633  SmallString<256> Buffer;
2634  mang_->getNameWithPrefix(Buffer, &mbb.getParent()->getFunction(), false);
2635  TCEString name(Buffer.c_str());
2636  name += " ";
2637  name += Conversion::toString(mbb.getNumber());
2638  return name;
2639 }
2640 
2641 /**
2642  * Returns true if the Constant value structure has initialized data.
2643  *
2644  * @param cv Initializer to check.
2645  * @return True, if the initializer has any non-Null data.
2646  */
2647 bool
2648 LLVMTCEBuilder::isInitialized(const Constant* cv) {
2649 
2650  if ((dyn_cast<ConstantArray>(cv) != NULL) ||
2651  (dyn_cast<ConstantStruct>(cv) != NULL) ||
2652  (dyn_cast<ConstantVector>(cv) != NULL)) {
2653 
2654  for (unsigned i = 0, e = cv->getNumOperands(); i != e; ++i) {
2655  if (isInitialized(cast<Constant>(cv->getOperand(i)))) {
2656  return true;
2657  }
2658  }
2659  return false;
2660  }
2661 
2662  return true;
2663 }
2664 
2665 /**
2666  * Emit stack pointer initialization move to the begining of the program.
2667  */
2668 void
2671 
2672  TTAProgram::Procedure& proc =
2673  dynamic_cast<TTAProgram::Procedure&>(first.parent());
2674 
2675  emitSPInitialization(proc);
2676 }
2677 
2678 void
2680 
2681  unsigned spDRN = spDRegNum();
2682  std::string spRfName = registerFileName(spDRN);
2683  int idx = registerIndex(spDRN);
2684  assert(mach_->registerFileNavigator().hasItem(spRfName));
2685  const RegisterFile* rf = mach_->registerFileNavigator().item(spRfName);
2686  assert(idx >= 0 && idx < rf->size());
2687  const RFPort* port = NULL;
2688  for (int i = 0; i < rf->portCount(); i++) {
2689  if (rf->port(i)->isOutput()) {
2690  port = rf->port(i);
2691  break;
2692  }
2693  }
2694  assert(port != NULL);
2695  TTAProgram::TerminalRegister* dst = new
2696  TTAProgram::TerminalRegister(*port, idx);
2697 
2698  unsigned ival = initialStackPointerValue_;
2699 
2700  const TCETargetMachine* tm = dynamic_cast<const TCETargetMachine*>(tm_);
2701  assert(tm != NULL);
2702  unsigned stackAlignment = tm->stackAlignment();
2703  unsigned mask = 0xffffffff;
2704 
2705  while (stackAlignment > 1) {
2706  mask = mask << 1;
2707  stackAlignment = stackAlignment >> 1;
2708  }
2709 
2710  if (initialStackPointerValue_ == 0 ||
2711  initialStackPointerValue_ > (addressSpaceById(0).end() & mask)) {
2712  ival = addressSpaceById(0).end() & mask;
2713  }
2714 
2715  SimValue val(ival, mach_->is64bit() ? 64 : 32);
2721  auto move = createMove(src, dst, bus);
2722  TTAProgram::Instruction* spInitInst =
2724  spInitInst->addMove(move);
2725  spInit->add(spInitInst);
2726  } else {
2727  // Immediate is not enough for the initial stack pointer value, //
2728  // must load it from memory. //
2729 
2730  // Data definition for initial stack pointer value stored at zero //
2731  // address //
2732 
2733  // FIXME: Assuming 8bit MAU.
2734  // TODO: FIXME: Also assumes 32-bit architecture!
2735  union {
2736  unsigned i;
2737  char bytes[4];
2738  } u;
2739 
2740  u.i = ival;
2741 
2742  std::vector<MinimumAddressableUnit> spmaus;
2743  unsigned nMaus = sizeof(unsigned);
2744  if (!mach_->isLittleEndian()) {
2745  for (unsigned i = 0; i < nMaus; i++) {
2746  spmaus.push_back(u.bytes[nMaus-i-1]);
2747  }
2748  } else {
2749  for (unsigned i = 0; i < nMaus; i++) {
2750  spmaus.push_back(u.bytes[i]);
2751  }
2752  }
2755  TTAProgram::Address zeroAddr(0, aSpace);
2757  zeroAddr, spmaus, mach_->isLittleEndian()));
2758 
2759  // Emit load for stack pointer //
2760  CodeGenerator codegen(*mach_);
2761  TTAProgram::TerminalAddress* zeroImm =
2762  new TTAProgram::TerminalAddress(SimValue(0, 32), aSpace);
2763 
2764  createSPInitLoad(*spInit, *zeroImm, *dst);
2765  }
2766 
2767  if (target.instructionCount() > 0) {
2768  TTAProgram::Instruction& first = target.firstInstruction();
2769  target.insertBefore(first, spInit);
2772  first, spInit->firstInstruction());
2773  }
2774  } else {
2775  target.append(spInit);
2776  }
2777 }
2778 
2779 /**
2780  * Handles INLINEASM nodes that hold real inline assembly code.
2781  *
2782  * This method should not be called for pseudo inline assembly - like TCE
2783  * operation macros (see emitOperationMacro()).
2784  */
2787  const MachineFunction& mf,
2788  const MachineInstr* mi,
2791 
2792  assert(isInlineAsm(*mi));
2793  assert(bb->instructionCount() == 0 && "Expected empty BB.");
2794 
2795  const TCETargetMachine* tm = dynamic_cast<const TCETargetMachine*>(tm_);
2796  assert(tm && "Inline asm parser requires TCETargetMachine.");
2797 
2798  // Avoid unintended overwrite of reserved registers.
2799  auto asmOpds = getInlineAsmOperands(*mi);
2800  for (auto& opds : asmOpds) {
2801  auto& asmOpdNodes = std::get<1>(opds.second);
2802  for (auto mo : asmOpdNodes) {
2803  if (!mo->isReg() ||
2804  !mf.getRegInfo().isReserved(mo->getReg())) {
2805  continue;
2806  }
2807  auto srcLoc = getSourceLocationString(*mi);
2808  std::cerr << srcLoc
2809  << "Error: An use of reserved register '"
2810  << tm->registerName(mo->getReg())
2811  << "' in inline assembly." << std::endl;
2813  CompileError,
2814  "Encountered errors in inline assembly.");
2815  }
2816  }
2817 
2818  // Static since the parser has state for "%=" template strings.
2819  static InlineAsmParser inlineAsmParser(*tm, *mang_);
2820 
2821  if (!inlineAsmParser.parse(*mi, dataLabels_, *bb, irm)) {
2822  auto& diag = inlineAsmParser.diagnostics();
2823  auto srcLoc = getSourceLocationInfo(*mi);
2824  if (!std::get<0>(srcLoc).empty()) {
2825  std::cerr << std::get<0>(srcLoc) << ":" << std::get<1>(srcLoc)
2826  << ":" << std::endl;
2827  }
2828  for (auto syntaxError : diag.errors()) {
2829  std::cerr << "Error in line " << syntaxError.lineNumber << ": "
2830  << syntaxError.message << std::endl;
2831  }
2832  for (auto internalError : diag.otherErrors()) {
2833  std::cerr << "Error: " << internalError.message << std::endl;
2834  }
2836  CompileError, "Encountered errors in inline assembly parsing.");
2837  }
2838 
2840  for (auto warning : inlineAsmParser.diagnostics().warnings()) {
2841  // TODO point to line in C code.
2842  std::cerr << warning.toString() << std::endl;
2843  }
2844  }
2845 
2846  return bb->instructionCount() ? &bb->instructionAtIndex(0)
2847  : nullptr;
2848 }
2849 
2850 /**
2851  * Handles operation macros which too uses INLINEASM nodes.
2852  *
2853  * Here the inline assembly string is expected to be just a name
2854  * of a (custom) operation. Operation operands are expected to be listed
2855  * as the inline assembly use and def registers. Architecture specific
2856  * pseudo assembly constructs are also supported (they start with dot) and
2857  * are delegated to emitSpecialInlineAsm().
2858  */
2861  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
2862 
2863 // mi->print(llvm::dbgs()); //DEBUG
2864 
2865 #ifndef NDEBUG
2866  unsigned numOperands =
2867 #endif
2868  mi->getNumOperands();
2869  // Count the number of register definitions.
2870  unsigned numDefs = 0;
2871  for (; mi->getOperand(numDefs).isReg() &&
2872  mi->getOperand(numDefs).isDef();
2873  ++numDefs) {
2874 
2875  }
2876  std::string opName = mi->getOperand(numDefs).getSymbolName();
2877 
2878  // ignore the dummy placeholder asm string
2879  if (opName == "") {
2880  return NULL;
2881  }
2882 
2883  if (opName[0] == '.') {
2884  // Special handling for dotted architecture-dependent asm contructs,
2885  // a.k.a. "pseudo assembly strings"
2886  return emitSpecialInlineAsm(opName, mi, proc);
2887  }
2888 
2889  std::vector<std::string> addressedFUs;
2890  // test this is an addressable instruction
2891  bool addressedOp = StringTools::containsChar(opName, '.');
2892 
2893  if (addressedOp) {
2894  if (opName.substr(0,3) == "_AS") {
2895  int addressSpaceId = -1;
2896  std::string foo;
2897  std::string addressedAS;
2898  std::istringstream iss(opName);
2899  std::getline(iss, foo, '.');
2900  std::getline(iss, addressedAS, '.');
2901  std::getline(iss, opName, '.');
2902  char *end;
2903 
2904  AddressSpace* targetAS = NULL;
2905 
2906  if (addressedAS.size() && addressedAS[0] == '#') {
2907  addressSpaceId = strtol(addressedAS.c_str()+1, &end, 10);
2908  if (end == addressedAS.c_str()+1) {
2909  std::cerr << "ERROR: Address space id following # not a number '" << addressedAS
2910  << std::endl;
2911  } else {
2912  // find addresspace with given id
2914  for (int i = 0; i < nav.count(); i++) {
2915  AddressSpace* as = nav.item(i);
2916  if (as->hasNumericalId(addressSpaceId)) {
2917  targetAS = as;
2918  break;
2919  }
2920  }
2921  }
2922  } else {
2924  for (int i = 0; i < nav.count(); i++) {
2925  AddressSpace* as = nav.item(i);
2926  if (as->name() == addressedAS) {
2927  targetAS = as;
2928  break;
2929  }
2930  }
2931  }
2932 
2933  if (targetAS == NULL) {
2934  std::cerr << "ERROR: Address space '" << addressedAS
2935  << "' not found."
2936  << std::endl;
2937  assert(false);
2938  }
2939 
2940  // find function units with given as.
2942  for (int j = 0; j < fuNav.count(); j++) {
2943  const FunctionUnit* fu = fuNav.item(j);
2944  if (fu->addressSpace() == targetAS) {
2945  addressedFUs.push_back(fu->name());
2946  }
2947  }
2948  } else {
2949  // Split the string to get the FU and the operation
2950  std::string addressedFU;
2951 
2952  std::istringstream iss(opName);
2953  std::getline(iss, addressedFU, '.');
2954  std::getline(iss, opName, '.');
2955  if (!mach_->functionUnitNavigator().hasItem(addressedFU)) {
2956  std::cerr << "ERROR: Function Unit '" << addressedFU
2957  << "' not found."
2958  << std::endl;
2959  assert(false);
2960  }
2961  addressedFUs.push_back(addressedFU);
2962  }
2963  }
2964 
2965  assert(numDefs != numOperands-1 && "No asm string?");
2966  assert(mi->getOperand(numDefs).isSymbol() && "No asm string?");
2967 
2968  if (StringTools::containsChar(opName, ' ') ||
2969  StringTools::containsChar(opName, ';') ||
2970  StringTools::containsChar(opName, '>') ||
2971  StringTools::containsChar(opName, '<')) {
2972 
2973  std::cerr << "ERROR: Inline assembly not supported!" << std::endl;
2974  assert(false);
2975  }
2976 
2978  if (!fu.hasOperation(opName)) {
2979  std::cerr
2980  << "ERROR: Explicitly executed operation '"
2981  << opName << "' does not match any operation definition in OSAL."
2982  << std::endl;
2983  assert(false);
2984  }
2985 
2986  HWOperation* op = fu.operation(opName);
2987 
2989  std::vector<TTAProgram::Instruction*> operandMoves;
2990  std::vector<TTAProgram::Instruction*> resultMoves;
2993 
2994 
2995  OperationPool pool;
2996  const Operation& operation = pool.operation(opName.c_str());
2997  int inputOperand = 0;
2998 
2999  const MachineFunction& mf = *mi->getParent()->getParent();
3000 
3001  // Go through the operands.
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()) {
3008  continue;
3009  } else if (o == asmDescOp && mo.isImm()) {
3010  // Skip inline assembly flags.
3011  unsigned flag = mo.getImm();
3012  if (InlineAsm::getKind(flag) == InlineAsm::Kind_Clobber) {
3013  clobberOp = o + 1;
3014  }
3015 
3016  asmDescOp += 1 + InlineAsm::getNumOperandRegisters(flag);
3017  continue;
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."
3023  << std::endl;
3024  }
3025  } else if (!(mo.isReg() || mo.isImm() || mo.isGlobal())) {
3026  // All operands should be immediates or in registers.
3027  // Everything else is ignored.
3028  std::cerr << "Ignoring an operand of " << opName << std::endl;
3029  continue;
3030  }
3031 
3032  TTAProgram::Terminal* src = NULL;
3033  TTAProgram::Terminal* dst = NULL;
3034  if (mo.isImm() || mo.isGlobal() || mo.isUse()) {
3035  // implicit usage of whole vector when one element used.
3036  if (useOps.empty()) {
3037  // ignore implicit defs that are too many.
3038  if (mo.isImplicit()) {
3039  continue;
3040  }
3041  std::cerr << std::endl;
3042  std::cerr <<"ERROR: Too many input operands for custom "
3043  << "operation '" << opName << "'." << std::endl;
3044  assert(false);
3045  }
3046  src = createTerminal(mo);
3047  dst = new TTAProgram::TerminalFUPort(*op, (*useOps.begin()));
3048  useOps.erase(useOps.begin());
3049  ++inputOperand;
3050  } else {
3051  if (defOps.empty()) {
3052  // ignore implicit defs that are too many.
3053  if (mo.isImplicit()) {
3054  continue;
3055  }
3056  std::cerr << std::endl;
3057  std::cerr << "ERROR: Too many output operands for custom "
3058  << "operation '" << opName << "'." << std::endl;
3059  assert(false);
3060  }
3061  assert(mo.isReg());
3062  if (mf.getRegInfo().isReserved(mo.getReg())) {
3063  std::cerr << "Warning: inline assembly overwriting"
3064  << " reserved register (regNum = " << mo.getReg()
3065  << ") has undefined behavior."
3066  << std::endl;
3067  }
3068 
3069  src = new TTAProgram::TerminalFUPort(*op, (*defOps.begin()));
3070  dst = createTerminal(mo);
3071  defOps.erase(defOps.begin());
3072 
3073  }
3074 
3075  auto move = createMove(src, dst, bus);
3077  instr->addMove(move);
3078 
3079  if (mo.isImm() || mo.isGlobal() || mo.isUse()) {
3080  operandMoves.push_back(instr);
3081 
3082  // Custom memory accessing operation? Assume absolute addr for now.
3083  if (operation.operand(inputOperand).isAddress()) {
3084  debugDataToAnnotations(mi, *move);
3085  addPointerAnnotations(mi, *move);
3086  }
3087  } else {
3088  resultMoves.push_back(instr);
3089  }
3090  }
3091 
3092  if (!defOps.empty() || !useOps.empty()) {
3093  std::cerr << "ERROR: All operands not defined for custom operation '"
3094  << opName << "'." << std::endl;
3095 
3096  std::cerr << "Undefined: " << defOps.size() << " output operands, "
3097  << useOps.size() << " input operands." << std::endl;
3098 
3099  abortWithError("Cannot continue");
3100  }
3101 
3102  // Return the first instruction of the whole operation.
3103  TTAProgram::Instruction* first = NULL;
3104  if (!operandMoves.empty()) {
3105  first = operandMoves[0];
3106  } else if (!resultMoves.empty()) {
3107  first = resultMoves[0];
3108  } else {
3109  assert(false && "No moves?");
3110  }
3111 
3112  for (unsigned i = 0; i < operandMoves.size(); i++) {
3113  proc->add(operandMoves[i]);
3114  if (addressedOp) {
3115  // remove other allowed fu annotations, they are not allowed
3116  operandMoves[i]->move(0).removeAnnotations(
3118 
3119  for (unsigned int j = 0; j < addressedFUs.size(); j++) {
3120  TTAProgram::ProgramAnnotation dstCandidate(
3122  addressedFUs[j]);
3123  operandMoves[i]->move(0).addAnnotation(dstCandidate);
3124  }
3125  }
3126  }
3127 
3128  for (unsigned i = 0; i < resultMoves.size(); i++) {
3129  proc->add(resultMoves[i]);
3130  if (addressedOp) {
3131  // remove other allowed fu annotations, they are not allowed
3132  resultMoves[i]->move(0).removeAnnotations(
3134 
3135  for (unsigned int j = 0; j < addressedFUs.size(); j++) {
3136  TTAProgram::ProgramAnnotation srcCandidate(
3138  addressedFUs[j]);
3139  resultMoves[i]->move(0).addAnnotation(srcCandidate);
3140  }
3141  }
3142  }
3143  return first;
3144 }
3145 
3146 /**
3147  * Constructs moves for architecture-dependant special asm.
3148  *
3149  * @param op Assembly instruction string.
3150  * @param mi Machine instruction including the inline asm.
3151  * @param proc TTA procedure to emit moves into.
3152  *
3153  * @return First instruction in emitted block.
3154  */
3157  const std::string op, const MachineInstr* mi,
3158  TTAProgram::CodeSnippet* proc) {
3159 
3160  assert(op[0] == '.');
3161 
3162  TCEString subOp(std::string(op, 1, op.length() - 1));
3163 
3164  if (subOp == "setjmp")
3165  return emitSetjmp(mi, proc);
3166 
3167  if (subOp == "longjmp")
3168  return emitLongjmp(mi, proc);
3169 
3170  if (subOp == "call_global_ctors")
3171  return emitGlobalXXtructorCalls(mi, proc, true);
3172 
3173  if (subOp == "call_global_dtors")
3174  return emitGlobalXXtructorCalls(mi, proc, false);
3175 
3176  if (subOp.startsWith("read_sp "))
3177  return emitReadSP(mi, proc);
3178 
3179  if (subOp.startsWith("write_sp "))
3180  return emitWriteSP(mi, proc);
3181 
3182  if (subOp.startsWith("return_to "))
3183  return emitReturnTo(mi, proc);
3184 
3185  // Just strip the pregion markers for now, later on, use it in the
3186  // alias analysis.
3187  if (subOp.startsWith("pregion_start.") || subOp.startsWith("pregion_end"))
3188  return NULL;
3189 
3190  // memory_category pseudo asms can be used to define
3191  // categories for different pointers. They mark those
3192  // pointers to alias only with others pointers in the
3193  // same category.
3194  if (subOp.startsWith("pointer_category"))
3195  return handleMemoryCategoryInfo(mi, proc);
3196 
3197  debugLog(subOp);
3198  abortWithError("Undetected special inline asm.");
3199 
3200  return NULL;
3201 }
3202 
3203 /**
3204  * Emits moves to read the stack pointer value.
3205  */
3208  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
3209 
3210  if (mi->getNumOperands() != 5) {
3212  "ERROR: wrong number of operands in \".read_sp\"");
3213  }
3214 
3215  // Get the stack pointer. It will be used as index into
3216  // the buffer.
3217  unsigned spDRN = spDRegNum();
3218  TCEString sp = (boost::format("%s.%d") %
3219  registerFileName(spDRN) %
3220  registerIndex(spDRN)).str();
3221 
3222  // We need to know where current procedure ends to
3223  // be able to return first generated instruction.
3224  TTAProgram::Instruction& lastInstruction =
3225  proc->lastInstruction();
3226 
3227  CodeGenerator codeGenerator(*mach_);
3228 
3229  TTAProgram::Terminal* srcTerminal =
3230  codeGenerator.createTerminalRegister(sp, false);
3231 
3232  const MachineOperand& dest = mi->getOperand(3);
3233  // Save SP at the first position in the buffer.
3234  TTAProgram::Terminal* destTerminal = createTerminal(dest);
3235 
3236  codeGenerator.addMoveToProcedure(*proc, srcTerminal, destTerminal);
3237  return &(proc->nextInstruction(lastInstruction));
3238 }
3239 
3240 /**
3241  * Emits moves that overwrite the RA and return to that address.
3242  */
3245  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
3246 
3247  if (mi->getNumOperands() != 5) {
3249  "ERROR: wrong number of operands in \".return_to\"");
3250  }
3251 
3252  // We need to know where current procedure ends to
3253  // be able to return first generated instruction.
3254  TTAProgram::Instruction& lastInstruction = proc->lastInstruction();
3255 
3256  CodeGenerator codeGenerator(*mach_);
3257  // the source from which to overwrite RA
3258  const MachineOperand& src = mi->getOperand(3);
3259 
3260  /* src -> RA */
3261  codeGenerator.addMoveToProcedure(
3262  *proc, createTerminal(src),
3263  codeGenerator.createTerminalRegister("RA", false));
3264  /* RA -> JUMP.1 */
3265  codeGenerator.registerJump(*proc, "RA");
3266 
3267  return &(proc->nextInstruction(lastInstruction));
3268 }
3269 
3270 
3271 /**
3272  * Emits moves to write the stack pointer value.
3273  */
3276  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
3277 
3278  if (mi->getNumOperands() != 5) {
3280  << "got " << mi->getNumOperands() << " operands" << std::endl;
3282  "ERROR: wrong number of operands in \".write_sp\"");
3283  }
3284 
3285  const TCETargetMachine* tm = dynamic_cast<const TCETargetMachine*>(tm_);
3286  assert(tm_ != NULL);
3287  // Get the stack pointer. It will be used as index into
3288  // the buffer.
3289  unsigned spDRN = tm->spDRegNum();
3290  TCEString sp = (boost::format("%s.%d") %
3291  tm->rfName(spDRN) %
3292  tm->registerIndex(spDRN)).str();
3293 
3294  // We need to know where current procedure ends to
3295  // be able to return first generated instruction.
3296  TTAProgram::Instruction& lastInstruction =
3297  proc->lastInstruction();
3298 
3299  CodeGenerator codeGenerator(*mach_);
3300 
3301  TTAProgram::Terminal* destTerminal =
3302  codeGenerator.createTerminalRegister(sp, false);
3303 
3304  const MachineOperand& src = mi->getOperand(3);
3305  TTAProgram::Terminal* srcTerminal = createTerminal(src);
3306 
3307  codeGenerator.addMoveToProcedure(*proc, srcTerminal, destTerminal);
3308  return &(proc->nextInstruction(lastInstruction));
3309 }
3310 
3311 /**
3312  * Handles the .pointer_category pseudo assembler instruction.
3313  *
3314  * First argument is a string defining the category, second refers to
3315  * the pointer.
3316  */
3319  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
3320 
3321  if (mi->getNumOperands() != 6) {
3323  << "got " << mi->getNumOperands() << " operands" << std::endl;
3325  "ERROR: wrong number of operands in \".pointer_category\"");
3326  }
3327 
3328  TTAProgram::Instruction& lastInstruction =
3329  proc->lastInstruction();
3330 
3331  CodeGenerator codeGenerator(*mach_);
3332 
3333  TTAProgram::Terminal* srcTerminal =
3334  createTerminal(mi->getOperand(5));
3335 
3336  TTAProgram::Terminal* dstTerminal =
3337  createTerminal(mi->getOperand(3));
3338  codeGenerator.addMoveToProcedure(*proc, srcTerminal, dstTerminal);
3339  return &(proc->nextInstruction(lastInstruction));
3340 }
3341 
3342 
3343 /*
3344  * setjmp/longjmp buffer structure description:
3345  *
3346  * buffer -> |-----------------|
3347  * | SP |
3348  * |-----------------|
3349  * | RA |
3350  * |-----------------|
3351  * | Return value |
3352  * |-----------------|
3353  * | ... |
3354  * | All RF regs |
3355  * | except SP |
3356  * | ... |
3357  * |-----------------|
3358  * | Return address |
3359  * | (to setjmp tail |
3360  * | code) |
3361  * |-----------------| <- buffer +
3362  * <number regs in all RFs> + 3
3363  */
3364 
3365 /**
3366  * Constructs moves for ".setjmp"
3367  *
3368  * @param mi Machine instruction including the inline asm.
3369  * @param proc TTA procedure to emit moves into.
3370  *
3371  * @return First instruction in emmited block.
3372  */
3373 
3376  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
3377 
3378  if (mi->getNumOperands() != 7) {
3379  std::cerr << "ERROR: wrong number of operands in "".setjmp"""
3380  << std::endl;
3381  assert(false);
3382  }
3383  const MachineOperand& val = mi->getOperand(3);
3384  const MachineOperand& env = mi->getOperand(5);
3385  // Get the stack pointer. It will be used as index into
3386  // the buffer.
3387  unsigned spDRN = spDRegNum();
3388  TCEString sp = (boost::format("%s.%d") %
3389  registerFileName(spDRN) %
3390  registerIndex(spDRN)).str();
3391 
3392  // We need to know where current procedure ends to
3393  // be able to return first generated instruction.
3394  int oldSize = proc->instructionCount();
3395 
3396  CodeGenerator codeGenerator(*mach_);
3397 
3398  // Save SP at the first position in the buffer.
3399  TTAProgram::Terminal* buffer = createTerminal(env);
3400  codeGenerator.storeToAddress(*proc, buffer, sp);
3401 
3402  // Now we can scratch the stack pointer.
3403 
3404  // First thing we need is to store buffer address in SP.
3405  buffer = createTerminal(env);
3406  TTAProgram::Terminal* spTerminal =
3407  codeGenerator.createTerminalRegister(sp, false);
3408 
3409  codeGenerator.addMoveToProcedure(*proc, buffer, spTerminal);
3410 
3411  // Increment index to jump over the place where SP was
3412  // stored.
3413  codeGenerator.incrementStackPointer(*proc, sp);
3414 
3415  // Save RA first (special register).
3416  codeGenerator.pushRegisterToStack(*proc, sp, "RA");
3417 
3418  // Now save the desired return value.
3419  SimValue immVal(mach_->is64bit() ? 64 : 32);
3420  immVal = 0;
3421  TTAProgram::TerminalImmediate *immTerminal =
3422  new TTAProgram::TerminalImmediate(immVal);
3423  codeGenerator.pushToStack(*proc, sp, immTerminal);
3424 
3425  // Now we can save every register there.
3428 
3429  int buffer_words = 0;
3430 
3431  for (int i = 0; i < nav.count(); i++) {
3432  const TTAMachine::RegisterFile& rf = *nav.item(i);
3433  for (int j = 0; j < rf.numberOfRegisters(); j++) {
3434  TCEString reg =
3435  (boost::format("%s.%d") % rf.name() % j).str();
3436  if (reg != sp) { // sp already saved, ignore it.
3437  codeGenerator.pushRegisterToStack(*proc, sp, reg);
3438  buffer_words++;
3439  }
3440  }
3441  }
3442 
3443  // Save the setjmp return point.
3444  TTAProgram::Instruction* returnInstruction =
3447 
3448  TTAProgram::InstructionReference returnReference =
3450  *returnInstruction);
3451 
3452  codeGenerator.pushInstructionReferenceToStack(*proc, sp, returnReference);
3453 
3454  codeGenerator.decrementStackPointer(*proc, sp);
3455 
3456  proc->add(returnInstruction);
3457 
3458  // Move back the stored registers.
3459  for (int i = 0; i < buffer_words; i++)
3460  codeGenerator.decrementStackPointer(*proc, sp);
3461 
3462  // Get return value.
3464  codeGenerator.popFromStack(*proc, sp, rv);
3465 
3466  // Restore original RA.
3467  codeGenerator.popRegisterFromStack(*proc, sp, "RA");
3468 
3469  // Restore SP from first position in the buffer.
3470  codeGenerator.popRegisterFromStack(*proc, sp, sp);
3471 
3472  return &(proc->instructionAtIndex(oldSize));
3473 }
3474 
3475 
3476 /**
3477  * Constructs moves for calling all global constructors or
3478  * destructors, if any.
3479  *
3480  * @param mi Machine instruction including the inline asm.
3481  * @param proc TTA procedure to append moves into.
3482  * @param constructors True, if emitting constructors, otherwise
3483  * destructors.
3484  */
3487  const MachineInstr* /*mi*/, TTAProgram::CodeSnippet* proc,
3488  bool constructors) {
3489 
3490  std::string globalName =
3491  constructors ?
3492  ("llvm.global_ctors") : ("llvm.global_dtors");
3493 
3494  TTAProgram::Instruction* firstInstruction = NULL;
3495 
3496  // find the _llvm.global_Xtors global with the
3497  // function pointers and priorities
3498  for (Module::const_global_iterator i = mod_->global_begin();
3499  i != mod_->global_end(); i++) {
3500 
3501  const GlobalVariable* gv = &(*i);
3502  if (gv->getName() == globalName && gv->use_empty()) {
3503  // The initializer should be an array of '{ int, void ()* }'
3504  // structs for LLVM 3.4 and lower, and an array of
3505  // '{ int, void ()*, i8* }' structs for LLVM 3.5.
3506  // The first value is the init priority, which we ignore.
3507  auto init = gv->getInitializer();
3508  if (!isa<ConstantArray>(init)) {
3509  abortWithError("Global array initializer not ConstantArray.");
3510  }
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))) {
3515 
3516  // LLVM 3.5 introduced an additional field, so test for
3517  // an array of 3-element structs.
3518  if (cs->getNumOperands() != 3) {
3519  return firstInstruction;
3520  }
3521 
3522  // Found a null terminator, exit printing.
3523  if (cs->getOperand(1)->isNullValue()) {
3524  return firstInstruction;
3525  }
3526 
3527  // Emit the call.
3528  GlobalValue* gv = dyn_cast<GlobalValue>(
3529  cs->getOperand(1));
3530  assert(gv != NULL&&"global constructor name not constv");
3531 
3532  SmallString<256> Buffer;
3533  mang_->getNameWithPrefix(Buffer, gv, false);
3534  TCEString name(Buffer.c_str());
3535 
3536  TTAProgram::Terminal* xtorRef = NULL;
3537 
3538  // cannot use instr. refs in the new builder as the
3539  // instructions won't belong in a procedure before
3540  // they have been fully scheduled.
3541  xtorRef = new TTAProgram::TerminalSymbolReference(name);
3542 
3543  CodeGenerator codeGenerator(*mach_);
3544 
3545  auto ctrCall =
3546  std::make_shared<TTAProgram::Move>(
3547  xtorRef, codeGenerator.createTerminalFUPort("call", 1),
3549 
3550  OperationPool opPool;
3551 
3552  // Create ProgramOperation also for return so DDGBuilder does not have
3553  // to do that.
3555  new ProgramOperation(opPool.operation("call")));
3556  createMoveNode(po, ctrCall, true);
3557 
3558  TTAProgram::Instruction* newInstr =
3561 
3562  newInstr->addMove(ctrCall);
3563  proc->add(newInstr);
3564 
3565  if (firstInstruction == NULL)
3566  firstInstruction = &proc->lastInstruction();
3567  }
3568  }
3569  return firstInstruction;
3570  }
3571  }
3572  return NULL;
3573 }
3574 
3575 /**
3576  * Constructs moves for ".longjmp"
3577  *
3578  * @param mi Machine instruction including the inline asm.
3579  * @param proc TTA procedure to emit moves into.
3580  *
3581  * @return First instruction in emitted block.
3582  */
3585  const MachineInstr* mi, TTAProgram::CodeSnippet* proc) {
3586 
3587  if (mi->getNumOperands() != 7) {
3588  std::cerr << "ERROR: wrong number of operands in "".longjmp"""
3589  << std::endl;
3590  assert(false);
3591  }
3592  const MachineOperand& env = mi->getOperand(3);
3593  const MachineOperand& val = mi->getOperand(5);
3594 
3595  // Get the stack pointer. It will be used as index into
3596  // the buffer.
3597  unsigned spDRN = spDRegNum();
3598  TCEString sp = (boost::format("%s.%d") %
3599  registerFileName(spDRN) %
3600  registerIndex(spDRN)).str();
3601 
3602  // We need to know where current procedure ends to
3603  // be able to return first generated instruction.
3604  int oldSize = proc->instructionCount();
3605 
3606  CodeGenerator codeGenerator(*mach_);
3607 
3608  // First thing we need is to load buffer address in SP.
3609  TTAProgram::Terminal* buffer = createTerminal(env);
3610  TTAProgram::Terminal* spTerminal =
3611  codeGenerator.createTerminalRegister(sp, false);
3612 
3613  codeGenerator.addMoveToProcedure(*proc, buffer, spTerminal);
3614 
3615  // Increment index to jump over the place where SP was
3616  // stored.
3617  codeGenerator.incrementStackPointer(*proc, sp);
3618 
3619  // Jump over RA (will be restored in setjmp tail).
3620  codeGenerator.incrementStackPointer(*proc, sp);
3621 
3622  // Now save the desired return value.
3624  codeGenerator.pushToStack(*proc, sp, rv);
3625 
3626  // Reload all registers but SP.
3629 
3630  for (int i = 0; i < nav.count(); i++) {
3631  const TTAMachine::RegisterFile& rf = *nav.item(i);
3632  for (int j = 0; j < rf.numberOfRegisters(); j++) {
3633  TCEString reg =
3634  (boost::format("%s.%d") % rf.name() % j).str();
3635  if (reg != sp) {
3636  // Using fromStack as I am restoring towards
3637  // higher memory addresses.
3638  codeGenerator.popRegisterFromStack(*proc, sp, reg);
3639  }
3640  }
3641  }
3642 
3643  // Done, jump to setjmp ending code.
3644  codeGenerator.loadFromRegisterAddress(*proc, sp, "RA");
3645  codeGenerator.registerJump(*proc, "RA");
3646 
3647  return &(proc->instructionAtIndex(oldSize));
3648 }
3649 
3650 /**
3651  * Creates instruction(s) to load initial stack pointer value.
3652  */
3653 void
3655  TTAProgram::CodeSnippet& target,
3656  TTAProgram::Terminal& src,
3657  TTAProgram::Terminal& dst) {
3658 
3659  CodeGenerator codegen(*mach_);
3660  codegen.loadTerminal(target, &src, &dst);
3661 }
3662 
3663 /**
3664  * Creates program object model move.
3665  *
3666  * @param src Source terminal of the move.
3667  * @param dst Destination terminal of the move.
3668  * @param bus Bus utilized to do the move.
3669  * @param guard Guard object for the move or NULL if the move is not
3670  * guarded.
3671  * @return Created move.
3672  */
3673 std::shared_ptr<TTAProgram::Move>
3675  TTAProgram::Terminal* src,
3676  TTAProgram::Terminal* dst,
3677  const TTAMachine::Bus& bus,
3678  TTAProgram::MoveGuard* guard) {
3679 
3680  std::shared_ptr<TTAProgram::Move> move = nullptr;
3681 
3682  bool endRef = false;
3683 
3684  if (src == NULL) {
3685  // Create a dummy source Terminal so the move can be added to an
3686  // instruction.
3687  SimValue val(0, mach_->is64bit() ? 64 : 32);
3688  src = new TTAProgram::TerminalImmediate(val);
3689  endRef = true;
3690  }
3691 
3692  if (guard == NULL) {
3693  move = std::make_shared<TTAProgram::Move>(src, dst, bus);
3694  } else {
3695  move = std::make_shared<TTAProgram::Move>(src, dst, bus, guard);
3696  }
3697 
3698  if (endRef) {
3699  endReferences_.push_back(move);
3700  }
3701 
3702  return move;
3703 }
3704 
3705 
3706 /**
3707  * Returns the program built during the pass.
3708  *
3709  * @return Result program object built.
3710  * @throw NotAvailable If program is not ready.
3711  */
3714  return prog_;
3715 }
3716 
3717 /**
3718  * Creates a register guard to given guard register.
3719  */
3721  const TTAProgram::Terminal* terminal, bool trueOrFalse) {
3722  const TTAProgram::TerminalRegister* guardReg =
3723  dynamic_cast<const TTAProgram::TerminalRegister*>(terminal);
3724  if (guardReg == NULL) {
3725  return NULL;
3726  }
3727 
3728  bool hasPortGuard = false;
3730  for (int i = 0; i < busNav.count(); i++) {
3731  Bus* bus = busNav.item(i);
3732  for (int i = 0; i < bus->guardCount(); i++) {
3733  RegisterGuard* regGuard = dynamic_cast<RegisterGuard*>(
3734  bus->guard(i));
3735  if (regGuard != NULL &&
3736  regGuard->registerFile() == &guardReg->registerFile() &&
3737  regGuard->registerIndex() == (int)guardReg->index() &&
3738  regGuard->isInverted() != trueOrFalse) {
3739  return new TTAProgram::MoveGuard(*regGuard);
3740  }
3741  PortGuard* portGuard = dynamic_cast<PortGuard*>(
3742  bus->guard(i));
3743  if (portGuard != nullptr &&
3744  portGuard->isInverted() != trueOrFalse)
3745  hasPortGuard = true;
3746  }
3747  }
3748 
3749  if (hasPortGuard) {
3750  RegisterGuard* bypassRegGuard =
3751  new RegisterGuard(!trueOrFalse, guardReg->registerFile(),
3752  guardReg->index(), nullptr);
3753 
3754  return new TTAProgram::MoveGuard(*bypassRegGuard);
3755  } else {
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?"
3758  << std::endl;
3759  return NULL;
3760  }
3761 }
3762 
3763 
3766 
3767  if (!multiDataMemMachine_)
3768  return *defaultDataAddressSpace_;
3769 
3772  for (int i = 0; i < asNav.count(); i++) {
3773  TTAMachine::AddressSpace& aSpace = *asNav.item(i);
3774  if (aSpace.hasNumericalId(id))
3775  return aSpace;
3776  }
3778  << "Address space with numerical id " << id << " not found."
3779  << std::endl;
3780  abort();
3781 }
3782 
3783 
3784 /**
3785  * Returns the position after the highest written data symbol for the
3786  * given address space.
3787  */
3788 unsigned&
3790  if (!MapTools::containsKey(dataEnds_, &aSpace)) {
3791  unsigned end =
3792  (&aSpace == defaultDataAddressSpace_ && options_ != nullptr &&
3794  options_->dataStartAddress() : aSpace.start();
3795  /* Avoid placing data to address 0 as it may break some null pointer
3796  tests. Waste a valuable word of memory and add a dummy word to
3797  prevent writing bytes to 1,2,3 addresses and thus then avoid reading
3798  valid data from address 0. */
3799  if (end == 0) {
3800  const TCETargetMachine* tm =
3801  dynamic_cast<const TCETargetMachine*>(tm_);
3802  assert(tm != NULL);
3804  }
3805  dataEnds_[&aSpace] = end;
3806 
3807  }
3808  return dataEnds_[&aSpace];
3809 }
3810 
3811 /**
3812  * Returns the "layout array" for the data memory of the given address
3813  * space.
3814  */
3817  if (!MapTools::containsKey(dmemIndex_, &aSpace)) {
3818  dmemIndex_[&aSpace] = new TTAProgram::DataMemory(aSpace);
3819  }
3820  return *dmemIndex_[&aSpace];
3821 }
3822 
3823 //#define DEBUG_LLVMTCEBUILDER
3824 //#define WARN_AS_FU_NOT_FOUND
3825 /**
3826  * Adds annotations to the given move that limit the choice of the
3827  * load-store unit to only those that support the given address space.
3828  */
3829 void
3831  unsigned asNum, TTAProgram::Move& move) {
3832 
3833  TCEString opName;
3834  if (move.destination().isFUPort()) {
3835  opName = dynamic_cast<TTAProgram::TerminalFUPort&>(
3836  move.destination()).hwOperation()->name();
3837  } else {
3838  opName = dynamic_cast<TTAProgram::TerminalFUPort&>(
3839  move.source()).hwOperation()->name();
3840  }
3841  bool foundLSU = false;
3844  for (int i = 0; i < fuNav.count(); i++) {
3845  const TTAMachine::FunctionUnit& fu = *fuNav.item(i);
3846  if (fu.hasAddressSpace()) {
3847  if (fu.addressSpace()->hasNumericalId(asNum) &&
3848  fu.hasOperation(opName)) {
3849  TTAProgram::ProgramAnnotation progAnnotation(
3851  ANN_ALLOWED_UNIT_DST, fu.name());
3852  move.addAnnotation(progAnnotation);
3853  foundLSU = true;
3854  }
3855  }
3856  }
3857 
3858  /* Fail silently for now.
3859 
3860  The problem here is that stack instructions should be mapped
3861  to AS0 but they do not have memoperands, thus
3862  addPointerAnnotations() does not manage to figure out any
3863  real address space info for it. Thus, we just could
3864  assume all such instructions belong to the default AS.
3865 
3866  The problem appears with custom operations which take in
3867  memory operands. For example, TRY_LOCK_ADDR etc. of the DILU.
3868  The INLINEASM blocks, even if the operand is marked as 'm', do not
3869  produce MachineInstrs with memoperands, thus the pointer info cannot
3870  be obtained. However, in that case the address space could be
3871  something else than the default.
3872 
3873  For now, we leave the AS info out in case FU with the operation and
3874  the address space is found, thus assume there is only one such FU
3875  which is then selected correctly during the scheduling.
3876  We only abort if the asNum != 0, otherwise fail silently.
3877  */
3878  if (!foundLSU) {
3879  if (asNum == 0){
3880 #ifdef WARN_AS_FU_NOT_FOUND
3881  if (true || Application::verboseLevel() > 0) {
3883  << "WARNING: no candidate FU found for "
3884  << move.toString() << " with address space id "
3885  << asNum << " not adding any AS info."
3886  << std::endl;
3887  }
3888 #endif
3889  } else {
3890  // If the asNum isn't already 0, we can't quietly make the
3891  // assumption that it should be 0. Instead abort.
3892  abortWithError((boost::format("ERROR: No candidate FU found for %s"
3893  " address space id %u") % move.toString() % asNum).str());
3894  }
3895  }
3896 }
3897 
3898 /**
3899  * Returns true if the instruction is real inline asm aka. holds moves.
3900  *
3901  * Returns false if instruction is not inline asm.
3902  * This also return false for operation macros (_TCE_OP(...)) that also use
3903  * inline asm statements in C code.
3904  *
3905  * @param instr The instruction.
3906  */
3907 bool
3908 LLVMTCEBuilder::isInlineAsm(const MachineInstr& instr) {
3909  return InlineAsmParser::isInlineAsm(instr);
3910 }
3911 
3912 
3913 
3914 
llvm::LLVMTCEBuilder::spillMoveCount_
int spillMoveCount_
Definition: LLVMTCEBuilder.hh:261
llvm::LLVMTCEBuilder::createSymbolReference
virtual TTAProgram::Terminal * createSymbolReference(const MachineOperand &mo)
Definition: LLVMTCEBuilder.cc:2298
getSourceLocationInfo
POP_COMPILER_DIAGS std::tuple< std::string, size_t > getSourceLocationInfo(const llvm::MachineInstr &mi)
Definition: LLVMUtilities.cc:54
UniversalMachine::integerRegisterFile
UnboundedRegisterFile & integerRegisterFile() const
Definition: UniversalMachine.cc:234
llvm::TCETargetMachine::rfName
std::string rfName(unsigned dwarfRegNum) const
Definition: TCETargetMachine.hh:204
TTAProgram::Terminal::isFUPort
virtual bool isFUPort() const
Definition: Terminal.cc:118
llvm::LLVMTCEBuilder::dataEnd
unsigned & dataEnd(TTAMachine::AddressSpace &aSpace)
Definition: LLVMTCEBuilder.cc:3789
TTAProgram::TerminalInstructionAddress
Definition: TerminalInstructionAddress.hh:45
END_SYMBOL_NAME
#define END_SYMBOL_NAME
Definition: LLVMTCEBuilder.cc:135
llvm::LLVMTCEBuilder::MAU_BITS
static unsigned MAU_BITS
Target architechture MAU size in bits.
Definition: LLVMTCEBuilder.hh:419
TerminalInstructionReference.hh
llvm
Definition: InlineAsmParser.hh:49
StringTools::containsChar
static bool containsChar(const std::string &source, char ch, bool caseSensitive=true)
Definition: StringTools.cc:101
UniversalFunctionUnit::operation
virtual TTAMachine::HWOperation * operation(const std::string &name) const
Definition: UniversalFunctionUnit.cc:102
TTAProgram::Program
Definition: Program.hh:63
TTAProgram::Instruction::addMove
void addMove(std::shared_ptr< Move > move)
Definition: Instruction.cc:147
TTAProgram::Program::addProcedure
void addProcedure(Procedure *proc)
Definition: Program.cc:524
llvm::LLVMTCEBuilder::ConstantDataDef::size
unsigned size
Definition: LLVMTCEBuilder.hh:287
OperationPool::operation
Operation & operation(const char *name)
Definition: OperationPool.cc:99
llvm::LLVMTCEBuilder::doFinalization
bool doFinalization(Module &M)
Definition: LLVMTCEBuilder.cc:1090
TTAProgram::Program::firstInstruction
Instruction & firstInstruction() const
Definition: Program.cc:353
TTAProgram::ProgramAnnotation::ANN_PARALLEL_REGION_ID
@ ANN_PARALLEL_REGION_ID
The ID from the _TCEPREGION_START(N) markers.
Definition: ProgramAnnotation.hh:171
MachineInfo::maxMemoryAlignment
static int maxMemoryAlignment(const TTAMachine::Machine &mach)
Definition: MachineInfo.cc:261
llvm::LLVMTCEBuilder::LLVMTCEBuilder
LLVMTCEBuilder(char &ID)
Definition: LLVMTCEBuilder.cc:167
llvm::LLVMTCEBuilder::emitInstruction
TTAProgram::Instruction * emitInstruction(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:1322
TTAMachine::Machine::hasOperation
bool hasOperation(const TCEString &opName) const
Definition: Machine.cc:1048
llvm::LLVMTCEBuilder::dl_
const llvm::DataLayout * dl_
The data layout for the machine.
Definition: LLVMTCEBuilder.hh:502
TTAProgram::CodeSnippet::firstInstruction
virtual Instruction & firstInstruction() const
Definition: CodeSnippet.cc:216
llvm::LLVMTCEBuilder::prog_
TTAProgram::Program * prog_
Current program being built.
Definition: LLVMTCEBuilder.hh:250
llvm::LLVMTCEBuilder::multiDataMemMachine_
bool multiDataMemMachine_
Set to true in case this machine has more than one data address spaces.
Definition: LLVMTCEBuilder.hh:434
TTAProgram::CodeSnippet::append
virtual void append(const CodeSnippet &cs)
Definition: CodeSnippet.cc:711
TTAProgram::DataDefinition
Definition: DataDefinition.hh:52
llvm::LLVMTCEBuilder::DataDef::name
std::string name
Definition: LLVMTCEBuilder.hh:274
llvm::LLVMTCEBuilder::createExprDataDefinition
void createExprDataDefinition(int addressSpaceId, unsigned &addr, const ConstantExpr *gv, int offset=0)
Definition: LLVMTCEBuilder.cc:836
llvm::LLVMTCEBuilder::dataMemoryForAddressSpace
TTAProgram::DataMemory & dataMemoryForAddressSpace(TTAMachine::AddressSpace &aSpace)
Definition: LLVMTCEBuilder.cc:3816
InlineAsmParser::diagnostics
const AssemblyParserDiagnostic & diagnostics() const
Definition: InlineAsmParser.hh:99
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
llvm::LLVMTCEBuilder::result
TTAProgram::Program * result()
Definition: LLVMTCEBuilder.cc:3713
llvm::LLVMTCEBuilder::emitMove
virtual TTAProgram::Instruction * emitMove(const MachineInstr *mi, TTAProgram::CodeSnippet *proc, bool conditional=false, bool trueGuard=true)
Definition: LLVMTCEBuilder.cc:2418
TTAProgram::Instruction::move
Move & move(int i) const
Definition: Instruction.cc:193
TTAProgram::Terminal::index
virtual int index() const
Definition: Terminal.cc:274
PRINT_VAR
#define PRINT_VAR(VARIABLE__)
Definition: Application.hh:118
TTAProgram::Address
Definition: Address.hh:51
TTAProgram::ProgramAnnotation::ANN_POINTER_ADDR_SPACE
@ ANN_POINTER_ADDR_SPACE
Definition: ProgramAnnotation.hh:177
TTAMachine::FunctionUnit::hasAddressSpace
virtual bool hasAddressSpace() const
Definition: FunctionUnit.cc:608
TCEString::startsWith
bool startsWith(const std::string &str) const
TTAProgram::DataDefinition::size
virtual int size() const
Definition: DataDefinition.cc:211
TTAMachine::HWOperation
Definition: HWOperation.hh:52
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
TTAProgram::Scope::addDataLabel
virtual void addDataLabel(const DataLabel *dataLabel)
Definition: Scope.cc:415
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
ExecutionPipeline.hh
TerminalSymbolReference.hh
llvm::LLVMTCEBuilder::addCandidateLSUAnnotations
void addCandidateLSUAnnotations(unsigned asNum, TTAProgram::Move &move)
Definition: LLVMTCEBuilder.cc:3830
TTAProgram::CodeGenerator::popFromStack
void popFromStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::Terminal *dstTerminal)
Definition: CodeGenerator.cc:436
llvm::LLVMTCEBuilder::DataDef
Data definition structure for global values.
Definition: LLVMTCEBuilder.hh:273
llvm::LLVMTCEBuilder::codeLabelReferences_
std::map< TTAProgram::TerminalInstructionAddress *, std::string > codeLabelReferences_
Dummy code label references that have to be fixed after all instrutions have been built.
Definition: LLVMTCEBuilder.hh:459
TTAProgram::Terminal::registerFile
virtual const TTAMachine::RegisterFile & registerFile() const
Definition: Terminal.cc:225
llvm::LLVMTCEBuilder::DataDef::alignment
unsigned alignment
Definition: LLVMTCEBuilder.hh:278
TTAProgram::CodeSnippet::insertBefore
virtual void insertBefore(const Instruction &pos, Instruction *ins)
Definition: CodeSnippet.cc:514
llvm::LLVMTCEBuilder::opset_
std::set< std::string > opset_
The operations supported by the current target machine.
Definition: LLVMTCEBuilder.hh:253
TTAMachine::AddressSpace::hasNumericalId
virtual bool hasNumericalId(unsigned id) const
Definition: AddressSpace.cc:383
UniversalMachine::universalBus
TTAMachine::Bus & universalBus() const
Definition: UniversalMachine.cc:306
llvm::LLVMTCEBuilder::options_
LLVMTCECmdLineOptions * options_
The compiler options.
Definition: LLVMTCEBuilder.hh:268
TTAProgram::Instruction
Definition: Instruction.hh:57
TTAProgram::CodeGenerator::createTerminalFUPort
TTAProgram::TerminalFUPort * createTerminalFUPort(const TCEString &opName, int operand)
Definition: CodeGenerator.cc:94
MapTools.hh
Procedure.hh
TTAMachine::Bus
Definition: Bus.hh:53
TTAProgram::AnnotatedInstructionElement::setAnnotation
void setAnnotation(const ProgramAnnotation &annotation)
Definition: AnnotatedInstructionElement.cc:79
llvm::LLVMTCEBuilder::emitComparisonForBranch
TTAProgram::Instruction * emitComparisonForBranch(TCEString firstOp, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:1727
TPEF::InstructionAnnotation::MAX_ANNOTATION_BYTES
static const size_t MAX_ANNOTATION_BYTES
Maximum number of bytes that annotation may contain.
Definition: InstructionElement.hh:65
llvm::LLVMTCEBuilder::addPointerAnnotations
void addPointerAnnotations(const llvm::MachineInstr *mi, TTAProgram::Move &move)
Definition: LLVMTCEBuilder.cc:1823
llvm::LLVMTCEBuilder::emitSpecialInlineAsm
TTAProgram::Instruction * emitSpecialInlineAsm(const std::string op, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:3156
TTAMachine::Port::width
virtual int width() const =0
PRegionMarkerAnalyzer.hh
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
llvm::LLVMTCEBuilder::createGlobalValueDataDefinition
void createGlobalValueDataDefinition(int addressSpaceId, unsigned &addr, const GlobalValue *gv, int offset=0)
Definition: LLVMTCEBuilder.cc:785
llvm::LLVMTCEBuilder::tm_
const llvm::TargetMachine * tm_
Target machine description.
Definition: LLVMTCEBuilder.hh:245
TTAMachine::Machine::is64bit
bool is64bit() const
Definition: Machine.hh:260
TTAProgram::InstructionReferenceManager::createReference
InstructionReference createReference(Instruction &ins)
Definition: InstructionReferenceManager.cc:73
MachineInfo.hh
TTAProgram::Terminal::hintOperation
virtual Operation & hintOperation() const
Definition: Terminal.cc:341
TTAProgram::TerminalProgramOperation::isProgramOperationKnown
bool isProgramOperationKnown() const
Definition: TerminalProgramOperation.hh:65
llvm::LLVMTCEBuilder::DataDef::initialize
bool initialize
Definition: LLVMTCEBuilder.hh:280
UniversalMachine::instance
static UniversalMachine & instance()
Definition: UniversalMachine.cc:73
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
TTAProgram::Instruction::toString
std::string toString() const
Definition: Instruction.cc:576
TTAProgram::CodeGenerator::addMoveToProcedure
TTAProgram::Instruction * addMoveToProcedure(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal)
Definition: CodeGenerator.cc:54
InlineAsmParser::parse
bool parse(const llvm::MachineInstr &inlineAsmMI, const std::map< std::string, unsigned > &symbolTable, TTAProgram::BasicBlock &bb, TTAProgram::InstructionReferenceManager &irm)
Definition: InlineAsmParser.cc:87
ProgramOperation
Definition: ProgramOperation.hh:70
TTAProgram::Move::toString
std::string toString() const
Definition: Move.cc:436
llvm::LLVMTCEBuilder::defaultDataAddressSpace_
TTAMachine::AddressSpace * defaultDataAddressSpace_
The default data memory address space (address space 0).
Definition: LLVMTCEBuilder.hh:430
llvm::TCETargetMachine::spDRegNum
unsigned spDRegNum() const
Definition: TCETargetMachine.hh:237
TTAProgram::CodeSnippet::nextInstruction
virtual Instruction & nextInstruction(const Instruction &ins) const
Definition: CodeSnippet.cc:318
llvm::LLVMTCEBuilder::curFrameInfo_
MachineFrameInfo * curFrameInfo_
Definition: LLVMTCEBuilder.hh:265
UniversalFunctionUnit
Definition: UniversalFunctionUnit.hh:50
CompileError
Definition: Exception.hh:1019
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
llvm::LLVMTCEBuilder::POINTER_SIZE_32
static unsigned POINTER_SIZE_32
Target architecture pointer size in maus.
Definition: LLVMTCEBuilder.hh:422
TTAMachine::FunctionUnit::addressSpace
virtual AddressSpace * addressSpace() const
Definition: FunctionUnit.cc:580
TTAProgram::CodeSnippet::startAddress
virtual Address startAddress() const
Definition: CodeSnippet.cc:780
llvm::LLVMTCEBuilder::udata_
std::vector< DataDef > udata_
Definition: LLVMTCEBuilder.hh:444
llvm::LLVMTCEBuilder::emitOperationMacro
TTAProgram::Instruction * emitOperationMacro(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:2860
HalfFloatWord
Definition: HalfFloatWord.hh:41
TTAProgram::ProgramAnnotation::ANN_DEBUG_SOURCE_CODE_LINE
@ ANN_DEBUG_SOURCE_CODE_LINE
The line number in the source code file the annotated move originates from.
Definition: ProgramAnnotation.hh:138
llvm::LLVMTCEBuilder::noAliasFound_
bool noAliasFound_
set to true in case at least one 'noalias' attribute (from the use of 'restricted' pointers) has been...
Definition: LLVMTCEBuilder.hh:487
InstructionElement.hh
Terminal.hh
TTAMachine::ExecutionPipeline::writtenOperands
OperandSet writtenOperands(int cycle) const
Definition: ExecutionPipeline.cc:429
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
llvm::LLVMTCEBuilder::functionAtATime_
bool functionAtATime_
Definition: LLVMTCEBuilder.hh:257
llvm::LLVMTCEBuilder::emitReturnTo
TTAProgram::Instruction * emitReturnTo(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:3244
llvm::LLVMTCEBuilder::createSPInitLoad
void createSPInitLoad(TTAProgram::CodeSnippet &target, TTAProgram::Terminal &src, TTAProgram::Terminal &dst)
Definition: LLVMTCEBuilder.cc:3654
llvm::LLVMTCEBuilder::mach_
TTAMachine::Machine * mach_
Machine for building the program.
Definition: LLVMTCEBuilder.hh:242
llvm::LLVMTCEBuilder::emitWriteSP
TTAProgram::Instruction * emitWriteSP(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:3275
llvm::LLVMTCEBuilder::initialStackPointerValue_
unsigned initialStackPointerValue_
Definition: LLVMTCEBuilder.hh:263
TTAMachine::Machine::Navigator::count
int count() const
TTAMachine::ExecutionPipeline::readOperands
OperandSet readOperands(int cycle) const
Definition: ExecutionPipeline.cc:408
llvm::LLVMTCEBuilder::fixProgramOperationReferences
void fixProgramOperationReferences()
Definition: LLVMTCEBuilder.cc:2276
DataInstructionAddressDef.hh
llvm::LLVMTCEBuilder::mbbs_
std::map< std::string, TTAProgram::Instruction * > mbbs_
Machine basic block -> first instruction in the BB map.
Definition: LLVMTCEBuilder.hh:448
llvm::LLVMTCEBuilder::dataLabels_
std::map< std::string, unsigned > dataLabels_
Data labels.
Definition: LLVMTCEBuilder.hh:454
llvm::LLVMTCEBuilder::createTerminal
TTAProgram::Terminal * createTerminal(const MachineOperand &mo, int bitLimit=0)
Definition: LLVMTCEBuilder.cc:2149
TTAProgram::TerminalRegister::index
virtual int index() const
Operand::isOutput
virtual bool isOutput() const
Definition: Operand.cc:155
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
DataAddressDef.hh
llvm::LLVMTCEBuilder::mang_
llvm::Mangler * mang_
Mangler for mangling label strings.
Definition: LLVMTCEBuilder.hh:247
llvm::LLVMTCEBuilder::createIntDataDefinition
void createIntDataDefinition(int addressSpaceId, unsigned &addr, const llvm::ConstantInt *ci, bool isPointer=false)
Definition: LLVMTCEBuilder.cc:634
llvm::LLVMTCEBuilder::cpData_
std::vector< ConstantDataDef > cpData_
Definition: LLVMTCEBuilder.hh:445
LLVMUtilities.hh
DataLabel.hh
Operand::isNull
virtual bool isNull() const
Definition: Operand.hh:130
llvm::LLVMTCEBuilder::emitConstantPool
void emitConstantPool(const llvm::MachineConstantPool &cp)
Definition: LLVMTCEBuilder.cc:2346
llvm::LLVMTCEBuilder::initMembers
void initMembers()
Definition: LLVMTCEBuilder.cc:172
Conversion::toString
static std::string toString(const T &source)
TYPE_CONST
#define TYPE_CONST
Definition: LLVMTCEBuilder.cc:130
llvm::LLVMTCEBuilder::bbIndex_
std::map< const llvm::BasicBlock *, TTAProgram::Instruction * > bbIndex_
Basic Block -> first instruction in the BB map.
Definition: LLVMTCEBuilder.hh:451
llvm::LLVMTCEBuilder::multiAddrSpacesFound_
bool multiAddrSpacesFound_
set to true in case at least one non-default address space memory access has been found in the genera...
Definition: LLVMTCEBuilder.hh:490
TTAMachine::RFPort
Definition: RFPort.hh:45
llvm::LLVMTCEBuilder::mod_
llvm::Module * mod_
Definition: LLVMTCEBuilder.hh:425
LLVMTCECmdLineOptions::dataStartAddress
uint64_t dataStartAddress() const
Definition: LLVMTCECmdLineOptions.cc:441
SimValue
Definition: SimValue.hh:96
ProgramOperationPtr
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition: MoveNode.hh:52
TTAProgram::CodeGenerator::pushRegisterToStack
void pushRegisterToStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, const TCEString &srcReg)
Definition: CodeGenerator.cc:493
TerminalRegister.hh
llvm::LLVMTCEBuilder::endReferences_
std::vector< std::shared_ptr< TTAProgram::Move > > endReferences_
Dummy references to the _end symbol.
Definition: LLVMTCEBuilder.hh:468
TTAMachine::BaseRegisterFile::numberOfRegisters
virtual int numberOfRegisters() const
TTAMachine::Machine::isLittleEndian
bool isLittleEndian() const
Definition: Machine.hh:258
llvm::LLVMTCEBuilder::emitSPInitialization
virtual void emitSPInitialization()
Definition: LLVMTCEBuilder.cc:2669
llvm::LLVMTCEBuilder::isInitialized
bool isInitialized(const Constant *cv)
Definition: LLVMTCEBuilder.cc:2648
POMDisassembler.hh
TTAProgram::CodeGenerator::createTerminalRegister
TTAProgram::Terminal * createTerminalRegister(const TTAMachine::RegisterFile &rf, int regNum, bool readPort) const
Definition: CodeGenerator.cc:115
getInlineAsmOperands
AsmOperandMap getInlineAsmOperands(const llvm::MachineInstr &mi)
Definition: LLVMUtilities.cc:92
llvm::LLVMTCEBuilder::copyFUAnnotations
void copyFUAnnotations(const std::vector< TTAProgram::Instruction * > &operandMoves, TTAProgram::Move &move) const
Definition: LLVMTCEBuilder.cc:1797
GlobalScope.hh
TCEString.hh
StringTools.hh
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAProgram::CodeGenerator::incrementStackPointer
void incrementStackPointer(TTAProgram::CodeSnippet &dstProcedure, const TCEString &spReg)
Definition: CodeGenerator.cc:417
UniversalMachine.hh
InlineAsmParser::isInlineAsm
static bool isInlineAsm(const llvm::MachineInstr &mi)
Definition: InlineAsmParser.cc:450
TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_SRC
@ ANN_ALLOWED_UNIT_SRC
Candidate units can be passed for resource manager for choosing the source/destination unit of the mo...
Definition: ProgramAnnotation.hh:112
llvm::LLVMTCEBuilder::emitDataDef
void emitDataDef(const DataDef &def)
Definition: LLVMTCEBuilder.cc:443
TTAProgram::ProgramAnnotation::ANN_CONSTANT_MEM
@ ANN_CONSTANT_MEM
Constant memory access.
Definition: ProgramAnnotation.hh:183
TTAProgram::ProgramAnnotation::id
ProgramAnnotation::Id id() const
Definition: ProgramAnnotation.cc:111
TTAProgram::CodeGenerator::storeToAddress
void storeToAddress(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *dstTerminal, const TCEString &srcReg)
Definition: CodeGenerator.cc:276
TTAProgram::ProgramAnnotation::ANN_CONN_CANDIDATE_UNIT_SRC
@ ANN_CONN_CANDIDATE_UNIT_SRC
Src. unit candidate.
Definition: ProgramAnnotation.hh:115
TTAProgram::Scope::addCodeLabel
virtual void addCodeLabel(const CodeLabel *codeLabel)
Definition: Scope.cc:376
TTAProgram::Program::addDataMemory
void addDataMemory(DataMemory *dataMem)
Definition: Program.cc:954
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
llvm::LLVMTCEBuilder::createMoveNode
virtual void createMoveNode(ProgramOperationPtr &, std::shared_ptr< TTAProgram::Move > m, bool)
Definition: LLVMTCEBuilder.hh:397
TTAProgram::Terminal::operationIndex
virtual int operationIndex() const
Definition: Terminal.cc:364
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
llvm::LLVMTCEBuilder::createTerminalRegister
TTAProgram::TerminalRegister * createTerminalRegister(const std::string &rfName, int index)
Definition: LLVMTCEBuilder.cc:2120
getSourceLocationString
std::string getSourceLocationString(const llvm::MachineInstr &mi)
Definition: LLVMUtilities.cc:78
HWOperation.hh
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
llvm::TCETargetMachine::registerName
std::string registerName(unsigned dwarfRegNum) const
Definition: TCETargetMachine.hh:216
llvm::LLVMTCEBuilder::createGuard
TTAProgram::MoveGuard * createGuard(const TTAProgram::Terminal *guardReg, bool trueOrFalse)
Definition: LLVMTCEBuilder.cc:3720
Instruction.hh
TTAProgram::DataMemory::addDataDefinition
void addDataDefinition(DataDefinition *dataDef)
Definition: DataMemory.cc:66
DataMemory.hh
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
LLVMTCECmdLineOptions::isDataStartAddressSet
bool isDataStartAddressSet() const
Definition: LLVMTCECmdLineOptions.cc:436
llvm::LLVMTCEBuilder::registerIndex
virtual int registerIndex(unsigned llvmRegNum) const =0
UniversalFunctionUnit.hh
THROW_EXCEPTION
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition: Exception.hh:39
TTAProgram::DataAddressDef
Definition: DataAddressDef.hh:45
TTAProgram::CodeSnippet::add
virtual void add(Instruction *ins)
Definition: CodeSnippet.cc:432
Conversion.hh
TTAProgram::DataDefinition::destinationAddress
virtual Address destinationAddress() const
Definition: DataDefinition.cc:241
llvm::LLVMTCEBuilder::DataDef::size
unsigned size
Definition: LLVMTCEBuilder.hh:279
LLVMTCECmdLineOptions.hh
TTAMachine::RegisterGuard
Definition: Guard.hh:137
TTAProgram::DataLabel
Definition: DataLabel.hh:45
TCETargetMachine.hh
dummy
SimValue dummy(32)
a dummy simvalue which is given for operands that are not bound
TTAMachine::Machine::Navigator::hasItem
bool hasItem(const std::string &name) const
TTAProgram::InstructionReferenceManager::hasReference
bool hasReference(Instruction &ins) const
Definition: InstructionReferenceManager.cc:143
llvm::LLVMTCEBuilder::raPortDRegNum
virtual unsigned raPortDRegNum() const =0
TTAProgram::Program::dataMemory
DataMemory & dataMemory(int index) const
Definition: Program.cc:967
TTAProgram::InstructionReferenceManager::replace
void replace(Instruction &insA, Instruction &insB)
Definition: InstructionReferenceManager.cc:96
NullInstruction.hh
Application::cmdLineOptions
static CmdLineOptions * cmdLineOptions()
Definition: Application.cc:397
UnboundedRegisterFile.hh
llvm::LLVMTCEBuilder::emitSelect
TTAProgram::Instruction * emitSelect(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:2561
TTAProgram::Instruction::parent
CodeSnippet & parent() const
Definition: Instruction.cc:109
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
llvm::LLVMTCEBuilder::globalCP_
std::map< const llvm::Constant *, unsigned > globalCP_
Global constant pool for all constants gathered from machine functions. Map key is unique constant an...
Definition: LLVMTCEBuilder.hh:473
llvm::LLVMTCEBuilder::emitLongjmp
TTAProgram::Instruction * emitLongjmp(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:3584
llvm::LLVMTCEBuilder::DataDef::address
unsigned address
Definition: LLVMTCEBuilder.hh:276
TTAProgram::TerminalInstructionReference
Definition: TerminalInstructionReference.hh:48
llvm::LLVMTCEBuilder::instrAddressSpace_
TTAMachine::AddressSpace * instrAddressSpace_
Definition: LLVMTCEBuilder.hh:427
TTAProgram::CodeSnippet::lastInstruction
virtual Instruction & lastInstruction() const
Definition: CodeSnippet.cc:387
TTAProgram::Terminal::isGPR
virtual bool isGPR() const
Definition: Terminal.cc:107
TTAProgram::CodeLabel
Definition: CodeLabel.hh:49
Guard.hh
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
Operation.hh
llvm::LLVMTCEBuilder::isInlineAsm
static bool isInlineAsm(const MachineInstr &instr)
Definition: LLVMTCEBuilder.cc:3908
TerminalFUPort.hh
TTAProgram::GlobalScope
Definition: GlobalScope.hh:47
Operation::isBaseOffsetMemOperation
virtual bool isBaseOffsetMemOperation() const
Definition: Operation.cc:323
llvm::LLVMTCEBuilder::~LLVMTCEBuilder
virtual ~LLVMTCEBuilder()
Definition: LLVMTCEBuilder.cc:196
TTAProgram::ProgramAnnotation::ANN_STACKUSE_FP_SAVE
@ ANN_STACKUSE_FP_SAVE
frame ptr save/load
Definition: ProgramAnnotation.hh:91
llvm::LLVMTCEBuilder::dataInitialized_
bool dataInitialized_
Definition: LLVMTCEBuilder.hh:495
TTAProgram::TerminalAddress
Definition: TerminalAddress.hh:48
TTAProgram::Move
Definition: Move.hh:55
llvm::LLVMTCEBuilder::operationName
virtual TCEString operationName(const MachineInstr &mi) const =0
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
Machine.hh
llvm::LLVMTCEBuilder::emitSetjmp
TTAProgram::Instruction * emitSetjmp(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:3375
TTAProgram::CodeGenerator::popRegisterFromStack
void popRegisterFromStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, const TCEString &dstReg)
Definition: CodeGenerator.cc:456
TTAProgram::CodeGenerator::loadTerminal
void loadTerminal(TTAProgram::CodeSnippet &dstProcedure, TTAProgram::Terminal *srcTerminal, TTAProgram::Terminal *dstTerminal)
Definition: CodeGenerator.cc:169
llvm::LLVMTCEBuilder::DataDef::addressSpaceId
unsigned addressSpaceId
Definition: LLVMTCEBuilder.hh:277
llvm::LLVMTCEBuilder::ConstantDataDef::address
unsigned address
Definition: LLVMTCEBuilder.hh:285
llvm::MachineDCE
Definition: MachineDCE.hh:66
llvm::LLVMTCEBuilder::symbolicPORefs_
std::set< TTAProgram::TerminalProgramOperation * > symbolicPORefs_
Definition: LLVMTCEBuilder.hh:497
TTAMachine::Machine::addressSpaceNavigator
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition: Machine.cc:392
llvm::LLVMTCEBuilder::currentFnCP_
std::map< unsigned, unsigned > currentFnCP_
Constant pool for the current machine function. Map key is constant pool index and the value is addre...
Definition: LLVMTCEBuilder.hh:476
TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST
@ ANN_ALLOWED_UNIT_DST
Dst. unit candidate.
Definition: ProgramAnnotation.hh:113
TTAMachine::ExecutionPipeline::OperandSet
std::set< int > OperandSet
Set for operand indexes.
Definition: ExecutionPipeline.hh:58
LLVMTCECmdLineOptions
Definition: LLVMTCECmdLineOptions.hh:48
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
TTAMachine::Port::isOutput
virtual bool isOutput() const
Definition: Port.cc:308
llvm::LLVMTCEBuilder::createMBBReference
virtual TTAProgram::Terminal * createMBBReference(const MachineOperand &mo)
Definition: LLVMTCEBuilder.cc:2288
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
llvm::LLVMTCEBuilder::emitReadSP
TTAProgram::Instruction * emitReadSP(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:3207
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
Operation
Definition: Operation.hh:59
TTAProgram::AnnotatedInstructionElement::hasAnnotations
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:165
TTAProgram::CodeGenerator::decrementStackPointer
void decrementStackPointer(TTAProgram::CodeSnippet &dstProcedure, const TCEString &spReg)
Definition: CodeGenerator.cc:423
PRegionMarkerAnalyzer::markersFound
bool markersFound() const
Definition: PRegionMarkerAnalyzer.cc:123
TTAProgram::Program::dataMemoryCount
int dataMemoryCount() const
Definition: Program.cc:942
llvm::LLVMTCEBuilder::data_
std::vector< DataDef > data_
Data definitions.
Definition: LLVMTCEBuilder.hh:443
TTAProgram::CodeSnippet
Definition: CodeSnippet.hh:59
TTAProgram::ProgramAnnotation::ANN_STACKUSE_RA_SAVE
@ ANN_STACKUSE_RA_SAVE
ra, new frontend
Definition: ProgramAnnotation.hh:90
TTAProgram::CodeGenerator::registerJump
void registerJump(TTAProgram::CodeSnippet &dstProcedure, const TCEString &jumpAddrReg)
Definition: CodeGenerator.cc:609
TTAProgram::TerminalFUPort
Definition: TerminalFUPort.hh:56
UniversalFunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: UniversalFunctionUnit.cc:85
llvm::LLVMTCEBuilder::createFUTerminal
virtual TTAProgram::Terminal * createFUTerminal(const MachineOperand &) const
Definition: LLVMTCEBuilder.hh:171
llvm::LLVMTCEBuilder::mbbReferences_
std::map< TTAProgram::TerminalInstructionAddress *, std::string > mbbReferences_
Dummy basic block references that have to be fixed after all basic blocks have been built.
Definition: LLVMTCEBuilder.hh:465
llvm::LLVMTCEBuilder::labeledPOs_
std::map< TCEString, ProgramOperationPtr > labeledPOs_
Definition: LLVMTCEBuilder.hh:499
ProgramOperation.hh
Operand.hh
TTAProgram::CodeGenerator::pushInstructionReferenceToStack
void pushInstructionReferenceToStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::InstructionReference &srcAddr)
Definition: CodeGenerator.cc:503
TTAProgram::TerminalProgramOperation::label
TCEString label() const
Definition: TerminalProgramOperation.hh:77
TTAProgram::TerminalProgramOperation::setProgramOperation
void setProgramOperation(ProgramOperationPtr po)
Definition: TerminalProgramOperation.hh:61
UniversalMachine::universalFunctionUnit
UniversalFunctionUnit & universalFunctionUnit() const
Definition: UniversalMachine.cc:205
llvm::LLVMTCEBuilder::dataEnds_
std::map< TTAMachine::AddressSpace *, unsigned > dataEnds_
The first position after the last data in the given address space.
Definition: LLVMTCEBuilder.hh:479
llvm::LLVMTCEBuilder::createProgramOperationReference
virtual TTAProgram::Terminal * createProgramOperationReference(const MachineOperand &mo)
Definition: LLVMTCEBuilder.cc:2260
TTAProgram::ProgramAnnotation::ANN_POINTER_NAME
@ ANN_POINTER_NAME
information retrieved (from LLVM) about a pointer access
Definition: ProgramAnnotation.hh:174
llvm::LLVMTCEBuilder::getHWOperation
const TTAMachine::HWOperation & getHWOperation(std::string opName)
Definition: LLVMTCEBuilder.cc:1288
TTAProgram::TerminalImmediate
Definition: TerminalImmediate.hh:44
TTAProgram::AnnotatedInstructionElement::annotation
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:100
Operation::operand
virtual Operand & operand(int id) const
Definition: Operation.cc:541
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
TTAProgram::AnnotatedInstructionElement::addAnnotation
void addAnnotation(const ProgramAnnotation &annotation)
Definition: AnnotatedInstructionElement.cc:63
TTAMachine::BaseRegisterFile::port
virtual RFPort * port(const std::string &name) const
Definition: BaseRegisterFile.cc:129
TerminalProgramOperation.hh
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
TTAProgram::CodeGenerator::loadFromRegisterAddress
void loadFromRegisterAddress(TTAProgram::CodeSnippet &dstProcedure, const TCEString &srcReg, const TCEString &dstReg)
Definition: CodeGenerator.cc:295
POMDisassembler::disassemble
static std::string disassemble(const TTAProgram::Move &move)
Definition: POMDisassembler.cc:629
TTAMachine::NullInstructionTemplate::instance
static NullInstructionTemplate & instance()
Definition: NullInstructionTemplate.cc:62
IGNORE_COMPILER_WARNING
#define IGNORE_COMPILER_WARNING(X)
Definition: CompilerWarnings.hh:51
llvm::LLVMTCEBuilder::doInitialization
bool doInitialization(Module &M)
Definition: LLVMTCEBuilder.cc:429
TTAProgram::TerminalRegister::registerFile
virtual const TTAMachine::RegisterFile & registerFile() const
Definition: TerminalRegister.cc:78
TTAProgram::Procedure::add
void add(Instruction *ins)
Definition: Procedure.cc:160
llvm::LLVMTCEBuilder::spDRegNum
virtual unsigned spDRegNum() const =0
LiveRangeData.hh
CodeGenerator.hh
TTAProgram::InstructionReferenceManager
Definition: InstructionReferenceManager.hh:82
TTAProgram::Program::instructionReferenceManager
InstructionReferenceManager & instructionReferenceManager() const
Definition: Program.cc:688
llvm::LLVMTCEBuilder::ConstantDataDef::value
const llvm::Constant * value
Definition: LLVMTCEBuilder.hh:288
llvm::LLVMTCEBuilder::padToAlignment
void padToAlignment(int addressSpaceId, unsigned &addr, unsigned align)
Definition: LLVMTCEBuilder.cc:917
llvm::LLVMTCEBuilder::POINTER_SIZE_64
static unsigned POINTER_SIZE_64
Definition: LLVMTCEBuilder.hh:423
llvm::LLVMTCEBuilder::hasAmbiguousASpaceRefs
bool hasAmbiguousASpaceRefs(const TTAProgram::Instruction &instr) const
Definition: LLVMTCEBuilder.cc:1259
TTAMachine::Guard::isInverted
virtual bool isInverted() const
TTAProgram::ProgramAnnotation::ANN_STACKUSE_SPILL
@ ANN_STACKUSE_SPILL
spilled variable
Definition: ProgramAnnotation.hh:89
llvm::LLVMTCEBuilder::runOnMachineFunction
bool runOnMachineFunction(MachineFunction &MF)
Definition: LLVMTCEBuilder.cc:947
Program.hh
TerminalImmediate.hh
TerminalAddress.hh
llvm::LLVMTCEBuilder::emitReturn
TTAProgram::Instruction * emitReturn(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:2530
llvm::LLVMTCEBuilder::addressSpaceById
TTAMachine::AddressSpace & addressSpaceById(unsigned id)
Definition: LLVMTCEBuilder.cc:3765
AssocTools.hh
llvm::LLVMTCEBuilder::ConstantDataDef
Data definition structure for constant pool values.
Definition: LLVMTCEBuilder.hh:284
PRegionMarkerAnalyzer::pregion
unsigned pregion(const llvm::MachineInstr &I) const
Definition: PRegionMarkerAnalyzer.cc:166
llvm::LLVMTCEBuilder::writeMachineFunction
virtual bool writeMachineFunction(MachineFunction &MF)
Definition: LLVMTCEBuilder.cc:959
InstructionReference.hh
TCEString
Definition: TCEString.hh:53
llvm::TCETargetMachine::registerIndex
unsigned registerIndex(unsigned dwarfRegNum) const
Definition: TCETargetMachine.hh:208
llvm::LLVMTCEBuilder::dmemIndex_
DataMemIndex dmemIndex_
Definition: LLVMTCEBuilder.hh:440
llvm::LLVMTCEBuilder::codeLabels_
std::map< std::string, TTAProgram::Instruction * > codeLabels_
Code labels.
Definition: LLVMTCEBuilder.hh:239
BasicBlock.hh
ControlUnit.hh
InlineAsmParser
Definition: InlineAsmParser.hh:64
POP_COMPILER_DIAGS
#define POP_COMPILER_DIAGS
Definition: CompilerWarnings.hh:68
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
SpecialRegisterPort.hh
TTAProgram::DataMemory::dataDefinition
DataDefinition & dataDefinition(Address address) const
Definition: DataMemory.cc:79
LLVMTCECmdLineOptions::printInlineAsmWarnings
bool printInlineAsmWarnings() const
Definition: LLVMTCECmdLineOptions.cc:446
TTAProgram::CodeGenerator
Definition: CodeGenerator.hh:53
InstructionReferenceManager.hh
llvm::LLVMTCEBuilder::pregions_
PRegionMarkerAnalyzer * pregions_
Definition: LLVMTCEBuilder.hh:259
llvm::TCETargetMachine
Definition: TCETargetMachine.hh:106
TTAMachine::HWOperation::pipeline
ExecutionPipeline * pipeline() const
Definition: HWOperation.cc:201
TTAProgram::Terminal
Definition: Terminal.hh:60
TTAProgram::Terminal::equals
virtual bool equals(const Terminal &other) const =0
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
llvm::LLVMTCEBuilder::setInitialStackPointerValue
void setInitialStackPointerValue(unsigned value)
Definition: LLVMTCEBuilder.cc:1240
llvm::LLVMTCEBuilder::debugDataToAnnotations
void debugDataToAnnotations(const llvm::MachineInstr *mi, TTAProgram::Move &move)
Definition: LLVMTCEBuilder.cc:2057
llvm::TCETargetMachine::stackAlignment
unsigned stackAlignment() const
Definition: TCETargetMachine.hh:277
TTAProgram::MoveGuard::copy
MoveGuard * copy() const
Definition: MoveGuard.cc:96
llvm::LLVMTCEBuilder::createFPDataDefinition
void createFPDataDefinition(int addressSpaceId, unsigned &addr, const llvm::ConstantFP *cfp)
Definition: LLVMTCEBuilder.cc:690
TTAProgram::Terminal::port
virtual const TTAMachine::Port & port() const
Definition: Terminal.cc:378
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
llvm::LLVMTCEBuilder::emitGlobalXXtructorCalls
TTAProgram::Instruction * emitGlobalXXtructorCalls(const MachineInstr *mi, TTAProgram::CodeSnippet *proc, bool constructors)
Definition: LLVMTCEBuilder.cc:3486
TTAMachine::PortGuard
Definition: Guard.hh:99
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
Operand::isAddress
virtual bool isAddress() const
Definition: Operand.cc:328
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
llvm::LLVMTCEBuilder::registerFileName
virtual TCEString registerFileName(unsigned llvmRegNum) const =0
TTAProgram::Terminal::setInstructionReference
virtual void setInstructionReference(InstructionReference ref)
Definition: Terminal.cc:404
TTAProgram::ProgramAnnotation
Definition: ProgramAnnotation.hh:49
TTAProgram::Program::globalScope
GlobalScope & globalScope()
Definition: Program.cc:180
llvm::MachineDCE::removeableFunctions
UnusedFunctionsList removeableFunctions
Definition: MachineDCE.hh:97
OperationPool
Definition: OperationPool.hh:52
TTAProgram::Instruction::movePtr
std::shared_ptr< Move > movePtr(int i) const
Definition: Instruction.cc:216
TTAProgram::DataMemory
Definition: DataMemory.hh:56
Move.hh
TTAMachine
Definition: Assembler.hh:48
llvm::LLVMTCEBuilder::addressSpaceId
unsigned addressSpaceId(TTAMachine::AddressSpace &aSpace) const
TTAProgram::Terminal::isRA
virtual bool isRA() const
Definition: Terminal.cc:129
MoveNode.hh
Operand::isInput
virtual bool isInput() const
Definition: Operand.cc:145
TTAProgram::DataInstructionAddressDef
Definition: DataInstructionAddressDef.hh:48
TTAProgram::Program::removeProcedure
void removeProcedure(Procedure &proc)
Definition: Program.cc:901
TTAProgram::MoveGuard
Definition: MoveGuard.hh:47
llvm::LLVMTCEBuilder::createDataDefinition
unsigned createDataDefinition(int addressSpaceId, unsigned &addr, const Constant *cv, bool forceInitialize=false, unsigned forceAlignment=0)
Definition: LLVMTCEBuilder.cc:519
debugLog
#define debugLog(text)
Definition: Application.hh:95
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
TTAProgram::ProgramAnnotation::ANN_POINTER_OFFSET
@ ANN_POINTER_OFFSET
Definition: ProgramAnnotation.hh:175
TTAProgram::TerminalProgramOperation
Definition: TerminalProgramOperation.hh:51
TTAProgram::InstructionReference
Definition: InstructionReference.hh:49
TTAProgram::TerminalSymbolReference
Definition: TerminalSymbolReference.hh:42
ProgramAnnotation.hh
TTAMachine::AddressSpace::start
virtual ULongWord start() const
Definition: AddressSpace.cc:166
TTAProgram::Program::procedure
Procedure & procedure(int index) const
Definition: Program.cc:622
TTAProgram::Procedure
Definition: Procedure.hh:55
OperationPool.hh
llvm::LLVMTCEBuilder::targetMachine
const TargetMachine & targetMachine() const
Definition: LLVMTCEBuilder.hh:157
llvm::LLVMTCEBuilder::deleteDeadProcedures
void deleteDeadProcedures()
Definition: LLVMTCEBuilder.cc:1197
Operation::numberOfOutputs
virtual int numberOfOutputs() const
Definition: Operation.cc:202
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
TTAMachine::AddressSpace::end
virtual ULongWord end() const
Definition: AddressSpace.cc:177
DataDefinition.hh
TTAProgram::CodeGenerator::pushToStack
void pushToStack(TTAProgram::CodeSnippet &dstProcedure, const TCEString &stackRegister, TTAProgram::Terminal *srcTerminal)
Definition: CodeGenerator.cc:474
llvm::LLVMTCEBuilder::emitRemaingingBrach
TTAProgram::Instruction * emitRemaingingBrach(TCEString opName, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:1765
CodeLabel.hh
llvm::LLVMTCEBuilder::initDataSections
void initDataSections()
Definition: LLVMTCEBuilder.cc:210
StringTools::stringToLower
static std::string stringToLower(const std::string &source)
Definition: StringTools.cc:160
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176
CompilerWarnings.hh
TTAProgram::TerminalRegister
Definition: TerminalRegister.hh:53
TTAProgram::ProgramAnnotation::payload
const std::vector< Byte > & payload() const
Definition: ProgramAnnotation.cc:121
MachineInfo::canEncodeImmediateInteger
static bool canEncodeImmediateInteger(const TTAMachine::Machine &mach, int64_t imm, unsigned destWidth=UINT_MAX)
Definition: MachineInfo.cc:444
LLVMTCEBuilder.hh
llvm::LLVMTCEBuilder::emitInlineAsm
TTAProgram::Instruction * emitInlineAsm(const MachineFunction &mf, const MachineInstr *mi, TTAProgram::BasicBlock *bb, TTAProgram::InstructionReferenceManager &irm)
Definition: LLVMTCEBuilder.cc:2786
TTAMachine::Machine
Definition: Machine.hh:73
llvm::LLVMTCEBuilder::isTTATarget
virtual bool isTTATarget() const
Definition: LLVMTCEBuilder.hh:132
TTAProgram::AnnotatedInstructionElement::annotationCount
int annotationCount(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:133
AssemblyParserDiagnostic::warnings
const std::set< CompilerMessage > & warnings() const
Definition: AssemblyParserDiagnostic.hh:78
llvm::LLVMTCEBuilder::mbbName
std::string mbbName(const MachineBasicBlock &mbb)
Definition: LLVMTCEBuilder.cc:2632
llvm::LLVMTCEBuilder::handleMemoryCategoryInfo
TTAProgram::Instruction * handleMemoryCategoryInfo(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
Definition: LLVMTCEBuilder.cc:3318
llvm::LLVMTCEBuilder::createMove
std::shared_ptr< TTAProgram::Move > createMove(const MachineOperand &src, const MachineOperand &dst, TTAProgram::MoveGuard *guard)
Definition: LLVMTCEBuilder.cc:2389
TTAProgram::ProgramAnnotation::ANN_CONN_CANDIDATE_UNIT_DST
@ ANN_CONN_CANDIDATE_UNIT_DST
Dst. unit candidate.
Definition: ProgramAnnotation.hh:116
MoveGuard.hh